51交通灯控制系统.docx
《51交通灯控制系统.docx》由会员分享,可在线阅读,更多相关《51交通灯控制系统.docx(18页珍藏版)》请在冰豆网上搜索。
51交通灯控制系统
MCS-51单片机课程设计报告
——交通灯控制系统
姓名:
朱正威
学号:
110901418
指导老师:
潘峰
东华大学信息学院自动化系
2014.6.22
一、项目概述
项目所要设计的是交通灯控制系统,十字路口交通灯由红、绿两色LED显示器(两位8段LED显示器)组成,LED显示器显示切换倒计时,以秒为单位,每秒更新一次;为确保安全,绿LED计数到0转红,经5秒延时(显示红色0)后,另一道开始绿色倒计时。
1)主干道(A道)先通行且通行时间为45s;(加5秒红灯延时,共50秒)
2)支道(B道)通行时间为25s;(加秒红灯延时,共30秒)
3)主道与支道的车辆交错通行;
4)若遇紧急情况,按开关时,主道与支道都为红灯20s
5)根据实时交通堵塞情况人为控制时,按K2时,主道延时30s通行,按K3时,支道延时30s通行。
设计以AT89C51为核心的控制电路,并编写相关的系统软件。
二、系统设计
1.设计思想
该模拟交通灯控制系统采用模块化结构,主要分为定时器中断控制、按键扫描、LED数码管显示三个部分。
在设计完成一个方向上的红绿灯数码管计时后,再进行两个方向红绿灯的切换显示以及特殊情况下的处理。
2.方案可行性分析
采用AT89C51作为系统主控芯片,其包含两个定时器中断T0和T1、两个外部中断,以及4个I/O端口P0到P3端口。
本系统采用其定时器T1进行定时,每隔一定时间定时中断一次,在中断程序内进行变量自加,以此可以设置任意长的定时时间。
如设置1s的定时改变红绿灯LED数码管显示值,设置0.2m的按键扫描周期进行按键定时扫描。
为了节省I/O口资源以及硬件连接上的方便,采用串口显示芯片MAX7219进行LED数码管显示部分的设计。
整个方案设计结构清晰明了,硬件连接简洁,软件编程模块清晰,经实践验证,此方案可行。
3.总体方案
在Proteus环境中进行硬件电路的设计和搭建,具体硬件电路设计如图1、2所示。
在Keil环境下进行软件设计51单片机编程,为定时器中断和MAX7219串口显示和主函数部分分别建立相应的源文件和头文件,进行模块化编程。
图1、硬件连接图
图2、整体系统图
三、硬件设计
系统硬件设计主要分为三个部分,即单片机最小系统部分、LED数码管串行显示部分和独立按键部分。
4.单片机最小系统部分
按要求选用AT89C51型号单片机,晶振频率12MHz,使用内部RAM和ROM。
由于Proteus环境下默认无需晶振电路和复位电路等,所以并未画出。
5.LED数码管串行显示部分
MAX7219是一种集成化的串行输入/输出共阴极显示驱动器,与单片机只需三根信号进行通信,可以连接8位数字的7段LED数码管。
其内部集成了数据保持、BCD译码器、多路扫描器、段驱动器和位驱动器。
每片MAX7219最多可同时驱动8个LED数码管,而交通灯控制系统正好需要8个LED数码管。
同时,利用其内部BCD译码功能,可以省去额外的软件或硬件译码操作。
具体连接如图3所示。
图3、MAX7219连接图
6.独立按键部分
该系统需要根据外部按键K1、K2和K3进行人工干预,按键较少,可以采用三个独立按键接在三个单片机I/O引脚上,在定时中断内进行按键的扫描。
按键连接部分如图4所示。
图4、按键连接图
四、软件设计
7.软件设计思想
在Keil环境下进行软件设计51单片机编程,软件部分主要分为定时器中断、MAX7219串口显示和主函数部分,进行模块化编程,为各个部分分别建立相应的.h头文件和.c源文件。
定时器中断部分:
选用定时器T1,方式2,8位自动重装初值。
250us产生一次定时器中断,由于单片机晶振为12MHz,经计算,计数初值为6。
在中断服务程序内进行变量counter的自加,当counter自加40次之后即为一次10ms中断,以此为基本时间单位可以进行进一步的定时。
MAX7219串口显示部分:
首先定义串口数据发送函数MAX7219_write,然后按照命令控制字,初始化MAX7219工作模式。
主要需要初始化的几个寄存器为:
寄存器地址
功能
0x0A
亮度控制,0x00~0x0F,0x0F最亮
0x0B
设置扫描LED个数
0x0C
工作模式0x00ShutDown0x01:
Normal
0x09
编码模式对应bit为1则支持编码
8.程序流程图
整个程序的流程图如图5所示。
图5、程序流程图
9.程序清单
1)MAX7219串口显示程序
#include
#include"MAX7219.h"
#defineucharunsignedchar
sbitMAX7219_DIN=P1^0;//串行数据输入DIN
sbitMAX7219_CLK=P1^1;//时钟信号CLK
sbitMAX7219_LOAD=P1^2;//数据锁存脉冲信号LOAD
/************MAX7219写寄存器函数**************/
//addr:
寄存器地址
//dat:
写入寄存器的值
//说明:
D12~D15为无关位,D8~D11为寄存器地址,D0~D7为命令或待显数据
voidMAX7219_write(ucharaddr,uchardat)
{
uchari=0;
MAX7219_LOAD=0;
for(i=0;i<8;i++)//先写地址
{
MAX7219_CLK=0;
MAX7219_DIN=(addr&(0x80>>i))?
1:
0;
i++;
i--;
MAX7219_CLK=1;//时钟上升沿写入
}
for(i=0;i<8;i++)//再写数据
{
MAX7219_CLK=0;
MAX7219_DIN=(dat&(0x80>>i))?
1:
0;
i++;
i--;
MAX7219_CLK=1;
}
MAX7219_LOAD=1;
}
/*********************************************/
/*************MAX7219初始化函数***************/
voidMAX7219_init()
{
MAX7219_write(0x0A,0x07);//亮度地址0AH,0x00~0x0F,0x0F最亮
MAX7219_write(0x0B,0x07);//设置扫描LED个数地址0BH,扫描8个
MAX7219_write(0x0C,0x01);//工作模式地址0x0C.0x00:
ShutDown;0x01:
Normal
MAX7219_write(0x09,0xFF);//编码模式地址0x09.0x00~0xFF:
哪一位为1,哪一位就支持译码
}
/*********************************************/
2)按键扫描函数
/******************按键扫描函数******************/
ucharkey_scan()
{
ucharkey,valid_key,delay=125;
key=P1&0x70;
while(delay--);
valid_key=P1&0x70;
if(key!
=valid_key)//按键消抖
return0;
switch(key)
{
case0x60:
//按下K1按键
return1;
case0x50:
//按下K2按键
return2;
case0x30:
//按下K3按键
return3;
default:
//其它情况不考虑
return0;
}
}
/************************************************/
3)定时器初始化及中断处理
/**************定时器1中断服务程序*************/
voidINT_timer0()interrupt3
{
ucharkey_temp=0;
counter++;
if(counter==40)//10ms一次中断处理
{
counter=0;
if(cnt>=100)
{
cnt=0;
led_counter();//1s刷新一次数码管
}
cnt++;
if(cnt1>=20)//0.2s一次按键扫描
{
cnt1=0;
key_temp=key_scan();
if(key_temp==1)
key=1;
elseif(key_temp==2)
{
num[3]+=3;//主干道为红灯时延时30s通行
if(num[3]>9)
num[3]=9;
}
elseif(key_temp==3)//支道为红灯时延时30s通行
{
num[1]+=3;
if(num[1]>9)
num[1]=9;//可累积延时,但不超过99s
}
}
cnt1++;
}
}
/************************************************/
/******************定时器初始化****************/
voidInit_timer()
{
counter=0;
TMOD=0x20;//8位定时器,自动重装初值
TH1=6;//定时250us
TL1=6;
TR1=1;
ET1=1;
}
/************************************************/
4)LED数码管模拟交通灯显示
staticucharcounter,cnt,cnt5,cnt1,hold_flag=0,dir_flag=0,key;
charnum[8]={6,4,6,2,1,2,0,0};//LED初始显示的数字
/*红绿灯数码管显示与数组值对应关系示意图
(主道)红灯绿灯
num[3]num[2]num[1]num[0]
(支道)绿灯红灯
num[3]num[2]num[1]num[0]
(紧急情况,主道支道)红灯
num[5],num[4]
*/
/*****************红绿灯计时函数***************/
voidled_counter()
{
if(key==1)//按下K1按键的处理
{
num[4]--;
if(num[5]>0)
{
if(num[4]<0)
{
num[4]=9;//个位从0数到9循环
num[5]--;
}
}
if(num[4]<0)//紧急情况延时20s完之后
{
key=0;
num[4]=1;
num[5]=2;
}
else
{
MAX7219_write(3,num[4]);//主道红灯20s计数
MAX7219_write(4,num[5]);
MAX7219_write(7,num[4]);//支道红灯20s计数
MAX7219_write(8,num[5]);
MAX7219_write(1,15);//主道绿灯灭
MAX7219_write(2,15);
MAX7219_write(5,15);//支道绿灯灭
MAX7219_write(6,15);
}
}
else
{
if(hold_flag)//5s红灯延时标志置位后5s延时
{
num[0]=6;
num[1]=4;
num[2]=6;
num[3]=2;
cnt5++;
if(cnt5>=4)
{
hold_flag=0;
cnt5=0;
}
}
elseif(!
dir_flag)//主干道通行
{
num[0]--;
if(num[1]>0)
{
if(num[0]<0)
{
num[0]=9;//个位从0数到9循环
num[1]--;
}
}
if(num[0]<0)//主道绿灯十位为0,个位也为0之后
{
num[0]=0;
num[1]=0;
hold_flag=1;//5s红灯延时标志置位
dir_flag=1;//换支道行驶标志置位
MAX7219_write(3,0);//主道红灯显示"0"
MAX7219_write(4,0);
MAX7219_write(1,15);//主道绿灯灭
MAX7219_write(2,15);
}
else
{
MAX7219_write(1,num[0]);//主道绿灯计数
MAX7219_write(2,num[1]);
MAX7219_write(7,num[0]);//支道红灯和主道绿灯同时计数
MAX7219_write(8,num[1]);
MAX7219_write(3,15);//主道红灯灭
MAX7219_write(4,15);
MAX7219_write(5,15);//支道绿灯灭
MAX7219_write(6,15);
}
}
else//支道通行
{
num[2]--;
if(num[3]>0)
{
if(num[2]<0)
{
num[2]=9;//个位从0数到9循环
num[3]--;
}
}
if(num[2]<0)//主道绿灯十位为0,个位也为0之后
{
num[2]=0;
num[3]=0;
hold_flag=1;//5s红灯延时标志置位
dir_flag=0;//换主道行驶标志置位
MAX7219_write(7,0);//支道红灯显示"0"
MAX7219_write(8,0);
MAX7219_write(5,15);//支道绿灯灭
MAX7219_write(6,15);
}
else
{
MAX7219_write(5,num[2]);//支道绿灯计数
MAX7219_write(6,num[3]);
MAX7219_write(3,num[2]);//主道红灯和支道绿灯同时计数
MAX7219_write(4,num[3]);
MAX7219_write(7,15);
MAX7219_write(8,15);//支道红灯灭
MAX7219_write(1,15);//主道绿灯灭
MAX7219_write(2,15);
}
}
}
}
/************************************************/
5)主函数
#include
#include"MAX7219.h"
#include"TIMER.h"
voidmain(void)
{
MAX7219_init();//7219串口显示芯片初始化
Init_timer();//定时器中断初始化
EA=1;//开总中断,系统开始计时
while
(1);
}
五、系统仿真及调试
在Proteus环境下,将上述程序进行编译后加载到单片机中。
单击“全速仿真”按钮,即可看到数码管按规律显示。
图2显示的是交通灯正常显示时的状态。
图6显示的是按下K1按键后主道和支道都为20s红灯显示状态。
图7显示的是按下K2按键后,主道延时20s通行,也就是支道绿灯延时20s。
图6、
图7、
六、结果与展望
经过反复调试,最终在Proteus环境下通过仿真验证,整个交通灯控制系统功能全部实现。
系统软件设计部分力求规范,模块分明,代码复用率高,注释详解。
硬件设计采用了串口显示芯片和红绿色的两位的7段数码管,硬件上力求简洁,占用单片机I/O资源少。
此次课程设计加强了我对单片机工作原理及应用的了解,对项目硬件设计、软件设计和项目仿真的过程,进一步培养了我的实践能力、独立分析问题和解决问题的能力。
七、参考文献
1.单片机应用技术——基于Proteus的项目设计与仿真韩克、薛迎霄编著电子工业出版社
2.单片机原理及控制技术王君编著机械工业出版社