基本上我的任务是使用汇编语言使微控制器板上的计数器从00-99连续计数。
因为无法同时显示两个7-Seg,我的解决方案是显示数十(0),显示数字(0),显示数十(0),显示一(1),显示十(0),显示一(2),显示十(0),显示一(3)等。我这样做的方法是有两个循环(一个用于十位数,一个用于一位数)通过一个数组。一旦数字循环遍历整个数组,循环就会中断并返回到十位数循环,将十位数移动到下一个元素,然后返回到一位数循环
MSB_Display equ $0B ; display on 'tens' digit/second most right of 7-Seg
LSB_Display equ $07 ; display on 'ones' digit/most right of 7-Seg
D_1MS equ 24000 / 6
DelayVal equ 35 ; 35 ms delay simulates both Hex Displays on at once
org $1000
; Lookup table for LED segments
array db $3F,$06,$5B,$4F,$66,$6D,$7C,$07,$7F,$6F
; 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
; Memory Reserved for Delay Routine
DCount ds 1
Counter ds 1
countones db 0
counttens db 0
org $2000 ; Program starts here
lds #$2000 ; Initalize the stack
; Configure Hardware
ldaa #$FF
staa DDRB ; Make PORTB output
staa DDRP ; PTP as Output
start
clr countones ; clear count back to 0
clr counttens
ldx #array
MSB
ldaa 1,x+
staa PORTB
ldaa #MSB_Display
staa PTP ; turn off 7-segment display
bsr Delay_ms
inc counttens
ldaa counttens
cmpa #10
bne LSB
LSB
ldy #array
ldab 1,y+
stab PORTB
ldab #LSB_Display
stab PTP
bsr Delay_ms
inc countones
ldaa countones
cmpa #10
bne LSB
bra MSB
Delay_ms
psha
pshy
ldaa #DelayVal ; Number of msec to delay
staa DCount ; store delay counter
ldaa DCount ; delay Dcount ms
staa Counter
Delay1 ldy #D_1MS ; 6000 x 4 = 24,000 cycles = 1ms
Delay2 dey ; this instruction takes 1 cycle
bne Delay2 ; this instruction takes 3 cycles
dec Counter
bne Delay1 ; not Dcount ms yet, delay again
pula ; Restore contents of ACC A before returning
puly
rts
end
现在似乎程序进入了一个数字循环(LSB)并且坐在那里,它不会退出该循环,也不会重新循环。我似乎无法找到我的程序逻辑中的错误
答案 0 :(得分:3)
从堆叠中拉出应该以相反的顺序从堆叠中完成。 正如艾拉指出你让你的柜台混淆了......
您应该将'显示两位数字'视为与循环中增加某些计数器分开的东西。 显示是带有时间延迟的简单切换“有效”输出,并为每个显示周期设置正确的数字值。
'tens' = 0
loop10 'ones' = 0
loop1 display 'tens'
delay
display 'ones'
delay
inc 'ones'
goto loop1 if 'ones' less than 10
inc 'tens'
goto loop10 if 'tens' less than 10
这是一种方法(调整延迟值 - 35ms看起来很快......):
MSB_Display equ $0B ; display on 'tens' digit/second most right of 7-Seg
LSB_Display equ $07 ; display on 'ones' digit/most right of 7-Seg
D_1MS equ 24000 / 6
DelayVal equ 35 ; 35 ms delay simulates both Hex Displays on at once
org $1000
; Lookup table for LED segments
array db $3F,$06,$5B,$4F,$66,$6D,$7C,$07,$7F,$6F
; 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
; Memory Reserved for Delay Routine
DCount ds 1
Counter ds 1
countones db 0
counttens db 0
org $2000 ; Program starts here
lds #$2000 ; Initalize the stack
; Configure Hardware
ldaa #$FF
staa DDRB ; Make PORTB output
staa DDRP ; PTP as Output
start
clr counttens ; 'tens' = 0
ldx #array ; x will point to 'tens'
MSB clr countones ; 'ones' = 0
ldy #array ; y will point to 'ones'
; at every start of 'tens' cycle
LSB
ldaa x ; Set value of 'tens' display
; Do not use 1,x+ here
; You don't want to increment 'tens'
; every time you display 'ones'
staa PORTB
ldaa #MSB_Display
staa PTP ; turn on 'tens' 7-segment display
bsr Delay_ms ; let it be lit for a while
ldab 1,y+ ; set value of 'ones' display (and increment it)
stab PORTB
ldab #LSB_Display
stab PTP ; turn on 'ones' 7-segment display
bsr Delay_ms ; let it be lit for a while
inc countones
ldaa countones
cmpa #10
bne LSB
inx ; now increment 'tens'
inc counttens
ldaa counttens
cmpa #10
bne MSB
bra start ; start from '00'
Delay_ms
psha
pshy
ldaa #DelayVal ; Number of msec to delay
staa Counter
Delay1 ldy #D_1MS ; 6000 x 4 = 24,000 cycles = 1ms
Delay2 dey ; this instruction takes 1 cycle
bne Delay2 ; this instruction takes 3 cycles
dec Counter
bne Delay1 ; not Dcount ms yet, delay again
puly ; Restore contents of ACC A before returning
pula
rts
end
将显示代码放在一个单独的例程中,并在每个计数器增加时多次切换活动显示器会更好。这对你来说可能是一个很好的练习:)