Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * TGI_10.asm
- *
- * Created: 28.11.2013 13:37:11
- * Author: Ehlers/Meyer/Boekhoff/Jaehn
- */
- .include "m16def.inc"
- .def TMP = R16
- ; Definieren Sie für die Gatter R20 bis R23 die Namen GATTER_TYPE, COUNTER, CURRENT_GATTER, BLINK.
- .def GATTER_TYPE = R20
- .def COUNTER = R21
- .def CURRENT_GATTER = R22
- .def BLINK = R23
- ; Definieren Sie die Konstanten NUM_GATTER_TYPES = 3, TYPE_AND = 0, TYPE_NAND = 1, TYPE_OR = 2 und TYPE_UNKNOWN = 3.
- .equ NUM_GATTER_TYPES = 3
- .equ TYPE_AND = 0
- .equ TYPE_NAND = 1
- .equ TYPE_OR = 2
- .equ TYPE_UNKNOWN = 3
- .dseg
- .org $0100
- ; Stellen Sie im RAM unter dem Label GATTER_TYPES 4 Byte zur Verfügung.
- GATTER_TYPES: .byte 4
- .cseg
- ; Interrupt Vektor Tabelle
- .org $0000
- rjmp init
- .org $0026 ; OC0addr
- rjmp TIMER0_COMP_ISR
- ; Legen Sie jeweils die vier Ausgaben der Gatter unter den Labeln AND_GATTER, NAND_GATTER und OR_GATTER im ROM ab.
- ; Verwenden Sie für jede Ausgabe jeweils 1 Byte.
- ; Diese sollen direkt zu der sequentiellen Belegungen der Eingänge mit den Werten null bis drei korrespondieren.
- .org $002A
- AND_GATTER: .db 0b00000000, 0b00001001, 0b00010010, 0b00111111
- NAND_GATTER: .db 0b00100100, 0b00101101, 0b00110110, 0b00011011
- OR_GATTER: .db 0b00000000, 0b00101101, 0b00110110, 0b00111111
- .org $0060
- ; *****************************************************************************
- ; Initialisierung
- ; *****************************************************************************
- init:
- ; Initialisierung des Stack Pointers
- ldi TMP, high(RAMEND)
- out SPH, TMP
- ldi TMP, low(RAMEND)
- out SPL, TMP
- ; Portdefinitionen (PORT A und B)
- ldi TMP, 0b11011011
- out DDRA, TMP
- out DDRB, TMP
- ; Portdefinitionen (PORT C)
- out DDRC, TMP
- ; Portdefinitionen (PORT D)
- ldi TMP, 0b11111110
- out DDRD, TMP
- ; Initialisierung der Anfangswerte einzelner Register
- ldi BLINK, 0
- ; ------ TODO ------ ;
- ; Initilaisierung des Timers
- ; Vergleichswert für Timer0 (~100 ms) in das Compare Register schreiben
- ; ------ TODO ------ ;
- ldi TMP, 100
- out OCR0, TMP
- ; Clear-Timer-On-Compare-Match (CTC) Modus einstellen &
- ; Prescaler auf clk/1024 für den Timer0 einstellen
- ldi TMP, (1<<COM01) | (1<<COM00) | (1<<WGM01) | (1<<CS02) | (1<<CS00)
- out TCCR0, TMP
- ; Interrupt für Compare-Match des Timers0 lokal aktivieren
- ldi TMP, (1<<OCIE0)
- out TIMSK, TMP
- ; Interrupts global aktivieren
- sei
- rjmp main
- ; Das Hauptprogramm verbleibt in einer Endlosschleife, bis an PD0 ein High-Pegel detektiert wird.
- ; Wärend des Wartens sollen die LEDs ausgeschaltet sein und keine Spannung an den Eingängen des Gatters anliegen.
- ; Ist der Taster gedrückt, so beginnt das Hauptprogramm sequentiell die einzelnen Gatter des ICs mithilfe des Unterprogramms TEST_GATTER zu übeprüfen
- ; und speichert die einzelnen Gattertypen entsprechend im RAM unter dem Label GATTER_TYPES ab.
- ; Wurden alle Gatter des ICs übeprüft, erfolgt die Ausgabe mithilfe des Unterprogramms OUTPUT.
- ; Dieses erwartet im Register R16 den Typ des ICs, welcher dem ersten im RAM gespeicherten Typen entspricht, der ungleich TYPE_UNKNOWN ist.
- ; Sollte es sich um ein unbekanntes oder komplett defektes Gatter handeln, so enthält R16 den Typ TYPE_UNKNOWN.
- ; Anschließen wird wieder zu main gesprungen.
- main:
- sbis PIND, PIND0
- rjmp main
- ; Analyse starten
- ldi CURRENT_GATTER, 0 ; aktuelles zu pruefendes Gatter
- ldi XH, high(GATTER_TYPES)
- ldi XL, low(GATTER_TYPES)
- gatter_loop:
- inc CURRENT_GATTER ; naechstes Gatter
- call TEST_GATTER
- st X+, GATTER_TYPE ; ermittelten Gatter-Typ speichern
- cpi CURRENT_GATTER, 4 ; sind alle Gatter ueberprueft?
- brne gatter_loop
- ldi COUNTER, 4
- ld R16, -X ; lade den ersten Typen
- ldi XH, high(GATTER_TYPES)
- ldi XL, low(GATTER_TYPES)
- suche_typ:
- ld R16, X+ ; speichere den Typ
- cpi R16, TYPE_UNKNOWN ; ist der Typ nicht unbekannt?
- brne typ_gefunden
- dec COUNTER
- brne suche_typ
- typ_gefunden:
- call OUTPUT ; Ausgeben des Vergleichsergebnisses: R16 enthaelt den Typ des gesamten Bausteins
- rjmp main
- ; Dieses Unterprogramm testet das in CURRENT_GATTER gegebene Gatter des ICs und
- ; liefert als Ergebnis in GATTER_TYPE den Gattertypen zurück.
- ; Dazu werden die Eingänge des Gatters sequentiell mit den Eingaben null bis drei belegt und die Ausgabe ensprechend der im ROM abgelegten Prüfwerte verglichen.
- ; Es muss bei der Ansteuerung der einzelnen Gatter darauf geachtet werden, dass die Ausgabe der LEDs nicht beeinflusst wird.
- ; Zwischen dem Setzen der Eingaben der Gatter und dem Auslesen der Ausgänge sollte eine kleine Wartezeit von einem Leertakt eingehalten werden.
- TEST_GATTER:
- ldi ZH, high(AND_GATTER<<1)
- ldi ZL, low(AND_GATTER<<1)
- ldi GATTER_TYPE, TYPE_AND ; Nummber des zu ueberpruefenden Gatter-Typen
- ldi COUNTER, 4 ; wie viele Tests wurden pro Gatter-Art schon ausgefuehrt
- type_loop:
- lpm TMP, Z+ ; nachsten Test laden
- out PORTA, TMP ; auf die Ports ...
- out PORTB, TMP ; ... schreiben
- in R17, PINA ; von den Pins ...
- in R18, PINB ; ... lesen
- eor R17, TMP ; Exklusiv- ...
- eor R18, TMP ; ... verodern
- ; switching
- cpi CURRENT_GATTER, 1
- breq test_PA2 ; Gatter 1 pruefen
- cpi CURRENT_GATTER, 2
- breq test_PA5 ; Gatter 2 pruefen
- cpi CURRENT_GATTER, 3
- breq test_PB2 ; Gatter 3 pruefen
- cpi CURRENT_GATTER, 4
- breq test_PB5 ; Gatter 4 pruefen
- test_PA2:
- sbrs R17, PINA2 ; ist PINA2 gesetzt (unterscheidet sich PINA2 von dem erwarteten Wert)?
- rjmp type_match ; ... wenn nicht, naechster Test
- rjmp type_mismatch ; sonst: naechster Typ
- test_PA5:
- sbrs R17, PINA5 ; PINA5 wie erwartet?
- rjmp type_match ; nein: naechster Test
- rjmp type_mismatch ; sonst: naechster Typ
- test_PB2:
- sbrs R18, PINB2 ; PINB2 wie erwartet?
- rjmp type_match ; nein: naechster Test
- rjmp type_mismatch ; sonst: naechster Typ
- test_PB5:
- sbrs R18, PINB5 ; PINB5 wie erwartet?
- rjmp type_match ; nein: naechster Test
- rjmp type_mismatch ; sonst: naechster Typ
- type_match:
- ; nachster Test
- dec COUNTER
- breq test_end ; alle 4 Tests waren erfolgreich
- rjmp type_loop ; naechsten Test durchfuehren
- type_mismatch:
- ; nachsten Typen ausprobieren
- inc GATTER_TYPE
- cpi GATTER_TYPE, TYPE_UNKNOWN ; Abbruchbedingung
- breq test_end ; alle Gatter-Typen getestet
- dec COUNTER ; zaehler noch dekrementieren
- brne z_restore ; sind noch unausgefuehrte Tests verblieben? -> Z-Register korrigieren
- ldi COUNTER, 4 ; Test-Zaehler zuruecksetzen
- rjmp type_loop ; zurueck zur Schleife
- z_restore:
- lpm TMP, Z+ ; inkrementiere die Adresse im Z-Register
- dec COUNTER
- brne z_restore ; bis sie auf dem ersten Test des naechsten Typs steht
- ldi COUNTER, 4
- rjmp type_loop
- test_end:
- ret
- ; Die Interrupt Service Routine soll das untere Bit des Register BLINK je Aufruf invertieren.
- TIMER0_COMP_ISR:
- push TMP ; Sichere TEMP
- in TMP, SREG ; Lade das SREG in TEMP
- push TMP
- ldi TMP, 1
- eor BLINK, TMP
- pop TMP ; Hole das SREG wieder vom Stack
- out SREG, TMP ; Und schreibe es raus
- pop TMP
- reti
- ; Das Unterprogramm OUTPUT erwartet im Register R16 den Typen des IC-Bausteins (TYPE_AND|TYPE_NAND|TYPE_OR|TYPE_UNKNOWN)
- OUTPUT:
- push R16
- push R17
- push R18
- push R19
- push COUNTER
- ; R16 enthält den Gattertypen
- ldi xl, low(GATTER_TYPES)
- ldi xh, high(GATTER_TYPES)
- clr COUNTER
- clr R19
- cpi R16, TYPE_UNKNOWN
- brne loop_out
- sbrs BLINK, 0
- rjmp all_off
- ldi R17, 0xC0
- out PORTA, R17
- out PORTB, R17
- ldi R17, 0xC3
- out PORTC, R17
- ldi R17, 0x1E
- out PORTD, R17
- rjmp loop_out_end
- all_off:
- clr R17
- out PORTA, R17
- out PORTB, R17
- out PORTC, R17
- out PORTD, R17
- rjmp loop_out_end
- loop_out:
- ld R18, x+
- lsr R19
- cp R18, R16
- brne loop_out_ne_blink
- ldi R17, 0x80
- add R19, R17
- rjmp loop_out_ne
- loop_out_ne_blink:
- sbrc BLINK, 0
- rjmp loop_out_ne
- ldi R17, 0x80
- add R19, R17
- loop_out_ne:
- inc COUNTER
- sbrs COUNTER,2
- rjmp loop_out
- ; Ausgabe ist in den 4 MSB von R19 enthalten
- cpi R16, TYPE_AND
- brne loop_out_nand
- mov R17, R19
- andi R17, 0xC0
- out PORTB, R17
- mov R17, R19
- lsl R17
- lsl R17
- out PORTA, R17
- rjmp loop_out_end
- loop_out_nand:
- cpi R16, TYPE_NAND
- brne loop_out_or
- swap R19
- lsl R19
- out PORTD, R19
- rjmp loop_out_end
- loop_out_or:
- mov R17, R19
- swap R17
- or R17, R19
- andi R17, 0xC3
- out PORTC, R17
- loop_out_end:
- pop COUNTER
- pop R19
- pop R18
- pop R17
- pop R16
- ret
Advertisement
Add Comment
Please, Sign In to add comment