📄 zh33.asm
字号:
.device AT90S8535
.equ SREG =$3F
.equ sph =$3E
.equ spl =$3D
.equ TIMSK =$39
.equ TIFR =$38
.equ OCR1AH =$2B
.equ OCR1AL =$2A
.equ TCCR1B =$2E
.equ TCNT1H =$2D
.equ TCNT1L =$2C
.equ PORTA =$1B
.equ DDRA =$1A
.equ PINA =$19
.equ PORTB =$18
.equ DDRB =$17
.equ PINB =$16
.equ PORTC =$15
.equ DDRC =$14
.equ PINC =$13
.equ PORTD =$12
.equ DDRD =$11
.equ PIND =$10
.def ZH =r31
.def ZL =r30
.org $0000
rjmp main
main: ldi r16,$02 ;栈指针置初值
out sph,r16
ldi r16,$5f
out spl,r16
ldi r28,$00 ;定义标志
ldi r16,$ff ;定义PA、PB、PD为输出口
out DDRA,r16
out PORTA,r16
out DDRB,r16
out DDRD,r16
out TIMSK,r16
clr r16 ;置TCNT1初值为0
out TCNT1L,r16
out TCNT1H,r16
ldi r16,$0c ;OCRLA置$0c35,即1s中断1次
out OCR1AH,r16
ldi r16,$35
out OCR1AL,r16
ldi r16,$0c ;T/C1对主频256分频定时
out TCCR1B,r16
here: ldi r16,10 ;置1s计数初值,100ms*10=1s
mov r2,r16
ldi r16,20 ;红灯亮20s
mov r3,r16
ldi r26,25 ;东西路口计时显示初值25s
ldi r27,25 ;南北路口计时显示初值25s
rcall state1
wait1: rcall play
in r16,TIFR
sbrs r16,4 ;查询100ms到否
rjmp wait1
ldi r16,$10
out TIFR,r16
dec r2
brne wait1 ;判断1s到否?未到继续状态1
ldi r16,10 ;置100ms计数初值
mov r2,r16
dec r26 ;东西路口显示时间减1s
dec r27 ;南北路口显示时间减1s
rcall play
dec r3
brne wait1 ;状态1维持20s
;**********************************************************
ldi r16,5 ;置100ms计数初值5*2=10
mov r2,r16
ldi r16,3 ;绿灯闪3s
mov r3,r16
ldi r16,2 ;闪烁间隔200ms
mov r4,r16
ldi r26,5
ldi r27,5
wait2: rcall play
in r16,TIFR
sbrs r16,4 ;查询100ms到否
rjmp wait2
ldi r16,$10
out TIFR,r16
dec r4 ;判断200ms到否?未到继续状态2
brne wait2
cpi r28,$00 ;东西绿灯闪
brne cl
sbi PORTA,1
com r28
rjmp dd
cl: cbi PORTA,1
com r28
dd: ldi r16,4 ;判断200ms到否?未到继续状态2
mov r4,r16
dec r2
brne wait2
ldi r16,5 ;置50ms计数初值
mov r2,r16
dec r26 ;东西路口显示时间减1s
dec r27 ;南北路口显示时间减1s
rcall play
dec r3
brne wait2
;**********************************************************
ldi r16,10 ;置100ms计数初值
mov r2,r16
ldi r16,2 ;黄灯亮2s
mov r3,r16
ldi r26,2 ;东西路口计时显示初值2s
ldi r27,2 ;南北路口计时显示初值2s
wait3: rcall play
rcall state3 ;调用状态3
in r16,TIFR
sbrs r16,4 ;查询100ms到否
rjmp wait3
ldi r16,$10
out TIFR,r16
dec r2
brne wait3 ;判断1s到否?未到继续状态3
ldi r16,10 ;置100ms计数初值
mov r2,r16
dec r26 ;东西路口显示时间减1s
dec r27 ;南北路口显示时间减1s
rcall play
dec r3
brne wait3
;**********************************************************
ldi r16,10 ;置1s计数初值,100ms*10=1s
mov r2,r16
ldi r16,20 ;红灯亮20s
mov r3,r16
ldi r26,25 ;东西路口计时显示初值25s
ldi r27,25 ;南北路口计时显示初值25s
wait4: rcall play
rcall state4 ;调用状态4
in r16,TIFR
sbrs r16,4 ;查询100ms到否
rjmp wait4
ldi r16,$10
out TIFR,r16
dec r2
brne wait4 ;判断1s到否?未到继续状态4
ldi r16,10
mov r2,r16
dec r26
dec r27
rcall play
dec r3
brne wait4
;**********************************************************
ldi r16,5 ;置100ms计数初值5*2=10
mov r2,r16
ldi r16,3 ;绿灯闪3s
mov r3,r16
ldi r16,2 ;闪烁间隔200ms
mov r4,r16
ldi r26,5
ldi r27,5
wait5: rcall play
in r16,TIFR
sbrs r16,4 ;查询100ms到否
rjmp wait5
ldi r16,$10
out TIFR,r16
dec r4 ;判断200ms到否?未到继续状态2
brne wait5
cpi r28,$ff ;南北绿灯闪
brne cll
sbi PORTA,4
com r28
rjmp ddd
cll: cbi PORTA,4
com r28
ddd: ldi r16,4 ;判断200ms到否?未到继续状态2
mov r4,r16
dec r2
brne wait5
ldi r16,5 ;置50ms计数初值
mov r2,r16
dec r26 ;东西路口显示时间减1s
dec r27 ;南北路口显示时间减1s
rcall play
dec r3
brne wait5
;**********************************************************
ldi r16,10 ;置100ms计数初值
mov r2,r16
ldi r16,2 ;黄灯亮2s
mov r3,r16
ldi r26,2 ;东西路口计时显示初值2s
ldi r27,2 ;南北路口计时显示初值2s
wait6: rcall play
rcall state6 ;调用状态3
in r16,TIFR
sbrs r16,4 ;查询100ms到否
rjmp wait6
ldi r16,$10
out TIFR,r16
dec r2
brne wait6 ;判断1s到否?未到继续状态3
ldi r16,10 ;置100ms计数初值
mov r2,r16
dec r26 ;东西路口显示时间减1s
dec r27 ;南北路口显示时间减1s
rcall play
dec r3
brne wait6
rjmp here ;大循环
;**********************************************************
state1: ldi r16,$35 ;东西路口绿灯亮,南北路口红灯亮
out PORTA,r16
ret
;**********************************************************
state3: ldi r16,$33 ;东西路口黄灯亮,南北路口红灯亮
out PORTA,r16
ret
;**********************************************************
state4: ldi r16,$2e ;东西路口红灯亮,南北路口绿灯亮
out PORTA,r16
ret
;**********************************************************
state6: ldi r16,$1e ;东西路口红灯亮,南北路口黄灯亮
out PORTA,r16
ret
;**********************************************************
play: mov r16,r26 ;东西寄存器中数二转十,送r19、r18
rcall b8td
mov r19,r17
mov r18,r16
mov r16,r27 ;南北寄存器中数二转十,送r21、r20
rcall b8td
mov r21,r17
mov r20,r16
rcall smiao
ret
b8td: clr r17 ;将r16中的二进制数转换为十进制数,十位、个位分别送r17、r16
b8td1: subi r16,10
brcs b8td2
inc r17
rjmp b8td1
b8td2: subi r16,(-10)
ret
smiao: ldi r16,$fe ;送东西个位位线
out PORTD,r16
mov r23,r18 ;将东西个位的BCD码送r23
rcall cqb ;查7段码,送B口输出
rcall t1ms ;延时1ms
ldi r16,$fd ;送东西十位位线
out PORTD,r16
mov r23,r19 ;将东西十位的BCD码送r23
rcall cqb ;查7段码,送B口输出
rcall t1ms ;延时1ms
ldi r16,$fb ;送南北个位位线
out PORTD,r16
mov r23,r20 ;将南北个位的BCD码送r23
rcall cqb ;查7段码,送B口输出
rcall t1ms ;延时1ms
ldi r16,$f7 ;送南北十位位线
out PORTD,r16
mov r23,r21 ;将南北十位的BCD码送r23
rcall cqb ;查7段码,送B口输出
rcall t1ms ;延时1ms
ret
cqb: ldi ZH,high(tab*2) ;7段码的首址给Z
ldi ZL,low(tab*2)
add ZL,r23 ;首地址+偏移量
lpm ;查表送B口输出
out PORTB,r0
ret
t1ms: ldi r24,101 ;延时1ms子程序
push r24
del2: push r24
del3: dec r24
brne del3
pop r24
dec r24
brne del2
pop r24
ret
tab: .db $3f,$06,$5b,$4f,$66,$6d,$7d,$07,$7f,$6f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -