之前我们写了延时的子程序,但是仅仅在电脑上运行,在CodeWarrior中调试根本给不了延时所实现的直观效果,也就是说程序运行到哪里但我们却无法直观地得出发生了延时的效果,所以我们要把这个延时的程序用出去,比如点亮一盏led灯,让它延时我们规定的时间后熄灭,然后再点亮再熄灭......这里我们使用清华版的MC9S08AW60开发板来验证延时的效果。对于开发板的使用和烧写请多看看数据手册和使用说明。我们直接给出验证延时的代码:
org $0070
num ds.b 1
count1 ds.b 1
count2 ds.b 1
org $1860
re_cycle:
mov #70T,num
dbnz num,*
rts
delay_10ms:
mov #78T,count1
re_call:
bsr re_cycle
dbnz count1,re_call
mov #07T,count1
dbnz count1,*
rts
delay_500ms:
mov #50T,count2
re:
bsr delay_10ms
dbnz count2,re
rts
main:
bset 5,PTFD ;初始化PTF5
bset 5,PTFDD ;将PTF5设置为输出
again:
bclr 5,PTFD ;点亮核心子板上的蓝色led
bsr delay_500ms ;延时
bset 5,PTFD ;熄灭核心子板上的蓝色led
bsr delay_500ms
jmp again
org $fffe
dc.w main
这个程序大部分我们都是了解过的,所不熟悉的就是对PTFD的操作,我们所需要记住的是:点亮开发板上的灯就是对MCU的端口发送相应的数据,因为led灯是共阳极的,所以数据为‘0’时点亮,为‘1’时熄灭。当然,在使用某个端口之前不要忘记对该端口进行初始化,也就是将其设为输出,并设置初始状态为熄灭。解释一下:bset即置‘1’,bclr即置‘0’。对方向来说:‘1’为输出,‘0’为输入;对小灯的点亮与否来说:‘1’为熄灭,‘0’为点亮。
既然我们可以点亮一颗小灯,我们当然也能点亮许多小灯,如果我们点亮的是七段led数码管上的小灯,这是不是就意味着我们可以在七段led数码管上显示出1、2、3、4、5.......之类的数字或者a、b、c......之类的字母。例子如下:在4个数码管上同时显示0123。
INCLUDE MC9S08AW60.inc
org $0070
seg ds.b 1
num ds.b 1
count ds.b 1
org $1860
table: ;共阳极的七段数码管的段码表
dc.b $c0,$f9,$a4,$b0 ;0123的字形码
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
main:
clrx
clrh
clra
sta $1802 ;禁止掉COP,否则程序运行时间长了会发生COP复位
jsr io_init
mov #$fe,seg ;设置位选
again:
clrh
lda table,x ;查表得出字形码
sta PTBD ;点亮七段led数码管
lsra
lsra
lsra
lsra
sta PTDD
mov seg,PTGD
jsr delay_1ms ;延时
mov #$ff,PTGD ;熄灭led
lda seg ;改变位选
sec ;1-->C
rola ;将A中数据和标志位C一同左移一位
sta seg
incx
cpx #$4 ;判断是否结束并开启下一轮循环
bne next
clrx
mov #$fe,seg
next:
jmp again
org $fffe
dc.w main
为了实现1234同时显示在七段led数码管上,我们采用动态显示方式,即瞬间只点亮一个数码管,延时后再点亮下一个数码管,如此不停的循环显示,利用人眼视觉暂留效应,打到同时显示的效果。此外,我精心设计出了一个实现1234滚动显示的程序,如下:
INCLUDE MC9S08AW60.inc
org $0070
seg ds.b 1
num ds.b 1
count ds.b 1
count2 ds.b 1
sum ds.b 1
sum1 ds.b 1
org $1860
table:
dc.b $c0,$f9,$a4,$b0,$ff
re_cycle:
mov #70t,num
dbnz num,*
rts
delay_1ms:
mov #08t,count
re_call:
bsr re_cycle
dbnz count,re_call
rts
delay_10ms:
mov #78t,count
re: bsr re_cycle
dbnz count,re
mov #07t,count
dbnz count,*
rts
delay_500ms:
mov #50t,count2
re1:bsr delay_10ms
dec count2
ldx count2
cpx #$00
bne re1
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
main:
clrx
clrh
clra
sta $1802
jsr io_init
mov #$00,sum
mov #$00,sum1
mov #$fe,seg
again:
ldx sum
cpx #$5
bne ne
mov #$00,sum
ne: clrh
ldx sum
lda table,x
sta PTBD
lsra
lsra
lsra
lsra
sta PTDD
mov seg,PTGD
jsr delay_500ms
mov #$ff,PTGD
lda seg
sec
rola
sta seg
inc sum
inc sum1
ldx sum1
cpx #$4
bne next
mov #$00,sum1
mov #$fe,seg
next:
jmp again
org $fffe
dc.w main
实现这个程序的主要思路是:位选依然在4个数码管之间循环,而点亮数码管的字形码则在加了一个不显示选项的段码表之间循环,由此形成的错位打到滚动显示的效果。