ITG-ABI 06/07 |
02.5.2007 |
Korrekturhinweise / Lösungsvorschlag |
---|
Verwendeter µC: ATMEL AVR 8 Bit RISC.
Im Lösungsvorschlag wurde von einer Maschinenzykluszeit von 1µs ausgegangen. Den Prüflingen wurde entsprechend abweichend von 12MHz ein Takt von 1MHz vorgegeben um die selbe Problemstellung zu erhalten.
Beim AVR-Controller können bestimmte Paare von 8Bit Registern zu 16Bit Registern zusammengeschaltet werden. Somit sind Lösungen mit nur einer Zählschleife möglich!
Siehe: mezdata.de/avr/110_warteschleifen/
Beim AVR-Controller gibt es einen Zähler/Timer mit 8Bit und einen mit 16Bit. Der Systemtakt kann u.a. durch 256 oder 1024 geteilt werden. Somit ergeben sich folgende Möglichkeiten:
8 Bit | 16 Bit |
---|---|
50000 / 1024 = 48,8 gewählt 49 -> 256-49 = 207
50000 / 256 = 195,3125 gewählt 195 -> 256-195 = 61 |
Taktung mit Systemtakt
65536-50000 = 15536 |
Es gibt die Möglichkeit pulsweitenmodulierte Signale an bestimmten Pins aus zu geben, wurde im Unterricht nicht explizit behandelt -daher nicht im Lösungsraum erwartbar.
; Initialisierung rjmp reset .org $006 ; Einsprung nach Timer0 Überlauf rjmp t0isr .org $10 ; Ende der ISR-Sprungtabelle reset: ldi r16, LOW(RAMEND); Stackpointer out SPL, r16 ; Initalisieren ldi r16, 0b101 ; Timer mit Takt/1024 out TCCR0, r16 ; Timer0 Controll Register ldi r16, 1 << TOIE0 ; Bit für Timer0 Overflow Interrupt Enable out TIMSK, r16 ; Diesen Interrupt freigeben ldi r16, 207 ; Timer mit 207 out TCNT0, r16 ; vorspannen ; --- weitere Initialisierungen Ports usw. --- sei ; Interrupts global freigeben ; --- Hauptprogramm --- ; --- ISR --- t0isr: ; Statusregister muss nicht gesichert werden, da hier keine Flags verändert werden push r16 ; Arbeitsregister retten wenn nicht explizit für isr reserviert ldi r16, 207 ; Timer wieder mit 207 out TCNT0, r16 ; vorspannen pop r16 ; r16 wieder herstellen sbis PORTB,0 ; überspringe folgenden Befehl wenn Bit0 von PORTB gesetzt rjmp setPB0 ; Sprung cbi PORTB,0 ; Lösche Bit0 von PORTB reti ; Return from Interrupt setPB0: sbi PORTB,0 ; Setze Bit0 von PORTB reti
// Includes.. SIGNAL(SIG_OVERFLOW0){ TCNT0=207; // Timer wieder vorspannen PORTB ^=1; // Bit0 umdrehen mit EXOR } void main(){ TCCR0 |= 0b101; // Timer mit Takt/1024 TIMSK |= 1 << TOIE0; // Overflow Interrupt ermöglichen TCNT0=207; // Timer vorspannen sei(); // global Interrupts freigeben // Hauptprogramm.. }