[51单片机]移位操作符实现LED流水灯

如果我们想要实现流水灯的效果,首先我们需要先让八个LED灯进入初始化状态,然后再让每一个灯按照规律依次亮起来,我们的初始化状态是0xfe,换算成二进制也就是11111110(0为低电平点亮,1为高电平熄灭)先让最开始的一个灯亮起来,不然无法使用移位操作符。

#include<reg52.h>
main()
{
   P1=0xfe;
}

接下来我们创建一个while循环,在循环里面让0xfe左移一位,以此类推,但是最终会发现不能实现流水灯的效果,因为这个左移操作符会持续向左把1变为0,但是第一个零和接下来的0都保持不变,依次循环一轮后全部都变成了0,也就是所有的灯都被点亮了,这个时候再左移也无济于事(如图所示,√为1,空格为0)

#include<reg52.h>
main()
{
   P1=0xfe;
   while(1)
   {
      P1=P1<<1;
   }
}

这个时候我们再次明确一下思路,我们需要做到的是:先让一个灯亮,然后按顺序依次点亮,点亮下一个的时候,把上一个熄灭,依次类推。那我们如何实现熄灭上一个呢?

我们采用逻辑门“或”,|的规则是有1为1,全0为0,11111100(0xfd)和00000001(0x01)做比或门运算得到11111101,你们可以试着在纸上写一下,很清楚。

main()
{
	P1 = 0xfe;
	while (1)
	{
		P1 = P1 << 1;
		P1 = P1 | 0x01;
	}
}

这个时候可以发现,刚开始的LED一直会微微亮,这是因为左移操作符移位和“或”门时间会有差异,左移的时候为0,再被“或”为1,那么我们怎么解决这个?我们可以巧妙的用一个变量来代替P1,因为这些都只是对一串二进制数进行赋值,移位,逻辑门。并且移位和逻辑门目的都是为了变换,所以可以用变量达到效果(如图所示)。

main()
{
	int j;
	P1 = j  0xfe;
	while (1)
	{
		j = j << 1;
		j = j | 0x01;
        P1 = j;
	}
}

根据上面的while循环,因为逻辑门的原因,最后会使所有的二进制数都变为1,移位不再起作用,我们就使用一个if判断语句来判断,如果P1等于全1,就跳出循环。

main()
{
	int j;
	P1 = j  0xfe;
	while (1)
	{
		j = j << 1;
		j = j | 0x01;
        P1 = j;
        if(P1 == 0xff)
		{
			break;
		}
	}
}

最后我们可以加上亿点适当的时间延迟,来让流水灯更加美观。

#include<reg52.h>
time()
{
	unsigned int i;
	for(i=0;i<10000;i++);
}
main()
{
	int j;
	P1=0xfe;
	time();
	while(1)
	{
		P1=P1<<1;
		P1=P1|0x01;
		time();
    if(P1 == 0xff)
		{
			break;
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值