LED闪烁

前言:
前一篇学会了点亮一颗LED以及驱动原理,那么这篇紧接着就来解锁LED的新功能,LED闪烁。当然这里指的闪烁,前提是基于肉眼余晖可见光达成的效果。

1、硬件电路设计和原理分析

开发板上 LED 模块电路原理图如下图所示:
在这里插入图片描述
看上图中 LED 采用共阳接法,D1-D8 连接到单片机的 P20-P27 口,即所有LED 阳极管脚接电源 VCC,阴极管脚通过一个 470 欧的限流电阻接到 P2 口上。
原理分析
根据前面篇章 点亮一颗LED 的介绍我们知道,要让 LED 发光即对应的阴极管脚应该为低电平,若为高电平则熄灭。
所以如果要想 51 单片机控制 LED实现亮灭闪烁的效果,就必须通过单片机管脚在 P2 口上反复的输出低电平或高电平,其次MCU执行程序语句都会有一定的时间,为了达到人肉眼的余晖效应,因此只需编写一个循环函数,让CPU 不干其它事,专门在那循环运行即可实现延时功能。

2、软件设计

2.1、功能实现:LED闪烁

//实验现象:下载程序后开发板的“LED 模块”D1 指示灯闪烁
/**/
#include "reg52.h"

typedef unsigned int u16;//对系统默认数据类型进行重命名

sbit LED1 = P2^0;//将 P2.0 管脚定义为 LED1

//实现延时功能
void delay_10us(u16 ten_us)//大约延时 10us,可通过访问进行初略计算得到编译所用的时间
{
	while(ten_us--);//作减减的运算占用编译时间达到延时的作用,但是这里的延时是实际编译估算的延时时间,不准确
}

void main()
{
	while(1)//循环亮灭,实现人肉眼可见的“一亮一灭”(20~50ms)
	{
		LED1 = 0;//LED1 端口设置为0低电平,从而点亮一颗led
		delay_10us(50000);//大约延时450ms,实现亮一会儿
		LED1 = 1;//LED1 端口设置为1高电平,从而熄灭一颗led
		delay_10us(50000);//大约延时450ms,实现灭一会儿
	}
}

解释说明
(1)、上述delay_10us函数的即为延时函数,主要通过 while 循环来实现延时效果。函数入口有一个形式参数ten_us,如果 ten_us 等于 1,则 while 循环执行一次,调用该函数执行一次延时时间大约 10us,目前没学定时器不够精确,不过能够满足人的肉眼余晖就行。
(2)、函数名的命名规则建议具备一定的含义,不可随意定义,比如delay_10us表示这个延时函数执行一次大约为10us,参数ten_us表示传参填写的是单位为us的数据,因为只需要执行延时不需要返回值,所以是void。
其次,参数的u16原型是unsigned int 因为相较之下比较繁琐,当程序量较多时,通常就采用此方式,使得程序简洁便捷,后续的程序中遇见此自定义的重命名类型,如:typedef unsigned char u8;等等,均同理。
值得注意的是:unsigned int具体占几个字节,由编译器决定,keil5是2个字节。根据参数类型就能够知道参数的传参范围,不能超过形参定义的范围。
如下表所示:

数据类型编译环境位数取值范围
unsigned int160 ~ 65535
unsigned int320 ~ 4294967295

(3)、最后主函数,main 函数内实现功能很简单,在 while 循环内,循环利用delay_10us( )函数间隔一定时间点亮 LED1和熄灭 LED1,这样即可实现 D1口 LED闪烁
当然我们发现。延时函数的参数写的50000,那么应该为500ms的延时时间才对,那么为什么实际大约在450ms呢?
解释说明
a、首先,50000这个参数呢是灵活的,因人而异,参数的大小是根据自己调试得出比较合适的闪烁效果,如果觉得闪烁太快参数就可以大一点(前提是符合u16的范围),觉得闪烁太慢参数就调小一点,最终得到的50000较为合适。
b、然后,为何实际延时大约为450ms呢?我们不妨直接使用调试功能一步步看。

2.2、通过 KEIL 软件自带仿真查看延时时间

首先,可以通过打开 KEIL 自带的软件仿真功能,操作如下:
**①打开实验工程,点击魔术棒,选择“Target”选项卡,在 Xtal(MHz)文本框中输入 12M,该值表示开发板上实际使用外部晶振大小,如果开发板上使用外部晶振是 11.0592M,则修改为对应值。**然后点击 OK。
在这里插入图片描述
②点击仿真按钮或组合快捷键Ctrl + F5,进入仿真界面,如下所示
在这里插入图片描述
③点击 RST 按钮,重新复位系统参数,此时参数列表中 sec(second 单位秒的意思) 则为 0,然后在所要查看调试的代码数字前面用鼠标左键双击即可出现“红色块”,我们称之为断点。如果再次双击,即可取消该断点。当点击红色标记 8 处运行的时候就能直接运行到我们设置的断点处。
在这里插入图片描述
④当点击红色标记 8 运行时,可以看到黄色箭头直接定位到 36 行代码,也就是我们刚才设置的第一个断点位置,此时参数列表中 sec 时间是 0.00039s。
在这里插入图片描述
⑤再次点击红色标记 8 运行时,此时黄色箭头指向第 37 行代码,此时 sec为 0.450601s。
在这里插入图片描述
最后,将现在这个时间减去上一步的 sec 时间就可以得到 delay_10us(50000)运行的实际时间大约为450ms了。再次点击仿真按钮则可退出仿真界面,回到程序编辑界面。

4、编译结果

至此,整个程序就编写完成,我们编译一下,如下图所示
在这里插入图片描述
从上图编译信息可以看出,我们的代码占用FLASH 大小为:code = 46 字节,所用的 SRAM 大小为:data = 9 个字节(9.0),xdata指是扩展的外部存储XSRAM所占的大小,并没有使用XSRAM所以为0。
硬件实验效果如图所示

C51基础实验 LED闪烁文章附件

5、结束语

写这篇文章记录作为自己学习的笔记,笔者水平有限,希望有错误的地方还请多多指教,各抒己见交流学习,同时希望笔者的内容有帮助到你。如果有所帮助还请点点赞,表示支持哦。最后感谢各位的阅读(不喜勿喷)。

更多推荐