实现上一节的功能其实还有更简洁的方法去书写,那就是引用数组,用数组存取灯的八种状态值。定义含有8个元素的数组如下:
unsigned char LEDSET[8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};每个元素轮流赋值给P0后延时即可。
#include <reg52.h> //sbit LED2 = P0^0; 本节代码中用不到这条语句了 sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; 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 = 0; unsigned char LEDSET[8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; ADDR3 = 1;//使能三八译码器 ENLED = 0;// ADDR2 = 1;//************************** ADDR1 = 1;//让三八译码器的IO6输出低电平 ADDR0 = 0;//************************** while(1) { P0=LEDSET[i]; i++; if(i>=8)i=0;//i需归0使P0只能使用数组中的8个元素,防止使用到超出数组元素以外的值,其实就是让i在0~7之间变化 delay_ms(100); } }
如果只是简单地实现上处代码单一的流水灯,那大可不必用数组,也不需要算出0xFE,0xFD这样的这些值,我们运用移位知识也可以实现上处功能,修改主函数如下
void main() { unsigned char i = 0; ADDR3 = 1;//使能三八译码器 ENLED = 0;// ADDR2 = 1;//************************** ADDR1 = 1;//让三八译码器的IO6输出低电平 ADDR0 = 0;//************************** while(1) { P0=~(0x01<<i);//第一次运行这条语句i是等于0的,先算出括号中的值:0x01左移0位还是0x01,算出了括号中的值再去取反就得0xFE, //所以第一次运行这条语句时就相当于“P0=0xFE;”,第二次循环运行时i已经等于1,0x01左移1位就为0x02,取反得0xFD,所以第二次执行这条语句是“P0=0xFD;” i++; if(i>=8)i=0; delay_ms(100); } }
如果读者对左移右移和取反等C语言知识尚未掌握,建议您上网学习基础教学,又或者参考《手把手教你学51单片机》文档4.8节。
当我们想实现花式流水灯时还是需要运用到数组的,毕竟数组可以修改LED的状态值,例如我们想实现这样的一个花式流水灯:
01111110 //对应十六进制=0x7E
10111101 //对应十六进制=0xBD
11011011 //对应十六进制=0xDB
11100111 //对应十六进制=0xE7
11011011 //对应十六进制=0xDB
10111101 //对应十六进制=0xBD
01111110
10111101
......
修改主函数
void main() { unsigned char i = 0; unsigned char LEDSET[6]={0x7E,0xBD,0xDB,0xE7,0xDB,0xBD}; ADDR3 = 1;//使能三八译码器 ENLED = 0;// ADDR2 = 1;//************************** ADDR1 = 1;//让三八译码器的IO6输出低电平 ADDR0 = 0;//************************** while(1) { P0=LEDSET[i]; i++; if(i>=6)i=0; //让i在0~5之间变化 delay_ms(100); } }
其他花样玩法大家可自行编写数组里的状态值,这次的花样流水灯我们只用了6种状态不停循环,大家编新的花样状态超过6种时记得修改LEDSET[6]里的6和“if(i>=6)i=0;”里的6为你所设置的花样状态种数。
本文固定URL:https://www.dotcpp.com/course/186