首先声明下,这并不是什么高科技,只是一个没有什么技术含量的单片机流水灯而已,文字记录下来为了以后能够更好学习进步。欢迎拍砖。 话说“计轴复零监测装置”完成之后,领导希望做一块演示板,以此来打动评委及现场观众。 第一,肯定是要画图嘛:这里用的是微软的Publisher。
 说下我们的构思及要求: 1、当“按键1”按下后,“1”蓝色LED灯依次点亮,保持点亮状态。 2、当“按键2”按下后,“ 2” 蓝色LED灯依次点亮,完了,“1” 蓝色LED灯灭掉。 4、“ 3”红色LED点亮1秒后,灭。 5、“4”黄色LED依然点亮。 6、“ 5”八段管计数加1。 7、“ 6” 红色LED点亮3秒后,灭。 8、“ 7”绿色、蓝色LED灯依次点亮。 9、“8”屏幕显示。 当这图画好后,接下来就是焊硬件,由图纸到实物。 背面的接线图:
 正面:
 其实,那时候我心里没底的,超过40个LED,哪怕是个别并联后,还是超过89C51单片机的32个IO口,更何况八段管已经占用P0口,这样算下来,LED能用的就只有P1、2、3四个,24个灯位了。 其实,最开始我也想到要用寄存器来扩展IO口,尤其是八段管,但苦于功力不足,74HC164寄存器驱动八段管的程序没有调试成功,于是不得不降低要求,直接用P0口来。 非常抱歉,由于当时时间关系,所以实际上演示板的电路图我是没有画的(直到现在也没有画出来),而是直接焊电路板的。 八段管与单片机的连接电路图大概如下: 
程序如下: //--------------定义八段管显示------------------ chartab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x02,0xf8,0x00,0x10}; int n=0; P0=0xc0; // 初始显示0 while(1) { if(k1==0) //判断按键按下 { delay(30); if(k1==0) ++n; //N加1 if(n==10) //如果N等于10,N为0 n=0; P0=tab[n]; //将段码送P0口 } } 八段管的问题解决了,接下来就是LED灯,一共47个LED灯,由于“4”、“7”部分LED灯是可以并联显示,所以,我还是要解决38个LED的显示。另外还需要2个按键、1个信号触发“8”显示屏,于是就变成22个IO口和38个LED灯。这样不得不用到寄存器了。华强北跑了一趟,买到的是74HC164。 74HC164与单片机、LED的连接电路图大概如下:
 有了寄存器,只需要2个IO口就可以扩展连接8个LED,整个电路中,我一共用了3个74HC164,终于解放了紧张的IO口。 上电……调试,这里LED灯连接方式是共阳极,那么就需要74HC164依然输出低电平,二进制就是“0111 1111”换算成16进制为“0x7f”。 程序如下: //--------------第一个74LS164函数----------------- void In_164(uchar dat) //送数据进74LS164 { uchar i; for(i=0;i<8;i++) { dat=dat>>1; //移位8位 DS1=CY; //溢出位给数据端 SCLK1=0; //时钟脉冲 _nop_(); _nop_(); SCLK1=1; _nop_(); _nop_(); SCLK1=0; } } void LS3(void) { uchar temp=0x7f; uchar i; { for(i=0;i<8;i++) { In_164(temp); Delay_1ms(90); //延时1s temp=(temp<<1)|(temp>>7); //循环移位 } } } 又有新的问题出现,由于74HC164平时是输出低电平的,故,只要一上电,LED全部点亮,执行程序后是依次灭灯。哎,几经周折,终于找到解决方法----直接在执行程序前先输出一串高电平……没想到我还是那么的聪明……嘻嘻 //-------------- 74LS164输出高电平----------------- void LS1(void) { uchar temp=0xff; uchar i; { for(i=0;i<8;i++) { In_164(temp); Delay_1ms(20); //延时1s temp=(temp<<1)|(temp>>7); //循环移位 } } } 至此,收工,主程序如下:
//--------------主函数----------------- void main() { intn=0; P0=0xc0; // 初始显示0 {LS1();} {LS3();} {LS5();} while(1) { if(k1==0) //如果第一个按键按下 { delay(30); //延时去抖 if(k1==0) //再判断是否按下 { la1 = 0; //蓝色LED0点亮 delay(90); //调用延时程序 la2 = 0; delay(90); la3 = 0; while(k1==0); //等待按键松开 } } if(k2==0) //如果第二个按键按下 { delay(30); //延时去抖 if(k2==0) //再判断是否按下 { la4 = 0; delay(90); la4 = 1; //蓝色LED4灭 la5 =0; delay(90); la5 = 1; la6 =0; delay(90); la6 = 1; la7 =0; delay(90); / la7 = 1; la8 =0; delay(90); la8 = 1; la1 = 1; la2 = 1; la3 = 1; //蓝色LED全部灭 ho1 =0; //红色LED点亮 delay(2000); ho1 = 1; hu1 = 0; delay(90); //调用延时程序 hu1 = 1; hu2 = 0; delay(90); hu2 = 1; hu3 = 0; delay(90); hu3 = 1; hu4 = 0; delay(90); hu4 = 1; hu5 = 0; delay(90); hu5 = 1; {LS2();LS1();} ++n; //N加1 if(n==10) //如果N等于10,N为0 n=0; P0=tab[n]; //将段码送P0口 ho2=0; //置P0口为低电平 delay(2000); //调用延时程序 ho2 = 1; {LS4();LS3();LS6();LS5();} da1 =0; delay(100); da1 = 1; } while(k2==0); //等待按键松开 } } } 赠送一张“核心电路板”:
 可惜,可惜51hei论坛坑爹,视频上传不了。
|