不同于上篇文章只用代码控制,这次我们要再加上独立按键一同控制LED灯
目录
- 独立按键控制LED亮灭:
- 代码实现:
- 独立按键控制LED状态:
- 代码实现:
- 独立按键实现二进制LED显示:
- 代码实现:
- 独立按键控制LED移位:
- 代码实现:
独立按键控制LED亮灭:
由题可知,按下的时候是亮,松开时是灭
数电中我们接触过寄存器的概念,是由触发器构成的串/并输入输出构成的各种不同的寄存器,寄存器可以写也可以读取。
我们上次是在P2寄存器
中写,进而控制LED灯
,这次我们要与独立按键联动进行控制,
有原理图可知,我们是根据P3
寄存器来进行控制,这里要先普及一个概念,当我们按下独立按键后,寄存器读取为0
,因为是线与状态(有一个为0就是0,独立按键接GND
),学习过单片机原理后会更清楚一点,故我们可以通过P3_1
来判断K1是否按下。
这里你可能又会有疑惑,我们之前用的都是P2这样的一整个寄存器,但是我们加个_
就可以使用其中一个,前提是包含#include <REGX52.H>
。
代码实现:
#include <REGX52.H>void main()
{while(1){if(P3_1 == 0)P2_0 = 0;elseP2_0 = 1; }
}
独立按键控制LED状态:
既然要使用按键,那么还要了解按键的特性
由图可知,按键会造成一定的影响,那我们如何消除这个影响呢?
用到我们之前学习的延时函数Delay
延时函数的使用,设置完之后我们可以延时20ms,虽然他的影响最大只有10ms。
如下代码就是按键防抖代码,要熟记于心噢
if(P3_1 == 0){Delay(20);while(P3_1 == 0);if(P3_1 == 1)Delay(20);//我们要执行的操作}
代码实现:
#include <REGX52.H>void Delay(unsigned int xms) //@11.0592MHz
{unsigned char i, j;while(xms--){i = 2;j = 199;do{while (--j);} while (--i);}
}void main()
{while(1){if(P3_1 == 0){Delay(20);while(P3_1 == 0);if(P3_1 == 1)Delay(20);P2_0 = ~P2_0;}}
}
独立按键实现二进制LED显示:
我们先来看这样一段代码:
void main()
{while(1){if(P3_1 == 0){Delay(20);while(P3_1 == 0);if(P3_1 == 1)Delay(20);P2++;}}
}
因为P2寄存器初始状态都为1111 1111
,++后会溢出,因此最后会成为该亮的不亮,不该亮的亮,但是我们可以借鉴这个思路,巧妙取反
代码实现:
void main()
{unsigned char LEDNum = 1;while(1){if(P3_1 == 0){Delay(20);while(P3_1 == 0);if(P3_1 == 1)Delay(20);P2 = ~(LEDNum++);}}
}
独立按键控制LED移位:
由于博主用的开发板的LED灯顺序与江科大使用的相反,所以江科大的右移反而是博主的左移,下图就是江科大的代码实现。
但是博主也想搞一个K1键就是向左,K2键就是向右,于是就搞了一个适配自己板子的代码。
先来讲一下博主的思路:
由于灯的顺序是反的,所以用二进制看的比较别扭。
所以我们选择先使用不按8421码编排的,随后改成8421码(倒序即可)
注意:假设1为亮,故代码实现时要取反
我们先让D1亮,即为1000 0000,
随后按下K1向左移,即为0000 0001
左移时只有这一种情况需要特判,其他情况使用>>
操作符(因为我们是反序)即可
继续: ::::::::0000 0010
继续: ::::::::0000 0100
. … … … … … …
循环: ::::::::1000 0000
右移也同理。
代码实现:
void main()
{ P2_0 = 0;while(1){//move leftif(P3_1 == 0){//防抖动Delay(20);while(P3_1 == 0);if(P3_1 == 1)Delay(20);if(P2 == ~(0x01)){P2 = ~(0x80);}else{P2 = ~((~P2)>>1);}}//move rightif(P3_0 == 0){Delay(20);while(P3_0 == 0);if(P3_0 == 1)Delay(20);if(P2 == 0x7F){P2 = 0xFE;}else{P2 = ~((~P2)<<1);}}}
}
欢迎交流。