一、项目结构
主函数main.c
二、main.c代码:
#include <REGX52.H> //51单片机相关函数、引脚定义的头文件
#include <INTRINS.H> //对应于_nop_()函数的头文件
void Delay500ms() //定义了一个函数,调用这个函数可以延时500ms执行下一行程序
{
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(); //延时500ms
P2=0xFF; //1111 1111 第八个灯灭
Delay500ms(); //延时500ms
}
}
逻辑比较简单,亮-等待-闪烁
三、逐步推演:
1、下面的代码可以实现LED亮一下大概一微秒
但是点亮时间太短,分辨不出时亮了还是没亮。
如果可以一直亮就可以看出来了。
#include <REGX52.H> //51单片机相关函数、引脚定义的头文件
void main() //主函数
{
P2=0xFE; //1111 1110 第八个灯亮
}
但是点亮时间太短,分辨不出时亮了还是没亮。
如果可以一直亮就可以看出来了。
2、下面的代码可以实现LED灯一直亮 while()语句(C语言的内容):反复 执行while里边的语句
#include <REGX52.H>
void main()
{
while(1)
{
P2=0xFE; //1111 1110
}
}
但是,目的是闪烁,我们还需要亮灭交替才能达到闪烁的效果。
3、下边的代码可以实现LED灯亮灭交替。
#include <REGX52.H>
void main()
{
while(1)
{
P2=0xFE; //1111 1110
P2=0xFF; //1111 1111
}
}
但是,单片机执行程序语句的速度远远快于肉眼识别的速度,视觉暂留效应视觉暂留_百度百科
把LED点亮与熄灭之间的时间间隔拉长一些,达到肉眼可分辨的范围内就可以看到明显的闪烁。
4、下边的函数可以实现延时功能,延时500毫秒。C语言函数的调用C语言函数的调用 - C语言教程 - C语言网
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 205;
k = 187;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
因为该函数中存调用了一个REGX52.H头文件库里没包含的函数_nop_,所以需要在开头把这个头文件添加进来#include <INTRINS.H>
5、添加头文件、调用延时函数,就是完整的LED闪烁代码了。
四、总结
视觉暂留问题的两种解决办法
(1)while()循环,适合需要持续观察单片机是否工作,或需要周期性进行的工作。
(2)Delay()函数,适合需要摁下暂停键才能出现效果的情况。Delay函数的生成可以使用烧录软件中自带的插件生成,也可以使用自定义函数(下一节讲)。