1.延时函数退出舞台
有了上一讲的理论讲解,代码的实现就比较简单了,实验现象就是高6位的6盏灯不停流水,我们用K4按键控制LED2的亮灭,并且途中并没有影响到6盏流水灯的运行。
我们知道以前流水灯是需要延时才能看得到流水现象的,那么现在再用延时函数的话,按键就没有意义了。比如流水灯的跳变需要间隔50ms才看得出是一个灯一个灯的亮,如果在死循环里使用“delay_ms(50);”,那么不支持连按代码里的times要加1都需要过了50ms才行,这样显然行不通,我们只能从流水灯的代码去思考了。
其实一次死循环里不一定就要求灯实现跳变,可以等到过了很多次死循环再去执行灯的跳变的,所以我们在死循环里让变量x每次加1,死循环了3000次之后再执行灯的跳变,这样不就能实现间隔50ms左右灯才跳变了吗,同时又不影响按键代码的times,也就是一次死循环所花费的时间被大大缩短了,扫描按键IO端口的机会更多了。那么延时函数在我们写一些高效率的代码的时候就很少去使用了,毕竟这样不仅影响执行效率,还会使某些功能模块失去作用。
2.流水灯代码新书写模式
#include <reg52.h> 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 main() { unsigned char key_up=1;//定义记录按键状态值的变量,初始值为1避免程序一开始就进入了“if(key_up==0)” unsigned char i=0; unsigned int times=0; //用来记录进入过按键判断语句的次数 unsigned int x; //作为记录死循环的次数以达到间隔切换灯的跳变 ADDR3 = 1;//使能三八译码器 ENLED = 0;// ADDR2 = 1;//************************** ADDR1 = 1;//让三八译码器的IO6输出低电平 ADDR0 = 0;//************************** P2 = 0xF7;//让K4能具备有被拉低的条件先 while(1) { if(key_up==0) { times++; if(times>=1000&&KEY4==1) { times=0; LED2=!LED2; } } key_up=KEY4; //以下是流水灯任务部分 x++; if(x>=3000)//程序的运行已经过去50ms左右了 { x=0; P0=~(0x04<<i)&(0xFE|LED2);//既不影响高6位,又可以使LED2随意亮灭 i++; if(i>=6)i=0; } } }
还是不明白“P0=~(0x04<<i)&(0xFE|LED2);”的意思大家就一步步用二进制地写出当i等于0时“~(0x04<<i)”是等于多少,得到的值再跟“(0xFE|LED2)”相与运算看看当LED2为0或者1时,“~(0x04<<i)&(0xFE|LED2)”的最终值是多少。
然后当i等于1时“~(0x04<<i)&(0xFE|LED2)”又是等于多少。
我们这个例程代码是对比了用“while(KEY4==0);”的时候是多么的不足,这样吧,我们把上面例程的这部分代码
if(key_up==0) { times++; if(times>=1000&&KEY4==1) { times=0; LED2=!LED2; } } key_up=KEY4;
改为以前初步学习的代码如下
if(KEY4==0) { delay_ms(10);//等待抖动过去 if(KEY4==0) //二次判断 { LED2=!LED2; while(KEY4==0); } }
延时函数大家再自己找以前的代码去添加,实验现象就是按键动作影响了流水灯的流速,如果按着不放直接导致停止流水。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程