历史上的今天
今天是:2025年08月19日(星期二)
2021年08月19日 | 51单片机-不支持连按
2021-08-19 来源:eefocus
1.缺陷
上一讲讲解的“不支持连按”模式贴合了我们在生活中的实际应用,虽然我们仅用“while(KEY4==0);”就把按键模式给切换了,不过这条语句严格来说是有缺陷的。
现在我们编写的都是简单的程序,如果后面还有更多更复杂的程序时,“while(KEY4==0);”就成为BUG了。
如果我们对按键按下不松手,那程序就一直在循环等待,不遇到高电平就不往下执行代码,如果这时有重要的程序要执行,那岂不是因按键而耽误。
还有我们再看下面这些代码
while(1)
{
if(KEY4==0)
{
delay_ms(10);//等待抖动过去
if(KEY4==0) //二次判断
{
//这里执行某些功能语句
}
}
}
即使我们不使用“while(KEY4==0);”,只要我们按键不松手,每次都要执行“delay_ms(10);”,这样的代码称不上高效率,我们只能再次完善代码了。
2.改善
首先我们为了让程序做到通用性,我们定义一个key_up为unsigned char类型的变量,而不是像宋老师那样在《手把手教你学51单片机》文档8.4.3节后面的文字内容说到的利用bit类型的变量,毕竟bit类型只适合在51单片机,要是移植到其他单片机里就不适用了,所以我们不打算使用这种变量。
我们新定义的key_up变量是用来记录此时按键IO端口的扫描值,进一步分析,当按键按下不松手时,
此时的key_up等于KEY4(也就是0),当按键松手后,key_up就等于1了。
然后想进入执行功能语句时,先过了“if(key_up==0)”这一关,因为我们一直让key_up在死循环里存取KEY4的值,所以只要没有按键动作,key_up一直等于1,这样连进入功能语句的第一关都没有资格。
当有按键按下时,key_up等于0了,进入了第一关,然后我们再设最后一关,如果通过了最后一关就可以执行功能语句了,最后一关是判断“if(KEY4==1)”,也就是说如果按键没松手,就无法执行功能语句了。没错,我们这次的不支持连按模式是只有按键松手之后才去执行的,上一讲则是按下之后过了10ms就执行代码了。
3.代码
#include sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; sbit LED2 = P0^0; sbit KEY4 = P2^7; void delay_ms(unsigned int x) { unsigned int i,j; if(x==1000) { for(i=0;i<19601;i++)//延时1s { for(j=5;j>0;j--); } } else while(x--)for(j=115;j>0;j--); } void main() { unsigned char key_up=1;//定义记录按键状态值的变量,初始值为1避免程序一开始就进入了“if(key_up==0)” unsigned char i=1; ADDR3 = 1;//使能三八译码器 ENLED = 0;// ADDR2 = 1;//************************** ADDR1 = 1;//让三八译码器的IO6输出低电平 ADDR0 = 0;//************************** P2 = 0xF7;//让K4能具备有被拉低的条件先 P0 = 0xFE;//先点亮LED2 while(1) { if(key_up==0) { if(KEY4==1)//只要不松手,KEY4就会等于0,只有在按键抬起之后才执行功能代码 { P0=~(0x01< i++; if(i>=8)i=0; } } key_up=KEY4; //如果不松手,key_up就会等于0 delay_ms(2); //假设这部分是要执行的其他程序 } } 大家可以照着代码分析一下,我们是不是已经解决了上一讲代码的两处缺陷。
上一篇:51单片机-按键模式
下一篇:51单片机-静态变量
史海拾趣
|
工程中遇到的实际问题:一座大厦,楼下部分为商业,上面为公寓写字楼,如何实现可视对讲的门禁作用?前提是:不影响商业部分使用电梯,日常营业,还要保证公寓的安全性。有这方面经验的同志们可以讨论一下。如果有具体产品,只要产品质量有保证,公 ...… 查看全部问答> |
|
硬件环境:硬件多普达智能手机带蓝牙. 软件环境:Smartphone. 程序主干: 1.g_hComDevice= RegisterDevice (L\"COM\", ComIndex, L\"btd.dll\", (DWORD)&pp); //创建虚拟串口,本地为服务器端 2.g_hComFile = CreateFile (szComPort, ...… 查看全部问答> |
|
这是一个正负脉宽数控调制信号发生器,就是没有运行成功,有的地方看不懂,请教高手帮忙解释一下,谢谢啦! LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY PULSE IS PORT(CLK:IN STD_LOGIC; &nbs ...… 查看全部问答> |
|
UltraEdit的SystemVerilog关键词设置共享 SystemVerilog部分在文件末尾(/L15 打头),每个人的惯用语言不一样,如果你只需要增加SystemVerilog部分而保留其它设置,则把这最后一部分拷下贴到你的 WORDFILE.TXT中就可(别忘了把该文件设为WORDLIST文件:菜单-> 高级->配置->语法高 ...… 查看全部问答> |
|
用Spartan-6做一个简单的PCIE通信板卡,在生成PCIE IP核时,开辟BAR0为128个字节的IO空间,然后直接利用生成的参考设计,生成bit文件和MCS文件。下载MCS文件到配置FLASH后,断电重新再上电后,工控机的WINDOWS XP设备管理器下能够看到该板卡,但是 ...… 查看全部问答> |
|
用的是arm linux交叉编译工具链编译的,连续的打印四句 printf(\"\\r\\n##### Test TFT LCD #####\\r\\n\"); printf(\"[1] TFT240320 8Bit\\n\\r\"); &nbs ...… 查看全部问答> |




