交通灯处在十字路口上。它有红﹑黄﹑绿三种颜色的灯组成。红灯亮时道路上的车辆停止运行;黄灯是一种过渡用的信号灯,当它亮时,表示道路上的红绿色信号灯即将进行转换。下面拿东西南北四个方向来说明。当东西方向允许行车(或者左转)的时候,南北方向就禁止行车,即此时东西方向的绿灯亮红灯灭,而南北方向的绿灯灭红灯亮。反之当南北方向允许行车(或者左转)的时候,东西方向就禁止行车,即此时南北方向的绿灯亮红灯灭,而东西方向的绿灯灭红灯亮。同时当有特殊的情况发生时,能手动控制各个方向的信号灯。设计任务就是将这一电路用单片机来实现具体的控制。交通灯以AT89S51单片机为设计核心,须掌握单片机的软件设计及调试方法。
设计目的:
1、巩固和加深对单片机原理和接口技术知识的理解;
2、培养根据课题需要选学参考书籍、查阅手册和文献资料的能力;
3、学会方案论证的比较方法,拓宽知识,初步掌握工程设计的基本方法;
4、掌握常用仪器、仪表的正确使用方法,学会软、硬件的设计和调试方法;
5、能正确反映设计和实验成果,能用计算机绘制电路图和流程图;
设计要求:
1、东西向通行时间为80s,南北向通行时间为60s,缓冲时间为3s;
2、本项目为典型的LED显示和中断定时电路。利用定时器T0产生每250us一次的中断,每4000次中断为1s;
3、对两个方向分别显示红、绿、黄灯,并显示相应的剩余时间。值得注意的是,A方向红灯时间=B方向绿灯时间+黄灯缓冲时间;
4、时间可设置;
5、温度显示;
6、紧急控制;
7、黄灯时声音提示行人车辆;
8、万年历显示;
9、增加左转弯方向灯;
四、单片机系统电路设计 4.1时钟电路 时钟电路用于产生MCS-51单片机工作时所必须的时钟控制信号。其内部电路在时钟信号控制下,严格地按时序执行指令进行工作。在执行指令时,CPU首先要到程序存储器中取出需要执行的指令操作码,然后译码,并由时序电路产生一系列控制信号去完成指令所规定操作。本设计采用12MHz晶振和两个30PF瓷片电容,他们构成一个稳定的自激振荡器。该电容的大小影响振荡器频率的高低、振荡器的稳定性和起振的快速性。为单片机提供标准时钟。其中两个瓷片电容起微调作用。 图4.1 时钟电路图
4.2复位电路 单片机在可靠的复位之后, 才会从 0000H地址开始有序的执行应用程序。同时,复位电路也是容易受到外部噪声干扰的敏感部分之一。单片机必须保证系统可靠的进行复位,具有一定的抗干扰的能力。采用上电复位方式,RST管脚接低电平。为保证复位可靠,RC时间常数应大于两个机器周期,电容取10uf,电阻取10K欧。
图4.2 复位电路图
4.3交通灯电路 根据前面的设计内容与原理分析,电路设计中应有控制模块、显示模块本电路的设计,将发光二极管作为信号灯的材料。电源将采用5V的直流电源。东西两个方向的绿灯是同时亮的,为了简化电路可以让这两个灯接同一个引脚。同理,东西方向的黄灯、红灯也可以分别接同一个引脚。南北方向同上。这样我们可以用一个8位口控制16盏信号灯。 各信号灯均是共阳极接法,LED正极均接电源,负极通过保护电阻接单片机P1口。这样单片机引脚的输出一个低电平时,相应的信号灯就被点亮。路口上的四个分别是红灯,黄灯,绿灯,左转向灯。 图4.3 交通灯电路图
4.4倒计时显示电路 采用74HC164实现数字的显示,单片机IO口将段码通过74HC164串入并出发送给数码管,大大节约了IO口,74HC164 是高速硅门 CMOS 器件,与低功耗肖特基型 TTL (LSTTL) 器件的引脚兼容。74HC164是 8 位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA 或 DSB)之一串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,不能悬空。 时钟 (CP) 每次由低变高时,数据右移一位,输入到 Q0,Q0是两个数据输入端(DSA 和 DSB)的逻辑与,它将上升时钟沿之前保持一个建立时间的长度。主复位 (MR) 输入端上的一个低电平将使其它所有输入端都无效,同时非同步地清除寄存器,强制所有的输出为低电平。 图4.4 倒计时电路图
4.5紧急按键控制 单片机采用循环查询的方式识别按键是否被按下,紧急按键控制有5个部分,当URGENT按键按下时,南北,东西方向均为红灯,此时此路口禁止通行,URGENT按键按下后通过其余四个按键分别控制只有南北方向允许通行,只有东西方向允许通行,只有南北方向允许左转弯,,只有东西方向允许左转弯等四个状态。
图4.5 紧急按键电路图
4.6时间设置按键 单片机采用外部中断方式识别时间设置按键是否被按下,两个按键分别控制通行时间的增加和减小。每按下依次,通行时间会增加或减少一秒。 图4.6 时间设置按键电路图
4.7温度传感器电路 通过DS18B20实现随温度的测量,单片机读取温度值并显示出来,DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。 图4.7 温度传感器电路图
4.8温度显示电路 图4.8 温度显示电路图
4.9黄灯蜂鸣器提示 蜂鸣器选择有源蜂鸣器,单片机IO经过驱动电路连接到蜂鸣器上,通过单片机IO口输出高低电平控制蜂鸣器发出或者不发声音,每当黄灯亮时,蜂鸣器用来提示行人和车辆。 图4.9 蜂鸣器电路图
4.10万年历显示电路 图4.10 万年历电路图
4.11总体电路 图4.11 总体电路图
五、程序设计 5.1软件设计方案 1、 为了使倒计时更为准确,使用定时器作为倒计时的基准时间,系统使用12M的晶振,定时器采用方式二,定时器设置为250us中断一次。 2、 设置开机初始化状态,东西方向为绿灯,南北方向为红灯,然后开始正常工作。 3、 每个方向的通行时间各由两位LED数码显示,通行时间可设置,绿灯向红灯转换前黄灯亮3秒钟,并且有蜂鸣器提醒。 4、 数码管使用静态显示加74HC164方式。 5.2程序流程图 图5.1 程序流程图
5.3程序源码 - #include <REGX51.H>
- unsigned int n=0;
- unsigned int second=0;
- unsigned int sec=0;
- unsigned int min=0;
- unsigned int hou=0;
- unsigned int day=0;
- unsigned int time_heng=80; //东西通行时间
- unsigned int time_zong=60; //南北通行时间
- unsigned int heng_left=5; //东西左转时间
- unsigned int shu_left=5; //南北左转时间
- sbit DAT1=P2^0;
- sbit CLK1=P2^1;
- sbit DAT2=P2^2;
- sbit CLK2=P2^3;
- #define DQ P3_7
- unsigned char m; //温度整数
- unsigned char s; //温度小数
- int array[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98};
- void seg(unsigned int seg_num)
- {
- unsigned int ten;
- unsigned int unit;
- int i,num;
- ten=seg_num/10;
- unit=seg_num%10;
- num=array[unit]+0x80;
- for(i=0;i<8;i++)
- {
- CLK2=0;
- DAT2=num&0x01;
- CLK2=1;
- num>>=1;
- }
- num=array[ten];
- for(i=0;i<8;i++)
- {
- CLK2=0;
- DAT2=num&0x01;
- CLK2=1;
- num>>=1;
- }
- }
- void DaoJiShi_seg(unsigned int hen_num,unsigned int shu_num)
- {
- unsigned int ten;
- unsigned int unit;
- int i,num;
- ten=shu_num/10;
- unit=shu_num%10;
- num=array[unit];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- num=array[ten];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- ten=hen_num/10;
- unit=hen_num%10;
- num=array[unit];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- num=array[ten];
- for(i=0;i<8;i++)
- {
- CLK1=0;
- DAT1=num&0x01;
- CLK1=1;
- num>>=1;
- }
- }
- void Disp(unsigned int seg_m,unsigned int seg_s)
- {
- unsigned int ten;
- unsigned int unit;
- ten=seg_s/10;
- unit=seg_s%10;
- SBUF=array[unit];
- while(TI==0);
- TI=0;
- SBUF=array[ten];
- while(TI==0);
- TI=0;
- ten=seg_m/10;
- unit=seg_m%10;
- SBUF=array[unit]+0x80;
- while(TI==0);
- TI=0;
- SBUF=array[ten];
- while(TI==0);
- TI=0;
- }
- void Delay_DS18B20(int num)
- {
- while(num--) ;
- }
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1;
- Delay_DS18B20(8);
- DQ = 0;
- Delay_DS18B20(80);
- DQ = 1;
- Delay_DS18B20(14);
- x = DQ;
- Delay_DS18B20(20);
- }
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0;
- dat>>=1;
- DQ = 1;
- if(DQ)
- dat|=0x80;
- Delay_DS18B20(4);
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- Delay_DS18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0x44);
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0xBE);
- a=ReadOneChar();
- b=ReadOneChar();
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
- t= tt*10+0.5;
- return(t);
- }
- void check_wendu(void)
- {
- unsigned int a,b,c;
- c=ReadTemperature();
- a=c/100;
- b=c/10-a*10;
- m=c/10;
- s=c-a*100-b*10;
- if(m<0){m=0;n=0;}
- if(m>99){m=99;n=9;}
- }
-
- void main()
- {
- P3_4=0;
- SCON=0x00;
-
- TMOD=0x02;
- TH0=256-250;
- TL0=256-250;
- ET0=1;
-
- IT0=1;
- EX0=1;
- IT1=1;
- EX1=1;
-
- EA=1;
- TR0=1;
- P1=0xF3;
- P2_5=1;
- P2_6=1;
- P2_7=1;
- P3_6=1;
- while(1)
- {
- Loop:
- if(P2_4==1){TR0=1;}
- if(P2_4==0)
- {
- TR0=0;
- P1=0xF6;
- RECEIVED:
- if(P2_5==0){P1=0xF3;goto RECEIVED;}
- if(P2_6==0){P1=0xDE;goto RECEIVED;}
- if(P2_7==0){P1=0xB7;goto RECEIVED;}
- if(P3_6==0){P1=0x7E;goto RECEIVED;}
- goto Loop;
- }
- if(n>=4000)
- {
- n=0;
- second++;
- sec++;
- if(second<time_heng) {DaoJiShi_seg(time_heng-second,time_heng+3+heng_left+3-second); seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng&&second<time_heng+3) {DaoJiShi_seg(time_heng+3-second,time_heng+3+heng_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3&&second<time_heng+3+heng_left) {DaoJiShi_seg(time_heng+3+heng_left-second,time_heng+3+heng_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left&&second<time_heng+3+heng_left+3) {DaoJiShi_seg(time_heng+3+heng_left+3-second,time_heng+3+heng_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3&&second<time_heng+3+heng_left+3+time_zong) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3+time_zong&&second<time_heng+3+heng_left+3+time_zong+3) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3+time_zong+3&&second<time_heng+3+heng_left+3+time_zong+3+shu_left) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong+3+shu_left-second);seg(sec);seg(min);seg(hou);seg(day);}
- if(second>=time_heng+3+heng_left+3+time_zong+3+shu_left) {DaoJiShi_seg(time_heng+3+heng_left+3+time_zong+3+shu_left+3-second,time_heng+3+heng_left+3+time_zong+3+shu_left+3-second);seg(sec);seg(min);seg(hou);seg(day);}
- check_wendu();
- Disp(m,s);
- }
- if(second==time_heng) {P1=0xF5;P3_4=1;}
- if(second==time_heng+3) {P1=0xB7;P3_4=0;}
- if(second==time_heng+3+heng_left) {P1=0xF5;P3_4=1;}
- if(second==time_heng+3+heng_left+3) {P1=0xDE;P3_4=0;}
- if(second==time_heng+3+heng_left+3+time_zong) {P1=0xEE;P3_4=1;}
- if(second==time_heng+3+heng_left+3+time_zong+3) {P1=0x7E;P3_4=0;}
- if(second==time_heng+3+heng_left+3+time_zong+3+shu_left) {P1=0xEE;P3_4=1;}
- if(second==time_heng+3+heng_left+3+time_zong+3+shu_left+3) {second=0;P1=0xF3;P3_4=0;}
- if(sec==60) {sec=0;min++;}
- if(min==60) {min=0;hou++;}
- if(hou==24) {hou=0;day++;}
- if(day==30) {day=0;}
- }
- }
- void t0() interrupt 1
- {
- n++;
- }
- void int0() interrupt 0
- {
- EX0=0;
- time_heng++;
- time_zong++;
- EX0=1;
- }
- void int1() interrupt 2
- {
- EX1=0;
- time_heng--;
- time_zong--;
- EX1=1;
- }
复制代码
六、仿真结果 图6.1 仿真结果图
七、实际电路 图7.1 实际电路图
全部资料51hei下载地址:
仿真程序.7z
(5.02 MB, 下载次数: 25)
|