单片机学习笔记---独立按键控制LED显示二进制

这节我们来实现独立按键的第三个功能,独立按键控制LED显示二进制

新创建一个工程文件,然后上来我们就要把基本框架写好,这是基本的习惯

老规矩,然后把Delay 1ms的代码复制过来

复制过来后改造一下:

把1ms删掉,然后给Delay函数传个参数unsigned int xms

把延时1ms的那段代码移到一个while(xms--)里面

Delay函数定义后之后,先写程序点亮测试一下

编译无错误下载程序,重启板子看看效果

点亮

延时500ms

灭掉

延时500ms

此时它正在以1秒为周期闪烁,证明程序写的没错

把测试程序的这段代码删掉

换成上一节的按键判断程序

这节主要讲解状态取反的新形式

上一节我们只是对P2的0口取反(P2_0=~P2_0)

那如果我们想要对P2的8个口都取反怎么办?

我们要引入一个变量,变量名为LEDnum,类型是unsigned char(因为char类型占1个字节,8个比特位,刚好等于寄存器的一组,寄存器以8个为一组)

我们可以先让LEDnum++然后再让它取反,赋值给P2的8个口

代码如下:

代码逻辑如下:

LEDnum原本是0,即0000 0000

第一次循环后:

LEDnum++;//0000 0001

~LEDnum;//1111 1110 (D1亮)

第二次循环后:

LEDnum++;//0000 0010

~LEDnum;//1111 1101 (D2亮)

第三次循环后:

LEDnum++;//0000 0011

~LEDnum;//1111 1100 (D1,D2亮)

第四次循环后:

LEDnum++;//0000 0100

~LEDnum;//1111 1011

第五次循环后:

LEDnum++;//0000 0101

~LEDnum;//1111 1010

第六次循环后:

LEDnum++;//0000 0110

~LEDnum;//1111 1001

第七次循环后:

LEDnum++;//0000 0111

~LEDnum;//1111 1000

第八次循环后:

LEDnum++;//0000 1000

~LEDnum;//1111 0111

第九次循环后:

LEDnum++;//0000 1001

~LEDnum;//1111 0110

第十次循环后:

LEDnum++;//0000 1010

~LEDnum;//1111 0101

第十一次循环后:

LEDnum++;//0000 1011

~LEDnum;//1111 0100

第十二次循环后:

LEDnum++;//0000 1100

~LEDnum;//1111 0011

第十三次循环后:

LEDnum++;//0000 1101

~LEDnum;//1111 0010

第十四次循环后:

LEDnum++;//0000 1110

~LEDnum;//1111 0001

第十五次循环后:

LEDnum++;//0000 1111

~LEDnum;//1111 0000

第十六次循环后:

LEDnum++;//0001 0000

~LEDnum;//1110 1111

第十七次循环后:

LEDnum++;//0001 0001

~LEDnum;//1110 1110

第十八次循环后:

LEDnum++;//0001 0010

~LEDnum;//1110 1101 

......

第255次循环后:

LEDnum++;//1111 1111

~LEDnum;//0000 0000 (全灭)

完整代码如下

#include <REGX52.H>

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)//后置--操作完之后给xms减1
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

void main()
{
	unsigned char LEDnum=0;//0000 0000
	while(1)
	{
		if(P3_1==0)
		{
			//按键判断
			Delay(20);//按下要消抖
			while(P3_1==0);//判断是否松手,松手变成==1
			Delay(20);//松开要消抖
			
			//状态取反
			LEDnum++;//0000 0001
			P2=~LEDnum;//1111 1110
	}
}

编译无错误下载查看效果

按第一次,D1亮

按第二次,D2亮

按第二次,D1,D2亮

......

按第254次时才是全亮

按第255次时全灭

按256次之后开启第二轮循环

以上就是这节要实现的效果!

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
51单片机流水灯的实现可以采用二进制移位的方式,每次将一个数值左移一位,最高位舍弃,最低位补0,然后将结果赋值给一个变量,再将这个变量输出到LED灯上,如此不断地重复这个过程,就可以实现流水灯的效果。 下面是一段基于51单片机的流水灯程序示例,使用 P1 口控制 LED 灯的亮灭状态: ```c #include <reg52.h> void main() { unsigned char led = 0x01; // 初始状态:只点亮最低位的LED灯 while (1) { P1 = ~led; // 将 led 取反后输出到 P1 口,控制 LED 灯的亮灭状态 led = led << 1; // 左移一位,最高位舍弃,最低位补0 if (led == 0) // 如果最高位也舍弃了,说明所有灯都已点亮,重新从最低位开始 { led = 0x01; } // 延时一段时间,使流水灯效果可见 for (int i = 0; i < 50000; i++) { // do nothing } } } ``` 在这个程序中,我们使用了一个无限循环 `while (1)`,每次循环都会执行以下三个操作: 1. 将当前的 `led` 取反后输出到 P1 口,控制 LED 灯的亮灭状态; 2. 将 `led` 左移一位,最高位舍弃,最低位补0; 3. 如果最高位也舍弃了,说明所有灯都已点亮,重新从最低位开始。 为了使流水灯效果可见,我们在每次循环中都加入了一个简单的延时操作。 需要注意的是,这个程序中 `led` 变量的初始值为 `0x01`,这是因为我们希望在最开始只点亮最低位的 LED 灯,然后逐渐向左侧移动。如果需要从最高位开始点亮,可以将初始值设置为 `0x80`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vera工程师养成记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值