PS/2 mit Assembler - Fehler wegen Interrupts

OP #2595797
Lesenswert?

Liebes Forum,

ich bin gerade für ein Projekt dabei, eine PS/2 Tastatur mit einem 
Atmega 16 auszulesen. Mein bisheriges Ziel war eigentlich nur, die von 
der Tastatur gesendeten Scancodes zu empfangen und über LEDs auszugeben.

Mein Code funktioniert im Prinzip so:
Tastatur CLK an INT2 (INT0 & 1 sind leider schon belegt) löst Interrupt 
bei fallender Flanke aus.
Es wir geprüft ob dies das Startbit ist, falls ja wird es nicht 
gespeichert, sondern einfach ein Zählregister inkrementiert.
In den darauffolgenden 8 Interrupts wird zunächst das Empfangsregister 
rotiert, sodass das LSB für das nächste am Data-Eingang anliegende Bit 
(PortB.3) frei wird. Das Paritätsbit wird wiederum herausgefiltert, und 
wenn das Stopbit empfangen wurde, wird das nun in Temp3 gesicherte Byte 
an PORTD ausgegeben. Dann werden die Variablen resettet um die nächste 
Übertragung abzuwarten.

Wenn ich das Programm nun auf dem µC habe, bekomme ich keine Ausgabe 
über die LEDs (beim normalen Durchlauf). Wenn ich es über einen JTAG 
debugge, wird immer ein Interrupt aktiviert (auch wenn keine Taste 
gedrückt wird) und es werden auch Bytes ausgegeben. Die haben allerdings 
noch keinen kausalen Zusammenhang mit den Scancodes.

Danke für jede Hilfe :)

EDIT: Habe den Code nochmal überarbeitet, selbes Problem:
1
.include "m16def.inc"
2

3
.def temp = r16
4
.def temp2 = r17
5
.def temp3 = r18
6

7
.org 0
8
    rjmp init
9
.org INT2addr
10
        rjmp int2_handler    
11

12
init:  ldi temp, LOW(RAMEND) ;Stack-Init
13
        out SPL, temp
14
        ldi temp, HIGH(RAMEND)
15
        out SPH, temp
16

17
    ldi temp, 0xFF
18
    out ddrd, temp
19

20
    ldi temp, 0b11110011  ;interrupt eingang portb2 + data leitung pordb3
21
        out DDRb, temp
22

23
    ldi temp, (1<<2)|(1<<3)
24
    out PORTB, temp
25

26
    ldi temp, (1<<INT2)
27
    out GICR, temp
28
    
29
    clr temp2
30
    clr temp3
31

32
    sei
33

34
loop:  rjmp loop
35

36

37
;Interrupt
38
int2_handler:
39

40
    cpi temp2, 1
41
    brlo skipbit ;Startbit
42
    
43
    cpi temp2, 0x0A ;Alles empfangen?
44
    brsh ausgabe
45
    
46
    cpi temp2, 0x09 ;Paritätsbit?
47
    brsh skipbit
48
    
49
    clc
50
    ror temp3 ; ausleseregister rotieren für nächsten Eingabe
51

52
    in temp, pinb
53
    bst temp, 3 ;Nächstes Bit ins Ausleseregister
54
    bld temp3, 7
55

56

57
skipbit:inc temp2
58
    reti
59

60
ausgabe:out portd, temp3
61

62
    clr temp3
63
    clr temp2
64
    reti
(Firma: TH Köln) Persönliche Seite #2596709
Lesenswert?

Malte B. schrieb:
> Es wir geprüft ob dies das Startbit ist

Das siehst du etwas falsch, du prüfst nur deinen Zähler und setzt dabei 
voraus, dass das Startbit dann kommt, wenn dieser auf 1 steht, selbst 
wenn das (falsche) 'Startbit' eine 1 ist. Mit viel Glück könnte das 
funktionieren, aber bei jeglichem Fehler läuft das sofort aus dem Ruder. 
Der int-IRQ ohne Noise-Canceler reagiert auch empfindlich auf Störungen.

Hab grad nicht im Kopf, wie's genau geht, aber du müsstest das Startbit 
als solches identifizieren (bspw. warten bis CLK >50µs high und dann 
erste fallende Flanke, wenn DAT auf low dann Startbit) und dann erst den 
Zähler starten und die nachfolgenden bits einlesen. Oder, falls noch 
frei, könntest du auch einfach den USART nehmen und dir die ganze Arbeit 
sparen(synchr.USART, odd-Parity und CLK und RxD mit pull-up an die 
Tastatur).

Mark

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren