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
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
Eine eigene Frage?
Dieser Thread ist über 14 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.