Zorbing icon

[TGI] Gatter-Tester

Zorbing | PRO | 01/24/14 02:16:53 AM UTC | 0 ⭐ | 374 👁️ | Never ⏰ | []
ASM (NASM) |

0 B

|

None

|

0 👍

/

0 👎

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

Comments