51单片机实现交通信号灯的实验,我用51开发板上的LED8+LED9作为绿灯、LED5+LED6作为黄灯、LED2+LED3作为红灯。同时,我用两个数码管作为秒表的倒计时显示。实验现象是默认的是从39秒绿灯开始亮的,39秒过后切换到黄灯,3秒后又从黄灯切换到红灯。这个程序如果自己想搭建也是非常简单的,不管你是毕业设计还是业余爱好,都可以很完美的实现出来,做出一个属于自己的交通信号灯。你只要两个数码管和三个灯,就可以用以下程序实现出来,当然你需要稍微改下必要的代码参数,因为我这样用的是6个LED灯。如果你想改红绿灯的时间,改下里面参数就可以实现了。下面是详细代码。
#include<reg52.h> sbit ADDR3=P1^3; sbit ENLED=P1^4; unsigned char code LedChar[]={ //数码管显示字符转换表 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E }; unsigned char LedBuff[7] = { //数码管+独立LED显示缓冲区 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; bit flag1s=1; unsigned char T0RH=0; unsigned char T0RL=0; void ConfigTimer0(unsigned int ms); void TrafficLight(); void main(){ EA=1; //开总中断 ENLED=0; //使能数码管和LED ADDR3=1; ConfigTimer0(1); //配置T0定时1ms while(1){ if(flag1s){ //每秒执行一次交通信号灯刷新 flag1s=0; TrafficLight(); } } } void ConfigTimer0(unsigned int ms){ unsigned long tmp; //临时变量 tmp=11059200/12; //定时器计数频率 tmp=(tmp*ms)/1000; //计算所需的计数值 tmp=65536-tmp; //计算定时器重载值 tmp=tmp+18; //补偿中断响应延时造成的误差 T0RH=(unsigned char) (tmp>>8); //定时器重载值拆分为高低字节 T0RL=(unsigned cahr) tmp; TMOD &=0xF0; //清零To的控制位 TMOD |=0x01; //配置T0为模式1 TH0 = T0RH; //加载T0重载值 TL0 = T0RL; ET0 = 1; //使能T0中断 TR0 = 1; //启动T0 } void TrafficLight(){ static unsigned char color=2; //默认红灯 static unsigned char timer = 0; if(timer==0){ switch(color){ case 0: //绿灯亮 color=1; timer=2; LedBuff[6]=0xE7; break; case 1: color=2; //红灯亮 timer=29; LedBuff[6]=0xFC; break; case 2: color=0; //切换到绿灯 timer=39; LedBuff[6]=0x3F; break; default; break; } }else{ timer--; } LedBuff[0]=LedChar[timer%10]; LedBuff[1]=LedChar[timer/10]; } void LedScan(){ static unsigned char i=0; //动态扫描索引 P0 = 0xFF; //关闭所有段选位,显示消隐 P1 = (P1 & 0xF8) |i; //位选索引值赋值到P1口低3位 P0 = LedBuff[i]; //缓冲区索引违章的数据送到P0口 if(i<6) //索引递增循环,遍历整个缓冲区 i++; else i=0; } void InterruptTimer0() interrupt 1{ static unsigned int tmr1s=0; //1秒定时器 TH0 = T0RH; //重新加载重载值 TL0 = T0RL; LedScan(); //LED扫描显示 tmr1s++; //1秒定时器处理 if(tmr1s>=1000){ tmr1s=0; flag1s=1; //设置秒定时标志 } }