当前位置:文档之家› 基于80C51单片机的交通灯设计

基于80C51单片机的交通灯设计

基于80C51单片机的交通灯设计班级:电信1101姓名:XXXX学号:0703110107一、设计说明及材料清单(一)设计说明:本交通灯的设计简化了十字路交通灯,只将东西和南北两个路向的交通灯情况表示出来,但也做了很多改进,设计了针对不同时间段不同的控制方案,并且采用串口通讯可将不同的控制方案下载到芯片中,外接掉电保存程序的非易失性存储芯片和掉电仍可计时的时钟芯片,以保证计时的正确性。

(二)材料清单:二、电路原理图设计本设计共用到四款主要芯片,分别为单片机芯片80C51、EEPROM芯片AT24C02、时钟芯片DS1302和转串口芯片MAX232。

(一)下图为80C51单片机芯片的管脚图,80C51有两个16位定时计数器,两个外中断,两个定时计数中断,及一个串行中断,并有4个8位并行输入口即I/O口。

80C51内部有时钟电路,但需要石英晶体和微调电容外接,本系统中采用12MHz的晶振频率。

(二)下图为AT24C02芯片的原理图,该芯片是一种带有I2C总线结构的EEPROM芯片,通过SDA和SCL端口与总线连接,具有非易失性,掉电仍可保存程序。

其管脚功能如下:管脚名称功能说明A0、A1、A2 器件地址选择本设计全部接地SDA 串行数据、地址与单片机的P1.6连接进行数据、地址的传输SCL 串行时钟与单片机的P1.7相连,串行时钟信号输入WP 写保护WP=1,只能对其读,写禁止,所以令WP=0VCC +1.8V~6.0V工作电压电源输入GND 地接地引脚(三)下图是时钟芯片的电路原理图,DS1307是一款低功耗,地址和数据通过两线双向的串行总线的传输,节省单片机资源,该芯片可以提供秒,分,小时等信息,芯片有一个内置的电源感应电路,具有掉电检测和电池切换功能,本设计中需要其停电后继续计时。

其中的7引脚是方波的输出端,可接入单片机的可引起中断的端口,利用引脚7产生的方波引起中断,从而显示时间的变化。

(四)下图是MAX232芯片的原理图,因为设计要求与电脑有串口通讯,就是将交通灯不同时间段程序控制方案通过串口下载到单片机里,单片机上有一个全双工的串行通讯口,但电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,所以采用了专用芯片MAX232进行转换,下图中的7、8端口分别和电脑上的RS232端口的2、3连接,芯片的9和10端口与单片机的串口相连,如下图所示:(五)下图为交通灯的总体原理图(不包括上述芯片原理图),根据要求选择六只LED灯作为东西和南北方向的红绿黄交通灯,并且每个方向上有时间计数提示,每个方向有两位数码管动态显示,最大为99,采用共阴极7段数码管,单片机通过驱动器SN7404的放大电流驱动每位数码管。

P1.0至P1.5控制六只LED灯,数码管由P0.0至P0.6控制进行段选,P2.0至P2.3控制位选。

三、程序设计(一)系统框图:(二)主程序如下:#include"reg51.h"#include<intrins.h>#define EW_H 0#define EW_L 1#define SN_H 2#define SN_L 3//函数声明void EW_NONE();void EW_RED();void EW_YELLOW();void EW_GREEN();void SN_NONE();void SN_RED();void SN_YELLOW();void SN_GREEN();void LED_INIT();void LED_WRITE(int dat,int con); //根据原理图定义交通灯的引脚sbit EW_LED_RED = P1^0;sbit EW_LED_YELLOW = P1^1;sbit EW_LED_GREEN = P1^2;sbit SN_LED_RED = P1^3;sbit SN_LED_YELLOW = P1^4;sbit SN_LED_GREEN = P1^5;//定义P2^0-P2^3=LED数码管控制sbit EW_weixuan_H = P2^0;sbit EW_weixuan_L = P2^1;sbit SN_weixuan_H = P2^2;sbit SN_weixuan_L = P2^3;//定义P0^0-P0^7=LED数码管段选引脚sbit LED_DATA_A = P0^0;sbit LED_DATA_B = P0^1;sbit LED_DATA_C = P0^2;sbit LED_DATA_D = P0^3;sbit LED_DATA_E = P0^4;sbit LED_DATA_F = P0^5;sbit LED_DATA_G = P0^6;sbit SCL = P1^6;sbit SDA = P1^7;//变量声明unsigned char counter,ew_sign,sn_sign,ew_time,sn_time,hour//定义段码code char LED_CODE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};/*main函数开始*/main(){counter = 3;//计数器,每3600s查询一次当前hourew_sign = 0;//东西标志位,0代表红灯,1代表绿灯,2代表黄灯sn_sign = 0;//南北标志位,0代表红灯,1代表绿灯,2代表黄灯ew_time = 3;//东西时间sn_time = 3;//南北时间hour = 24;//当前hourunsigned ew_total_time[24] = {1,1,1,1,1,30,30,30,30,30,30,30,60,60,60,60,30,30,30,30,30,30}//东西各时间段绿灯亮总时间unsigned char sn_total_time[24] = {1,1,1,1,1,30,30,60,60,60,60,60,30,30,30,30,30,30,30,30,30,30}//南北各时间段绿灯亮总时间LED_INTI();EW_RED();SN_RED();while(1){if(counter == 0){hour = GET_HOUR();counter = 3600;switch(hour){case 5:ew_time = 30;sn_time = 33;ew_sign = 1;sn_sign = 0;EW_GREEN();SN_RED();break;case 7:ew_time = 30;sn_time = 33;ew_sign = 1;sn_sign = 0;EW_GREEN();SN_RED();break;case 12:ew_time = 60;sn_time = 63;ew_sign = 1;sn_sign = 0;EW_GREEN();SN_RED();break;case 18:ew_time = 30;sn_time = 33;ew_sign = 1;sn_sign = 0;EW_GREEN();SN_RED();break;default:break;}}if(ew_time == 0){switch(ew_sign){case 0:ew_sign = 1;ew_time = ew_total_time[hour];EW_GREEN();break;case 1:ew_sign = 2;ew_time = 3;EW_YELLOW();break;case 2:ew_sign = 0;ew_time = sn_total_time[hour] + 3;EW_RED();break;}}if(sn_time == 0){switch(sn_sign){case 0:sn_sign = 1;sn_time = sn_total_time[hour];SN_GREEN();break;case 1:sn_sign = 2;sn_time = 3;SN_YELLOW();break;case 2:sn_sign = 0;sn_time = ew_total_time[hour] + 3;SN_RED();break;}}LED_WRITE(ew_time/10,EW_H);LED_WRITE(ew_time%10,EW_L);LED_WRITE(sn_time/10,SN_H);LED_WRITE(sn_time%10,SN_L);}//main函数到此结束,以下是所用到函数的定义/*所用函数的定义*/void LED_INIT(){LED = 0x00;EW_weixuan_H = 1;EW_weixuan_L = 1;SN_weixuan_H = 1;SN_weixuan_L = 1;}void LED_WRITE(int dat,int con){EW_weixuan_H = 0;EW_weixuan_L = 0;SN_weixuan_H = 0;SN_weixuan_L = 0;if(dat < 10){LED = LED_CODE[dat];switch(con){case EW_H:{EW_weixuan_H = 1;break;}case EW_L:{EW_weixuan_L = 1;break;}case SN_H:{SN_weixuan_H = 1;break;}case SN_L:{SN_weixuan_L = 1;break;}}}void timer_int() interrupt 0{EA = 0;counter--;switch(hour){case 0:case 1:case 2:case 3:case 4:EW_YELLOW();SN_YELLOW();EW_NONE();SN_NONE();break;default:ew_time--;sn_time--;if(ew_sign == 1 && ew_time <= 3 && ew_time > 0){EW_GREEN();EW_NONE();}if(sn_sign == 1 && sn_time <= 3 && sn_time > 0){SN_GREEN();SN_NONE();}break;}EA = 1;}/* 延迟函数定义*/void DELAY2(){_nop_();_nop_();}//延迟2usvoid DELAY4(){DELAY2();DELAY2();}//延迟4usvoid DELAY8(){DELAY4();DELAY4();}//延迟8us//void IIC_WRITE( unsigned char dat) {unsigned char temp;for(temp = 0; temp < 8; temp++){SCL=0;if((dat << temp) & 0x80){SDA=1;}else{SDA=0;}DELAY2();SCL=1;DELAY4();SCL=0;}DELAY4();SDA = 1;DELAY2();SCL = 1;DELAY4();SCL = 0;}unsigned char GET_HOUR(){//STARThour = 0;unsigned char temp;SDA = 1;DELAY8();SDA = 0;DELAY8();//WRITEIIC_WRITE(0XD0);//HOURADDRESSIIC_WRITE(0X02);//RESTARTSDA = 1;SCL = 1;DELAY8();SDA = 0;DELAY8();//READIIC_WRITE(0XD1);//READHOURSDA = 1;for(temp = 0; temp < 8; temp++){hour = hour << 1;SCL=1;DELAY2();if(SDA == 1){hour++;}SCL=0;}//SENDNOACKSDA = 1;SCL = 1;DELAY4();SCL = 0;//STOPSDA = 0;DELAY8();SDA = 1;DELAY4();SCL = 0;return hour;}四、心得体会通过这次的实验设计,我深入了对单片机的了解,也明白了日常生活中处处有自动控制的例子,其中不乏有各种系列的单片机,同时我也认识到对单片机的学习应该更加深入才能得心应手,虽然只是一个芯片而已,但是如果你具备足够的知识,就可以充分利用,根据自己的设想就可以做出各种实用的东西,而我现在发现自己基本还处于初级阶段,需要更加努力,特别是编程能力,当然也有收获,首先我对protel的使用更有信心了,又发现了其中的一些功能,同时我也了解了一些其它芯片,比如EEPROM存储芯片AT24C02的非易失性,DS1302时钟芯片可以精确的计时,为了与电脑进行串口通讯必须采用转串口芯片比如MAX232,从而实现单片机的TTL电平到RS232电平的转换。

相关主题