ITG-ABI 08/09

30.3.2009

Korrekturhinweise / Lösungsvorschlag

Gruppe 1 Aufgabe 2

Verwendeter µC: ATMEL AVR 8 Bit RISC.

Mögliche Pin-Belegung

Portpin PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0 PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
Segment --- g f e d c b a --- --- --- --- A4 A3 A2 A1

2.2.2 Assembler

         .def akku = R16            ;Hommage an die alten Akku-Maschinen
         .def zaehler = R17
         .def null = R18            ;Hilfsregister mit Inhalt 0
       .dseg                        ;SRAM Bereich
daten:   .byte 4                    ;reserviere 4 Byte für A1..A4
       .cseg                        ;Programmbereich
steuer:  .db 0x0E, 0x0D, 0x0B, 0x07 ;Tabelle zur Ansteuerung der Anzeigen
seg7:    .db ...                    ;Tabelle zum 7-Segmentkodierer
anzeige: clr zaehler                ;Anzeigezähler zurücksetzen
loop:    ldi akku 0x0F
         out PORTB,akku             ;alle Anzeigen aus
         ldi XH, HIGH(daten)        ;laden der Daten aus dem SRAM
         ldi XL, LOW(daten)
         add XL, zaehler
         adc XH, null
         ld akku, X                 ;Daten für Anzeige lesen
         ldi ZH, HIGH(seg7*2)       ;laden des Segmentcodes aus dem Programmspeicher
         ldi ZL, LOW(seg7*2)
         add ZL, akku
         add ZH, null
         lpm akku, Z                ;Anzeigedaten kodieren
         out PORTC, akku            ;ausgeben Segmentcode
         ldi ZH, HIGH(steuer*2)     ;laden Steuercode aus dem Programmspeicher
         ldi ZL, LOW(steuer*2)
         add ZL, zaehler
         add ZH, null
         lpm akku, Z                ;Steuercode laden
         out PORTB, akku            ;Anzeige aktivieren
         cpi zahler, 3
         brne inc_za
         ret
inc_za:  inc zahler 
         rjmp loop

Lösung entspricht PAP, allerdings ist sie nicht praxisgerecht, LEDs würden recht dunkel bleiben, da nur kurz eingeschaltet während eines Zyklus.

2.2.4 Assembler

Externe Interrupts können bei Atmel AT90S2313 an Pin 6 (INT0/PD2) und Pin 7 (INT1/PD3) ausgelöst werden.

          .def akku = R16
          rjmp reset
          rjmp isr_int0
          rjmp isr_int1
          .org 0x10
steuer:...
seg7:...
isr_int0:...
          reti
isr_int1:...
          reti
anzeige:...
          ret
reset:    ldi akku,high(RAMEND)
          out SPH,akku        ;Stackpointer initialisieren
          ldi akku,low(RAMEND)
          out SPL,akku
          ldi akku,0b01111111 ;7Segment Anzeige
          out DDRC,akku       ;PC Ausgänge
          ldi akku,0b00001111
          out PORTB,akku      ;Enable aus
          out DDRB,akku       ;PB Ausgänge
          ldi akku,0b00001010 ;Fallende Flanken bei beiden Interrups
          out MCUCR,akku
          ldi akku,0b11000000 ;Externe Interrups freigeben
          out GIMSK,akku
          sei                 ;Globale Interruptfreigabe
loop:     rcall anzeige
          rjmp loop

2.2.4 C-Lösung

void main(){
  DDRC = 0x7F; //PC als Ausgang für 7Segment Anzeige
  PORTB= 0x0F; //Enable aus
  DDRB = 0x0F; //PB Enableausgänge
  MCUCR |= (1<<ISC01)|(1<<ISC11); //Fallende Flanken
  GIMSK |= (1<<INT0)|(1<<INT1);   //Interrupts freigeben
  sei();  //Globale Interruptfreigabe
  while(1)
    anzeige();
}