交通信号灯模拟控制系统汇编Word文档格式.docx
《交通信号灯模拟控制系统汇编Word文档格式.docx》由会员分享,可在线阅读,更多相关《交通信号灯模拟控制系统汇编Word文档格式.docx(28页珍藏版)》请在冰豆网上搜索。
四、设计内容
1.设计思路
⑴工具
使用AT89C51单片机控制四组数码管,12个发光二极管的亮暗,用pretues和keil软件进行仿真。
⑵硬件选取
对于交通信号灯来说,应该有东西南北共四组灯,但由于同一道上的两组的信号灯的显示情况是相同的,所以只要用两组就行了,因此,采用单片机内部的I/O口上的P1口中的6个引脚即可来控制6个信号灯。
用延时程序进行状态的转换。
⑶信号灯状态选取
初始状态0:
为东西绿灯亮,南北红灯亮;
假设数码管为共阴极,0表示灯灭,1表示灯亮,列出交通灯的状态表如下:
交通灯状态表
状态
东
西
南
北
说明
时间
绿黄红
0
001
东西南北都红
5s
1
100
东西红南北绿
30s
2
010
东西红南北黄
3
东西绿南北红
4
010
东西黄南北红
2.软硬件介绍及其分配
⑴器件介绍
①AT89C51
AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—FalshProgrammableandErasableReadOnlyMemory)的低电压,高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。
AT89C51的引脚图如下
主要特性:
与MCS-51兼容;
4K字节可编程闪烁存储器;
寿命1000写/擦循环数据保留时间10年;
全静态工作0Hz-24Hz;
三级程序存储器锁定;
128*8位内部RAM;
32可编程I/O线;
两个16位定时器/计数器;
5个中断源;
可编程串行通道;
低功耗的闲置和掉电模式;
片内振荡器和时钟电路
管脚说明:
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口也可作为AT89C51的一些特殊功能口,如下表所示:
口管脚备选功能
P3.0RXD(串行输入口)
P3.1TXD(串行输出口)
P3.2/INT0(外部中断0)
P3.3/INT1(外部中断1)
P3.4T0(记时器0外部输入)
P3.5T1(记时器1外部输入)
P3.6/WR(外部数据存储器写选通)
P3.7/RD(外部数据存储器读选通)
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:
来自反向振荡器的输出。
②数码管工作原理
2位8段数码管电路采用“共阴”连接,阴极公共端(COM)由晶体管推动。
如图4-3所示:
段码和位码,段码即段选信号SEG,它负责数码管显示的内容,图中a~g、dp组成的数据(a为最低位,dp为最高位)就是段码。
位码即位选信号DIG,它决定哪个数码管工作,哪个数码管不工作。
当需要某一位数码管显示数字时,只需要先选中这位数码管的位信号,再给显示数字的段码。
LED显示中的发光二极管共有两种连接方法:
a.共阳极接法:
把发光二极管的阳极连在一起构成公共阳极。
使用时公共阳极接+5V。
这样阴极端输入低电平的段发光二极管就导通点亮,而输入高电平的则不亮。
b.共阴极接法:
把发光二极管的阴极连在一起构成公共阴极。
使用时公共阴极接地。
这样阳极端输入高电平的段发光二极管就导通点亮,而输入低电平的则不亮。
十进制数字形代码如下表:
十进制数字形代码表
字型
共阳极代码
共阴极代码
C0H
3FH
9
90H
6FH
F9H
06H
A
88H
77H
A4H
5BH
B
83H
7CH
B0H
4FH
C
C6H
39H
99H
66H
D
A1H
5EH
5
92H
6DH
E
86H
79H
6
82H
7DH
F
8EH
71H
7
F8H
07H
灭
FFH
00H
8
80H
7FH
控制数码管驱动级的控制电路有静态式和动态式两类:
a.静态驱动:
它是指每个数码管都要用一个译码器译码驱动。
b.动态驱动:
它是所的数码管使用一个专门的译码驱动器,使各位数码管逐个轮流显示,它的扫描速度极快,因此显示效果与静态驱动相同。
采用动态数码管显示,可以大幅度地降低硬件成本和电源的功耗,因为某一时刻只有一个数码管工作,就是所谓的分时显示,显示所需要的硬件电路可分时复用。
③发光二极管用来显示亮灯情况
④相关寄存器
与定时器/计数器相关的寄存器有定时器/计数器工作方式寄存器(TMOD)、定时器/计数器控制寄存器(TCON)。
a.定时器/计数器工作方式寄存器(TMOD),字节地址89H,不可进行位寻址。
定时器/计数器工作方式寄存器(TMOD)的8位分为两组,高4位控制T1,低4位控制T0。
TMOD每一位的功能如下。
GATE:
门控位。
GATE=0,仅由运行控制位TRX(X=0,1)=1来启动定时器/计数器运行;
GATE=1,由运行控制位TRX(X=0,1)=1和外部中断引脚上的高电平共同来启动定时器/计数器运行。
C/T:
定时器模式和计数器模式选择位。
C/T=0,为定时器模式;
C/T=1,为计数器模式。
M1、M0:
工作方式选择位。
M1、M0的4中编码对应4种工作方式
b.TCON为定时器/计数器的控制寄存器,字节地址为88H,可位寻址,TCON寄存器中与中断系统有关的各标志位的功能如下:
TF1:
片内定时器/计数器T1的溢出中断请求标志位。
当启动T1计数器后,定时器/计数器T1从初值开始加1计数,当最高位产生溢出中断时,由硬件使TF置1,向CPU申请中断。
CPU响应TF1中断时,TF1标志由硬件自动清0,TF1也可由软件清0。
TF0:
片内定时器/计数器T0的溢出中断请求标志位,功能与TF1类似。
IE1:
外部中断请求1的中断请求标志位。
IE0:
外部中断请求0的中断请求标志位。
IT1:
选择外部中断请求1为跳沿触发方式还是电平触发方式。
IT1=0,为电平触发方式,加到INT1上的外部中断请求输入信号为低电平有效,并把IE置1。
转向中断服务程序时,则由硬件自动把IE1清零。
IT1=1,为跳沿触发方式,加到INT1上的外部中断请求输入信号电平从高到低的负跳变有效,并把IE置1。
IT0:
选择外部中断请求0为跳沿触发方式还是电平触发方式,其意义与IT1类似。
c.IE中断允许寄存器
AT89C51的CPU对各中断源的开放或屏蔽,是由片内的中断允许寄存器IE所控制的,IE中各位的功能如下;
EA:
中断允许总开关控制位。
EA=0,所有的中断请求被屏蔽;
EA=0,所有的中断请求被开放;
ES:
串行口的中断允许位;
ES=0,禁止串行口中断;
ES=1,允许串行口中断。
ET1:
定时器/计数器T1的溢出中断允许位。
ET1=0,禁止T1溢出中断。
ET1=1,允许T1溢出中断。
EX1:
外部中断1中断允许位。
EX1=0,禁止外部中断1中断。
EX1=1,允许外部中断1中断。
ET0:
定时器/计数器T0的溢出中断允许位。
ET0=0,禁止T0溢出中断。
ET0=1,允许T0溢出中断。
EX0:
外部中断0中断允许位。
EX1=0,禁止外部中断0中断。
EX1=1,允许外部中断0中断。
d.IP中断优先级寄存器
PS:
串行口中断优先级控制位。
PS=1,串行口中断为高优先级。
PS=0,串行口中断为低优先级。
PT1:
定时器T1中断优先级控制位。
PT1=1,定时器T1中断为高优先级。
PT1=0,定时器T1中断为低优先级。
PX1:
外部中断1中断优先级控制位。
PX1=1,外部中断1中断为高优先级。
PX1=0,外部中断1中断为低优先级。
PT0:
定时器T0中断优先级控制位。
PT0=1,定时器T0中断为高优先级。
PT0=0,定时器T0中断为低优先级。
PX0:
外部中断0中断优先级控制位。
PX0=1,外部中断0中断为高优先级。
PX0=0,外部中断0中断为低优先级。
⑵软件构思
交通灯的基本功能大致可分为两部分,一部分为信号灯的控制,另一部分为数码管时间的显示。
另外还有通过按键来终止灯的显示。
a.定时中断子程序:
中断服务程序的主要功能是进行计时操作,设计一个以1秒为周期的中断子程序。
流程图如下:
中断程序流程图
voidtimer(void)interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t0++;
if(t0==20)
{
t0=0;
mun--;
}
}
b.黄灯闪烁5s是通过延时程序来实现的,每1s闪烁一次。
延时函数:
voiddelay(unsignedcharx)
unsignedchari,j;
while(x--)
for(i=250;
i>
0;
i--)
for(j=4;
j>
j--);
显示黄灯闪烁的函数:
do
{
redzhu=0;
display(mun);
yellowzhu=~yellowzhu;
delay(120);
}
while(mun!
=0);
C.按键按下时交通灯停止显示是通过中断程序来实现的。
设按键是aj,P1^6,P1^7分别接到了数码管的片选端,P1^0至P1^5接发光二极管,所以当扫描到aj=0时,说明按键被按下,应该置P1=0e4H;
当扫描到aj恢复为1时,应返回断点,执行原来的程序,交通灯继续正常显示。
voidint1(void)interrupt2
if(aj==0)
while
(1)
P1=0xe4;
if(aj!
=0)
break;
⑶硬件分配
①P0^0至P0^6接数码管的十位位选端,P2^0至P2^6接数码管的个位位选端,P1^6至P1^7分别接十位和各位的片选端。
P1^0至P1^6分别接发光二极管。
二极管
方向
东西
南北
P1.2P1.1P1.0
P1.5P1.4P1.3
红黄绿
②定时/计数器T0用来产生1秒的定时
③P1^0至P1^5分别接发光二极管。
3.元件清单及简介
元件清单:
AT89S51单片机1个;
发光二极管(红绿黄)各4个;
共阴极数码管8个;
12MHz晶振1个;
2K电阻1个;
1K排阻1个;
500Ω排阻1个;
30pF电容2个;
22pF电解电容1个;
按键1个;
开关1个;
+5V电源
导线若干
5.硬件电路图
1.电路连接图
仿真结果:
六.系统实现
⑴使用keilC51编写程序;
⑵.将编好的程序“.C”文件用KeilC51转换成“.hex”文件;
⑶.画出设计系统仿真图;
⑷打开proteus7.5,将画好的仿真图载入,鼠标右击图中的51单片机选择“编辑属性”,在ProgramFile中载入之前的“.hex”文件,再点击“调试”中的“开始”或点击软件左下角的“
”,即仿真开始运行;
⑸观察运行现象是否与设计结果相符。
七.C语言程序代码
#include<
reg52.h>
#defineport1P0
#defineport2P2
sbitgreenzhi=P1^0;
sbityellowzhi=P1^1;
sbitredzhi=P1^2;
sbitgreenzhu=P1^3;
sbityellowzhu=P1^4;
sbitredzhu=P1^5;
sbitws=P1^6;
sbitwg=P1^7;
sbitaj=P3^3;
unsignedcharmun=5,t0=0,a=1;
unsignedcharcodetab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
voidinit_timer0(void)
TMOD=0x01;
ET0=1;
EA=1;
TR0=1;
EX1=1;
IT1=0;
t0=0;
voiddisplay(unsignedcharx)
i=x/10;
j=x%10;
port1=tab[i];
ws=0;
port2=tab[j];
wg=0;
voidinit(void)
P1=0x00;
init_timer0();
voidmain()
init();
while(a)
{
display(mun);
redzhu=1;
redzhi=1;
greenzhu=0;
greenzhi=0;
yellowzhu=0;
yellowzhi=0;
if(mun==0)
{a=0;
mun=35;
while
(1)
{do
greenzhi=0;
redzhi=1;
greenzhu=1;
redzhu=0;
=5);
if(mun==5)
{
redzhi=1;
greenzhi=0;
yellowzhi=0;
redzhu=0;
greenzhu=0;
}
do
mun=35;
yellowzhu=0;
}
greenzhi=1;
redzhi=0;
redzhu=1;
{
greenzhi=0;
redzhu=1;
redzhi=0;
yellowzhi=~yellowzhi;
mun=35;
yellowzhi=0;
yellowzhu=0;
八.汇编语言程序代码
ORG0000H
LJMPSTART
ORG0003H
LJMPIINT0
ORG0013H
LJMPIINT1
ORG0030H
START:
MOVSP,#6FH;
系统初始化
MOV61H,#20H
MOV60H,61H
LIGHT:
SETBEA
SETBEX0
SETBEX1
CLRIT1
CLRIT0
MOVP1,#0F3H;
东西红,南北绿,计时时间为30s
A1:
MOVR1,#75
A2:
ACALLBCD
ACALLDISPCLK
DJNZR1,A2
MOVA,60H
MOVR0,60H
ADDA,#99