能够实现用七段led数码管显示出数字和字母、让它们同时显示甚至于滚动显示,这些功能已经很不错了,但是这样还不够,我们还想实现更准确的控制,让数码管按照我们的想法来显示,而不是呆板的循环,这样我们引入中断的想法。也许其他人会从查询和中断的关系这些地方来引出中断,但是我还是倾向于从控制的观点来引出中断,毕竟中断也是实现更直观的人为控制的方法,程序的运行变得可以加入人的意愿来执行,如果我们要让程序进入某一个中断程序,那么给主程序发一个中断,让它跳到中断子程序中运行就行了;我们不发中断,中断子程序就不会执行。还是用七段led数码管来演示,我们没发一个中断信号,数码管就在0~9之间变化一下。代码如下:
INCLUDE MC9S08AW60.inc
org $0070
IRQ_Count ds.b 1
org $1860
tab: dc.b $c0,$f9,$a4,$b0,$99,$92,$82,$f8,$80,$90,$88,$83,$a7,$a1,$86,$8e
io_init:
mov #$00,PTBD
mov #$00,PTDD
mov #$ff,PTGD
lda #%11111111
sta PTBDD
sta PTDDD
sta PTGDD
sta PTBDS
sta PTDDS
sta PTGDS
rts
IRQ_init: ;IRQ模块初始化
mov #$00,IRQ_Count
lda #%00010010
sta IRQSC ;IRQ功能允许,仅下降沿触发,允许中断
rts
IRQ_ISR: ;中断子程序
inc IRQ_Count ;该中断子程序主要实现的功能:累加中断次数
bset 2,IRQSC ; 向IRQACK位写1以清零IRQF
rti ;中断返回
main:clra
clrx
clrh
jsr io_init
sta SOPT ;禁止COP
jsr IRQ_init
cli ;开总中断
mov #$00,IRQ_Count
again:
clra
clrx
clrh
ldx IRQ_Count
lda tab,x
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
mov #$f7,PTGD
cpx #$10
bne next
mov #$00,IRQ_Count
next:jmp again
org $fffa
dc.w IRQ_ISR ;IRQ中断向量
org $fffe
dc.w main
该程序就是加入了中断之后的,关于中断的一些说明可以参看下图:
接着给出按16进制累加(255以内)显示的程序:
INCLUDE MC9S08AW60.inc
org $0070
IRQ_Count ds.b 1
num ds.b 1
count ds.b 1
org $1860
tab: dc.b $c0,$f9,$a4,$b0,$99,$92,$82,$f8,$80,$90,$88,$83,$a7,$a1,$86,$8e
re_cycle:
mov #70t,num
dbnz num,*
rts
delay_1ms:
mov #08t,count
re_call:
bsr re_cycle
dbnz count,re_call
rts
io_init:
mov #$00,PTBD
mov #$00,PTDD
mov #$ff,PTGD
lda #%11111111
sta PTBDD
sta PTDDD
sta PTGDD
sta PTBDS
sta PTDDS
sta PTGDS
rts
IRQ_init:
mov #$00,IRQ_Count
lda #%00010010
sta IRQSC
rts
IRQ_ISR:
inc IRQ_Count
bset 2,IRQSC
rti
main:clra
clrx
clrh
sta $1802
jsr io_init
sta SOPT
jsr IRQ_init
cli
mov #$00,IRQ_Count
again:
clra
clrx
clrh
lda IRQ_Count
ldx #16t
div
pshh
clrh
clrx
tax
clra
lda tab,x
mov #$fb,PTGD
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
jsr delay_1ms
mov #$ff,PTGD
clrx
clrh
clra
pula
tax
clrh
lda tab,x
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
mov #$f7,PTGD
jsr delay_1ms
mov #$ff,PTGD
jmp again
org $fffa
dc.w IRQ_ISR
org $fffe
dc.w main
思路是这样的:我们要显示的是中断的次数,也就是将中断的次数用16进制显示出来,我们将中断的次数提取出来,用它除以16,得到商和余数,商就作为高位,我们找到其字形码显示到数码管中,余数作为低位,并做相同的处理。这样我们就实现了16进制显示中断次数。注意一点,我们先处理商后处理余数,因为如果扩大显示的范围,先处理余数时也要做除法,比如将上面的例子改为用10进制显示范围还是0~255,当然这里完全可以做到0~999,我们将中断次数除以100后商可以直接处理,而余数还得除以10之后分为商和余数来处理。代码如下:
INCLUDE MC9S08AW60.inc
org $0070
IRQ_Count ds.b 1
num ds.b 1
count ds.b 1
org $1860
tab: dc.b $c0,$f9,$a4,$b0,$99,$92,$82,$f8,$80,$90,$88,$83,$a7,$a1,$86,$8e
re_cycle:
mov #70t,num
dbnz num,*
rts
delay_1ms:
mov #08t,count
re_call:
bsr re_cycle
dbnz count,re_call
rts
io_init:
mov #$00,PTBD
mov #$00,PTDD
mov #$ff,PTGD
lda #%11111111
sta PTBDD
sta PTDDD
sta PTGDD
sta PTBDS
sta PTDDS
sta PTGDS
rts
IRQ_init:
mov #$00,IRQ_Count
lda #%00010010
sta IRQSC
rts
IRQ_ISR:
inc IRQ_Count
bset 2,IRQSC
rti
main:clra
clrx
clrh
sta $1802
jsr io_init
sta SOPT
jsr IRQ_init
cli
mov #$00,IRQ_Count
again:
clra
clrx
clrh
lda IRQ_Count
ldx #100t
div
pshh
clrh
clrx
tax
clra
lda tab,x
mov #$fd,PTGD
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
jsr delay_1ms
mov #$ff,PTGD
clrx
clrh
clra
pula
ldx #10t
div
pshh
clrh
clrx
tax
clra
lda tab,x
mov #$fb,PTGD
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
jsr delay_1ms
mov #$ff,PTGD
clrx
clrh
clra
pula
tax
lda tab,x
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
mov #$f7,PTGD
jsr delay_1ms
mov #$ff,PTGD
jmp again
org $fffa
dc.w IRQ_ISR
org $fffe
dc.w main