ITG-ABI 09/10 |
19.4.2010 |
Korrekturhinweise / Lösungsvorschlag |
|---|
Verwendeter µC: ATMEL AVR 8 Bit RISC.
Globale Variable stufe : GZ mit Werten von 0..9.

Globale Variable zaehl: GZ (unsigned char) für Assembler eine reservierte lokale Variable itmp
| C-Lösung | Assembler |
|---|---|
// 1.4
ISR(INT0_vect){
if (zaehl < 99)
zaehl++;
}
|
ISR_int0: ; Aufgabe 1.4 in itmp,SREG ; Statusregister laden push itmp ; Statusregister retten cpi zaehl,99 brge ende ; Sprung wenn goesser oder gleich inc zaehl ; sonst erhoehe zaehl ende: pop itmp ; Statusregister holen out SREG,itmp ; Statusregister zurueckschreiben reti ; return from Interrupt |
Problem 1 Sekunde und Timer hat maximal 16 Bit. 1MHz, mögliche Vorteiler 1,8,64,256,1024
| Vorteiler | Lösungen |
|---|---|
| 1 | Alle 50 ms Interrupt (von 15535 bis 65535 zählen) und dann in ISR bis 20 zählen |
| 64 | Alle 64 µs Timerinkrement, von 49910 bis 65535 zählen. |
Globale Variable anzeige: GZ (unsigned char)
| C-Lösung | Assembler |
|---|---|
// 1.5
ISR(TIMER1_OVF1_vect){
TCNT1 = 49910; // Zeit einstellen
anzeige = zaehl; // Messung zur Anzeige speichern
zaehl = 0; // Sensorzaehler zurueck setzen
}
|
ISR_ovf1: ; Aufgabe 1.5 ldi itmp,HIGH(49910) ; obere Bits laden out TCNT1H,itmp ; oben setzen ldi itmp,LOW(49910) ; untere Bits laden out TCNT1H,itmp ; unten setzen Uebernahme mov anzeige,zaehl ; Messung speichern ldi zaehl,0 ; Sensorzaehler zurueck setzen reti ; return from Interrupt |
Hinweis zur Assembler-Lösung: Da keiner der Befehle die Flags des Statusregisters ändern kann seine Rettung und Wiederherstellung unterbleiben.
| C-Lösung | Assembler |
|---|---|
// 1.6
volatile unsigned char stufe=0,zaehl=0,anzeige=0; // glob. Var.
void init(){
DDRA = 0xFF; // PA als Ausgang
DDRB = 3; // PB0 und PB1 als Ausgang
MCUCR |= 1 << ISC01; // fallende Flanke
GIMSK |= 1 << INT0; // INT0 frei schalten
TCNT1 = 49910; // Zeit einstellen
TCCR0 = 3; // Systemtakt / 64
TIMSK |= 1 << TOIE1; // Timer1 Overflow Interrupt Enable
sei(); // globale Interruptfreigabe
}
int main(){
init();
while (1){
A_SG_T();
}
return 0; // damit Compiler nicht meckert
}
|
.def tmp = R16 ; Hilfsregister .def itmp =R17 ; Hilfsregister in Interrupts .def stufe = R18 .def zaehl = R19 .def anzeige = R20 rjmp reset .org INT0addr ; Interruptvektoradresse rjmp ISR_int0 .org OVF1addr rjmp ISR_ovf1 .org INT_VECTORS_SIZE ; nach Interrupts init: ldi tmp,RAMEND out SPL,tmp ; Stackpointer initialisieren ldi tmp,0xFF out DDRA,tmp ; PA als Ausgang ldi tmp,3 out DDRB,tmp ; PB0 und PB1 als Ausgang in tmp, MCUCR sbr tmp,ISC01 ; setze ISC01 Bit out MCUCR,tmp ; fallende Flanke in tmp,GIMSK sbr tmp, INT0 ; INT0 frei schalten out GIMSK,tmp ldi itmp,HIGH(49910) ; obere Bits laden out TCNT1H,itmp ; oben setzen ldi itmp,LOW(49910) ; untere Bits laden out TCNT1H,itmp ; unten setzen Uebernahme ldi tmp,3 out TCCRO,tmp ; Systemtakt / 64 in tmp,TIMSK sbr tmp,TOIE1 ; OVF1 frei schalten out TIMSK, tmp sei ; globale Interruptfreigabe ret reset: rcall init loop: rcall A_SG_T rjmp loop |
