当前位置: 首页 > ds >正文

基于51单片机的交通信号灯设计

交通信号灯

基于51单片机的交通信号灯设计

简介

1.本系统采用STC89C51单片机以及单片机最小系统和74HC245电路以及外围的按键和数码管显示等部件,设计一个基于单片机的交通灯设计。设计通过两位一体共阴极数码管显示,并能通过按键对定时进行设置,而且具有蜂鸣器提示。
2、本设计拟实现的性能指标如下:
设在十字路口,分为东西向和南北向,在任一时刻只有一个方向通行,另一方向禁行,持续一定时间,经过短暂的过渡时间,将通行禁行方向对换。
四个状态归纳如下:
(1)东西方向红灯灭,同时绿灯亮,南北方向黄灯灭,同时红灯亮,倒计时20秒。此状态下,东西向禁止通行,南北向允许通行。
(2)东西方向绿灯灭,同时黄灯亮,南北方向红灯亮,倒计时5秒。此状态下,除了已经正在通行中的其他所以车辆都需等待状态转换。
(3)南北方向红灯灭,同时绿灯亮,东西方向黄灯灭,同时红灯亮,倒计时30秒。此状态下,东西向允许通行,南北向禁止通行。
(4)南北方向绿灯灭,同时黄灯亮,东西方向红灯亮,倒计时5秒。此状态下,除了已经正在通行中的其他所以车辆都需等待状态转换。
STC89C51单片机
STC89C51是一种低功耗、高性能CMOS8位微控制器,具有 4K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 具有以下标准功能: 4k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。
STC89C51单片机引脚图
STC89C51单片机引脚图
(一)STC89C51主要功能、性能参数如下:
(1)内置标准51内核,机器周期:增强型为6时钟,普通型为12时钟;
(2)工作频率范围:040MHZ,相当于普通8051的080MHZ;
(3)STC89C51RC对应Flash空间:4KB;
(4)内部存储器(RAM):512B;
(5)定时器\计数器:3个16位;
(6)通用异步通信口(UART)1个;
(7)中断源:8个;
(8)有ISP(在系统可编程)\IAP(在应用可编程),无需专用编程器\仿真器;
(9)通用I\O口:32\36个;
(10)工作电压:3.8~5.5V;
(11)外形封装:40脚PDIP、44脚PLCC和PQFP等。
(二)STC89C51单片机的引脚说明:
(二)STC89C51单片机的引脚说明:
VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(记时器0外部输入)
P3.5 T1(记时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
I/O口作为输入口时有两种工作方式,即所谓的读端口与读引脚。读端口时实际上并不从外部读入数据,而是把端口锁存器的内容读入到内部总线,经过某种运算或变换后再写回到端口锁存器。只有读端口时才真正地把外部的数据读入到内部总线。上面图中的两个三角形表示的就是输入缓冲器CPU将根据不同的指令分别发出读端口或读引脚信号以完成不同的操作。这是由硬件自动完成的,不需要我们操心,1然后再实行读引脚操作,否则就可能读入出错,为什么看上面的图,如果不对端口置1端口锁存器原来的状态有可能为0Q端为0Q^为1加到场效应管栅极的信号为1,该场效应管就导通对地呈现低阻抗,此时即使引脚上输入的信号为1,也会因端口的低阻抗而使信号变低使得外加的1信号读入后不一定是1。若先执行置1操作,则可以使场效应管截止引脚信号直接加到三态缓冲器中实现正确的读入,由于在输入操作时还必须附加一个准备动作,所以这类I/O口被称为准双向口。89C51的P0/P1/P2/P3口作为输入时都是准双向口。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。

数码管显示
数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按能显示多少个“8”可分为1位、2位、4位等等数码管:按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。

硬件电路设计
1.信号显示驱动电路
74HC245译码器可接受3位二进制加权地址输入(A0, A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。74HC245特有3个使能输入端:两个低有效(E1和E2)和一个高有效(E3)。除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。利用这种复合使能特性,仅需4片74HC245芯片和1个反相器,即可轻松实现并行扩展,组合成为一个1-32(5线到32线)译码器。任选一个低有效使能输入端作为数据输入,而把其余的使能输入端作为选通端,则74HC245亦可充当一个8输出多路分配器,未使用的使能输入端必须保持绑定在各自合适的高有效或低有效状态。
信号显示驱动电路
2.键盘输入电路
单片机键盘有独立键盘和矩阵式键盘两种:独立键盘每一个I/O 口上只接一个按键,按键的另一端接电源或接地(一般接地),这种接法程序比较简单且系统更加稳定;而矩阵式键盘式接法程序比较复杂,但是占用的I/O少。根据本设计的需要这里选用了独立式键盘接法。
注意消抖
键盘输入电路
3.蜂鸣器驱动电路
蜂鸣器驱动电路一般都包含以下几个部分:一个三极管、一个蜂鸣器、一个限流电阻。
蜂鸣器为发声元件,在其两端施加直流电压(有源蜂鸣器)或者方波(无源蜂鸣器)就可以发声,其主要参数是外形尺寸、发声方向、工作电压、工作频率、工作电流、驱动方式(直流/方波)等。这些都可以根据需要来选择。本设计采用有源蜂鸣器。
三极管Q1起开关作用,其基极的低电平使三极管饱和导通,使蜂鸣器发声;而基极高电平则使三极管关闭,蜂鸣器停止发声。
蜂鸣器驱动电路

源文件下载
链接:原文件资源下载

仿真图

交通灯仿真图

代码

#include <reg51.h>				//头文件
#define uchar unsigned char
#define uint  unsigned int		//宏定义uchar data buf[4];					//秒显示的变量
uchar data sec_dx=20;  			//东西数默认
uchar data sec_nb=30;			//南北默认值
uchar data set_timedx=20;		//设置东西方向的时间
uchar data set_timenb=30;		//设置南北方向的时间
int n;
uchar data countt0,countt1;//定时器0中断次数
//定义6组开关
sbit  k4=P3^7;      //切换方向
sbit  k1=P3^5;		//时间加
sbit  k2=P3^6;		//时间减
sbit  k3=P3^4;		//确认
sbit  k5=P3^1;		//禁止
sbit  k6=P1^5;		//夜间模式sbit Red_nb=P2^6;		//南北红灯标志
sbit Yellow_nb=P2^5;	//南北黄灯标志
sbit Green_nb=P2^4;     //南北绿灯标志sbit Red_dx=P2^3;		//东西红灯标志
sbit Yellow_dx=P2^2;	//东西黄灯标志
sbit Green_dx=P2^1;		//东西绿灯标志bit set=0;				//调时方向切换键标志 =1时,南北,=0时,东西
bit dx_nb=0;			//东西南北控制位
bit shanruo=0;			//闪烁标志位
bit yejian=0;			//夜间黄灯闪烁标志位uchar code table[11]={	//共阴极字型码0x3f,  //--00x06,  //--10x5b,  //--20x4f,  //--30x66,  //--40x6d,  //--50x7d,  //--60x07,  //--70x7f,  //--80x6f,  //--90x00   //--NULL
};//函数的声明部分
void delay(int ms);			//延时子程序
void key();					//按键扫描子程序
void display();				//显示子程序
void logo();   				//开机LOGO
void Buzzer();
//主程序
void main()
{TMOD=0X11;	   				//定时器设置TH1=0X3C;		TL1=0XB0;TH0=0X3C;					//定时器0置初值 0.05STL0=0XB0;EA=1;						//开总中断ET0=1;						//定时器0中断开启ET1=1;					   //定时器1中断开启TR0=1;						//启动定时0TR1=0;						 	//关闭定时1logo();						//开机初始化P2=0Xc3;					// 开始默认状态,东西绿灯,南北黄灯   sec_nb=sec_dx+5; 			//默认南北通行时间比东西多5秒while(1)					  //主循环{	 key(); 					//调用按键扫描程序display(); 				//调用显示程序}	
}
//函数的定义部分
void key(void)	//按键扫描子程序
{	 if(k1!=1)							//当K1(时间加)按下时{display();       				//调用显示,用于延时消抖if(k1!=1)							//如果确定按下{TR0=0;	       				//关定时器	shanruo=0;					//闪烁标志位关P2=0x00;					//灭显示TR1=0;							//启动定时1if(set==0)					//设置键按下set_timedx++;   		//南北加1Selseset_timenb++;    		//东西加1Sif(set_timenb==100)set_timenb=1;if(	set_timedx==100)set_timedx=1;   		//加到100置1sec_nb=set_timenb ; 		//设置的数值赋给东西南北sec_dx=set_timedx;			do{ display();				 //调用显示,用于延时}while(k1!=1);			 //等待按键释放}}if(k2!=1)							//当K2(时间减)按键按下时{		display();       				//调用显示,用于延时消抖  if(k2!=1)						//如果确定按下{	TR0=0;         				//关定时器0	shanruo=0;					//闪烁标志位关P2=0x00;					//灭显示TR1=0;						//关定时器1	if(set==0)set_timedx--;  			//南北减1Selseset_timenb--;  			//东西减1Sif(set_timenb==0)set_timenb=99;	if(	set_timedx==0 )set_timedx=99;   		//减到1重置99sec_nb=set_timenb ;	 		//设置的数值赋给东西南北sec_dx=set_timedx;do	{ display();       		//调用显示,用于延时}while(k2!=1);			   //等待按键释放}}if(k3!=1)							//当K3(确认)键按下时{	display();       				//调用显示,用于延时消抖if(k3!=1)						//如果确定按下{TR0=1;  						//启动定时器0sec_nb=set_timenb;				//从中断回复,仍显示设置过的数值sec_dx=set_timedx;				//显示设置过的时间TR1=0;							//关定时器1	if(set==0)						//时间倒时到0时{ P2=0X00;					 //灭显示Green_dx=1;						//东西绿灯亮Red_nb=1;					//南北红灯亮sec_nb=sec_dx+5; 			//回到初值}else { P2=0x00;					//南北绿灯,东西红灯Green_nb=1;Red_dx=1;sec_dx=sec_nb+5; }}}if(k4!=1)							//当K4(切换)键按下{display();       				//调用显示,用于延时消抖if(k4!=1)						//如果确定按下{  TR0=0;						//关定时器0	set=!set;					//取反set标志位,以切换调节方向TR1=0;						//关定时器1dx_nb=set;do{display(); 			   //调用显示,用于延时}				while(k4!=1);			  //等待按键释放}}	if(k5!=1)							//当K5(禁止)键按下时{display();       				//调用显示,用于延时消抖if(k5!=1)						//如果确定按下{ 	TR0=0;						//关定时器P2=0x00;					//灭显示Red_dx=1;Red_nb=1;					//全部置红灯TR1=0;sec_dx=00;					//四个方向的时间都为00sec_nb=00;do{display(); 				//调用显示,用于延时}	while(k5!=1);			//等待按键释放	}}if(k6!=1)							//当K6(夜间模式)按下 {display();       				//调用显示,用于延时消抖 if(k6!=1)						//如果确定按下{ 	TR0=0;						//关定时器P2=0x00;TR1=1;sec_dx=00;					//四个方向的时间都为00sec_nb=00;do{display(); 			  //调用显示,用于延时}	while(k6!=1);			//等待按键释放	}}
}
void display(void) //显示子程序
{		buf[1]=sec_nb/10; 		//第1位 东西秒十位buf[2]=sec_nb%10; 		//第2位 东西秒个位buf[3]=sec_dx/10; 		//第3位 南北秒十位buf[0]=sec_dx%10; 		//第4位 南北秒个位		P1=0xff;          		// 初始灯为灭的P0=0x00;				 灭显示P1=0xfe;           		//片选LED1P0=table[buf[1]];		//送东西时间十位的数码管编码			delay(1);				//延时P1=0xff;				//关显示P0=0x00;				//灭显示P1=0xfd;             	//片选LED2P0=table[buf[2]];		 //送东西时间个位的数码管编码delay(1);				 //延时P1=0xff;				//关显示P0=0x00;				//关显示P1=0Xfb;		  		//片选LED3P0=table[buf[3]];		//送南北时间十位的数码管编码delay(1);				//延时P1=0xff;				 //关显示P0=0x00;				 //关显示P1=0Xf7;				 //片选LED4	P0=table[buf[0]];		//送南北时间个位的数码管编码delay(1);				//延时
}void time0(void) interrupt 1 using 1  	//定时中断子程序
{TH0=0X3C;							//重赋初值TL0=0XB0;							//12m晶振50ms//重赋初值TR0=1;								//重新启动定时器countt0++;							//软件计数加1if(countt0==10)						//加到10也就是半秒{if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1))  		//东西黄灯闪		{Green_dx=0;Yellow_dx=0;}		   				if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1))  		//南北黄灯闪		{  Green_nb=0;Yellow_nb=0;}	}if(countt0==20)	                  	// 定时器中断次数=20时(即1秒时){	countt0=0;						//清零计数器sec_dx--;						//东西时间减1sec_nb--;						//南北时间减1if((sec_nb<=5)&&(dx_nb==0)&&(shanruo==1))  		//东西黄灯闪		{Green_dx=0;Yellow_dx=1;}		   				if((sec_dx<=5)&&(dx_nb==1)&&(shanruo==1))  		//南北黄灯闪		{  Green_nb=0;Yellow_nb=1;}		 						if(sec_dx==0&&sec_nb==5) 		//当东西倒计时到0时,重置5秒,用于黄灯闪烁时间   {sec_dx=5;shanruo=1;}if(sec_nb==0&&sec_dx==5)		//当南北倒计时到0时,重置5秒,用于黄灯闪烁时间   {sec_nb=5;shanruo=1;}if(dx_nb==0&&sec_nb==0)			//当黄灯闪烁时间倒计时到0时,{P2=0x00;					//重置东西南背方向的红绿灯Green_nb=1;Red_dx=1;dx_nb=!dx_nb;shanruo=0;sec_nb=set_timenb;			//重赋南北方向的起始值sec_dx=set_timenb+5;		//重赋东西方向的起始值}		if(dx_nb==1&&sec_dx==0)			//当黄灯闪烁时间到{P2=0X00;					//重置东西南北的红绿灯状态Green_dx=1;					 //东西绿灯亮Red_nb=1;					 //南北红灯亮dx_nb=!dx_nb;				 //取反shanruo=0;					//闪烁sec_dx=set_timedx;			//重赋东西方向的起始值sec_nb=set_timedx+5;		//重赋南北方向的起始值}}	
}
void time1(void) interrupt 3 	//定时中断子程序
{TH1=0X3C;							//重赋初值TL1=0XB0;							//12m晶振50ms//重赋初值countt1++;							//软件计数加1if(countt1==10)					   // 定时器中断次数=10时(即0.5秒){Yellow_nb=0;				//南北黄灯灭Yellow_dx=0;				//东西黄灯灭}if(countt1==20)	                  	// 定时器中断次数=20时(即1秒时){	countt1=0;						//清零计数器Yellow_nb=1;					//南北黄灯亮Yellow_dx=1;			  	//东西黄灯亮}	
}void logo()//开机的Logo  "- - - -"
{ for(n=0;n<50;n++)	//循环显示----50次{P0=0x40;  //送形“-”P1=0xfe;	//第一位显示delay(1);	//延时P1=0xfd;	//第二位显示delay(1);	//延时P1=0Xfb;	//第三位显示delay(1);	//延时P1=0Xf7;	//第四位显示delay(1);	//延时P1 = 0xff;	//灭显示}
}void delay(int ms)		//延时子程序
{uint j,k;for(j=0;j<ms;j++)			//延时msfor(k=0;k<124;k++);		//大约1毫秒的延时
}`
http://www.xdnf.cn/news/11434.html

相关文章:

  • 阿里与腾讯人的区别,就是明教与武当的反差
  • Firefox 3.0 简体中文正式版官方下载及精选插件集合
  • 免费语音转字幕功能介绍
  • 四款黑客游戏全部通关,你就是大佬
  • 时间序列的平稳性
  • 一个超好看的音乐网站设计与实现(HTML+CSS)
  • 自然语言处理基础技术之分词介绍
  • VGA, QVGA, HVGA, WVGA, FWVGA和iPhone显示分辨率
  • TWiki
  • 计算机投稿
  • pacman用法详解
  • 华大HC32F460 内存使用注意事项(内存bug)
  • 函数----ModifyStyle
  • STC15单片机自带的AD功能的使用
  • VirtualBox虚拟机网络设置(四种方式)
  • 两台电脑如何建立局域网?三种简便方法推荐
  • 运行程序提示access violation at address的解决方法
  • 阿姆达尔定律的演进:古斯塔夫森定律
  • Intel Developer Cloud - AI 模型性能评估
  • 【odoo15】在Action设置里增添一个自己的list
  • 多日之苦终得救:“威金”专杀工具发布(转)
  • 制作img镜像文件的5种方法
  • Matlab:自定义等高线图的填充颜色
  • 【贝加莱PLC基础教学】1.AutiomationStudio软件安装
  • viper4android fx 驱动,ViPER4Android FX 音效驱动社区版安
  • 前端知识2-CSS
  • 传奇私服架设(温故2002,自己制作传奇私服服务器)
  • MIPI 系列之 DCS
  • 软件可靠性、可维护性、可用性
  • 使用PowerDesigner设计数据库保姆级教程