2011-12-05 63 views
1

基本上我的任務是使微控制器板上的計數器從00-99連續使用匯編語言進行計數。我的解決方案是顯示十(0),顯示一個(0),顯示十個(0),顯示一個(1),顯示一個(0),顯示一個(0),顯示兩個7-Seg同時顯示。 ,顯示十位(0),顯示一位(2),顯示十位(0),顯示一位(3)等。我這樣做的方法是有兩個循環(一個用於十位數字,一個用於個位數字)通過一個數組。一次個位數環已經通過整個陣列中,環路斷裂消失了,又回到了十位數循環,彙編語言中從00到99的計數器

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

你的hardward做什麼不明確。你想顯示兩位數......我假設你至少有2個7段顯示器。您如何選擇哪個7段顯示器獲得特定的顯示代碼?程序啓動後,您只能將顯示代碼輸出到PortB;硬件如何知道哪個數字點亮? –

+0

...我是一個老計時器,這看起來像一個6800 cpu,但我不承認'ldab 1,x +'指令。它有什麼作用? (我可以猜pshy dey puly就好)。 –

+0

硬件知道它通過這兩條線點亮 MSB_Display EQU $ 0B LSB_Display EQU $ 07 LSB使得選擇最右邊的7賽格,MSB使得選擇第二最右邊的7賽格 LDAB 1,X +基本上使它通過陣列/查找表運行 – livelaughlove

回答

3

從堆棧中拉出應該按照與堆疊相反的順序完成。 正如Ira指出的那樣,你讓你的計數器混淆了......

你應該把'顯示兩位數字'看作是一個單獨的東西,而不是增加循環中的計數器。 顯示簡單切換'有效'輸出延時,併爲每個顯示週期設置正確的數字值。

  '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 

它甚至會更好,有顯示的代碼在一個單獨的程序,並每個計數器增加一次以上切換活動顯示。這可能是一個很好的鍛鍊:)