能不能在这个交通灯系统里,加上一个紧急状态按键,使所有红灯亮。
单片机程序在下面:
ORG 0000H ;主函数地址
LJMP MAIN
ORG 000BH ;中断定时器0 地址
LJMP INTERPUT
ORG 0030H ;表的首地址
LJMP TABLE
TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
MAIN:
MOV P2, #00H ;给P2 口赋初值,让数码管刚开始都不亮
MOV R2, #60 ;给R2 赋60,使东西的数码管显示初值为60
MOV R3, #40 ;给R3 赋40,使南北的数码管显示初值为40
MOV P3, #0 ;使人形道的灯初始都不亮
MOV R5, #0 ;给R5,R6 赋初值0
MOV R6, #0
MOV TMOD, #01H ;定时器0 工作方式1
MOV TH0, #79 ;给定时器赋初值
MOV TL0, #0AEH
SETB EA ;允许总中断
SETB EX0
SETB IT0
SETB ET0 ;开启定时器0 中断
SETB TR0 ;开启定时器计时
L2:
LCALL DISPLAY1 ;显示东西数码管
LCALL DISPLAY2 ;显示南北数码管
LCALL CHOOSE1 ;调用东西判断函数
LCALL CHOOSE2 ;调用南北判断函数
SJMP L2 ;一直循环
INTERPUT:
MOV TH0, #22H ;定时器中断里重现给定时器0 赋初值
MOV TL0, #0D8H
MOV A, R4
INC R4 ;定时器中断一次50MS,中断一次R4+1
CJNE A, #20,L3 ; 判断是不是加到20 了,即定时器定时1S
MOV R4, #0 ;R4 加到20,则清0
DEC R3 ;要是定时1S 到了,则把R2,和R3 的值都减1
DEC R2
L3:
RETI ;中断退出
CHOOSE1: ;东西判断函数
MOV A, R5 ;R5是一个标志
CJNE A, #1, K1 ;判断R5 是不是等于1,不等于1 跳到K1
MOV A, R2 ;要是标志位等于1
CJNE A, #4, K5 ;而且R2 等于4,则开启黄灯,关闭车道绿灯
SETB P3.2
CLR P3.3
SJMP K3
K5: JNC K3 ;要是R2 小于4 则闪烁绿灯
CPL P1.7
MOV A, R2
CJNE A, #0, K3 ;判断R2 是不是等于0,
INC R5 ;等于0 则让标志位+1
CLR P3.2 ;清黄灯,开车道的左行绿灯,置人行道红灯
SETB P3.0
MOV R2, #20
SETB P2.6
CLR P2.7
SJMP K3
K1: JNC K2 ;CJNE 这个指令比较好R5 和1 的值,要是R5 大于1,则C=0,反之C=1,这里判断C 是否等于0,既判断是否小于1,小于1 执行下行, 大于1 则跳转K2
MOV A, R2
CJNE A, #60, K7 ;初值状态R2 是60,判断R2 是不是60,60 的话开车道的红灯,开人行道的绿灯
SETB P3.1
SETB P2.7
CLR P2.6
SJMP K3 ;退出
K7: CJNE A, #0, K3 ;要是R2 不等于60,判断R2 是不是等于0,等于0 则把标志位R5 加1,让车道绿灯亮,红灯灭,人行道红灯亮
INC R5
CLR P3.1
SETB P3.3
MOV R2, #40 ;再给数码管赋初值
CLR P2.7
SETB P2.6
SJMP K3 ;退出
K2: MOV A, R2 ;标志位R5 大于1 则跳到这里
CJNE A, #4, K6 ;判断R2 和4 的值, 等于4 则开启黄灯, 关闭车道的绿灯,要是不等于是,则跳到K6
CLR P3.0
SETB P3.2 SJMP K3
K6: JNC K3 ;判断R2 是不是小于4,小于4 则闪烁黄灯,大于4 则直接退出
CPL P3.2 ;取反
MOV A, R3
CJNE A, #0, K3 ;判断R2 是不是等于0
MOV R5, #0 ;等于0 则清标志位,因为我们只设置了0.1.2 这三个状态,到2了以后要清0,让他重新开始循环
MOV R2, #60 ;给R2 赋初值,开车道红灯,关车道左行绿灯,开人行道绿灯,关人行道红灯
SETB P3.1
CLR P3.2
SETB P2.7
CLR P2.6
K3: RET
CHOOSE2: ;南、北判断函数,程序和东、西判断一致
MOV A, R6
CJNE A, #1, H2
MOV A, R3
CJNE A, #4, H6
SETB P3.6
CLR P3.4
SJMP H3
H6: JNC H3
CPL P3.6
CJNE A, #0, H3
INC R6
CLR P3.6
SETB P3.5
MOV R3, #60
SETB P2.4
CLR P2.5
SJMP H3
H2: JNC H4
MOV A, R3
CJNE A, #40,H7
SETB P3.7
SETB P2.5
CLR P2.4
SJMP H3
H7: MOV A, R3
CJNE A, #4, H5
SETB P3.6
CLR P3.7
SJMP H3
H5: JNC H3
CPL P3.6
CJNE A, #0, H3
SETB P3.4
CLR P3.6
INC R6
MOV R3, #20
SETB P2.5
CLR P2.4
SJMP H3
H4:
MOV A, R3
CJNE A, #0, H3
SETB P3.7
CLR P3.5
MOV R6, #0
MOV R3, #40
SETB P2.5
CLR P2.4
H3: RET
DISPLAY1: ;显示东西数码管(动态显示)
MOV A, R2 ;将R2 放到A 中
MOV B, #10
DIV AB ;将2 位的10 进制数的十位和个位分开
MOV DPTR, #TABLE ; 取TABLE 表的首地址给DPTR
MOVC A, @A+DPTR ;把表的第N 个数据给A
MOV P1, A ;把数据送到数码管中
SETB P2.0 ;显示数码管
LCALL DELAY ;延时
CLR P2.0 ;把数码管暗掉
MOV A ,B ;把个位给A
MOVC A, @A+DPTR ;把表的个位个数给A
MOV P1, A ;把数据送到数码管中
SETB P2.1 ;显示数据
LCALL DELAY ;延时
CLR P2.1 ;让数码管暗掉
RET
DISPLAY2: ;显示南北数码管(显示函数和上面一样,这里注释就不写了)
MOV A, R3
MOV B, #10
DIV AB
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P0, A
SETB P2.2
LCALL DELAY
CLR P2.2
MOV A, B
MOVC A, @A+DPTR
MOV P0, A
SETB P2.3
LCALL DELAY
CLR P2.3
RET
DELAY: ;延时函数
MOV R0, #20
L1: MOV R1, #25
DJNZ R1, $
DJNZ R0, L1
RET
END