1.余晖效应
流水灯如果在流速太快的基础上再加速,那么我们看到的则是一排灯都在亮着,这就叫人眼的余晖效应。同理,我们想让多个数码管同时亮,那么就要让三八译码器的IO0~IO5每个输出引脚轮流快速切换出低电平,需要显示什么数字再由P0的8个IO端口控制。
这里提供了一段代码供大家调试玩玩,用实验现象领悟余晖效应。
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 | #include <reg52.h> sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; void main() { unsigned char i=1; unsigned int x; ADDR3 = 1; //使能三八译码器 ENLED = 0; // P0=0xC0; //让6个数码管都显示0 while (1) { switch (i) { case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0; break ; //让IO0输出低电平 case 2: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1; break ; //让IO1输出低电平 case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0; break ; //让IO2输出低电平 case 4: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1; break ; //让IO3输出低电平 case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0; break ; //让IO4输出低电平 case 6: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;i=0; break ; //让IO5输出低电平 } i++; for (x=0;x<5000;x++); //这里是延时,大家把5000不断地改小到200,中间不断地下载进开发板来领悟余晖效应, //其实我们做的只是让三八译码器的不同IO输出持续时间不同而已,然后就产生了不一样的实验效果 } } |
2.题目
如果我们既要6个数码管同时亮,还要使6个数码管都同时间隔一秒地显示0~F的状态不停循环,模拟图像如下
EEEEEE //持续一秒
FFFFFF //持续一秒
000000 //持续一秒
……
请思考如何下手?
提示:软件调试仿真出1秒内所要执行的内容。
还有大家别傻乎乎加个“delay_ms(1000);”用来实现间隔1秒的数字自加,这样做我们怎么去实现IO0~IO5的快速切换出低电平呀。
请大家先自己思考尝试动手练练写写,实在没头绪再参考一下这些代码,其实这跟无源蜂鸣器的间隔鸣叫的编程技巧是一样的
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 | #include <reg52.h> sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; unsigned char code LedChar[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //数码管状态值初始化 void main() { unsigned int i,x; unsigned char sec; //定义一个一秒之后自增1的变量 ADDR3 = 1; //使能三八译码器 ENLED = 0; // P0=0xC0; //先让所有数码管显示0 while (1) { for (x=0;x<28492;x++) //软件调试得出这个循环耗时1秒 { switch (i) { case 0: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;i++; break ; //让IO0输出低电平 case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;i++; break ; //让IO1输出低电平 case 2: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;i++; break ; //让IO2输出低电平 case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;i++; break ; //让IO3输出低电平 case 4: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;i++; break ; //让IO4输出低电平 case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;i=0; break ; //让IO5输出低电平 } } sec++; //一秒之后变量自加1 if (sec>=16)sec=0; P0=LedChar[sec]; //取数组元素中标号为0~15的元素 } } |
我们把i放到了前面的case语句中自加,这样阅读起来更加快速明白switch语句是每条都要按顺序轮流去执行的意思(参考了宋老师的代码)。还有大家别把i定义成unsigned char型,不然无论怎么修改x的值都调试不出for循环持续1秒。
学到这里需要大家进一步学会自己分析整体代码的系统结构了。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程