#include <reg51.h>
void main
{
while(1)
{
P1=0; //灯亮
P1=1; //灯灭
}
}
有同学使用这个方法,发现灯是常亮,没有闪烁,原因是在该代码中灯亮后就立马执行灯灭,CPU执行灯亮或灯灭的语句只需要几微秒的时间,也就是灯亮、灯灭的频率太快了,眼睛来不及反应,所以看着是常亮的状态,要改变这个现象我们要在灯亮和灯灭后延时一段时间,延时我们可以用CPU循环执行空语句很多次就行了,加上延时语句后代码如下:
#include <reg51.h>
void main()
{
int i;
while(1)
{
P1=0; //灯亮
for(i=0;i<=10000;i++); //延时
P1=1; //灯灭
for(i=0;i<=10000;i++); //延时
}
}
我们将以上代码编译下载到单片机中并运行,发现接在P1口的第0脚上的LED闪烁,实验成功。但我们要是把8个LED等接到P1口上,我们发现所有LED都闪烁,我们只需要一盏LED灯闪烁,其他灯不闪烁,让怎么办呢?我们可以利用上次的内容,从两个方面
改进,一个是直接定义位,对位赋值。代码如下:
#include <reg51.h>
sbit LED=P1^0;
void main()
{
int i;
while(1)
{
LED=0; //灯亮
for(i=0;i<=10000;i++); //延时
LED=1; //灯灭
for(i=0;i<=10000;i++); //延时
}
}
这里还可以进一步简化程序,我们发现“LED=0;”和“LED=1;”是相反的两条语句,我们可以利用“~”位取反操作符直接对指定的位取反,上面的灯闪实验可以改写成如下代码:
#include <reg51.h>
sbit LED=P1^0;
void main()
{
int i;
while(1)
{
LED=~LED;
for(i=0;i<=10000;i++); //延时
}
}
正如上次课说的,有的寄存器不支持按位赋值,那上面的代码就不可行,我们可以使用上次课的方法,将代码改写如下:
#include <reg51.h>
sbit LED=P1^0;
void main()
{
int i;
while(1)
{
P1 &=~(1<<0);//灯亮
for(i=0;i<=10000;i++);
P1 |=(1<<0);//灯灭
for(i=0;i<=10000;i++);
}
}
xxxx xxx1 0000 0001
&1111 1110
xxxx xxx0 不管最右边的是0还是1,都要把它变为0
其实灯亮灯灭刚好是两个相反的过程,我们可以直接使用让灯取反操作就行了,其他位不变的语句就行了,可以简化代码如下:
#include <reg51.h>
void main()
{
int i;
while(1)
{
P1^=(1<<0); //灯状态取反
for(i=0;i<=10000;i++); //延时
}
}