使用汇编语言从00到99计数器

时间:2011-12-05 04:36:19

标签: assembly microcontroller led

基本上我的任务是使用汇编语言使微控制器板上的计数器从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)并且坐在那里,它不会退出该循环,也不会重新循环。我似乎无法找到我的程序逻辑中的错误

1 个答案:

答案 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

将显示代码放在一个单独的例程中,并在每个计数器增加时多次切换活动显示器会更好。这对你来说可能是一个很好的练习:)