2011-12-05 2 views
1

기본적으로 내 작업은 어셈블리 언어를 사용하여 00-99부터 계속해서 마이크로 컨트롤러 보드의 카운터를 계산하는 것입니다.어셈블리 언어로 00에서 99까지 카운터

두 개의 7-Seg를 동시에 표시 할 수 없기 때문에 내 솔루션은 수십 (0), 1 (0), 10 (0), 1 (1) (0), 디스플레이 수십 (0), 디스플레이 수십 (0), 디스플레이 하나 (3) 등이 내 접근 방식은 두 개의 루프 (10 자릿수에 대해 하나, 1 자릿수에 하나) 배열을 통과합니다. 사람 숫자 루프는 전체 배열, 루프 나누기를 통과하고 수십 자리 루프로 돌아갑니다 일단,

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 

지금 사람의 숫자 루프의 뒤쪽으로, 다음 요소에 수십 자리 이동이 프로그램이 1 자리 자릿수 (LSB)를 입력하고 거기에 앉아있는 것처럼 보이지만 루프를 종료하지 않고 루프를 다시 돌릴 수도 없습니다. 내 프로그램의 논리에서 무엇이 잘못되었는지 찾아 볼 수 없습니다.

+0

당신의 힘든 일은 분명하지 않습니다. 두 자릿수를 표시하고 싶습니다. 적어도 7 세그먼트 디스플레이가 2 대 있다고 가정합니다. 어떤 7- 세그먼트 디스플레이를 선택하면 특정 디스플레이 코드가 생깁니 까? 프로그램이 시작되면 표시 코드 만 PortB로 출력합니다. 하드웨어가 어떤 디지트를 밝힐 지 어떻게 알 수 있습니까? –

+0

... 전 오래된 타이머입니다, 이것은 6800CPU처럼 보이지만 'ldab 1, x +'명령을 인식하지 못합니다. 그것은 무엇을합니까? (나는 pshy에서 우습게 만날 수있다. –

+0

하드웨어가이 두 선으로 점등 할 알고 MSB_Display 가공 장비 $ 0B LSB_Display 가공 장비 $ 07 LSB가 MSB가가 2 권리를 선택할 수 있습니다, 대부분의 7 SEG 권리를 선택하게 대부분의 7 세그 ldab 1, X + 기본적으로 배열을 통해 실행하게/표를 봐 – livelaughlove

답변

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 

별도의 루틴에서 디스플레이 코드를 가지고 더 나은, 그리고 것 카운터 증가 당 활성 디스플레이를 두 번 이상 전환 할 수 있습니다. 그게 당신을위한 좋은 운동이 될 수 있습니다 :)

관련 문제