单片机交通灯控制系统设计文档.docx
《单片机交通灯控制系统设计文档.docx》由会员分享,可在线阅读,更多相关《单片机交通灯控制系统设计文档.docx(38页珍藏版)》请在冰豆网上搜索。
![单片机交通灯控制系统设计文档.docx](https://file1.bdocx.com/fileroot1/2023-1/31/d84468de-ddc3-45d1-992a-2b3fece03a05/d84468de-ddc3-45d1-992a-2b3fece03a051.gif)
单片机交通灯控制系统设计文档
单片机交通灯控制系统
设计说明书
制作人:
康恺
制作日期:
2009-5-25
第一章设计说明……………………………………………3
第二章设计目标……………………………………………3
第三章总体设计……………………………………………3
3.1硬件功能设计………………………………………….4
3.2软件模块划分………………………………………...4
3.3软件模块功能设计…………………………………….4
3.4系统工作流程设计…………………………………….4
第四章硬件设计……………………………………………6
4.1器件选择…………………………………………………………6
4.2系统原理图设计…………………………………………………6
4.3主要器件应用简介………………………………………………7
第五章软件设计……………………………………………10
5.1主程序模块设计……………………………………….10
5.2按键扫描模块设计……………………………………11
5.3按键处理模块设计……………………………………11
5.4数码管显示、闪烁模块设计…………………………14
5.5数码管计数,数码管切换、交通灯切换模块设计…15
第六章代码设计……………………………………………15
第七章方案对比……………………………………………27
第八章系统测试……………………………………………27
8.1数码管显示最大时间时间测试………………………...28
8.2数码管显示最小时间时间测试………………………..30
第九章遇到的问题及解决方案……………………………34
第十章心得体会……………………………………………38
第一章设计说明
本设计的意义在于通过具体的控制系统的设计,掌握微机控制系统设计的一般方法和处理问题的思路,特别是一些常用的技术手段。
在实践教学环节中,积累设计经验,开拓思维空间,全面提高个人的综合能力
第二章设计目标
1、实现交通灯控制系统的基本功能;
2、可以通过按键调整主次干道的通行时间;
3、系统具有较强的稳定性;
4、系统可根据需要附加一些功能;
第三章总体设计方案
硬件功能设计
1、用二极管显示红绿黄等;
2、用数码管显示十字路口两个方向的剩余时间;
3、用单片机的定时器产生秒信号,控制十字路口的红绿黄灯交替点亮和熄灭;
4、用按键设置两个方向的通行时间(绿灯点亮时间)和暂缓黄灯通行时间(黄灯点亮的时间)
软件模块划分
软件模块功能设计
1、主程序负责初始化以及循环扫描键盘;
2、定时器0负责闪烁以及数码管的闪烁;
3、定时器1负责计数以及数码管的循环显示,交通灯的循环点亮;
4、键盘扫描模块负责获得键号并转到相应的程序进行处理;
5、键盘处理模块负责调整交通的通行以及暂缓通行时间
系统工作流程设计
1、系统启动后,系统按程序给定的时间工作,即东西向通行60秒,南北向通行40秒,黄灯亮4秒,工作模式如表1所示。
首先东西向通行,然后南北向通行,如此循环。
2、通行时间的设置:
当需要更改主、次干道的通行时间时,可以用设置键、增加键、减少键”进行设置。
第一次按“设置键”时,东西向的绿灯亮,东西向的LED数码管显示当前东西向的通行时间,并且按每秒3次的频率闪烁(每秒钟亮3次暗3次),其余的信号指示灯和南北向的LED数码管熄灭,此时可以用“增加键”和“减少键”来改变南北向的通行时间,每按一次键,数码管的显示时间增加1秒或减少1秒,长按键(按下的时间超过1秒钟以上),则数码管显示的时间按每秒钟增加或减少10的速度快速变化。
第二次按“设置键”时,东西向的黄灯亮,东西向的数码管显示当前东西向黄灯的点亮时间,并且按每秒3次的频率闪烁,其余的信号指示灯和南北向的数码管熄灭,此时可以用“增加键”和“减少键”来改变东西向黄灯的点亮时间。
第三次按“设置键”时,南北向的绿灯亮,南北向的数码管显示当前南北向绿灯的通行时间,并且按每秒3次的频率闪烁,其余的信号指示灯和东西向的数码管熄灭,此时可以用“增加键”和“减少键”来改变南北向绿灯的通行时间。
第四次按“设置键”时,南北向的黄灯亮,南北向的数码管显示当前南北向黄灯的点亮时间,并且按每秒3次的频率闪烁,其余的信号指示灯和东西向的数码管熄灭,此时可以用“增加键”和“减少键”来改变南北向黄灯的点亮时间。
第五次按“设置键”时,系统退出设置状态,回到交通信号灯状态,并且东西向先通行,南北向后通行。
“设置键”的功能如表2所示。
交通灯工作模式
设置键的功能
第四章硬件设计
1、器件选择
元件名
参数
备注
AT89C51
1
单片机
8255A
2
可编程外设接口
LED-RED、GREEN、YELLOW
3
红绿黄LED
7SEG-MPX2-CC
4
2位共阴极数码管
RES
220Ω、1K
电阻
BUTTON
5
按钮
74LS373
6
锁存器
2、系统原理图设计
3、主要器件应用简介
AT89C51单片机
AT89C51单片机与8051系列单片机全兼容,但其内部带有4KB的FLASHROM,设计时无需外接程序存储器。
单片机各口的应用:
P1口负责控制交通灯,P0口负责给8255a传送数据以及给锁存器传递8255a的地址,P2口为8255a的地址以及选择8255a,P3口负责控制按键;
可编程外设接口8255a
8255a可编程并行接口芯片有三个输入输出端口,即A口、B口和C口,对应于引脚PA7~PA0、PB7~PB0和PC7~PC0。
其内部还有一个控制寄存器,即控制口。
有三种工作方式:
方式0,方式1,方式2
8255A方式控制选择字
D7
D6
D5
D4
D3
D2
D1
D0
控制字
标识位
A口
方式选择
A口
I/O选择
C高4位
I/O选择
B口
方式选择
B口
I/O选择
C低4位
I/O选择
1:
方式控制
0:
C位操作
00:
方式0
01:
方式1
10:
方式2
1:
IN
0:
OUT
1:
IN
0:
OUT
0:
方式0
1:
方式1
1:
IN
0:
OUT
1:
IN
0:
OUT
8255A各口的应用:
PA负责传输南北向数码管的值,PB负责传输东西向数码管的值,PC负责控制东西向、南北向数码的暗灭,控制寄存器(假设为PD)负责控制8255a的工作方式,此系统中值为0x80,即无条件传输方式;
74ls373
74LS373是一种带三态门的8D锁存器,1D-8D为8个输入端,
1Q-8Q为8个输出端,LE为数据打入端:
当LE为“1”时,锁存器输出状态同输入状态;当LE由“1”变“0”时,数据打入锁存器,OE为输出允许端:
当OE=0时,三态门打开;当OE=1时,三态门关闭,输出高阻。
因为P0口为数据线、地址线复用,所以用一个锁存器将8255a的地址所存;
第五章软件设计
1、主程序模块设计
2、按键扫描模块设计
3、按键处理模块设计
短按键(时间小于0.5s,值加1)
长按键(时间大于0.5s小于1s,值加10)
持续按键(时间大于1s,值每隔1s加10)
设置键处理
增加键处理
减少键处理
4、数码管显示、闪烁模块设计
5、数码管计数,数码管切换、交通灯切换模块设计
第六章代码设计
/*****************************************************************************/
/************************单片机交通灯控制系统************************/
/*****************************************************************************/
#include"at89x51.h"
#include"absacc.h"
#definePA_ADDRXBYTE[0x7ffc]
#definePB_ADDRXBYTE[0x7ffd]
#definePC_ADDRXBYTE[0x7ffe]
#definePD_ADDRXBYTE[0x7fff]
#defineSN_LED_REDP1_3
#defineSN_LED_GREENP1_5
#defineSN_LED_YELLOWP1_4
#defineEW_LED_REDP1_0
#defineEW_LED_GREENP1_2
#defineEW_LED_YELLOWP1_1
//定义8255A的地址
unsignedcharled[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
charset_value[4]={60,4,40,4};//设置数码管的显示值,依次为东西向绿灯、东西向黄灯、南北向绿灯、南北向黄灯
unsignedcharsign[4]={1,0,0,0};//标志变量,用于控制LED的顺序
unsignedchardisp_ew,disp_sn;//数码管的显示值
unsignedcharfalsh_sign,direction_sign,flash_count;//控制数码管闪烁
unsignedintsecnum;//时间计数
unsignedcharkey;//键值,实现一键多功能
voiddelay_ms(unsignedinta);
voidadd_process();
voidsub_process();
voidset_process();
voidscan_key();
voidinit();
/*延时函数*/
voiddelay_ms(unsignedinta)
{
unsignedchari;
while(a--)
{
i=70;
while(i--);
}
}
/**************************按键处理模块******************************/
/*增加数码管的值*/
voidadd_process()
{
delay_ms(600);
if(!
P3_4)
{
delay_ms(500);
if(P3_4)
{
if(key==1)
{
set_value[0]=set_value[0]+10;
if(set_value[0]>99)
{
set_value[0]=set_value[0]%10;
}
disp_ew=set_value[0];
}
if(key==2)
{
set_value[1]++;
if(set_value[1]>9)
{
set_value[1]=0;
}
disp_ew=set_value[1];
}
if(key==3)
{
set_value[2]=set_value[2]+10;
if(set_value[2]>99)
{
set_value[2]=set_value[2]%10;
}
disp_sn=set_value[2];
}
if(key==4)
{
set_value[3]++;
if(set_value[3]>9)
{
set_value[3]=0;
}
disp_sn=set_value[3];
}
}
while(!
P3_4)
{
if(key==1)
{
set_value[0]=set_value[0]+10;
if(set_value[0]>99)
{
set_value[0]=set_value[0]%10;
}
disp_ew=set_value[0];
}
if(key==2)
{
set_value[1]++;
if(set_value[1]>9)
{
set_value[1]=0;
}
disp_ew=set_value[1];
}
if(key==3)
{
set_value[2]=set_value[2]+10;
if(set_value[2]>99)
{
set_value[2]=set_value[2]%10;
}
disp_sn=set_value[2];
}
if(key==4)
{
set_value[3]++;
if(set_value[3]>9)
{
set_value[3]=0;
}
disp_sn=set_value[3];
}
delay_ms(1200);
}
}
else
{
while(!
P3_4);
if(key==1)
{
set_value[0]++;
if(set_value[0]>99)
{
set_value[0]=0;
}
disp_ew=set_value[0];
}
if(key==2)
{
set_value[1]++;
if(set_value[1]>9)
{
set_value[1]=0;
}
disp_ew=set_value[1];
}
if(key==3)
{
set_value[2]++;
if(set_value[2]>99)
{
set_value[2]=0;
}
disp_sn=set_value[2];
}
if(key==4)
{
set_value[3]++;
if(set_value[3]>9)
{
set_value[3]=0;
}
disp_sn=set_value[3];
}
}
}
/*减少数码管的值*/
voidsub_process()
{
delay_ms(600);
if(!
P3_5)
{
delay_ms(500);
if(P3_5)
{
while(!
P3_5);
if(key==1)
{
set_value[0]=set_value[0]-10;
if(set_value[0]<0)
{
set_value[0]=set_value[0]+100;
}
disp_ew=set_value[0];
}
if(key==2)
{
set_value[1]--;
if(set_value[1]<0)
{
set_value[1]=9;
}
disp_ew=set_value[1];
}
if(key==3)
{
set_value[2]=set_value[2]-10;
if(set_value[2]<0)
{
set_value[2]=set_value[2]+100;
}
disp_sn=set_value[2];
}
if(key==4)
{
set_value[3]--;
if(set_value[3]<0)
{
set_value[3]=9;
}
disp_sn=set_value[3];
}
}
while(!
P3_5)
{
if(key==1)
{
set_value[0]=set_value[0]-10;
if(set_value[0]<0)
{
set_value[0]=set_value[0]+100;
}
disp_ew=set_value[0];
}
if(key==2)
{
set_value[1]--;
if(set_value[1]<0)
{
set_value[1]=9;
}
disp_ew=set_value[1];
}
if(key==3)
{
set_value[2]=set_value[2]-10;
if(set_value[2]<0)
{
set_value[2]=set_value[2]+100;
}
disp_sn=set_value[2];
}
if(key==4)
{
set_value[3]--;
if(set_value[3]<0)
{
set_value[3]=9;
}
disp_sn=set_value[3];
}
delay_ms(1200);
}
}
else
{
while(!
P3_5);
if(key==1)
{
set_value[0]--;
if(set_value[0]<0)
{
set_value[0]=99;
}
disp_ew=set_value[0];
}
if(key==2)
{
set_value[1]--;
if(set_value[1]<0)
{
set_value[1]=9;
}
disp_ew=set_value[1];
}
if(key==3)
{
set_value[2]--;
if(set_value[2]<0)
{
set_value[2]=99;
}
disp_sn=set_value[2];
}
if(key==4)
{
set_value[3]--;
if(set_value[3]<0)
{
set_value[3]=9;
}
disp_sn=set_value[3];
}
}
}
/*设置数码管的值*/
voidset_process()
{
while(!
P3_2);
ET1=0;
TR1=0;
key=key+1;
falsh_sign=1;
if(key>5)
{
key=1;
}
if(key==1)
{
disp_ew=set_value[0];
P1=0xfb;
direction_sign=1;
}
if(key==2)
{
disp_ew=set_value[1];
P1=0xfd;
direction_sign=1;
}
if(key==3)
{
disp_sn=set_value[2];
P1=0xdf;
direction_sign=2;
}
if(key==4)
{
disp_sn=set_value[3];
P1=0xef;
direction_sign=2;
}
if(key==5)
{
disp_sn=set_value[0]+set_value[1];
disp_ew=set_value[0];
P1=0xf3;
falsh_sign=0;
ET1=1;
TR1=1;
}
}
/*****************************按键扫描模块**************************/
/*扫描键盘*/
voidscan_key()
{
while(P3_2&&P3_4&&P3_5);
delay_ms(15);
if(!
P3_2)
{
set_process();
}
if(!
P3_4)
{
add_process();
}
if(!
P3_5)
{
sub_process();
}
else
return;
}
/*定时器中断0,用于显示数码管的值*/
voiddisp_t0(void)interrupt1
{
TR0=0;
if(falsh_sign==1)
{
flash_count++;
if(flash_count<=16)
{
if(direction_sign==1)
PC_ADDR=0xef;
elseif(direction_sign==2)
PC_ADDR=0xfe;
PA_ADDR=led[disp_sn/10];
PB_ADDR=led[disp_ew/10];
delay_ms
(2);
if(direction_sign==1)
PC_ADDR=0xdf;
elseif(direction_sign==2)
PC_ADDR=0xfd;
PA_ADDR=led[disp_sn%10];
PB_ADDR=led[disp_ew%10];
delay_ms
(2);
}