摘要:自从1858年英国人,发明了原始的机械扳手交通灯之后,随后的一百多年里,交通灯改变了交通路况,也在人们日常生活中占据了重要地位,随着人们社会活动日益增加,经济发展,汽车数量急剧增加,城市道路日渐拥挤,交通灯更加显示出了它的功能,使得交通得到有效管制,对于交通疏导,提高道路导通能力,减少交通事故有显著的效果。
近年来,随着科技的飞速发展,电子器件也随之广泛应用,其中单片机也不断深入人民的生活当中。本模拟交通灯系统利用单片机AT89S51作为核心元件,实现了通过信号灯对路面状况的智能控制。从一定程度上解决了交通路口堵塞、车辆停车等待时间不合理、急车强通等问题。系统具有结构简单、可靠性高、成本低、实时性好、安装维护方便等优点,有广泛的应用前景。
本模拟系统有单片机硬/软件系统,8位8段数码管显示系统。和复位电路控制电路等组成,较好的模拟了交通路面的控制。
一:设计思路
(1):分析目前交通路口的基本控制技术以及各种通行方案,并以此为基础提出自己的交通控制的初步方案。
(2):确定系统交通控制的总体设计,包括,十字路口具体的通行禁行方案设计以及系统应拥有的各项功能,在这里,本设计除了有信号灯状态控制能实现基本的交通功能,还有倒计时显示提示、紧急情况下,全面禁行、黄绿红灯及左转周期随时可调这三项项特特殊功能。
(3)进行显示电路,按键电路的设计和对各器件的选择及连接,大体分配各个器件及模块的基本功能要求。
(4)进行软件系统的设计,对于本系统,本人采用单片机汇编语言编写,对单片机内部结构和工作情况做了充足的研究,了解中断以及延时原理,总体上完成了软件的编写。然后在开发板上进行硬件调试。
二:单片机交通控制系统方案
2.1电源的供电方案
为使模块稳定的工作,必须有可靠的电源。同时由于我们此次设计是基于开发板的,其内部已经将电源供电模块安装好,为了方便节省时间,我们采用开发板上的电源模块。 2.2显示界面设计
该系统要求完成倒计时功能,又由于所买开发板的限制,我们无法同时分别控制使用开发板上的LED灯和八段数码显示管,因此我们采取用最右边的两个数码管显示时间,其余六个数码管分别代表南北、东西方的红黄绿灯及左转信号。
1
2.3输入方式
受限于开发板,我们采用4x4矩阵键盘输入,其中10个作为0-9数字键,4个作为输入选择键,两个弃用。
三:单片机的交通控制系统的总体设计
3.1单片机交通控制系统的通行方案设计
设在十字路口,分为东西向和南北向,在任一时刻只有一个方向通行,另一方向禁行,持续一定时间,经过短暂的过渡时间,将通行禁行方向对换。其具体状态如下:
(1)南北、东西方向黄灯都亮3秒,其他灯灭(为了方便演示,我们把初始时间设得较短,进入程序后,可根据需求用键盘把黄灯时间设定为0-9秒中的任意值)
(2)南北方向黄灯灭,同时绿灯亮,东西方向红灯亮,同时黄灯灭,倒计时2秒(为了方便演示,我们把初始时间设得较短,进入程序后,可根据需求用键盘把黄灯时间设定为0-99秒中的任意值)。此状态下,东西向禁止通行,南北向允许通行。
(3)重复(1)
(4)南北方向红灯亮,同时黄灯灭,东西方向绿灯亮,同时红灯灭,倒计时4秒(为了方便演示,我们把初始时间设得较短,进入程序后,可根据需求用键盘把黄灯时间设定为0-99秒中的任意值)。此状态下,东西向允许通行,南北向禁止通行。
(5)步骤(1)-(4)循环N次后(默认为1,运行后可设置为0-9任一值),选择相间执行(6)或(7)
(6)南北方红灯,东西方黄灯+绿灯,时长为南北向红灯时间。此时,南北向禁行,东西向可前行和左转。南北向黄灯,东西方红灯,时长为黄灯时长。回到(1)重新循环。
(7)南北向黄灯,东西向黄灯,时长为黄灯时长。接着是南北向黄灯+绿灯,东西向红灯,时长为红灯时长。此时,南北向可前行和左转。回到(1)重新循环。
由于开发板中灯与数码管的端口是同一端口,所以我们决定用剩余的数码管来显示红绿灯的状态。某个管全亮,代表这个管所代表的灯亮,黄绿灯齐亮表示可左转。
3.2 单片机交通控制系统的功能要求
本设计能模拟基本的交通控制系统,用红绿黄灯表示禁行,通行和等待的 信号发生,还能进行倒计时显示,通行时间调整功能和紧急情况全面禁行。 (1)倒计时显示
倒计时显示可以提醒驾驶员在信号灯灯色发生改变的时间、在“停止”和“通过”两者间作出合适的选择。驾驶员和行人普遍都愿意选择有倒计时显示的信号控制方式,并且认为有倒计时显示的路口更安全。倒计时显示是用来减少驾驶员
2
在信号灯色改变的关键时刻做出复杂判断的1种方法,它可以提醒驾驶员灯色发生改变的时间,帮助驾驶员在“停止”和“通过”两者间作出合适的选择 。 (2)时间的设置
本设计中可通过键盘对时间进行手动设置,为了体现人性化,我们的设计可满足人们对红黄绿灯三种时间的随时设定,还可以设定循环多少次后才左转。进行设置时,只需先按下时间设置键,再按下红黄绿N四键之一,选择需更改的项目,再通过数字键依次输入时长的十位个位即可;再按四件之一,又可以设置别的项目;为了简化程序以及根据实际情况,我们把黄灯时长和循环次数设定都限定在0-9,十位输入非0值时系统还是按十位为0处理;红绿灯时长可设定为0-99。同时,为了防止按键抖动错读输入,以及防止一次按键多次读入,我们分别采取了延时3.33ms和1.116s。整个键盘程序设计使操作简单方便,以便此设计可适应各种路况,增加了人为的可控性,避免自动故障和意外发生。
3.3单片机交通控制系统的基本构成及原理
单片机设计交通灯控制系统,可用单片机直接控制信号灯的状态变化,基本上可以指挥交通的具体通行,当然,接入LED数码管就可以显示倒计时以提醒行使者,更具人性化。本系统在此基础上,加入了时间调整功能。据此,本设计系统以单片机为控制核心,由按键设置模块产生输入,6个八段数码管灯,2个数码管组成的倒计时模块接受输出。系统的总体框图如下所示。
单片机上电后,系统进入正常工作状态,执行交通灯状态显示控制,同时将时间数据倒计时输入到LED数码管上实时显示。在此过程中随时调用时间调节中断和紧急情况中断。
四:智能交通灯的硬件设计
4.1AT89S51的内部构造如下图所示。 4.2主要功能引脚:
3
VCC:电源电压 GND:接地
P0口:P0口是一组8位双向I/0口。P0口即可作地址/数据总线使用,又可以作为通用的I/O口使用。当CPU访问片外存储器时,P0口分时先作低8位地址总线,后作双向数据总线,此时,P0口就不能再作I/O口使用了。在访问期间激活要使用上拉电阻。
P1口:Pl 是一个带内部上拉电阻的8准位双向I/O口,P1作为通用的I/O口使用。
P2 口:P2 是一个带有内部上拉电阻的8 位准双向I/O 口,P2即可作为通用的I/O口使用,也可以作为片外存储器的高8位地址总线,与P0口配合,组成16位片外存储器单元地址。
P3 口:P3 口是一组带有内部上拉电阻的8 位准双向I/0 口。P3 口除了作为通用的I/O口使用之外,每个引脚还具有第二功能,具体分配如表2。 表2 具有第二功能的P3口引脚 端口引脚 第二功能: 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外部数据存储器读选通) 89S51
的引脚图
RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。WDT 溢出将使该引脚输出高电平,设置SFR AUXR的DISRT0 位(地址8EH)可打开或关闭该功能。DISRT0位缺省为RESET输出高电平打开状态。
4
ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。即使不访问外部存储器,ALE 仍以时钟振荡频率的1/6 输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲。对F1ash存储器编程期间,该引脚还用于输入编程脉冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH 单元的D0 位置位,可禁止ALE 操作。该位置位后,只有一条M0VX和M0VC指令ALE才会被激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE无效。PSEN程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89S51 由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。当访问外部数据存储器,没有两次有效的PSEN信号。EA/VPP:外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接VCC端),CPU则执行内部程序存储器中的指令。F1ash存储器编程时,该引脚加上+12V的编程电压Vcc。
·XTAL1:振荡器反相放大器及内部时钟发生器的输入端。
————
——————
————
————
————
4.3 MCS—51的中断源
8051有5个中断源,它们是两个外中断INT0(P3.2)和INT1(P3.3)、两个片内定时/计数器溢出中断TF0和TF1,一个是片内串行口中断TI或RI,这几个中断源由TCON和SCON两个特殊功能寄存器进行控制,其中5个中断源的程序入口地址如表4所示: 表3中断源程序入口
中断源的服务程序入口地址 中断源 入口地址 外中断0 0003H 定时/计数器0 000BH 外中断1 0013H 定时/计数器0 001BH 串行口中断 0023H
4.4 系统硬件总电路构成和工作原理
4.4.1其中P0用于送显8片LED数码管,P1用于键盘输入,XTAL1和XTAL2接
入晶振时钟电路,REST引脚接上复位电路,p2.0,p2.1,p2.2对数码管进行片选, P3.2即INT0接时间调整中断按键,P3.3即INT1接紧急情况中断按键。 4.4.2系统工作原理
系统上电或手动复位之后,系统依次分别用3.33ms显示时间值的个位和十
5
位以及要点亮的数码管灯,在1s时间内重复这些操作,到达1s后根据变换设定继续进行各项操作。
当然,在进入程序后两个外部中断都开启了,一旦紧急情况或时间设定按钮按下,使中断信号有效时进入中断服务子程序,处理紧急情况或对时间进行设置。紧急情况中断(按S18键)相对简单,只是使所有灯都亮,对此不再详述。对于时间设定,按下时间设置键(S19)后,需说明的是————用户需先选择对哪个项目进行输入,否则输入数据不但无效,反而会影响系统读入十位个位的顺序(系统默认先读入十位,再度个位)。当对某项设定输入一个两位数后,若需更改在没选择进入别的项目时,可继续输入一个两位数进行更改,若已进入别的项目的设定,则需再按想要更改的项目的选择按键一下,方可更改。在紧急情况处理或时间设定完成后,按下退出键(S17)中断结束返回。
LED数码管显示 最小系统 外围接口电路 单片机 按键 控制电路 数码管灯信号
单片机系统的总体框图
4.5其它硬件介绍及连接
4.5.1八段LED数码管
LED显示屏作为大型显示设备的一种,具有亮度高、价格低、寿命长、维护简便等优点。LED数码管的结构简单,分为七段和八段两种形式,也有共阳和共阴之分。以八段共阳管为例,它有8个发光二极管(比七段多一个发光二极管,用来显示dP,即点),每个发光二极管的阳极连在一起,如下图所示。这样,一个LED数码管就有I根位选线和8根段选线,要想显示一个数值,就要分别对它们的高低电平来加以控制。为方便起见,本文主要讨论共阳八段LED数码显示管,其他类形的显示管与其类似。
注:我们用的开发板数码管为共阴,因此数值段码与共阳的为取反关系。
6
图6 LED数码管
LED 灯的显示原理:通过同名管脚上所加电平的高低来控制发光二极管是否点亮而显示不同的字形,如 dp,g,f,e,d,c,b,a全亮显示为8,采用共阳极连接驱动代码,代码表如下表所示。
驱动代码表
显示数值 0 1 2 3 4 5 6 7 8 9 dp,g,f,e,d,c,b,a 11000000 11111001 10100100 10110000 10011001 10010010 10000010 11111000 10000000 10010000 驱动代码 C0H F9H A4H B0H 99H 92H 82H F8H 80H 90H 相应在程序软件上,可以通过调用程序给定的秒值经过查表把对应的代码输出即可显示所要显示的值。 4.5.2矩阵键盘:
举例说明如何得到按键的特征编码:
假设“1”键被按下,找其按键的特征编码。从P1口的高四位输出低电平。即
P1.4一P1.7为输出口。低四位输出高电平。即 P1.0一P1.3为输入口。读P1 口的低四位状态为“1110”,P1值为“0EH”。再从 P 1口的高四位输出高电平。 即 P1.4一P1.7为输入口。低四位输出低电平。即P1.0一P1.3为输出口。读 P1口的高四位状态为“1101”。其值为“0D0H”。将两次读出的P0口的状态值进行逻辑或运算就得到其按键的特征编码,为“0DEH”。用同样的方法可以得到其他15个按键的特征编码。将用上述方法得到的16个按键的特征编码与顺序编码的对应关系表,然后用当前读的特征编码来查表,当表中有该特征编码时,它所在的位置就是对应的顺序编码。
矩阵键盘的具体编程:
1:识别键盘有无按键按下,若无按键按下则继续扫描键盘。
7
2:如果有数字键按下,找出具体的按键值(顺序码)。 程序表:
0EEH,0DEH,0BEH,7EH; 0-3 0EDH,0DDH,0BDH,7DH; 4-7 0EBH,0DBH,0BBH,7BH; 8-B 0E7H,0D7H,0B7H,77H; C-F
五:程序流图
见附录1
六:子程序模块设计
6.1
状态灯、时间显示及判断
共有6种状态:①南北,东西黄灯②南北绿,东西红③南北红,东西绿④南北红,东西黄+绿⑤南北黄,东西红⑥南北黄+绿,东西红
红绿灯及时间显示: ①南北、东西黄灯子程序:
Y: CPL F0 MOV 32H,#0 MOV 33H,5BH Y1:
MOV 70H,60H D0:
MOV P2,#07H;0号管亮 MOV DPTR,#2000H MOV A,33H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H;1号管亮 MOV DPTR,#2000H MOV A,32H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#04H
MOV P0,#0FFH;显示东西方黄灯,3号显像管全亮 ACALL DLY MOV P2,#01H
8
MOV P0,#0FFH;显示南北方黄灯,6号显像管全亮 ACALL DLY
DJNZ 70H,D0;使整段子程序用时1秒 DJNZ 33H,Y1
JB F0,BLUE;个位为0,即刻变灯,F0=1,绿灯。F0=0,红灯 SJMP RED
②南北绿,东西红子程序
BLUE:
MOV 34H,5CH MOV 35H,5DH MOV A,34H
JNZ BLUE2;定时大于9秒,则转移 BLUE1:
MOV 70H,60H D2:
MOV P2,#07H; 0号管亮 MOV DPTR,#2000H MOV A,35H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H; 1号管亮 MOV DPTR,#2000H MOV A,34H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#02H
MOV P0,#0FFH;显示南北方绿灯,5号显像管全亮 ACALL DLY MOV P2,#03H
MOV P0,#0FFH;显示东西方红灯,4号显像管全亮 ACALL DLY
DJNZ 70H,D2;使整段子程序用时1秒 DJNZ 35H,BLUE1
SJMP Y; 个位为0,即刻变灯 BLUE2:
MOV 70H,60H D3:
MOV P2,#07H; ;0号管亮 MOV DPTR,#2000H MOV A,35H
MOVC A,@A+DPTR
9
MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H;; 1号管亮 MOV DPTR,#2000H MOV A,34H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#02H
MOV P0,#0FFH;显示南北方绿灯,5号显像管全亮 ACALL DLY MOV P2,#03H
MOV P0,#0FFH;显示东西方红灯,4号显像管全亮 ACALL DLY
DJNZ 70H,D3;使整段子程序用时1秒 DEC 35H MOV A,35H
CJNE A,#0FFH,BLUE2; MOV 35H,#9
DJNZ 34H,BLUE2 SJMP BLUE1
③南北红,东西绿子程序
RED:
MOV 36H,58H MOV 37H,59H MOV A,36H
JNZ RED2; 定时大于9秒,则转移
RED1:
MOV 70H,60H D4:
MOV P2,#07H;0号管亮 MOV DPTR,#2000H MOV A,37H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H;; 1号管亮 MOV DPTR,#2000H MOV A,36H
MOVC A,@A+DPTR MOV P0,A;显示十位
10
ACALL DLY MOV P2,#00H
MOV P0,#0FFH;显示南北方红灯,7号显像管全亮 ACALL DLY MOV P2,#05H
MOV P0,#0FFH;显示东西方绿灯,2号显像管全亮 ACALL DLY
DJNZ 70H,D4;使整段子程序用时1秒 DJNZ 37H,RED1
SJMP N; 个位为0,即刻变灯
RED2:
MOV 70H,60H D5:
MOV P2,#07H; ;管亮 MOV DPTR,#2000H MOV A,37H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H;; 管亮 MOV DPTR,#2000H MOV A,36H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#00H
MOV P0,#0FFH;显示南北方红灯,7号显像管全亮 ACALL DLY MOV P2,#05H
MOV P0,#0FFH;显示东西方绿灯,2号显像管全亮 ACALL DLY
DJNZ 70H,D5;使整段子程序用时1秒 DEC 37H MOV A,37H
CJNE A,#0FFH,RED2; MOV 37H,#9 DJNZ 36H,RED2 SJMP RED1
④左转控制子程序
N:
DJNZ 38H,Z
11
JB 7EH,TL LJMP L1 Z:
LJMP Y; TL: CPL 7EH MOV 39H,#0
MOV 38H,5FH;循环次数 MOV 36H,58H
MOV 37H,59H ;南北向红灯时长 MOV A,36H
JNZ RED02; 定时大于9,则转移
RED01:
MOV 70H,61H D6:
MOV P2,#07H; 0号管亮 MOV DPTR,#2000H MOV A,37H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY MOV P2,#06H
MOV DPTR,#2000H MOV A,36H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#00H
MOV P0,#0FFH;显示南北方红灯,7号显像管全亮 ACALL DLY MOV P2,#05H MOV P0,#0FFH; ACALL DLY MOV P2,#04H
MOV P0,#0FFH;显示东西方黄绿灯,2、3号显像管全亮, ; 表示继续+左转+倒车 ACALL DLY
DJNZ 70H,D6;使整段子程序用时1秒 DJNZ 37H,RED01
SJMP Y00 ;个位为0,即刻变灯
12
RED02:
MOV 70H,61H D7:
MOV P2,#07H; ;0号管亮 MOV DPTR,#2000H MOV A,37H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H;; 1号管亮 MOV DPTR,#2000H MOV A,36H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#00H
MOV P0,#0FFH;显示南北方红灯,7号显像管全亮 ACALL DLY MOV P2,#05H MOV P0,#0FFH; ACALL DLY MOV P2,#04H
MOV P0,#0FFH;显示东西方黄绿灯,2、3号显像管全亮 ACALL DLY
DJNZ 70H,D7;使整段子程序用时1秒 DEC 37H MOV A,37H
CJNE A,#0FFH,RED02; MOV 37H,#9
DJNZ 36H,RED02 AJMP RED01
Y00:MOV 32H,#0 MOV 33H,5BH Y01:
MOV 70H,60H D8:
MOV P2,#07H; ;0号管亮 MOV DPTR,#2000H MOV A,33H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
13
MOV P2,#06H;;1号管亮 MOV DPTR,#2000H MOV A,32H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#01H
MOV P0,#0FFH;显示南北方黄灯,6号显像管全亮 ACALL DLY MOV P2,#03H
MOV P0,#0FFH;显示东西方红灯,4号显像管全亮 ACALL DLY
DJNZ 70H,D8;使整段子程序用时1秒 DJNZ 33H,Y01 LJMP Y L1: CPL 7EH MOV 39H,#0 MOV 38H,5FH MOV 33H,5BH
Y001: MOV 32H,#0 MOV 70H,60H D10:
MOV P2,#07H; ;0号管亮 MOV DPTR,#2000H MOV A,33H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H;; 1号管亮 MOV DPTR,#2000H MOV A,32H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#01H
MOV P0,#0FFH;显示南北方黄灯,6号显像管全亮 ACALL DLY MOV P2,#04H
MOV P0,#0FFH;显示东西方黄灯,3号显像管全亮 ACALL DLY
14
DJNZ 70H,D10;使整段子程序用时1秒 DJNZ 33H,Y001 YL:
MOV 36H,58H MOV 37H,59H MOV A,36H
JNZ YL2;定时大于秒,则转移 YL1:
MOV 70H,61H D15:
MOV P2,#07H; 0号管亮 MOV DPTR,#2000H MOV A,37H
MOVC A,@A+DPTR MOV P0,A;显示个位 ACALL DLY
MOV P2,#06H; 1号管亮 MOV DPTR,#2000H MOV A,36H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#02H
MOV P0,#0FFH;显示南北方黄灯+绿灯,5,6号显像管全亮 ACALL DLY MOV P2,#01H MOV P0,#0FFH ACALL DLY MOV P2,#03H
MOV P0,#0FFH;显示东西方红灯,4号显像管全亮 ACALL DLY
DJNZ 70H,D15;使整段子程序用时1秒 DJNZ 37H,YL1
LJMP Y; 个位为0,即刻变灯 YL2:
MOV 70H,61H D14:
MOV P2,#07H; ;0号管亮 MOV DPTR,#2000H MOV A,37H
MOVC A,@A+DPTR MOV P0,A;显示个位
15
ACALL DLY
MOV P2,#06H;; 1号管亮 MOV DPTR,#2000H MOV A,36H
MOVC A,@A+DPTR MOV P0,A;显示十位 ACALL DLY MOV P2,#02H
MOV P0,#0FFH;显示南北方绿灯,5,6号显像管全亮 LCALL DLY MOV P2,#01H MOV P0,#0FFH ACALL DLY MOV P2,#03H
MOV P0,#0FFH;显示东西方红灯,4号显像管全亮 ACALL DLY
DJNZ 70H,D14;使整段子程序用时1秒 DEC 37H MOV A,37H
CJNE A,#0FFH,YL2; MOV 37H,#9 DJNZ 36H,YL2 LJMP YL1
6.2键盘输入子程序
JIANPAN:
JNB P3.4,Z2; MOV R7,P2 KC0:
JNB P3.4,Z2; MOV P1,#0FH LCALL DLY MOV A,P1 ANL A,#0FH MOV B,A
MOV P1,#0F0H LCALL DLY MOV A,P1 ANL A,#0F0H ORL A,B
CJNE A,#0FFH,QUDOU1; ;为无键按下 JNB P3.4,Z2 ;3.4=0,中断结束
16
AJMP KC0 Z2:
MOV P2,R7 LJMP RETURN
QUDOU1: JNB P3.4,Z2
ACALL DLY; ;延时
ACALL KC1; 延迟后再判断
CJNE A,#0FFH,XZ; ;不相等,有按键,进入判断按键程序 SJMP KC0; ;(相等,无按键,接着扫描) KC1:
JNB P3.4,Z2
MOV P1,#0FH;判断是否为抖动 LCALL DLY MOV A,P1 ANL A,#0FH MOV B,A
MOV P1,#0F0H LCALL DLY MOV A,P1 ANL A,#0F0H ORL A,B RET XZ:
JNB P3.4,Z2 MOV P1,#0FH ACALL DLY
JB P1.3,SR;判值1;P1.3=0 灯种键按下,=1,按下的为时间键
PD:JNB P3.4,Z2 MOV B,A
MOV DPTR,#1000H MOV R1,#0FFH PD1: INC R1 MOV A,R1
MOVC A,@A+DPTR CJNE A,B,PD1
17
MOV A,R1
MOV DPTR,#2100H MOVC A,@A+DPTR MOV P2,#07H
MOV P0,A ;数码管显示灯种 ACALL DLY ACALL DELAY;
SJMP KC0; 扫描,等待输入时间) SR:
JB 7DH,TN2;F0=1则跳到设置个位值的程序
TN1:
MOV B,A; ;判断键值 MOV DPTR,#1000H MOV R3,#0FFH TN10:JNB P3.4,Z2 INC R3 MOV A,R3
MOVC A,@A+DPTR CJNE A,B,TN10
MOV A,R3;R2值为按键代表的值(0-9) MOV DPTR,#2000H; MOVC A,@A+DPTR;
MOV P0,A ;;显示输入的时间值 MOV A,R1;
RL A; ;把数值扩大一倍,方便前面的存时间 ADD A,#40H;
MOV R1,A; ;R1存储数据要输向的地址 MOV A,R3
MOV @R1,A ;红灯的时间十位存于58H,黄5AH,绿5CH,次数5EH CPL 7DH;
ACALL DELAY ;延时1秒,防止重复计入一个输入 AJMP KC0; 继续扫描,等待输入个位值
TN2:
MOV B,A;判断键值 MOV DPTR,#1000H; MOV R4,#0FFH; TN20:JNB P3.4,Z3 INC R4 MOV A,R4
18
MOVC A,@A+DPTR; CJNE A,B,TN20
MOV A,R4;R3值为按键代表的值(0-9) MOV DPTR,#2000H MOVC A,@A+DPTR;
MOV P0,A; 显示输入的时间值 INC R1 MOV A,R4
MOV @R1,A ;红灯的时间个位存于59H,黄5BH,绿5DH,次数5FH CPL 7DH;
ACALL DELAY ;延时1秒,防止重复计入一个输入 LJMP KC0; 继续扫描,等待输入十位值 Z3:
MOV P2,R7 LJMP RETURN
6.3紧急情况子程序
JJQK:
MOV P2,#00H
XS:MOV P0,#0FFH INC P2
JNB P3.4,Z3; P3.4=0,中断结束
6.4 延时子程序
DLY: MOV 76H,#6; DLY1:
MOV 71H,#0FEH; DJNZ 71H,$; DJNZ 76H,DLY1; RET DELAY: MOV 72H,#100 DELAY1:
晶振频率为11.0592,此循环延时约3.33ms
19
MOV 73H,#20 DELAY2: MOV 74H,#0FFH DJNZ 74H,$ DJNZ 73H,DELAY2
DJNZ 72H,DELAY1 ;晶振频率为11.0592,此循环延时约1.116s RET
6.5 中断出口子程序
RETURN: RETI
6.6 表
ORG 1000H
DB 0EEH,0DEH,0BEH,7EH;0-3 DB 0EDH,0DDH,0BDH,7DH;4-7 DB 0EBH,0DBH,0BBH,7BH;8-B
DB 0E7H,0D7H,0B7H,77H;C-F(按键值判断用码)
ORG 2000H
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH;(0-9的八段码)
ORG 210CH
DB 77H,66H,7FH,37H;(红R,黄Y,绿B,次数N,共阴)
七:集成开发环境KEIL
KEIL IDE Vision2集成开发环境主要由以下部分组成:
1:u Vision2 IDE。ision2 IDE包括:一个工程管理器,一个功能丰富并有交互式错误提示的编辑器选项设置生成工具,以及在线帮助。使用vision2创建源文件并组成应用工程加以管理。vision2可以自动完成编译汇编链接程序的操作;
20
2:C51编译器和A51汇编器。Vision2 IDE创建的源文件可以被C51编译器或A51
汇编器处理生成可重定位的object文件。KEIL C51编译器遵照ANSI C语言标准支持C语言的所有标准特性,另外还增加了几个可以直接支持80C51结构的特性。KEIL A51宏汇编器支持80C51及其派生系列的所有指令集; 3:LIB51库管理器。B51库管理器可以从由汇编器和编译器创建的目标文件建立
目标库,这些库是按规定格式排列的目标模块,可在以后被链接器所使用当链接器处理一个库时仅仅使用了库中程序使用了的目标模块而不是全部加以引用;
4:BL51链接器定位器。L51链接器使用从库中提取出来的目标模块和由编译器汇
编器生成的目标模块创建一个绝对地址目标模块,绝对地址目标文件或模块包括不可重定位的代码和数据所有的代码和数据都被固定在具体的存储器单元中。
利用KEIL开发和调试系统软件流程大致如下: 5:启动Vision2,进入KEIL软件的集成开发环境;
6:利用KEIL内置的文本编辑器进行程序源文件的编辑,因为KEIL集成的文本编辑器对中文支持不是很好,可以选择其他的编辑器(本文使用的文本编辑器是Ultraedit—32),Vision2能够自动识别外部改变了的源文件;
7:建立工程,指定针对哪种单片机进行开发,指定对源程序的编译、链接参数,指定调试方式(本文采用外部硬件仿真器仿真调试的方式,即使TKS仿真器仿真),然后对工程进行相关设置;
8:设置好工程后即可进行编译、链接。连接仿真器对软件进行调试。也可以生成下载到单片机存储器上的HEX文件。
八:参考文献
[1]张毅刚.单片机原理及应用 高等教育出版社
[2] 单片机新手入门实例详解之三_4×4矩阵键盘的工作原理与
编程 百度文库
九:设计心得
两周的时间匆匆而过,由于各种考试、实验都集中在这几周,总的来说时间很是仓促。不过经过两周的努力工作,终于完成了自己的单片机课程设计。虽说忙碌了点,有时还因为处理程序更改设计而熬夜,但看到自己的劳动成果时,所产生的喜悦,把一切疲劳都赶走,那种成就感,是无法言语的。这几天,感觉很充实,当然,也获益匪浅。
在实验初期,由于不知所买的开发板的具体布局和元件组成,只能按自己的设想进行初步的功能设计,和流程设计。我还清晰的记得当拿到开发板时的兴奋。不过,兴奋劲一下就没了,当看到开发板硬件把八个彩灯和八个数码管都连在P1端口时,我清楚的认识到灯和管只能二选一了,因此不得不改变当初的设计规划了。当天晚上,我就熬夜把程序改了过来。
进行到中期时,当把程序写入51后,运行时发现结果并非设想的那么好,而且几乎是彻底的失败,不过,这并没有打击我的积极劲,反而促使我更加专注于程序设计。然而,现实永远是那么残酷,当满怀信心的把自认为接近完美的程序导入后,各种问题不断出现。而令人最无法忍受的是,自己及同学都无法查处程
21
序逻辑上存在的问题。
上周五检查成果时,因为程序本身原因,错误颇多,还有因为开发板按键不太好,经常自动引发进入紧急中断。总的来说,很是失败,不过幸亏老师叫我们周一再检查,不然,若这么多天的努力和付出都付东流真的会很委屈。
当天,检查完后,看到贺金义学长在打乒乓球,就去请教了他。学长把我带到他的实验室,教会了我如何用Kell软件一条指令一条指令的执行程序和如何采用断点更方便的查看程序的走向以及如何看个端口的输出、各存储单元的值。
晚上,用学长教会的方法,不断模拟,终于找到了问题的根源——忽视了SP的值的变法。由于我把本该使用转移指令的命令用成了子程序调用,导致SP所存值不断增加,从而当进入中断而想再出来时,由于PC值错误,无法回到中断前的程序。发现这个问题后,我立马改正,终于使主程序正常运行了。不过,键盘输入程序问题犹在。经过模拟键盘程序,发现设计把输入值存入单片机内部存储器RAM58H单元的操作并没有进行,仔细检查发现R1存的地址并不是期望的58H,认真分析后终于明白是自己忘了R1值经过上一子程序操作后已经改变,因此,我改变了存储调用途径,使R1值一直保持期望值。
经过又一个通宵,终于完成了主程序、键盘程序两个板块的纠错。
在课程设计的过程中,我对单片机原理、各条指令、各个端口功能有了进一步的了解和巩固,通过自学,掌握了如何编写矩阵式键盘的扫描、去抖、防重复、读入等各子程序。当然,也学会了如何处理客观因素带来的影响,比如当我调试程序时,由于Kell软件本身的缺陷,经常导致我的程序编译时出现警告,导致无法顺利编译,让我误以为是自己程序有问题。后来,我把开发板自带程序以及已经成功运行了的同学的程序写入,发现还是有警告,从而确认是软件问题,所以我就改用同学的电脑完成了调试工作。还有一个问题是,由于开发板按键问题,导致P3.3端口信号经常自动有效而导致程序运行时自动进入紧急情况中断,改用开发板后,情况明显改善。在这些过程中,我学会了克制、冷静。
在此,感谢所有在设计过程中给予我以帮助的同学和老师。感谢娄艳阳同学在我电脑程序无法使用时,给我在软件上的支持;感谢徐效文老师在专业知识上的教诲指导;授人鱼不如授之以渔,因此,特别感谢贺金义学长对我在调试纠错上的指导!谢谢你们!
22
23
24
因篇幅问题不能全部显示,请点此查看更多更全内容