1.题目
为了更好地体现上一讲优化好的不支持连按代码的优势,我们来一道题目:用上7盏灯,左边6盏不停地流水,最右边1盏实现按键切换灯的打开和关闭,且按键动作不能干扰到流水灯的流速状态。
实验现象状态模拟如下
11111011//按键没按下 11110111//按键没按下 11101110//按键按下后抬起 11011110//按键没按下 10111111//按键按下后抬起 01111111//按键没按下 11111011//按键没按下 ......
2.升华
在书写代码之前,我们来思考一下如何做到简化,如果按照以前的思路就是sbit的一个一个位地定义,这样的话就可以避免影响到LED2,因为LED2要实现自由,仅允许让按键来控制它的亮灭而已。
如果像之前用“P0=~(0x04<<i)”的方式确实可以实现流水灯,但是P0明显会强制的把P0.0输出高电平,这样的话LED2就被强制熄灭了。不过没关系,我们再次利用C语言知识就可以解决问题了。
首先要了解到“0xFE|0x00”还是等于0xFE,“0xFE|0x01”就等于0xFF了。
我们也知道LED2要么是等于0,要么是等于1的。当然也可以这么说:LED2要么是等于0x00,要么是等于0x01。十进制和十六进制表示的都是确定的数,只是书写方法不一样而已,比如我们都知道“P0=0xFF;”是熄灭8盏灯的作用,
但是我们也可以这样写“P0=255;”,因为0xFF和255都是一个确定的数,只不过用0xFF更能让人快速反应出这个值用二进制表示会立马呈现出8个IO端口的输出状况。
所以我们只要这样表示“0xFE|LED2”,那这个表达式要么是等于0xFE要么是等于0xFF。
我们接着再了解,“(~0x04)&0xFF”还是等于(~0x04),用二进制表示为11111011,赋给P0就是只有LED4亮。
而“(~0x04)&0xFE”等于0xFA, 用二进制表示11111010,赋给P0就是只有LED2和LED4亮。
于是这么写“P0=~(0x04)&(0xFE|LED2);”的时候,LED2等于0时,就是LED2和LED4亮;LED2等于1时,只有LED4亮而已。
要想实现六盏灯流水则“P0=~(0x04<<i)&(0xFE|LED2);”i在0和5之间变化即可,这个表达式的意思就是,高6位的灯随便流水,但是LED2却是自由独立的,它等于0或者1都不影响高6位。这样我们用按键控制“LED2=! LED2”,于是LED2就可以独立显示了。
本讲的代码我们在下一讲贴出,目的是为了比较当使用“while(KEY4==0);”的方式时是有多拙劣。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程