ITG-ABI 05/06 |
06.4.2006 |
Korrekturhinweise / Lösungsvorschlag |
---|
Verwendeter µC: ATMEL AVR 8 Bit RISC.
Mögliche Belegung der Ports
PD4 | PD3 | PD2 | PD1 | PD0 | PB7 | PB6 | PB5 | PB4 | PB3 | PB2 | PB1 | PB0 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Q4 | Q3 | Q2 | Q1 | Q0 | a | b | c | d | e | f | g | dp |
.def status = R3 ;Speichern des Statusregisters während Interrupt in Register R3 .def temp = R16 ; Arbeitsregister .def isrtemp = R18 ; Arbeitsregister für ISR rjmp start ; Nach Reset fangen Programme bei Adresse 0 an ; -- ISR für Externer Interrupt 0 sbis PORTD,2 ; überspringe den nächsten Befehl, wenn Bit 2 in PD gesetzt ist reti ; Rücksprung, da Bit PD2 null in status,SREG ;Statusregister retten lpm isrtemp, Z+ ; Lade Zeichen aus Zeiger Z und erhöhe Zeiger um 1 out PORTB, isrtemp ; Ausgabe Zeichen cpi R30, 10 ; vergleiche R30 also low (Z) mit 10 brlo weiter ; wenn es kleiner ist weiter cli ; Global Interrupt Disable weiter: out SREG,status ;Statusregister herstellen reti ; Zurück start: ldi temp, 0b00011111 out DDRD,temp ; PortD Ausgänge ldi temp, $FF out DDRB,temp ; PortB Ausgänge ldi R31, high(seg7code); High-Byte in Zeiger Z ldi R30, low (seg7code); Low-Byte in Zeiger Z lpm temp, Z+; lade Zeichen 0 und erhöhe Zeiger um 1 out PORTB, temp ; gib die 0 auf 7-Segmentanzeige aus sbi GIMSK, INT0 ; gib ext Interrupt 0 frei sbi MCUCR, ISC01 ; reagiert auf negative Flanke sei ;Interrupts global freigeben (I-Bit), jetzt ist es scharf haupt: ldi temp, 0b00000001 out PORTD, temp rcall wait100ms ldi temp, 0b00000010 out PORTD, temp rcall wait100ms ldi temp, 0b00000100 out PORTD, temp rcall wait100ms ldi temp, 0b00001000 out PORTD, temp rcall wait100ms ldi temp, 0b00010000 out PORTD, temp rcall wait100ms ldi temp, 0b00001000 out PORTD, temp rcall wait100ms ldi temp, 0b00000100 out PORTD, temp rcall wait100ms ldi temp, 0b00000010 out PORTD, temp rcall wait100ms rjmp haupt .org $300 ; es wird lange keinen Überlauf von low-Byte nach high-Byte in Zeiger Z geben seg7code: .db 0b11111100 ;252 .db 0b01100000 ;96 .db 0b11011010 .db 0b11110010 .db 0b01100110 .db 0b10110110 .db 0b01111110 .db 0b11100000 .db 0b11111110 .db 0b11110110
Es muss nicht immer so genau sein – etwa 100 ms bei 1 Mhz Takt warten:
wait100ms: ldi aussen,130 loop_aussen: ldi innen,0 ;Register auf 0 loop_innen: dec innen brne loop_innen dec aussen brne loop_aussen ret ; Rücksprung |
Die innere Schleife benötigt 1+255*(1+2)+1+1 = 256 * 3 = 768 Zyklen = 0,768 ms
Mit der äusseren Schleife ergibt sich 3 (rcall) + 1 (ldi) + 130 * 768 + 130 * 1 (dec) + 129 * 2 (brne) + 1 (brne) + 4 (ret) = |