ITG-ABI 05/06

06.4.2006

Korrekturhinweise / Lösungsvorschlag

Gruppe 1 Aufgabe 1

Verwendeter µC: ATMEL AVR 8 Bit RISC.

3.2 a & c Hauptprogramm und ISR

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  

3.2 b 100 ms warten

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) =
4 + 130 * 769 + 129 *2 + 5 = 100237 Zyklen = 100,237 ms.