资源描述
xxxxxxxxx
基于AT89S52交通灯设计
学 院: 电子信息工程
专业班级: xxxxxxxxxxxxxx
姓 名: xx xx
学 号: xxxxxxxxxxx
指导老师: xxxxxxxxxx
摘要
交通灯在我们日常生活中随地可见,它在交通系统中处于至关关键位置。交通灯使用大大降低了交通繁忙路口事故发生,给行人和车辆提供一个安全交通环境,大家生命和财产安全有了保障。本设计意在模拟十字路口交通灯,以AT89S51单片机为基础,结合按键和数码管等元器件设计出一个简单且完全交通灯系统。
关键词:交通灯 AT89S52 单片机
目录
一、设计任务 3
二、AT89S52单片机及其它元器件介绍 3
(1)AT89S52单片机 3
三、系统硬件电路设计 5
(1)时钟电路设计 5
(2) 复位电路设计 5
(3) 灯控制电路设计 6
(4) 按键控制电路设计 6
四、元件清单及实物图 7
1、程序清单 7
2、原理图 8
五、试验心得 8
附1 源程序代码 9
附2 原理图 15
一、设计任务
(1)、设计一个十字路口交通灯控制电路,要求南北方向和东西方向两条交叉道路上车辆交替运行,每次通行时间全部设30秒,时间可设置修改。
(2)、在绿灯转为红灯时,要求黄灯先亮5秒钟,才能变换运行车道,且黄灯亮时,要求每秒亮一次。
(3)、有紧急车辆要求经过时,系统要能严禁东西和南北两条路上全部车辆通行。
二、AT89S52单片机及其它元器件介绍
(1)AT89S52单片机
AT89S52是一个低功耗、高性能CMOS8位微控制器。片上Flash许可程序存放器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧8位CPU和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效处理方案。AT89S52含有以下标准功效:8K字节Flash,256字节RAM,32位I/O口线,看门狗定时器,2个数据指针,三个16位定时器/计数器,一个6位向量2级中止结构,全双工串行口,片内晶振立即钟电路。空闲模式下,CPU停止工作,许可RAM、定时器计数器、串口、中止继续工作。鉴于以上优点本系统采取AT89S52作为主控芯片,实现对整个系统控制。
(2)芯片74LS245
74LS245是我们常见芯片,用来驱动led或其它设备,它是8路同相三态双向总线收发器,可双向传输数据。当19脚E为H时,A、B为高阻。E为L时,DIR为L时,数据由B传向A;DIR为H时,由A传向B。
(3)两位共阴数码管
16脚和11脚对应A、15脚和10脚对应B、3脚和8脚对应C、2脚和6脚对应D、1脚和5脚对应E、18脚和12脚对应F、17脚7脚对应G、4脚和9脚对应DP。公共脚为14脚和13脚,分别对应左边和右边显示数字。
三、系统硬件电路设计
(1)时钟电路设计
图所表示,采取内部时钟产生方法,在XTAL1和XTAL2两端跨接晶体或陶瓷振荡器,和内部反相器组成稳定自击震荡。其发出时钟脉冲直接送入片内定时控制部件。
(2) 复位电路设计
如上图所表示,采取上电+按钮电平复位方法,当按下按钮时,RST管脚高电平触发。为确保复位可靠,RC时间常数应大于两个机器周期,电容取10uf,电阻取1000欧。
(3) 灯控制电路设计
如上图所表示,交通灯状态显示电路由东西南北四个方向各三个LED灯组成,分别显示四个方向上红、黄、绿三个状态,用以指示十字路口各方向车辆行驶。经过软件编程,可使路口交通改变情况为:南北方向和东西方向两条交叉道路上车辆交替运行,主干道每次通行时间全部设为30秒。在绿灯转为红灯时,要求黄灯先亮5秒钟,才能变换运行车道;黄灯亮时每秒闪亮一次。
(4) 按键控制电路设计
开关控制由7个连接到单片机控制按钮组成。经过软件编程,使得各个开关功效如上图所表示, 基础满足了交通灯需要。
四、元件清单及实物图
1、程序清单
名 称
规 格
数 量
单片机
AT89S52
1
排阻
9脚10K
1
晶振
11.0592MHz
1
发光二极管
GREEN
3
发光二极管
RED
3
发光二极管
YELLOW
3
数码管
两位共阴
2
电阻
1K
1
电阻
10K
6
按键
8
电解电容
10uF
1
独石电容
22pF
2
电源插头
1
排座
20脚
1
排座
40脚
1
双排针
2.54间距
单排针
2.54间距
排线
15cm
16根
试验板
10*15cm
1
2、原理图
五、试验心得
这次交通灯制作是我学会了不少东西,首先是proteus和keil使用。单片机程序编写和原理图仿真全部是在这两个软件运行下才能够进行。这个试验最关键是让我对51系列单片机有了更深层次了解,这一学期 开接触单片机时候认为这是一门极其高深课程,老师讲什么基础完全不懂,课后看依旧是一头雾水。经过交通灯学习和制作,对单片机有了初步了解,知道了它组成、工作原理等等。
在软件编写这一块,开始时碰到了很大难题,因为两百行程序,哪怕有一个错误,修改起来也不是十分方便。时常没有心思去寻求和更正错误,所以软件这一块花了很大一部分时间。几次调试后总算出现“0 warning”和“0 error”字样。
焊接也是比较麻烦,因为万能板买小了,再加上需要连接线有很多根,所以首先必需考虑到元器件排布问题,尽可能让自己焊接时候方便一点。借鉴她人经验,数码管和排阻之间用排线相连接,很大程度上节省焊接时间,而且让板子看起来愈加整齐、美观。
除了学会很多东西认为,也发觉了自己不足。因为自己在这首先只是短缺,所以很多问题全部需要查阅资料或向别同学请教。比如说proteus和keil使用方法,全部是看着她人操作几遍以后才慢慢学会。还有在焊接这首先也存在着很大问题。因为焊接在万能板反面,所以有时候会把单片机引脚看错,然后用吸枪慢慢清理。这不仅浪费时间而且还可能破坏万能板。在焊接过程中还出现短路问题,一不小心锡丝用多了就有可能造成两个点之间短路问题,这一点说明了焊接能力还有待提升。
试验结果是成功,模拟出了交通灯功效,各个按键功效也和模拟时一致,看着数字跳动自己信息也感到十分快乐。即使想过在这个交通灯里加入部分额外功效,但终究因为自己知识不足而放弃,有点遗憾,不过能够学到东西就好。此次试验增加了自己单片机知识外也让我知道实践和理论学习差异。实践过程中学到知识自己记得会愈加牢靠部分,不轻易忘记。总来说,单片机制作让我收获不小。
附1 源程序代码
#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 b;//定时器中止次数
sbit k1=P1^6;//定义5组开关
sbit k2=P1^7;
sbit k3=P2^7;
sbit k4=P3^0;
sbit k5=P3^1;
sbit Yellow_nb=P2^5; //南北黄灯标志
sbit Yellow_dx=P2^2; //东西黄灯标志
sbit Green_nb=P2^4;
sbit Green_dx=P2^1;
sbit Buzz=P3^7;
bit Buzzer_Indicate;
bit time=0;//灯状态循环标志
bit set=1;//调时方向切换键标志
uchar code table[11]={ //共阴极字型码
0x3f, //--0
0x06, //--1
0x5b, //--2
0x4f, //--3
0x66, //--4
0x6d, //--5
0x7d, //--6
0x07, //--7
0x7f, //--8
0x6f, //--9
0x00 //--NULL
};
//函数申明部分
void delay(int ms);//延时子程序
void key();//按键扫描子程序
void key_to1();//键处理子程序
void key_to2();
void key_to3();
void display();//显示子程序
void logo(); //开机LOGO
void Buzzer();
//主程序
void main()
{
TMOD=0X01;
TH0=0XD8;
TL0=0XF0;
EA=1;
ET0=1;
TR0=1;
EX0=1;
EX1=1;
logo();
P2=0Xc3;// 开始默认状态,东西绿灯,南北黄灯
sec_nb=sec_dx+5;
while(1)
{
key(); //调用按键扫描程序
display(); //调用显示程序
Buzzer();
}
}
//函数定义部分
void key() //按键扫描子程序
{
if(k1!=1)
{
delay(10);
if(k1!=1)
{
while(k1!=1)
{
key_to1();
for(n=0;n<40;n++)
{ display();}
}
}
}
if(k2!=1)
{
delay(10);
if(k2!=1)
{
while(k2!=1)
{
key_to2();
for(n=0;n<40;n++)
{ display();}
}
}
}
if(k3!=1)
{
TR0=1; //开启定时器
Buzzer_Indicate=0;
sec_nb=set_timenb; //从中止回复,仍显示设置过数值
sec_dx=set_timedx;
if(time==0)
{ P2=0X99;sec_nb=sec_dx+5; }
else { P2=0xC3;sec_dx=sec_nb+5; }
}
if(k4!=1)
{
delay(5);
if(k4!=1)
{
while(k4!=1);
set=!set;
}
}
if(k5!=1)
{
delay(5);
if(k5!=1)
{
while(k5!=1)
key_to3();
}
}
}
void display() //显示子程序
{
buf[1]=sec_dx/10; //第1位 东西秒十位
buf[2]=sec_dx%10; //第2位 东西秒个位
buf[3]=sec_nb/10; //第3位 南北秒十位
buf[0]=sec_nb%10; //第4位 南北秒个位
P1=0xff; // 初始灯为灭
P0=0x00;
P1=0xfe; //片选LCD1
P0=table[buf[1]];
delay(1);
P1=0xff;
P0=0x00;
P1=0xfd; //片选LCD2
P0=table[buf[2]];
delay(1);
P1=0xff;
P0=0x00;
P1=0Xfb; //片选LCD3
P0=table[buf[3]];
delay(1);
P1=0xff;
P0=0x00;
P1=0Xf7;
P0=table[buf[0]]; //片选LCD4
delay(1);
}
void time0(void) interrupt 1 using 1 //定时中止子程序
{
b++;
if(b==19) // 定时器中止次数
{ b=0;
sec_dx--;
sec_nb--;
if(sec_nb<=5&&time==0) //东西黄灯闪
{ Green_dx=0;Yellow_dx=!Yellow_dx;}
if(sec_dx<=5&&time==1) //南北黄灯闪
{ Green_nb=0;Yellow_nb=!Yellow_nb;}
if(sec_dx==0&&sec_nb==5)
sec_dx=5;
if(sec_nb==0&&sec_dx==5)
sec_nb=5;
if(time==0&&sec_nb==0)
{ P2=0x99;time=!time;sec_nb=set_timenb;sec_dx=set_timenb+5;}
if(time==1&&sec_dx==0)
{P2=0Xc3;time=!time;sec_dx=set_timedx;sec_nb=set_timedx+5;}
}
}
void key_to1() //键盘处理子程序之+
{
TR0=0; //关定时器
if(set==0)
set_timenb++; //南北加1S
else
set_timedx++; //东西加1S
if(set_timenb==100)
set_timenb=1;
if( set_timedx==100)
set_timedx=1; //加到100置1
sec_nb=set_timenb ; //设置数值赋给东西南北
sec_dx=set_timedx;
}
void key_to2() //键盘处理子程序之-
{
TR0=0; //关定时器
if(set==0)
set_timenb--; //南北减1S
else
set_timedx--; //东西减1S
if(set_timenb==0)
set_timenb=99;
if( set_timedx==0 )
set_timedx=99; //减到1重置99
sec_nb=set_timenb ; //设置数值赋给东西南北
sec_dx=set_timedx;
}
void key_to3() //键盘处理之紧急车通行
{
TR0=0;
P2=0Xc9;
sec_dx=00;
sec_nb=00;
Buzzer_Indicate=1;
}
void int0(void) interrupt 0 using 1 //只许可东西通行
{
TR0=0;
P2=0Xc3;
Buzzer_Indicate=0;
sec_dx=00;
sec_nb=00;
}
void int1(void) interrupt 2 using 1 //只许可南北通行
{
TR0=0;
P2=0X99;
Buzzer_Indicate=0;
sec_nb=00;
sec_dx=00;
}
void logo()//开机Logo "- - - -"
{ for(n=0;n<50;n++)
{
P0=0x40;
P1=0xfe;
delay(1);
P1=0xfd;
delay(1);
P1=0Xfb;
delay(1);
P1=0Xf7;
delay(1);
P1 = 0xff;
}
}
void Buzzer()
{
if(Buzzer_Indicate==1)
Buzz=!Buzz;
else Buzz=0;
}
void delay(int ms) //延时子程序
{
uint j,k;
for(j=0;j<ms;j++)
for(k=0;k<124;k++);
}
附2 原理图
展开阅读全文