01-51单片机LED与独立按键

一、单片机概述

注意:个人学习笔记,里面涉及到的C语言和进程转换相关的知识在C语言部分已经写了,这里是默认都会的状态学习单片机。

1.什么是单片机

单片机,英文Micro Controller Unit,简称MCU。其内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能。

我们可以依靠单片机的传感器采集相应的数据,可以通过 CPU 处理数据,还可以完成对硬件设备,如:LED,蜂鸣器,电机等的控制。

  • 单片机相当于一台微型计算机,相比于我们平时使用的电脑,有优势也有劣势:
    • 缺点:在性能上,与计算机相差甚远,处理数据的能力要远低于计算机;
    • 优点:单片机成本低、体积小、结构简单,有其适用的领域,比如智能家居、工业自动化控制等。并不一定说性能越高的就越好,要看起使用需求,合适的才是最好的。

2. 51单片机简介

2.1命名规范

在这里插入图片描述

2.2笔记使用单片机配置

本笔记学习使用的是普中科技 STC89C52RC 的开发板。

  • 系列:51单片机系列
  • 公司:STC公司
  • 位数:8位
  • RAM:512字节,理解为电脑内存条,断电丢失
  • ROM:8K(Flash),理解为电脑磁盘,断电不丢失
  • 工作频率:12MHz

二、LED 模块

1.认识LED

LED:发光二极管,外文名(Light Emitting Diode),用于:照明、广告灯、指引灯、屏幕等。

LED 具有单向导电性,即电流只能从正极流向负极,引脚较长的一端为正极,引脚较短的一端为负极。

2.单片机中 LED 模块电路图

在这里插入图片描述

  • 说明:
    1. LED 的电路图可以看出,这是一个共阳极电路,我们需要通过芯片从另外一端(阴极)控制 LED 的亮灭,串联的电阻用于限流,防止烧坏 LED;
    2. 单片机里用 1 表示高电平(简单理解为给电),0 表示低电平(不给电),当我们给阴极赋 1 的的时候,两边都给电,没有压差,没有电势差,无法形成电流, LED 就无法点亮,因此这里给阴极赋 0 就可以点亮对应的LED;
    3. 而芯片控制 LED 对应线路的方式,单片机的芯片引出一定数目的引脚,此单片机 40 引脚,分为几组(也有独立的),8个引脚为一组,正好一字节数据也是 8 位。一组一个寄存器,一个寄存器分为 8 个,每个就是一个驱动器。我们通过代码的一字节数据,给对应位赋 0 ,其它位赋 1 ,就能点亮我们想要点亮的 LED 灯泡了;
    4. 上图可以看到,每条线路对应了一个编号,如 P21 ,这里的 p2 就代表了使用 P2 号锁存器来控制 LED ,后面的 1 对应的是锁存器的其中一个位选段,具体到驱动几号 LED。

3. LED 实验

3.1点亮一颗 LED

  • 代码演示
#include <REGX52.H>void main()
{P2=0xFE; // 1111 1110while(1);
}
  • 说明:

    1. 上面的演示效果,是点亮了电路图中的 D1 号 LED;
    2. 在分析每位二进制的时候,对应的 LED 灯泡从 D1 ~ D8 分别对应二进制中的由低位到高位,代码里面显示的从右往左依次是低位到高位,但是C语言里面没有二进制类型,依次通过十六进制表示;
    3. 要想通过C语言调用对应的寄存器和驱动器,需要包含头文件#include <REGX52.H>
    4. 单片机里程序运行结束不会直接停止,而是会反复去执行,因此下面放一个死循环,防止反复执行,减小 CPU 占用,但是实现效果上是没有区别的。
  • 点亮指定多颗 LED

#include <REGX52.H>void main()
{P2=0xAA; // 1010 1010while(1);
}
  • 说明:上面的代码点亮了,D1 3 5 7 四颗 LED。

3.2 LED 闪烁

  • 代码演示
#include <REGX52.H>
#include <INTRINS.H> // _nop_需要的头文件void Delay500ms()		//@12.000MHz
{unsigned char i, j, k;_nop_();i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);
}void main()
{while(1){P2=0xFE; // 1111 1110 亮Delay500ms(); // 延时500msP2=0xFF; // 1111 1111 灭Delay500ms();}
}
  • 说明:
    1. 上面的演示效果,是实现了 D1 LED 每 0.5 秒闪烁一次的效果;
    2. 上面的延时函数可直接通过软件 STC-ISP 软件的延时计算器生成,需要包含头文件#include <INTRINS.H>
    3. 这里实现原理很简单,即先点亮,过 0.5s 熄灭,再过 0.5s 点亮,通过 while 实现循环。

3.3 LED 流水灯

  • 代码演示
#include <REGX52.H>
#include <INTRINS.H>// 自定义延时多少毫秒
void Delayxms(unsigned int xms)		//@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main()
{// 定义变量,保存延时的毫秒数unsigned int time_ms = 500;while(1){P2=0xFE; // 1111 1110Delayxms(time_ms);P2=0xFD; // 1111 1101Delayxms(time_ms);P2=0xFB; // 1111 1011Delayxms(time_ms);P2=0xF7; // 1111 0111Delayxms(time_ms);P2=0xEF; // 1110 1111Delayxms(time_ms);P2=0xDF; // 1101 1111Delayxms(time_ms);P2=0xBF; // 1011 1111Delayxms(time_ms);P2=0x7F; // 0111 1111Delayxms(time_ms);}
}
  • 说明:
    1. 代码运行结果,会从 D1 ~ D8 号 LED 依次点亮 0.5s ,如此循环;
    2. 和上面闪烁原理一样,只不过交替闪烁而已,需要计算出每个 LED 点亮对应的十六进制码就行了;
    3. 这里实现了自定义点亮时间,即先生成一个一毫秒的延时函数,然后在延时函数里放一个 while 循环,将延时函数函数体放到循环里面,要延时多少毫秒,就循环多少遍函数体即可;
    4. 需要注意的是,在单片机里,int 类型占16位,2字节。

三、按键控制 LED

1.认识独立按键模块

1.1独立按键介绍

  • 按键的结构实物图

在这里插入图片描述

如图右边,按键的底部有四个引脚,左边两个是接通的,右边两个是接通的,左右两边不接通,当我们按下的时候,左图所示的金属弹片会将左右接通,因此按下的时候,四个引脚都是接通的。

1.2独立按键电路图

在这里插入图片描述

  • 说明:
    1. 如图所示,这里的独立按键是一个共阴极电路;
    2. 前面讲到的寄存器,除了可以将指令发送到 IO 口控制 LED 的亮灭,还能读取线路中的高低电平状态返回到 IO 口;
    3. 因此,按键按下的时候,和 GND 接通,回馈信号为 0 ,松开按键,回馈信号为1;
    4. 这里使用的是 P3 锁存器,1 ~ 4 位选段。

2.按键实验

2.1按键控制 LED 亮灭

  • 代码演示
#include <REGX52.H>void main()
{while(1){// 按键按下回馈信号为0,反之为1if(P3_1==0)P2_0=0;elseP2_0=1;}
}
  • 说明:
    1. 运行效果:按键 K1 按下的时候,LED 亮起,松开 LED 熄灭;
    2. 除了上面 LED 实验里,一次性对一个段的 8 位进行操作以外,也能单独对某一位进行操作。

2.2按键控制 LED 状态

2.2.1按键抖动

前面提到的按键里面的金属弹片,按键按下的时候,弹片会将左右引脚接通,但是机械触点也会产生振动,虽然这振动对于宏观世界而言无关紧要。但从微观来看,机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动,如下图:

在这里插入图片描述

因此,在按键按下和松开的时候,各设置一个延时函数消抖即可。

2.2.2按键点亮 LED
  • 代码演示
#include <REGX52.H>
#include <INTRINS.H>void Delayxms(unsigned int xms)		//@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main()
{while(1){if(P3_1 == 0){// 延时为了消除按键抖动Delayxms(20);// 如果按键不松开就一直循环while(P3_1 == 0);Delayxms(20);// 这一次值为上一次的取反,即上一次灭,这一次就亮P2_0 =~ P2_0;}}}
  • 说明:
    1. 上面代码运行的效果:按下松开, LED 点亮,再次按下松开,LED 熄灭;
    2. 在按下和松开的瞬间各设置一个延时消抖,如果按下没有松开,通过一个 while 循环阻塞,直到松开按键,循环解阻塞;
    3. 当前 LED 的亮灭状态为按键前的取反,即按键前是亮,则按下后是灭,按下前是灭,按下后是亮。

2.3按键控制 LED 以二进制显示

  • 代码演示
#include <REGX52.H>
#include <INTRINS.H>void Delayxms(unsigned int xms)		//@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main()
{unsigned char LEDNum = 0;while(1){if(P3_1 == 0){Delayxms(20);while(P3_1 == 0);Delayxms(20);LEDNum++;P2 = ~LEDNum;}}}
  • 说明:
    1. 上面代码的运行效果:每按下一次按键,LED 就以二进制数值递增的方式显示;
    2. 定义一个局部变量,用于存放每个 LED 的高低电平状态,每按键一次,对变量 +1 ;
    3. 因为 LED 模块是共阳极电路,因此给 0 LED 才亮,因此对局部变量按位取反,实现真正的效果。

2.4按键控制 LED 左右移动

  • 代码演示
#include <REGX52.H>
#include <INTRINS.H>void Delayxms(unsigned int xms)		//@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main()
{unsigned char LEDNum = 0;P2=~0x01; // led默认开始在第一个while(1){// 实现灯号递增移动if(P3_1 == 0){Delayxms(20);while(P3_1 == 0);Delayxms(20);LEDNum++;if(LEDNum >= 8)LEDNum = 0;P2 = ~(0x01<<LEDNum);}// 实现灯号递减少移动if(P3_0 == 0){Delayxms(20);while(P3_0 == 0);Delayxms(20);if(LEDNum == 0)LEDNum = 7;LEDNum--;P2 = ~(0x01<<LEDNum);}}
}
  • 说明:
    1. 运行结果:点按 K1 按键, LED 从低位向高位,每按键一次,移动一个;
    2. 点按 K2 按键,LED 从高位向低位,每按键一次,移动一个;
    3. 这里设置 LED 默认点亮 D1 号,定义一个变量用于保存下一次按键点亮 LED 的偏移量,通过左移右移实现每按键一次,左移或右移一个 LED ;
    4. 同时判断,移动范围,低位到高位移动,最大偏移量为 7 ,当超过 7 的时候复位到最低位 LED ;同理由高位到低位移动,最低位偏移量为0,先判断为 0,复位到最高位 LED,如此循环实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音视频入门基础:MPEG2-PS专题(6)——FFmpeg源码中,获取PS流的视频信息的实现

音视频入门基础&#xff1a;MPEG2-PS专题系列文章&#xff1a; 音视频入门基础&#xff1a;MPEG2-PS专题&#xff08;1&#xff09;——MPEG2-PS官方文档下载 音视频入门基础&#xff1a;MPEG2-PS专题&#xff08;2&#xff09;——使用FFmpeg命令生成ps文件 音视频入门基础…

【网络协议】静态路由详解

网络中的路由器通过以下两种方式之一发现远程网络&#xff1a; 静态配置路由动态路由协议 在本文&#xff0c;我们将学习关于静态路由的各种概念&#xff0c;例如如何配置静态路由、路由表如何进行决策、路由接口等相关知识。 文章目录 引言直连网络静态路由路由表原则原则1原…

Dependency check 通过Maven构建时,配置Mysql数据库遇到的三个坑

使用过Dependency check的同学&#xff0c;一定会遇到这个问题—— 每次执行依赖扫描时&#xff0c;由于网络问题会导致NVD下载种子数据的过程中的种种失败&#xff0c;不仅浪费了大量时间&#xff0c;还会因为下载文件的不完整性直接导致依赖检测的失败。所以我在使用Dependen…

【面试题】技术场景 5、日志采集ELK

日志采集的重要性与采集方式 重要性&#xff1a;在项目开发、测试及生产环境中&#xff0c;日志是定位系统问题的关键手段&#xff0c;对系统维护与问题排查至关重要。采集方式 常规采集&#xff1a;按天保存日志文件至专门目录&#xff0c;文件名包含项目名、端口及日期&…

【数据库】三、SQL语言

文章目录 三、SQL语言1 概述2 数据定义(DDL)2.1 定义数据库2.2 定义基本表2.3 修改基本表2.4 删除基本表 3 数据操作(DML)3.1 数据查询3.1.1 单表查询3.1.2 连接查询3.1.3 嵌套查询3.1.4 集合查询 3.2 数据更新3.2.1 插入数据3.2.2 修改数据3.2.3 删除数据 4 数据控制(DCL)5 视…

Unity中 Xlua使用整理(二)

1.Xlua的配置应用 xLua所有的配置都支持三种方式&#xff1a;打标签&#xff1b;静态列表&#xff1b;动态列表。配置要求&#xff1a; 列表方式均必须是static的字段/属性 列表方式均必须放到一个static类 建议不用标签方式 建议列表方式配置放Editor目录&#xff08;如果是H…

Python Matplotlib教程-Matplotlib 多子图布局

Python Matplotlib 多子图布局 Matplotlib 是 Python 中最常用的数据可视化库&#xff0c;它提供了强大的功能来绘制不同类型的图表。在实际应用中&#xff0c;通常需要将多个图表绘制在同一个画布上&#xff0c;这就需要用到 多子图布局。本篇文章将详细介绍如何使用 Matplot…

全方位解读消息队列:原理、优势、实例与实践要点

全方位解读消息队列&#xff1a;原理、优势、实例与实践要点 一、消息队列基础认知 在数字化转型浪潮下&#xff0c;分布式系统架构愈发复杂&#xff0c;消息队列成为其中关键一环。不妨把消息队列想象成一个超级“信息驿站”&#xff0c;在古代&#xff0c;各地的信件、物资运…

Photon最新版本PUN 2.29 PREE,在无网的局域网下,无法连接自己搭建的本地服务器

1.图1为官方解答 2.就是加上这一段段代码&#xff1a;PhotonNetwork.NetworkingClient.SerializationProtocol SerializationProtocol.GpBinaryV16; 完美解决 unity 商店最新PUN 2 插件 不能连接 &#xff08;环境为&#xff1a;本地局域网 无外网情况 &#xff09; …

消息中间件类型介绍

消息中间件是一种在分布式系统中用于实现消息传递的软件架构模式。它能够在不同的系统或应用之间异步地传输数据&#xff0c;实现系统的解耦、提高系统的可扩展性和可靠性。以下是几种常见的消息中间件类型及其介绍&#xff1a; 1.RabbitMQ 特点&#xff1a; • 基于AMQP&#…

51单片机(二)中断系统与外部中断实验

中断即单片机因为某些原因E暂定现在的工作P0&#xff0c;转去做其他的工作P1&#xff0c;完了之后继续之前的事P0&#xff0c;其他工作P1就是中断程序&#xff0c;原因E就是中断事件&#xff0c;原因由外部发生&#xff0c;程序不能预测到的是硬中断&#xff0c;可以由程度触发…

python-42-使用selenium-wire爬取微信公众号下的所有文章列表

文章目录 1 seleniumwire1.1 selenium-wire简介1.2 获取请求和响应信息2 操作2.1 自动获取token和cookie和agent2.3 获取所有清单3 异常解决3.1 请求url失败的问题3.2 访问链接不安全的问题4 参考附录1 seleniumwire Selenium WebDriver本身并不直接提供获取HTTP请求头(header…

汽车信息安全 -- S32K1如何更新BOOT_MAC

目录 1.安全启动模式回顾 2.为什么要讨论BOOT_MAC 3.S32K1如何更新? 1.安全启动模式回顾 之前提到过,S32K1系列提供了Crypto Service Engine硬件加密模块(简称CSEc),大家可以通过该芯片系统寄存器SDID.FEATURES(System Device Identification Register)来判断自己的片子…

【Python】Python与C的区别

文章目录 语句结束符代码块表示变量声明函数定义注释格式Python的标识符数据输入input()函数数据输出print()函数 语句结束符 C 语言 C 语言中每条语句必须以分号;结束。例如&#xff0c;int a 10;、printf("Hello, World!");。分号是语句的一部分&#xff0c;用于…

理解Unity脚本编译过程:程序集

https://docs.unity3d.com/Manual/script-compilation.html 关于Unity C#脚本编译的细节&#xff0c;其中一个比较重要的知识点就是如何自定义Assembly。 预定义的assembly 默认情况下&#xff0c;Unity会按照这个规则进行编译。 PhaseAssembly nameScript files1Assembly-…

Linux内核TTY子系统有什么(6)

接前一篇文章&#xff1a;Linux内核TTY子系统有什么&#xff08;5&#xff09; 本文内容参考&#xff1a; Linux TTY子系统框架-CSDN博客 一文彻底讲清Linux tty子系统架构及编程实例-CSDN博客 linux TTY子系统(3) - tty driver_sys tty device driver-CSDN博客 Linux TTY …

《代码随想录》Day31打卡!

《代码随想录》贪心算法&#xff1a;合并区间 本题的完整题目如下所示&#xff1a; 本题的完整思路如下所示&#xff1a; 1.本题依然是先对数组的左边界进行排序。将数组的第一个元素赋值给current。 2.遍历数组&#xff0c;判断current中的右边界和当前元素的左边界是否有重叠…

KL 散度:多维度解读概率分布间的隐秘 “距离”

深入理解KL散度&#xff1a;从多维度全面剖析 损失函数相关文章&#xff08;置顶&#xff09; 1. KL 散度&#xff1a;多维度解读概率分布间的隐秘 “距离” 2. 熵与交叉熵&#xff1a;从不确定性角度理解 KL 散度 3. 机器学习、深度学习关于熵你所需要知道的一切 引言 KL散即…

node-sass@4.14.1报错的最终解决方案分享

输入npm i全安装文件所需的依赖的时候&#xff0c;博主是使用sass去书写的&#xff0c;使用的是node-sass4.14.1和sass-loader7.3.1的版本的&#xff0c;安装的时候老是出现错误&#xff0c; node-sass4.14.1版本不再被支持的原因 node-sass 是一个基于 LibSass 的 Node.js 绑…