点亮LED以后,如果我们想实现LED间隔性的亮灭,我们又该怎么办呢?这里我们就需要使用单片机进行延时。延时的方法有两种,一个是使用软件延时,这个不精确,但能满足简单的需要;二是使用单片机内部的定时器,这个很精确,可以精确到微秒级。在这里,我们讨论一下如何使用软件延时。
我们知道,单片机执行每一条代码都需要时间,那么如果我们重复让单片机执行某些指令,就可以“拖住”单片机,让它去干其他的事情,从而实现延时的效果。例如以下代码:
#include <REGX52.H>
#define uint unsigned int
sbit led1 = P2^0;
uint i,j;
void main(void)
{
while(1)
{
led1 = 0; //点亮LED1
for(i=1000; i>0; i--) //延时
for(j=110; j>0; j--);
led1 = 1; //关闭LED1
for(i=1000; i>0; i--) //延时
for(j=110; j>0; j--);
}
}
以上程序,可以实现LED的一亮一灭,达到闪烁的效果。但是,延时的时间究竟是多少呢?我们该如何计算2层嵌套for语句执行的时间呢?
其实,我们可以使用Keil软件进行仿真,从而对延时语句进行精确的计算。
接下来,我们对源代码进行编译,并进入软件模拟调试模式。
成功编译通过
进入软件模拟调试模式,这里可以单行执行语句,并观察寄存器、变量以及硬件I/O口的变化。此时的sec = 0.00042209 s。这是程序启动执行到目前位置所花的累计时间。
设置断点(断点处即下一步要执行的指令),点击全速运行(Run, F5)。
停在断点处,即将执行延时语句。此时从程序开始,累积时间为0.00042318 s。
此时,延时语句已经执行完毕,时间来到0.96831272 s。进行简单的数学计算,延时语句执行,耗费了0.96831272 - 0.00042318 = 0.96788954 s = 967.88954 ms。大约1s的时间。
这里有个经验,只要变量i, j是unsigned int 类型,并且j = 110不变,那么i的值为多少就代表延时约多少毫秒。
在实际的编程中,为了效率和方便,可以将延时语句写成一个带参函数类型,从而能实现我们想要的延时效果。源代码如下:
void delay_xms(unsigned int xms)
{
uint i, j;
for(i=xms; i>0; i--)
for(j=110; j>0; j--);
}
全部源代码如下:
#include <REGX52.H>
#define uint unsigned int
sbit led1 = P2^0;
void delay_xms(unsigned int);
void main(void)
{
while(1)
{
led1 = 0; //点亮LED1
delay_xms(1000);
led1 = 1; //关闭LED1
delay_xms(1000);
}
}
void delay_xms(unsigned int xms)
{
uint i, j;
for(i=xms; i>0; i--)
for(j=110; j>0; j--);
}