当然按键的功能不是像前两讲的代码这么单调,前两讲的代码是认识到程序中寄存器位的值是可以受外部电路影响而改变的。这一讲我们要做的就是根据前两讲的知识不断探索按键的一些规律和原理。
1.状态图
可能我们理想中的按键过程图如下
那我们不妨在这种猜想下用代码测试看看是什么效果。
首先要测试的是我们自己快速按下按键后就松开,上图的“按键按下时P2.7的状态”持续的时间到底是多长,我们就用流水灯的方式来查看按下之后迅速松开,小灯会跳到哪里显示。
2.代码及分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <reg52.h> sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; 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 i=1; ADDR3 = 1; //使能三八译码器 ENLED = 0; // ADDR2 = 1; //************************** ADDR1 = 1; //让三八译码器的IO6输出低电平 ADDR0 = 0; //************************** P2 = 0xF7; //让K4能具备有被拉低的条件先 P0 = 0xFE; //先点亮最右端的小灯 while (1) { if (KEY4==0) { delay_ms(10); P0=~(0x01<<i); i++; if (i>=8)i=0; } } } |
笔者在此程序下做实验,即使手速再怎么快地按下K4马上松开,可在这段时间里点亮的LED2跳到了LED5点亮,也就是说按键在物理上的导通时间超过了30ms。
后面i绝对大于3,因为LED5亮,所以有“P0=0xF7;”推出“ ~(0x01<<3)”,然后再有“i++;”,i绝对大于3。
这也就不难解释上一讲的“按键&数码管”的代码原理了,按照我们平时按键的手速,可以看到下面的现象
我们只是简单的一个按键动作,实验现象里从1阶段的状态一下子来到了4阶段,而在2,3阶段一闪而过(当然手速不同,可能也会在另一个阶段处停留),我们再看一下程序的部分代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | while (1) { P0=0xFF; switch (i) { case 0: IO0_OUT();P0=LedChar[0]; break ; case 1: IO0_OUT();P0=LedChar[1]; break ; case 2: IO0_OUT();P0=LedChar[2]; break ; case 3: IO0_OUT();P0=LedChar[3]; break ; case 4: IO1_OUT();P0=LedChar[3]; break ; case 5: IO2_OUT();P0=LedChar[3]; break ; case 6: IO3_OUT();P0=LedChar[3]; break ; case 7: IO4_OUT();P0=LedChar[3]; break ; case 8: IO5_OUT();P0=LedChar[3]; break ; case 9: IO5_OUT();P0=LedChar[4]; break ; case 10:IO5_OUT();P0=LedChar[5]; break ; case 11:IO5_OUT();P0=LedChar[0]; break ; case 12:IO4_OUT();P0=LedChar[0]; break ; case 13:IO3_OUT();P0=LedChar[0]; break ; case 14:IO2_OUT();P0=LedChar[0]; break ; case 15:IO1_OUT();P0=LedChar[0]; break ; } if (KEY4==0)i++; if (i>=16)i=0; //让i在0~15之间变化 delay_ms(30); } |
1阶段一下子来到4阶段,那么i肯定是因为按键的动作,被加了3次等于3才会在4阶段处停留,而在按键按下的动作中i自加一次之后都需要经过“delay_ms(30);”,可想而知,P2.7在按键动作中被拉低的持续时间就有60~90ms。
因为我们有了“delay_ms(30);”才会看到2,3阶段有亮度的持续短时间显示,之前叫大家按着K4不放,看到的是数码管在循环做跑马灯,i在K4按下不放中KEY4一直等于0所以i一直从0~15不停的改变,加上延时部分,6个数码管上的16段灯就看起来像流水灯一样在跑了。讲解到这里我们已经对按键的原理和代码操作有一定的了解了。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程