MezData-Logo

Blinklicht mit Timer und Interrupt mit Assembler

Problemstellung

Ein ATtiny2313 läuft mit 1 MHz Systemtakt und soll eine LED mit 0,5 Hz blinken lassen unter Verwendung eines Timer-Overflow-Interrupts.

Prinzip des Timer-Overflow-Interrupts

Präsentation

(Pfeiltasten verwenden)

Die richtigen Einstellungen ermitteln

Blockschaltbild TimerInterruptDie Interrupt Service Routine (ISR) soll zu bestimmten Zeiten aufgerufen werden, hier alle 250ms. Ein Overflow-Interrupt wird beim Überlauf des Zählers vom höchsten Wert -hier $FF nach $00 ausgelöst. Um die gewünschte Zeit zu erreichen muss eine geeignete Kombination aus Systemtakt-Vorteilung und Vorspannung des Zählers, also des Wertes von dem er bis zum Maximum läuft, gefunden werden. Dazu ermittelt man für verschiedene Vorteilerwerte die mögliche Genauigkeit:

Vorteilerwert Abstand Zählerimpuls Zählertakte Genauigkeit
1024 1024µs 250000/1024 = 244.1 244*1024µs = 249,86 ms
256 256µs 250000/256 = 976,56 zu groß für 8 Bit

Hier ist nur der Vorteilerwert 1024 möglich, kleinere Werte würden mehr Zählimpulse erfordern als mit 8Bit zählbar wären. Bei einer Vorspannung des Zählers mit dem Wert 12 wird nach 256-12=244 Takten der Overflow-Interrupt ausgelöst.

Tipp: Ist der Vorteilerwert schon maximal und die notwendigen Zähltakte passen nicht mehr in den Zähler, dann entweder grösseren Zähler verwenden oder in der ISR weiterzählen.

Quellcode für Version mit 8Bit Timer0

Quellcode [blinker-mit-timer.asm]
; *** Blinklicht mit 8Bit Timer 1.0 (c) Oliver Mezger 01.01.2011
.include "tn2313def.inc"
 
;* Blinker (PB0) soll mit 0,5Hz blinken, Interrupt wird alle 250ms aufgerufen
;* Interner RC-Oszillator mit 8MHz geteilt durch 8 (tiny2313 Spezialitaet)
;* Systemtakt Phi ist somit 1MHz
;* Zaehlertakt von 8Bit-Timer0 sei Phi/1024 somit waere Interruptintervall = 256*1024us = 262ms
;* Zaehler startet deshalb nicht mit 0 sondern einem hoeheren Wert 12 damit Zeit stimmt.
 
.def tmp  = R16     ;Hilfsregister
.def itmp = R17     ;Hilfsregister fuer Interrupt
 
  rjmp reset    ;Sprung zur Initialisierung
  .org OVF0addr     ;naechter Befehl an der Interrupteinsprungadresse
  rjmp isrOVF0      ;Sprung zur Interruptbehandlungsroutine
  .org INT_VECTORS_SIZE ;weiter nach Interrupttabelle
 
reset:                ;Initialisierung nach Reset
  ldi tmp,low(RAMEND) ;oberste RAM-Adresse laden
  out SPL,tmp       ;Stackpointer initialisieren
  ldi tmp,$ff
  out PORTB,tmp     ;alle LED aus
  out DDRB,tmp      ;PB als Ausgang
  ldi tmp,5         ;Vorteiler auf Phi/1024 setzen
  out TCCR0B,tmp    ;alle 1024us ein Zaehl-Impuls
  ldi tmp,1<<TOIE0  ;Timer Overflow Interrupt Enable 0 setzen 
  out TIMSK,tmp     ;Timer kann nun Interrupt ausloesen
  ldi tmp, 12       ;Vorspannen des Timers
  out TCNT0,tmp     ;damit die Zeit bis Overflow stimmt
  sei               ;globale Interrupt Freigabe
loop:
  rjmp loop           ;Endlos-Schleife
 
isrOVF0:         
  ldi itmp,12    ;Wert zum Vorspannen des Timers laden
  out TCNT0,itmp ;in den Timer schreiben
  sbic PORTB,0   ;wenn PB0
  rjmp clearPB0  ;loesche PB0
  sbi  PORTB,0   ;sonst setze PB0
  reti           ;Interruptbehandlung ist zu Ende
clearPB0: 
  cbi  PORTB,0   ;loesche PB0
  reti           ;Interruptbehandlung ist zu Ende

Der Blinker soll nun mit 1Hz blinken, modifizieren Sie den Code.

Verwenden Sie nun den 16-Bit Timer1 um das 1Hz Blinken zu erzeugen.

Lösung anzeigen..

Weitere Übungsaufgaben

Gegeben: 4 MHz Systemtakt, 8Bit-Timer 0, Overflow-Interrupt, Blinken mit 1 Hz (0,5s an; 0,5s aus) an PB0.

Gegeben: 12 MHz Systemtakt, 16Bit-Timer 1, Overflow-Interrupt, Blinken mit 1 Hz an PB0.

Dimmen einer LED mit Pulsweitenmodulation

Die Helligkeit von LEDs kann man durch schnelles Ein- und Ausschalten variieren.

  • Eine LED an PB0 leuchtet bei log. 0.
  • Die Helligkeit der LED soll einstellbar sein.
  • Die Zeit in der sie leuchtet ist tein und in der sie aus ist taus.
  • Die Zeiten teinund taus werden durch einen 8 Bit Timer realisiert.
  • Die Periodendauer T ist tein+taus.
  • Bei maximaler Einschaltdauer (tein = T) ist die Ausschaltzeit taus = 0
  • Der Timer wird mit Systemtakt 1Mhz ohne Vorteilung betrieben.
  • Verwenden Sie den Overflow Interrupt.
  • Die LED soll zunächst ca. 10% Hell sein.
0 1 2 3 4 5 6 7
LED leuchtet hell da länger 0 als 1

tein> taus

0 1 2 3 4 5 6 7
LED leuchtet dunkel da länger 1 als 0

tein< taus

Wie viele Helligkeitsabstufungen sind möglich -Begründung?

Erstellen Sie das Programm.

Die Helligkeit soll selbständig langsam variieren.

Lösung anzeigen..

Die Helligkeit soll über zwei Taster an PD eingestellt werden können.