《单片机实验》设计报告交通信号灯模拟系统设计交通信号灯模拟系统设计摘要:本系统以单片机为核心,主要应用单片机中定时器计数器,IO接口,中断系统等,结合8279键盘控制电路,数码管显示以及LED灯实现对十字路口交通信号灯的智能控制。
成功实现了利用单片机的定时器定时,令十字路口的红绿灯交替点亮和熄灭,通过按键对红绿灯点亮和熄灭时间进行调整及设置以及对红绿灯点亮和熄灭时间进行倒计时时间显示等基本功能。
并在此基础上进一步扩展,实现了对某些特殊功能的操作,如:突发紧急情况,所有路线全部红灯,或南北向(主干道)强制绿灯通行,以及东西向(次干道)强制绿灯等,并且可在交通高峰期(系统默认上午7:00-8:00,下午17:00-18:00)自动修改绿灯时间。
系统功能完善,可操控性好,代码通俗易懂。
关键字:51单片机交通信号灯智能控制 8279主要功能:分析题目可知,有两种方案设计的方法,也即两条不同的主干分别对应不同的方案,方案一以键盘控制为主干,穿插对系统时钟的检测,倒计时的检测等,系统主干为循环检测键盘是否被按下并作出相应操作。
方案二以交通信号灯不同的点亮与熄灭状态为主干,即系统的主干是交通灯状态的循环,在循环中检测按键并作出相应调整。
此次试验选择的是方案二,因为对方案一的代码实现比较复杂。
信号灯的状态依次为:南北绿灯,东西红灯->南北黄灯,东西红灯->南北红灯,东西绿灯->南北红灯,东西黄灯。
解决这部分问题的关键在于8279键盘扫描和相应的数码管显示,在实验帮助里有详细代码,另一个难点在于内置时钟和倒计时显示,这一部分内容通过使用单片机内的定时器能很好的解决,实验帮助五有详细的代码,通过定时器T1产生中断来定时,从而完成一秒的时间。
具体详见附录代码。
设计的主要内容:第一部分,系统开机界面,设置及人机互动的按键控制,流程图如下:(相应的功能流程图中已给出)第二部分,系统主干部分,即交通信号灯4个大循环以及循环内部检测按键完成拓展功能的实现,在循环内检测按键,实现相应功能,流程如下:具体细节,例如定时器的设计等在纸质档报告中有详细分析,在这里就不赘述总结:总的来说这次试验比较成功,题目要求的功能基本都实现了,对于单片机汇编程序语言的理解也更深刻了,课本上的知识比较分散,每部分之间都没有什么联系,通过实验很好的把各部分之间联系起来,加深记忆,更便于理解。
唯一不足的是对于题目的考虑不周,特殊功能采用键盘扫描子程序解决了,而没有采用终端,使得程序应激性不好,没有很好的应变性。
在以后的编程中会注意这方面的内容。
附录:(详细代码);-------------------------------------------------------Z8279 EQU 0FF82H ;8279 状态/命令口地址D8279 EQU 0FF80H ;8279 数据口地址LEDMOD EQU 00H ;左边输入八位字符显示;外部译码键扫描方式,双键互锁LEDFEQ EQU 2FH ;扫描速率LEDCLS EQU 0C1H ;清除显示 RAMLEDWR0 EQU 80H ;设定的将要写入的显示RAM地址READKB EQU 40H ;读 FIFO RAM 地址 0 的命令字;-------------------------------------------------------ORG 0000HAJMP STARTORG 001BH ;INT T1 入口地址AJMP INT_T1ORG 0040HSTART:MOV SP,#60HLCALL INIT8279 ;初始化8279MOV R3,#0H ;时MOV R2,#0H ;分MOV R1,#0H ;秒MOV R7,#0H ;倒计时时间MOV R0,#20 ;50毫秒MOV 40H,#0 ;用于改变主次干道时长比MOV R6,#0FFH ;标志MOV TMOD,#10HMOV TL1,#00H ;50毫秒的时间常数MOV TH1,#4CHSETB EX0SETB ET1SETB EA ;允许中断; 初始状态,全红灯MOV DPTR,#8300HMOV A,#0FHMOVX @DPTR,A; 键盘操作WAIT:LCALL GETKEY ;读键盘CJNE A,#0FFH,CONT ;判断是否有键输入MOV A,BCJNE A,#3CH,KEY_C ;输入键是'C',转CLEAR_T LCALL CLEAR_TKEY_C:CJNE A,#3AH,KEY_A ;输入键是'A',转START_T LCALL START_TKEY_A:CJNE A,#3DH,KEY_D ;输入键是'D',转STOP_T LCALL STOP_TKEY_D:CJNE A,#3BH,KEY_E ;输入键是'B',转SET_T LCALL SET_T ;设置系统时间KEY_E:CJNE A,#3FH,KEY_B ;输入键是'F',转SET_COUTLCALL SET_COUT ;设置倒计时间KEY_B:CJNE A,#3EH,CONT ;输入键是'E',转MONITOR AJMP MONITORCONT:CJNE R6,#0FFH,WAIT;若无秒标志则循环LCALL DISPLAY ;显示时间MOV R6,#0 ;清标志SJMP WAIT ;循环MONITOR:NOPSJMP $ ;等待回到监控;按键对应的功能CLEAR_T: ;时间清零子程序CLR TR1 ;关计数器MOV R3,#0H ;小时清零MOV R2,#0H ;分钟清零MOV R1,#0H ;秒清零MOV R0,#20 ;10毫秒清零MOV R7,#0H ;倒计时时间清零MOV R6,#0FFH ;置秒标志RETSTART_T: ;电子钟计时子程序;程序主要部分;程序开始执行后将循环在这部分CIRCLE:LCALL STATION1 ;南北绿灯,东西红灯LCALL STATION2 ;南北绿灯闪转黄灯,东西红灯 LCALL STATION3 ;南北红灯,东西绿灯LCALL STATION4 ;南北红灯,东西绿灯闪转黄灯 LJMP CIRCLERET;STATION1STATION1: ;南北绿灯,东西红灯MOV R7,30HMOV A,R7ADD A,40HMOV R7,AMOV DPTR,#8300HMOV A,#96H ;南北绿灯,东西红灯SETB TR1; 扫描键盘WO1: LCALL GETKEY ;读键盘CJNE A,#0FFH,JB1 ;判断是否有键输入MOV A,BCJNE A,#3FH,PUSHB1 ;若是按下F,则清零并且返回MOV R4,#1LCALL GETWORD ;读倒计时时间数MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R7,A ;保存输入的值INC AMOV 30H,ALCALL DISPLAY ;显示时间PUSHB1:CJNE A,#3BH,PUSHC1 ;若是按下B,则清零并且返回WAIT CLR TR1 ;关计数器MOV R3,#0H ;小时清零MOV R2,#0H ;分钟清零MOV R1,#0H ;秒清零MOV R0,#20 ;10毫秒清零MOV R7,#0H ;倒计时时间清零MOV R6,#0FFH ;置秒标志AJMP WAITPUSHC1:CJNE A,#3CH,PUSHD1MOV R7,#3 ;若按下C,输出3秒红灯MOV DPTR,#8300HMOV A,#0FHMOVX @DPTR,APUSHD1:CJNE A,#3DH,PUSHE1 ;若按下D,南北绿灯5秒MOV R7,#5MOV A,#96HMOVX @DPTR,APUSHE1:CJNE A,#3EH,JB1MOV R7,#5MOVX @DPTR,AJB1: CJNE R7,#0H,WO1RET;STATION2STATION2:MOV R7,#3MOV DPTR,#8300HMOV A,#06HMOVX @DPTR,ASETB TR1WO2: LCALL GETKEY ;读键盘CJNE A,#0FFH,JB2 ;判断是否有键输入MOV A,BCJNE A,#3FH,PUSHB2 ;若是按下F,则清零并且返回MOV R4,#1LCALL GETWORD ;读倒计时时间数MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R7,A ;保存输入的值INC AMOV 30H,ALCALL DISPLAY ;显示时间PUSHB2:CJNE A,#3BH,PUSHC2 ;若是按下B,则清零并且返回WAIT CLR TR1 ;关计数器MOV R3,#0H ;小时清零MOV R2,#0H ;分钟清零MOV R1,#0H ;秒清零MOV R0,#20 ;10毫秒清零MOV R7,#0H ;倒计时时间清零MOV R6,#0FFH ;置秒标志AJMP WAITPUSHC2:CJNE A,#3CH,PUSHD2MOV R7,#3 ;若按下C,输出3秒红灯MOV DPTR,#8300HMOV A,#0FHMOVX @DPTR,APUSHD2: CJNE A,#3DH,PUSHE2 ;若按下D,南北绿灯5秒MOV R7,#5MOV A,#96HMOVX @DPTR,APUSHE2: CJNE A,#3EH,JB2MOV R7,#5MOV A,#69HMOVX @DPTR,AJB2: CJNE R7,#0H,WO2RET;STATION3STATION3: ;南北红灯,东西绿灯MOV R7,30HMOV DPTR,#8300HMOV A,#69HMOVX @DPTR,ASETB TR1WO3: LCALL GETKEY ;读键盘CJNE A,#0FFH,JB3 ;判断是否有键输入MOV A,BCJNE A,#3FH,PUSHB3 ;若是按下F,则清零并且返回MOV R4,#1LCALL GETWORD ;读倒计时时间数MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R7,A ;保存输入的值INC AMOV 30H,ALCALL DISPLAY ;显示时间PUSHB3:CJNE A,#3BH,PUSHC3 ;若是按下B,则清零并且返回WAIT CLR TR1 ;关计数器MOV R3,#0H ;小时清零MOV R2,#0H ;分钟清零MOV R1,#0H ;秒清零MOV R0,#20 ;10毫秒清零MOV R7,#0H ;倒计时时间清零MOV R6,#0FFH ;置秒标志AJMP WAITPUSHC3:CJNE A,#3CH,PUSHD3MOV R7,#3 ;若按下C,输出3秒红灯MOV DPTR,#8300HMOV A,#0FHMOVX @DPTR,APUSHD3: CJNE A,#3DH,PUSHE3 ;若按下D,南北绿灯5秒MOV R7,#5MOV A,#96HMOVX @DPTR,APUSHE3: CJNE A,#3EH,JB3MOV R7,#5MOV A,#69HMOVX @DPTR,AJB3: CJNE R7,#0H,WO3RET;STATION4STATION4:MOV R7,#3MOV DPTR,#8300HMOV A,#09HMOVX @DPTR,ASETB TR1WO4: LCALL GETKEY ;读键盘CJNE A,#0FFH,JB4 ;判断是否有键输入MOV A,BCJNE A,#3FH,PUSHB4 ;若是按下F,则清零并且返回MOV R4,#1LCALL GETWORD ;读倒计时时间数MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R7,A ;保存输入的值INC AMOV 30H,ALCALL DISPLAY ;显示时间PUSHB4:CJNE A,#3BH,PUSHC4 ;若是按下B,则清零并且返回WAIT CLR TR1 ;关计数器MOV R3,#0H ;小时清零MOV R2,#0H ;分钟清零MOV R1,#0H ;秒清零MOV R0,#20 ;10毫秒清零MOV R7,#0H ;倒计时时间清零MOV R6,#0FFH ;置秒标志AJMP WAITPUSHC4:CJNE A,#3CH,PUSHD4MOV R7,#3 ;若按下C,输出3秒红灯MOV DPTR,#8300HMOV A,#0FHMOVX @DPTR,APUSHD4: CJNE A,#3DH,PUSHE4 ;若按下D,南北绿灯5秒 MOV R7,#5MOV A,#96HMOVX @DPTR,APUSHE4: CJNE A,#3EH,JB4MOV R7,#5MOV A,#69HMOVX @DPTR,AJB4: CJNE R7,#0H,WO4RET;电子钟停止的部分STOP_T: ;电子钟停止计时子程序CLR TR1RET;时钟设置部分SET_T: ;设置初值子程序CLR TR1 ;关计数器MOV R4,#7LCALL GETWORD ;读小时数CJNE A,#0FFH,INVALID ;判断输入合法性MOV A,BADD A,#232JC INVALID ;判断输入小时值 < 24MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R3,A ;保存输入的值MOV R4,#5LCALL GETWORD ;读分钟数CJNE A,#0FFH,INVALID ;判断输入合法性MOV A,BADD A,#196JC INVALID ;判断输入分钟数 < 60 MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R2,A ;保存输入的值MOV R4,#3LCALL GETWORD ;读秒钟数CJNE A,#0FFH,INVALID ;判断输入合法性MOV A,BADD A,#196JC INVALID ;判断输入分钟值 < 60 MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R1,A ;保存输入的值AJMP SET_TOKSET_COUT:MOV R4,#1LCALL GETWORD ;读倒计时时间数CJNE A,#0FFH,INVALID ;判断输入合法性MOV A,BMOV B,#10DIV ABSWAP AADD A,BMOV R7,A ;保存输入的值INC AMOV 30H,AAJMP SET_TOKINVALID:LCALL CLEAR_T ;时间清零SET_TOK:LCALL DISPLAY ;显示时间RET;读取输入按键的部分GETWORD: ;读数子程序WKEY1:LCALL GETKEY ;读键盘CJNE A,#0FFH,WKEY1;无键输入,则再读MOV A,BADD A,#0C6HJC ERROR1 ;判断输入是否大于9 MOV A,BSUBB A,#30HJC ERROR1 ;判断输入是否小于0MOV R5,ALCALL DISLED ;显示输入的字符MOV B,#10MUL ABPUSH ACC ;保存输入的值WKEY2:LCALL GETKEY ;读键盘CJNE A,#0FFH,WKEY2;无键输入则再读MOV A,BADD A,#0C6H ;判断输入是否大于9 JC ERROR2MOV A,BSUBB A,#30H ;判断输入是否小于0 JC ERROR2DEC R4MOV R5,ALCALL DISLED ;显示输入的字符MOV B,APOP ACCADD A,BMOV B,A ;把得到的值存在B MOV A,#0FFH ;置合法输入标志AJMP KEYOKERROR2: POP ACCERROR1: MOV A,#0 ;置非法输入标志KEYOK: RET;8279初始化INIT8279: ;8279初始化子程序PUSH DPH ;保存现场PUSH DPLPUSH ACCLCALL DELAY ;延时MOV DPTR ,#Z8279MOV A,#LEDMOD ;置8279工作方式MOVX @DPTR,AMOV A,#LEDFEQ ;置键盘扫描速率MOVX @DPTR,AMOV A,#LEDCLS ;清除 LED 显示MOVX @DPTR,APOP ACC ;恢复现场POP DPLPOP DPHRET;读取键盘子程序GETKEY:;输入: 无 ; 输出: B: 读到的键码 A: 按键的标志 PUSH DPH ;保存现场PUSH DPLPUSH PSWMOV DPTR,#Z8279MOVX A,@DPTR ;读8279状态ANL A,#07H ;屏蔽D7-D3JNZ GETVAL ;判断是否有键输入MOV A,#0H ;置标志(无键输入)SJMP NKBHITGETVAL:MOV A,#READKB ;读 FIFO RAM 命令MOVX @DPTR,AMOV DPTR,#D8279MOVX A,@DPTR ;读键ANL A,#3FH ;屏蔽 SHIFT 和 CTRL 键MOV DPTR,#KEYCODE;键码表起始地址MOVC A,@A+DPTR ;查表MOV B,A ;置返回键值MOV A,#0FFH ;置标志(有键输入)NKBHIT:POP PSW ;恢复现场POP DPLPOP DPHRET;T1定时器中断控制部分,INT_T1: ;INT_T1中断服务子程序 PUSH DPH ;保护现场PUSH DPLPUSH ACCPUSH PSWMOV TL1,#00H ;50毫秒定时常数MOV TH1,#4CHDJNZ R0,EXIT ;判断毫秒=0MOV R0,#20 ;DELAY 1 SECONDMOV R6,#0FFH ;置秒标志COUNT1: MOV A,R7ADD A,#99HDA AMOV R7,A ;减1CJNE R1,#59H,SECOND;判断秒=59MOV R1,#99HCJNE R2,#59H,MINUTE;判断分=59MOV R2,#99HCJNE R3,#23H,HOUR ;判断时=23MOV R3,#99HHOUR:MOV A,R3ADD A,#1 ;时加1DA AMOV R3,AMINUTE:MOV A,R2ADD A,#1 ;分加1DA AMOV R2,ASECOND:MOV A,R1ADD A,#1 ;秒加1DA AMOV R1,A;判断是否到了特定时间7~8,17~18点CJNE R3,#7,EXIT1MOV 40H,#5CJNE R3,#00010111B,EXIT1MOV 40H,#5SJMP SHOWTEXIT1: MOV 40H,#0SHOWT: CJNE R6,#0FFH,EXIT;若无秒标志则循环LCALL DISPLAY ;显示时间MOV R6,#0 ;清标志EXIT:POP PSW ;恢复现场POP ACCPOP DPLPOP DPHRETI ;中断返回;实验帮助11延时部分,不太清楚具体功能是什么,可能是键盘消抖DELAY: ;延时子程序PUSH 0 ;保存现场PUSH 1MOV 0,#0HDELAY1:MOV 1,#0HDJNZ 1,$DJNZ 0,DELAY1POP 1 ;恢复现场POP 0RET;显示控制部分,但不是具体显示部分DISPLAY:MOV A,R3ANL A,#0FHADD A,#10HMOV R5,AMOV R4,#6LCALL DISLED ;显示小时低位MOV A,R3SWAP AANL A,#0FHMOV R5,AMOV R4,#7LCALL DISLED ;显示小时高位MOV A,R2ADD A,#10HMOV R5,AMOV R4,#4LCALL DISLED ;显示分钟低位MOV A,R2SWAP AANL A,#0FHMOV R5,AMOV R4,#5LCALL DISLED ;显示分钟高位MOV A,R1ANL A,#0FHADD A,#10HMOV R5,AMOV R4,#2LCALL DISLED ;显示秒低位MOV A,R1SWAP AANL A,#0FHMOV R5,AMOV R4,#3LCALL DISLED ;显示倒计时高位MOV A,R7ANL A,#0FHADD A,#10HMOV R5,AMOV R4,#0LCALL DISLED ;显示倒计时低位MOV A,R7SWAP AANL A,#0FHMOV R5,AMOV R4,#1LCALL DISLEDRET;显示部分DISLED: ;显示字符子程序;输入: R4,位置 R5,值 PUSH DPH ;保存现场PUSH DPLMOV A,#LEDWR0 ;置显示起始地址ADD A,R4 ;加位置偏移量MOV DPTR,#Z8279MOVX @DPTR,A ;设定显示位置MOV DPTR,#LEDSEG ;置显示常数表起始位置MOV A,R5MOVC A,@A+DPTR ;查表MOV DPTR,#D8279MOVX @DPTR,A ;显示数据POP ACC ;恢复现场POP DPLPOP DPHRET;LED显示常数表LEDSEG:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H ;'0,1,2,3,4,5,6,7'DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ;'8,9,A,B,C,D,E,F'DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,087H ;'0.,1.,2.,3.,4.,5.,6.,7.' DB 0FFH,0EFH,0F7H,0FCH,0B9H,0DEH,0F9H,0F1H ;'8.,9.,A.,B.,C.,D.,E.,F.' DB 6DH,02H,08H,00H,59H,0FH,76H ;'U,-,_, ,I,O,P, ';键盘键码表KEYCODE:DB 30H,31H,32H,33H,34H,35H,36H,37H ;'0,1,2,3,4,5,6,7'DB 38H,39H,3AH,3BH,3CH,3DH,3EH,3FH ;'8,9,A,B,C,D,E,F'END【返回】。