/* * 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< 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