【单片机】05灯闪

文章讲述了如何在单片机中通过C语言编程实现LED灯闪烁的效果。初始代码由于灯亮和灯灭间隔时间过短导致肉眼无法察觉闪烁,通过添加延时循环解决了这个问题。接着,通过位操作对特定LED进行控制,简化了代码,最后介绍了使用位取反操作进一步优化程序,实现灯状态的切换,同时讨论了对不支持位操作的寄存器的处理方法。
摘要由CSDN通过智能技术生成
#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++);  //延时
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值