Zorbing

[TGI] Timer + Segmentanzeige

Jun 20th, 2013
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .include "m16def.inc"
  2. ; =============================================================================
  3. ; Interrupt-Vektor-Tabelle
  4. ; =============================================================================
  5. .cseg
  6. .org    0x000
  7.     jmp     main
  8. ; =============================================================================
  9. ; ; Loesung zu 11.2 c ii)
  10. ; =============================================================================
  11. .org    0x008
  12. ;   jmp     clock_isr               ; im Sekundentakt: Ueberlauf von Timer2
  13.  
  14. ; =============================================================================
  15. ; Tabelle mit Ziffernansteuerung
  16. ; Loesung zu 11.2 a i)
  17. ; =============================================================================
  18. ; =============================================================================
  19. .org    0x02a
  20. digittab:                           ; Tabelle mit den Ansteuerungsbitmustern:
  21.     .db     0x3f,0x06               ; 0, 1
  22.     .db     0x5b,0x4f               ; 2, 3
  23.     .db     0x66,0x6d               ; 4, 5
  24.     .db     0x7d,0x07               ; 6, 7
  25.     .db     0x7f,0x6f               ; 8, 9
  26.  
  27. ; =============================================================================
  28. ; Reservierter Speicher fuer Zeitwerte
  29. ; =============================================================================
  30. .dseg
  31. .org    0x0100
  32.     seconds:        .byte   1
  33.     minutes:        .byte   1
  34.     hours:          .byte   1
  35.  
  36. ; =============================================================================
  37. ; Beginn Programmcode
  38. ; =============================================================================
  39. .cseg
  40. .org    0x034
  41.  
  42. ; =============================================================================
  43. ; Loesung zu 11.2 a ii)
  44. ; =============================================================================
  45. digitout:
  46.     push    R16
  47.     ldi     ZL,low(digittab*2)      ; lade den
  48.     ldi     ZH,high(digittab*2)     ; entsprechenden
  49.     add     ZL,R17                  ; Tabelleneintrag
  50.     lpm     R17, Z                  ; in R17
  51.     ser     R16                     ; Maske = 0b11111111
  52.     out     DDRA, R16               ; PORTA in Schreibmodus setzen
  53.     out     PORTA, R17              ; R17 auf PORTA ausgeben
  54.     pop     R16
  55.     ret
  56.  
  57. ; *****************************************************************************
  58. ; *****************************************************************************
  59. ; Vorgegebene Unterprogramme
  60. ; *****************************************************************************
  61. ; *****************************************************************************
  62.  
  63. ; INC_SEC
  64. ; -------
  65. inc_sec:
  66.     push    R16                     ;Register retten.
  67.     lds     R16,seconds             ;Sekundenwert holen.
  68.     cpi     R16,$59                 ;Bereits $59?
  69.     breq    inc_sec_59              ;Dann Sonderbehandlung.
  70.     inc     R16
  71.     sts     seconds,R16             ;abspeichern.
  72.     jmp     inc_sec_end             ;Das war's.
  73. inc_sec_59:
  74.     clr     R16                     ;Sekunden auf $00
  75.     sts     seconds,R16             ;setzen.
  76. inc_sec_end:
  77.     pop     R16                     ;Register wiederherstellen
  78.     ret
  79.  
  80. ; INC_MIN
  81. ; -------
  82. inc_min:
  83.     push    R16                     ;Register retten.
  84.     lds     R16,minutes             ;Minutenwert holen.
  85.     cpi     R16,$59                 ;Bereits $59?
  86.     breq    inc_min_59              ;Dann Sonderbehandlung.
  87.     inc     R16
  88.     sts     minutes,R16             ;abspeichern.
  89.     jmp     inc_min_end             ;Das war's.
  90. inc_min_59:
  91.     clr     R16                     ;Minuten auf $00
  92.     sts     minutes,R16             ;setzen.
  93. inc_min_end:
  94.     pop     R16                     ;Register wiederherstellen
  95.     ret
  96.  
  97. ; INC_HOURS
  98. ; -------
  99. inc_hours:
  100.     push    R16                     ;Register retten.
  101.     lds     R16,hours               ;Stundenwert holen.
  102.     cpi     R16,$23                 ;Bereits $23?
  103.     breq    inc_hours_23            ;Dann Sonderbehandlung.
  104.     inc     R16
  105.     sts     hours,R16               ;abspeichern.
  106.     jmp     inc_hours_end           ;Das war's.
  107. inc_hours_23:
  108.     clr     R16                     ;Stunden auf $00
  109.     sts     hours,R16               ;setzen.
  110. inc_hours_end:
  111.     pop     R16                     ;Register wiederherstellen
  112.     ret
  113.  
  114. ; CLOCK_UPDATE
  115. ; -------
  116. clock_update:
  117.     push R16                        ;Register retten.
  118.     call inc_sec                    ;Sekunden weiterzaehlen.
  119.     tst R16                         ;Ueberlauf (59 -> 00)?
  120.     brne clock_update_end           ;Nein, dann fertig.
  121.     call inc_min                    ;Sonst Minuten weiterzaehlen.
  122.     tst R16                         ;Ueberlauf (59 -> 00)?
  123.     brne clock_update_end           ;Nein, dann fertig.
  124.     call inc_hours                  ;Sonst Stunden weiterzaehlen.
  125. clock_update_end:
  126.     pop R16                         ;Register wiederherstellen.
  127.     ret
  128.  
  129. ; DIV_8U
  130. ; -------
  131. div8u:  push    R18
  132.         clr     r15         ;clear remainder and carry
  133.         ldi     r18,9       ;init loop counter
  134. d8u_1:  rol     r16         ;shift left dividend
  135.         dec     r18         ;decrement counter
  136.         brne    d8u_2       ;if done
  137.         pop     R18
  138.         ret                 ;return
  139. d8u_2:  rol     r15         ;shift dividend into remainder
  140.         sub     r15,r17     ;remainder = remainder - divisor
  141.         brcc    d8u_3       ;if result negative
  142.         add     r15,r17     ;restore remainder
  143.         clc                 ;clear carry to be shifted into result
  144.         rjmp    d8u_1       ;else
  145. d8u_3:  sec                 ;set carry to be shifted into result
  146.         rjmp    d8u_1
  147. ; *****************************************************************************
  148. ; *****************************************************************************
  149.  
  150. ; =============================================================================
  151. ; Initialisierung
  152. ; Loesung zu 11.2 b i)
  153. ; =============================================================================
  154. main:
  155.     ldi     R16,low(RAMEND)         ; Stack-
  156.     out     SPL,R16                 ; pointer-
  157.     ldi     R17,high(RAMEND)        ; initiali-
  158.     out     SPH,R17                 ; sierung
  159.     ser     R16                     ; R21 <- 0xFF
  160.     out     DDRB,R16                ; PORTA in Schreibemodus setzen
  161.  
  162. ; =============================================================================
  163. ; ; Loesung zu 11.2 c i)
  164. ; =============================================================================
  165.     ldi     R16,(1<<CS22)|(1<<CS20) ; CLK/128 (Prescale)
  166.     out     TCCR2,R16               ; Modus setzen
  167.     ldi     R16,(1<<TCN2UB)         ; Bit 3 des Asynchronous Status
  168.     out     ASSR, R16               ; Registers setzen (32768Hz-Takt)
  169.     ldi     R16,(1<<TOIE2)          ; Interrupt
  170.     out     TIMSK,R16               ; enablen
  171.  
  172. ; =============================================================================
  173. ; Initialisierung
  174. ; Loesung zu 11.2 b ii)
  175. ; =============================================================================
  176. loop:
  177.     lds     R16,seconds             ; Dividend = Sekunden
  178.     ldi     R17,2                   ; Divisor = 2
  179.     call    div8u                   ; Unterprogramm aufrufen und dividieren
  180.     ldi     R18,(1<<PINB0)          ; 0. Anzeigenelement
  181.    
  182.  
  183.     ldi     R18,(1<<PINB4)          ; Anzeigenelement (Doppelpunkt)
  184.     clr     R19                     ; Segmentwert
  185.     cpi     R17,0                   ; bei geraden Sekunden...
  186.     breq    weiter                  ; ... Doppelpunkt nicht aktivieren
  187.     ldi     R19,1                   ; Doppelpunkt an
  188. weiter:
  189.     out     PORTB,R18               ; Doppelpunkt setzen
  190.     out     PORTA,R19               ; ... auf den entsprechenden Wert
  191. ;   ... hier jetzt alle einzelnen Anzeigenelemente durchlaufen
  192. ;   und auf den jeweiligen Segmentwert setzen...
  193.     rjmp    loop                    ; Schloop
  194.  
  195. ; =============================================================================
  196. ; Initialisierung
  197. ; Loesung zu 11.2 c iii)
  198. ; =============================================================================
  199. clock_isr:                          ; jede Sekunde:
  200.     call    clock_update            ; Uhr updaten
Advertisement
Add Comment
Please, Sign In to add comment