Forum: Mikrocontroller und Digitale Elektronik Tastaturaufzeichnung mit AVR


von Matthias (Gast)


Lesenswert?

Hallo,

ich will mit einem AVR eine Tastaturaufzeichnung realisieren. D.h. der 
AVR hängt zwischen Tastatur und PC und zeichnet alle Tastendrücke in 
einem externen EEPROM auf.
Wie schaffe ich es, in die Kommunikation zwischen Tastatur und PC 
"reinzuhören", ohne diese zu stören? (Ich will der Einfachkeit halber 
zunächst einmal eine Tastatur mit normalem DIN-Stecker verwenden)
Ich habe schon im "Hardware Book" (http://www.hardwarebook.net) 
nachgeschaut, die Leitungen "CLOCK" und "DATA" sind beide Open 
Collector. Reicht es, wenn ich einfach zwei Pins auf Eingang mit PullUp 
konfiguriere und an beide Leitungen hänge?

Gruß
Matthias

von Sebastian Wille (Gast)


Lesenswert?

Hi Matthias,

schau' mal unter www.mikrocontroller.com unter Downloads.

Dort gibt es eine Beschreibung für die Abfrage von PC-Tastaturen (egal 
ob DIN oder PS/2). Allerdings unter einem C-Compiler und leider nicht in 
Assembler.

Einfach nur dranhängen bringt glaube ich noch nichts. Ich denke, es 
funktioniert ähnlich wie I2C.

Genau dasselbe Projekt hatte ich übrigens auch vor! Wenn Du willst, 
können wir es ja auch gemeinsam (möglichst natürlich in Assembler) 
angehen.

Grüße,

Sebastian

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Sebastian,

danke erstmal für die schnelle Antwort. Das Projekt können wir gerne zu 
zweit machen (in Assembler)!
Ich hab mir den C-Source von www.mikrocontroller.com runtergeladen; 
allerdings stehen da wenig Infos zum Protokoll drin. Aber ich habe ein 
Assembler-Programm für die C-Control Unit angehängt, das ich noch 
gefunden habe. Dort stehen einige Infos zum Protokoll drin.

Gruß
Matthias

von DaNope (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab' zumindest mal den Tastaturteil in C realisiert. Es müßte 
übrigens überhaupt kein Problem sein ps/2 mitzusniffen!

Check:
http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/PS2/ps2.htm

viel Spaß damit

c'ya

DaNope

P.S.: Das seltsam erscheinende array text existiert, da meine LCD 
Ausgabe momentan nur arrays verträgt.

von Sebastian Wille (Gast)


Lesenswert?

Hi DaNope,

danke für den Links, das wird mir/uns sehr weiterhelfen! :-)

Matthias: Ich arbeite das ganze Zeugs mal durch und melde mich, wenn ich 
weiter bin. Sieht aber bisher alles sehr vielversprechend aus, ich 
denke, das Projekt ist zu schaffen!

Leider verreise ich nächste Woche Montag-Freitag. Vielleicht schreib' 
ich vorher aber nochmal.

Grüße,

Sebastian

von Matthias (Gast)


Lesenswert?

@DaNope: Ebenfalls danke für den Link! Ich habs mal überflogen, das wird 
uns echt weiterhelfen.
@Sebastian: Ich werd das ganze auch mal durcharbeiten und schauen, was 
wir daraus machen können. Außerdem muss ich mir noch konkret Gedanken 
zur Hardware machen.

Gruß
Matthias

von Jonas Diemer (Gast)


Lesenswert?

müsste man nicht einfach "mitlauschen" können, wenn die ausgänge auf 
tri-state sind? also einfach abgreifen und auslesen... die pins sollten 
dann dooch keine störungen verursachen.

von DaNope (Gast)


Lesenswert?

Die Hardware für das PS/2 Interface ist der Witz! Das kann man direkt 
auf den AVR klemmen (mit 2 Hochohmigen Pullups).
Den Externen EPROM würde ich über i2c ansteuern - wenn Ihr nicht zu viel 
Speicher braucht könnt Ihr ja auch den SRAM vergrößern.

von Sebastian Wille (Gast)


Lesenswert?

Hi an Alle!

Zur Hardware: Ich denke, ein ganz simpler AVR, z.B. 2323, reicht als 
Basis aus. Wir brauchen ja nur 2 Pins für die Tastatur. Und noch 2 Pins 
für das (Software-)UART.

Als externes EEPROM hätte ich auch I2C vorgeschlagen, das lässt sich ja 
locker erweitern.

Für den PC brauchen wir nur ein kleines Programm, das die gespeicherten 
Daten abruft. Das könnte ich leicht programmieren.

Was hälst Du von der Hardware, Matthias?

Den restlichen Interessierten vielen Dank!!! :-)

Grüße,

Sebastian

von Matthias (Gast)


Lesenswert?

Hallo Sebastian,

die Hardware ist OK! Als AVR habe ich einen 2333 mit MAX232 zur 
Verfügung. Speicher ist auch kein Problem, da habe ich noch ein neues 
8-KByte I2C EEPROM (wenn ich mich nicht irre, dann ist das der 24C65).
Ein entsprechendes Abrufprogramm am PC könnte ich in Delphi proggen.

Gruß
Matthias

von Sebastian Wille (Gast)


Lesenswert?

Hi Matthias,

dann sind wir uns ja mit der Hardware einig. Ich werde mir vielleicht 
noch einen 2333 besorgen, im Moment habe ich nur 4433/2343/2313.

Im Conrad-Katalog (S. 952) gibt es ein serielles EEPROM mit 8k und der 
Bezeichnung "24C65". Ich denke dann, daß es wohl I2C ist.

Das mit dem Abrufen können wir vielleicht noch viel eleganter lösen: 
Sobald man auf der Tastatur einen Code, wie z.B. "ABCDEF" eingibt, 
erkennt dies der AVR und sendet dann alles, was er gespeichert hat. Dann 
würde als PC-Proramm auch der Editor reichen. Was hälst Du davon? Am 
Anfang können wir der Einfach heit halber auch das UART verwenden (hat 
das 2333 einen Hardware-UART?).

Was heißt eigentlich "tri-State"? Einfach eine Parallel-Verbindung zu 
den zwei Daten-Pins der Tastatur? Oder muß man da irgendwie mit 
Transistoren usw. hantieren?

Ich bin bis morgen Vormittag noch da, dann leider erst wieder Samstag.

Grüße,

Sebastian

von Jonas Diemer (Gast)


Lesenswert?

tri-state heißt, wenn ich mich nicht irre, dass der pin hochohmig ist, 
d.h. fast keinen einfluss auf die schaltung nimmt, aber halt gelesen 
werden kann. über ne detailliertere antwort würd ich mich auch freuen... 
:-)

von Rudolf Sosnowsky (Gast)


Lesenswert?

Tristate gibt es nur bei Ausgängen. Es bedeutet, dass in einer 
Push-pull-Ausgangsstufe mit zwei Transistoren beide inaktiv sind, d.h. 
den Bus nicht aktiv beeinflussen. CMOS-Eingänge sind stets hochohmig, 
wenn nicht ein interner Pullup-Widerstand aktiviert wird. Für Eure 
Applikation bedeutet das, dass der AVR ohne weitere Maßnahmen an CLK und 
DATA geklemmt werden kann. Die Open-Collector-Struktur sorgt ja dafür, 
dass immer ein gültiger Pegel anliegt: Low, wenn einer der Ausgänge (PC 
oder Tastatur) durchgeschaltet ist, ansonsten high, weil der Pullup den 
Pegel bestimmt.

Gruß, Rudolf.

Rudolf Sosnowsky +++ LC Design
EPSON Technology Partner
Internet http://www.LC-Design.de

von Stefan Heindel (Gast)


Lesenswert?

Schaut mal auf www.beyondlogic.org . Geht dort auf "Misc" und da auf 
Interfacing PC-AT-Keyboard. Is alles sehr anschaulich erklärt. Habe auch 
schon mal nen ganz einfachen Morsezeichengenerator geschrieben, der 
tastatureingaben in piepstöne umwandelt. Viel Spass und Glück!

von Matthias (Gast)


Lesenswert?

Hi Sebastian,

dein 2313 funktioniert auch, da brauchst du dir nicht extra einen 2333 
kaufen (dem 2313 fehlt ledeglich der AD-Wandler sowie PWM, aber das 
brauchen wir sowieso nicht).

Das EEPROM im Conrad Katalog ist das richtige, allerdings ist das Teil 
unverschämt teuer (Ich hatte mir mein 24C65 vor längerer Zeit für meine 
C-Control Unit als Ersatzteil besorgt, hat mindestens 5 Euro gekostet). 
Beim Reichelt gibt es das 24C64 (ebenfalls 8Kb) für ledeglich 1,80 Euro 
(Katalog Seite 60). Das 24C65 und das 24C64 sind meines Wissens 
kompatibel, dem 24C64 fehlt ledeglich irgend ein Write-Protect Mode oder 
so, da müssten wir uns mal die Datenblätter ziehen.

Deine Idee zum Abrufen ist gut, da sparen wir uns den Umweg über 
irgendein Programm. Am Anfang testen wir das ganze mit dem UART, wie du 
vorschlägst (Der 2333 hat ein UART).
Ich würde drei verschiedene Codes vorschlagen:
1. Ausgabe der gespeicherten Daten (Tastaturemulation)
2. Löschen der gespeicherten Daten
evtl. 3. Abfrage (sind überhaupt Daten gespeichert worden?)

Danke auch allen anderen für die Antworten!

Gruß
Matthias

von Jornbyte (Gast)


Lesenswert?

Hallo an Alle
Ich habe mal vor einiger Zeit nach einer Leseroutine in Assembler für 
eine PS2-Tastatur gefragt. Sei so gut, und Veröffentlicht sie hier. Da 
sind doch einige User, die darann Interesse haben.
Ich selbst hatte noch keine Zeit für das Projekt.

von Jornbyte (Gast)


Lesenswert?

Hier ein Schaltunsvorschlag für den Tastaturanschluss.
http://home.t-online.de/home/jens.dietrich/seite99.htm

von Sebastian Wille (Gast)


Lesenswert?

Hi,

ich wollte nur kurz Bescheid geben, daß ich nun wieder da bin. Ich werde 
heute mal ein bissle experimentieren, dann melde ich meine Ergebnisse. 
Hast Du schon irgendwas gemacht, Matthias?

Danke auch für den neuen Link!

Sebastian

von Sebastian Wille (Gast)


Angehängte Dateien:

Lesenswert?

Hi (Matthias),

nun habe ich ein bissle rumgespielt und für meinen 4433 ein kleines 
Programm geschrieben.

Ich verwende eine AT-Tastatur, direkt an einen "weiblichen Adapter" 
angeschlossen. Wahlweise legt man Clock oder Data an den Pin 0 des Port 
C. Gedacht ist es für Clock.

Sobald sich nun was ändert (von high auf low oder umgekehrt), wird 
entweder eine 0 oder eine 1 (als ASCCI-Zeichen!) an die serielle 
Schnittstelle gesendet. Leider geht's erst ab 57600 gescheit, da kommen 
nur keine Einsen oder Nullen an, sondern andere Zeichen. Die Anzahl 
stimmt aber.

Wär' nett, wenn Du Dich/Ihr Euch mal dazu äußern könntest/könntet!

Sebastian

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hi Sebastian,

ich bin leider noch nicht dazu gekommen irgend etwas zu machen, aber ich 
werde heute mit ein paar Experimenten anfangen.
Dein Programm habe ich überarbeitet, die neue Version ist im Anhang (ist 
allerdings weder getestet noch assembliert). Wenn ich sie getestet habe, 
melde ich mich wieder.
Dass falsche Zeichen ausgegeben werden, könnte daran liegen, dass bei 
einer Baudrate von 57600 und einem 4 MHz Quarz ein Fehler von 9% 
entsteht.

Gruß
Matthias

von Sebastian Wille (Gast)


Lesenswert?

Hi Matthias,

mit 4 MHz und 19200Baud funktionierts wieder mit 0 und 1. Bei 57600Baud 
liegt laut Atmel die Fehlerrate bei 7% ich hatte aber 100%!!! Außerdem 
bekam ich immer die gleichen falschen Zeichen.

Das mit den Pullups ist gut, hat aber nicht wirklich was verändert.

Schließe ich DATA an, bekomme ich, bei z.B. der Leertaste, fast (!) 
immer die gleichen Ergebnisse:

0010100100101
0010100100101
0010100100101
0010100100101

000100100101
000100100101
000100100101

0000100010101

0000100100101

Die Reihenfolge der Ergebnisse stimmt nicht, ich habe sie sortiert. In 
Wirklichkeit waren Sie vermischt.

Warum bekomme ich nicht immer das gleiche Ergebnis? Ich habe die 
Leertaste immer nur ganz kurz gedrückt.

Hast Du schon was?

Grüße,

Sebastian

von Matthias (Gast)


Lesenswert?

Hallo Sebastian,

die Ergebnisse ändern sich, soweit ich das verstanden habe, da ein 
Tastendruck drei Ausgaben zur Folge hat:
- Taste zum ersten Mal gedrückt
- Taste weiterhin gedrückt
- Taste losgelassen

Ich habe gestern nichts mehr gemacht, werde aber heute ganz sicher mit 
Experimenten anfangen und hoffe, abends erste Ergebnisse posten zu 
können!

Gruß
Matthias

von Matthias (Gast)


Lesenswert?

Hi Sebastian,

ich habs jetzt auch ausprobiert. Es funktioniert zwar, aber das ganze 
sagt mir noch nicht allzu viel. Ich muss jetzt endlich die Beschreibung 
zum Protokoll durcharbeiten ...

Gruß
Matthias

von Jornbyte (Gast)


Angehängte Dateien:

Lesenswert?

Hier ist das Protokoll.

mfg Jornbyte

von Sebastian Wille (Gast)


Lesenswert?

Hi,

also ich hab' heut' noch ein bissle rumprobiert. Mit dem Protokoll hast 
Du recht Matthias, diesen Aspekt hatte ich schon wieder vergessen.

Trotzdem gibt es noch kein wirkliches System: Selbst wenn ich die 
Leertaste dauerhaft drück, kommt so ca. jedes 5. Mal etwas "falsches". 
Vielleicht sind 19200Baud ja zu langsam. Die Tastatur kann ja ca. 
15000mal eine 0 oder 1 abgeben. Aber meine Nullen und Einsen brauchen ja 
je ein Byte, also 10Bit (mit Start- und Stop-Bit). Ich krieg also nur 
max. 1920 Zeichen rüber. Theoretisch müssten es aber 15000 sein.

Wir müssen das Programm wahrscheinlich so verändern, daß es erstmal die 
Daten speichert (z.B. in 12 Registern) und dann "langsam" über das UART 
ausgibt. Wenn ich Zeit habe, werd ich's mal optimieren.

Den neuen Protokoll-Link werde ich auch mal durchlesen, an dieser Stelle 
vielen Dank!!!

Wo wohnst Du eigentlich ungefähr, Matthias? Vielleicht könnten wir uns 
auch mal treffen (wenn's recht ist).

Grüße,

   Sebastian

von Rudolf Sosnowsky (Gast)


Lesenswert?

Hallo,

diskutiert Ihr hier überhaupt über das gleiche Thema? Das 
Tastaturprotokoll ist seriell synchron, nicht asynchron. Das bedeutet, 
dass die Clock-Leitung mit abgefragt werden muß. Eine typische Anwendung 
für das SPI, nicht den UART.
Näheres siehe
http://www.beyondlogic.org/keyboard/keybrd.htm

Deshalb bekommt Sebastian ja auch nicht immer das gleiche Ergenbis, je 
nachdem, wo der UART gerade abtastet.

Gruß, Rudolf.

Rudolf Sosnowsky +++ LC Design
EPSON Technology Partner
Internet http://www.LC-Design.de

von Sebastian Wille (Gast)


Lesenswert?

Hallo Rudolf,

ich denke schon, daß wir vom Gleichen reden.

Das Tastatur-Protokoll ist seriell, richtig. Wir lesen im Moment 
entweder Clock oder Data ein. Und zwar über einen normalen Pin und nicht 
(!) über das UART. Danke an der Stelle auch für den Link, er ist aber 
das gleiche, wie Jornbytes Zip.

Am Ende müssen wir natürlich sowohl Clock als auch Data parallel 
einlesen. Dies sind ja aber noch unsere ersten Gehversuche.

Trotz allem müsste Clock doch immer gleich sein, oder?

Grüße,

   Sebastian

von Rudolf Sosnowsky (Gast)


Lesenswert?

Hallo Sebastian,

meiner Meinung nach ist der Ansatz nicht korrekt. Du kannst nicht ein 
Signal, das in seinem zeitlichen Ablauf nicht definiert ist, mit einem 
festen Zeitraster abtasten und ein reproduzierbares Ergebnis erwarten. 
Sieh Dir mal das Timingdiagramm auf der in dem Link angegebenen Seite 
an. Als "Host" mußt Du Clock- und Datenleitung beobachten. Wenn Du das 
Keyboard die Übertragung startet, mußt Du die Clock-Pulse verfolgen. 
Immer dann, wenn die fallende Flanke kommt, liest Du die Datenleitung 
ein und sammelst das Bit in einem (Software-) Schieberegister. Nach dem 
letzten Bit hast Du das Scanbyte, mit dem Du weiter arbeiten kannst. Mit 
dem UART funktioniert das nicht. Auf der Keyboard-Seite sitzt ja auch 
nur ein kleiner Prozessor, der mit seinen Leitungen wackelt, sobald er 
neben dem Scannen der Tasten dazu Zeit hat.

Gruß, Rudolf.

Rudolf Sosnowsky +++ LC Design
EPSON Technology Partner
Internet http://www.LC-Design.de

von Sebastian Wille (Gast)


Lesenswert?

Hallo Rudolf,

also das ganze funktioniert bisher so: Sobald sich der Zustand von 0 auf 
1 ändert, gibt das UART eine "1" aus. Ändert sich diese 1 wieder auf 
eine 0, gibt das UART eine "0" aus. Also ist mir die Zeit erstmal egal.

Das UART hat also erstmal gar nichts mit der Tastatur zu tun. Es dient 
uns nur zur Kontrolle auf dem Monitor. Wir könnten genauso gut auch eine 
LED blinken lassen.

Zumindest Clock müsste doch immer gleich sein, oder?!?

Sebastian

von Jornbyte (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Ich würde die Clockabfrage mit einem Interrupt machen.
In MCUCR 1 0 (eine fallende Flanke löst den Interrupt aus)
Damit steht an einem 2. Anschluss das Datenbit (Tastenscancodebit) zu 
diesem Zeitpunkt bereit.
1. Int. einen Registercounter starten.
2 bis 9 Int -> Pin2 lesen und in das Softwareschieberegister laden; 
Counter inc oder dec.
Int 10 und 11 Ignore.
und alles wieder von Anfang an.
Danach folgt die Auswertung des Scancodes.
Im Upload ist ein Beispiel für den 89C2051 in ASM.
(ich habe immer noch keine Zeit dafür gefunden)

mfg Jornbyte

von Rudolf Sosnowsky (Gast)


Lesenswert?

Hallo Sebastian,

der Vergleich mit der LED hinkt. Du schaust ja nicht jede Sekunde hin 
und notierst den Zustand, sondern registrierst nur die Änderungen. Das 
ist das, was der UART macht. Der Vorschlag von Jornbyte ist besser. Dann 
gibt es zwei LEDs: immer, wenn die eine ausgeht, schreibst Du auf, was 
die andere macht, egal, wie lange die Pausen dazwischen sind.

Gruß, Rudolf.

Rudolf Sosnowsky +++ LC Design
EPSON Technology Partner
Internet http://www.LC-Design.de

von Stefan Heindel (Gast)


Lesenswert?

Also die Sache ist nicht so schwer. Wie gesagt schaut euch die 
Zeichnungen auf Beyondlogic.org an.
Ok, wie geht man vor? Man besorgt sich erst mal ein Register wo man das 
zu empfangende Datenbyte reinschieben kann, ich nenne es mal R16.
Ok, also wenn beide Leitungen auf +5V sind dann geschieht nix. Man baut 
sich also ne Clock-Schleife. Diese hat die Aufgabe so lange zu kreisen 
bis das Clk-Signal von HIGH auf LOW fällt. Das macht man so

ClkHl:

LoopClkLow:
SBIS PIND,1                     ;An PIND1 hängt jetzt mal die Clk
RJMP LoopClkLow
LoopClkHigh:
SBIC PIND,1
RJMP LoopClkHigh

RET

==> Also wenn diese Schleife beendet wird dann ist die Clk von HIGH auf 
LOW umgesprungen; und man WEISS, dass die Daten an Data gültig sein 
MÜSSEN.

Ok. So jetzt kommt der Haupt-Interface-Teil.
Man weiss, dass das erste Bit ein Startbit ist, das man eh nicht 
braucht.

Receive:
RCALL ClkHl               ;Das Startbyte abwarten
CLR R16                   ;Das Empfangsbyte leeren
CLR LoopCnt               ;Einen Loop-Counter

RcvLoop:
RCALL ClkHl               ;Einen Clk-Zyklus abwarten
CLC                       ;Das Carry-Bit leeren.
SBIC PIND,2               ;Wenn logisch "high" anliegt,
SEC                       ;Carry-Bit setzen
ROR R16                   ;und Bit ins Register schieben
INC LoopCnt
CPI LoopCnt,7             ;7 Bits empfangen
BRNE RcvLoop
ROR R16                   ;nochmal ein Bit nach rechts schieben
RCALL ClkHl               ;partity Bit abwarten und postwendend
                          ;ins Daten-Nirvana schieben
RCALL ClkHl               ;Stoppbit abwarten


Ok.... also so in etwa funktioniert des. Des hab ich eben nur mal 
schnell geschrieben, als Anregung wie man es ungefähr machen kann. Ich 
gebe natürlich keine Funktionsgarantie. Naja also zumindest braucht man 
KEINE Interrupts, dafür is die Sache viiell zu laaaaannnnngsssaaaaammm 
:=)
Ein Problem bei empfangsroutinen is allgemein das sowas leicht aus dem 
Tritt kommen kann. Deswegen ist es für eine sauber arbeitendes Prog 
extrem wichtig, dass man Timeouts einbaut. Am besten in die 
Clk-Schleife. Also wenn man ein paar ms nicht kommt was kommen soll, 
dann muss sich des programm in den Anfangszustand zurückversetzen. Sowas 
realisiert man am besten mit dem T/C 0 oder aber auch mit einem 
einfachen Software-Zähler.

Na dann gebt mal Feedback, Jungs

Gruss Stefan

von Jornbyte (Gast)


Lesenswert?

Es ist aber nicht sinnvol den Controller ständig mit einer Abfrage der 
Tastaturbits auszubremsen. Der soll ja auch noch andere Dinge tun. 
Dehalb der vorschlag - Interrupt, wobei diese Routine die Int-Routine 
sein kann. Guter Ansatz!

mfg Jornbyte

von Sebastian Wille (Gast)


Lesenswert?

Hallo Stefan,

also erstmal vielen Dank für's "Reindenken" und Beispiel-Programm 
schreiben! :-)

Ich denke das Prinzip, wie eine Tastatur im Groben funktioniert, ist 
inzwischen klar. Persönlich hatte ich bisher nur noch keine Zeit das 
Beispielprogramm von mir und Matthias zu erweitern. Dein Ansatz ist 
schon sehr gut, danke!

Unser Progrämmchen sollte ja auch nur mal veranschaulichen, daß "da halt 
auch was" auf Clock und Data drauf ist und noch nicht zur konkreten 
Ermittlung der Zeichen dienen.

Noch eine Idee zum "Aufhängen": Wie wäre es mit dem Watchdog? Ist doch 
viel einfacher, oder?!?

Danke auf jeden Fall nochmals!!!

Sebastian

von Stefan Heindel (Gast)


Lesenswert?

Es gibt da nen feinen Trick... der nennt sich Tastaturpuffer. Du musst 
die Leitungen nur in einen bestimmten Zustand versetzen, und die 
Tastatur weiss eben das der "PC" "busy" is. Wenn man dann grade 
Prozessorzeit frei hat, kann man eben die Leitungen auf "Idle" setzen 
und die Tastatur kann ihre Notdurft ablassen ;=)

von Jornbyte (Gast)


Lesenswert?

Ich habe die Sache mal mit dem Interrup gemacht. (So auf die schnelle.) 
Der Scancode wird sauber erkannt.

; Für AT90S2313.
.include "2313def.inc" ;Pfad zur Include-Datei ggf. anpassen

.def temp   = r16
.def temp1  = r17
.def temp2  = r18
.def counter     = r19
.def fbin   = r20         ;Ausgangswert
.def tBCDL   = r20         ;Untere Dezimalstelle
.def tBCDH   = r21         ;Obere Dezimalstelle

.org 0000

  rjmp reset     ; RESET =$001 ;Reset
  rjmp TastInt     ; INT0addr=$001 ;External Interrupt0 Vector Address
  RETI ; INT1addr=$002   ;External Interrupt1 Vector Address
  RETI ; ICP1addr=$003   ;Input Capture1 Interrupt Vector Address
  RETI ; OC1Aaddr=$004   ;Output Compare1A Interrupt Vector Address
  RETI ; OVF1addr=$005    ;Overflow1 Interrupt Vector Address
  RETI ; OVF0addr=$006   ;Overflow0 Interrupt Vector Address
  RETI ; SPIaddr =$007   ;SPI Interrupt Vector Address
  RETI ; URXCaddr=$008   ;UART Receive Complete Interrupt Vector Address
  RETI ; UDREaddr=$009   ;UART Data Register Empty Interrupt Vector 
Address
  RETI ; UTXCaddr=$00a   ;UART Transmit Complete Interrupt Vector 
Address
  RETI ; ADCCaddr =$00b   ;ADC Interrupt Vector Address
  RETI ; ERDYaddr =$00c   ;EEPROM Interrupt Vector Address
  RETI ; ACIaddr =$00d   ;Analog Comparator Interrupt Vector Address

reset:

;Stackpointer initialisieren
  ldi temp, RAMEND
  out SPL, temp
  ldi temp, 4000000/(9600*16)-1   ;9600 baud bei 4 MHz
  out UBRR, temp
  ldi temp, 0x00
  out DDRD, temp
  ldi temp, 0b00000000   ;INT0 konfigurieren
  out MCUCR, temp
  ldi temp, 0b01000000   ;INT0 aktivieren
  out GIMSK, temp
  sei                    ;Allgemeine Interruptfreigabe
loop:
  rjmp loop


;******************************************************
bin2bcd8:
  clr  tBCDH    ;clear result MSD
bBCD8_1:subi  fbin,10    ;input = input - 10
  brcs  bBCD8_2    ;abort if carry set
  inc  tBCDH    ;inc MSD
  rjmp  bBCD8_1    ;loop again
bBCD8_2:subi  fbin,-10  ;compensate extra subtraction
  ret

;**** Serielle ausgabe ********************************
serout:
    sbi ucr,txen     ;set sender bit
    sbis usr,udre     ;wait till register is cleared
    rjmp serout
    out udr,temp    ;send the variable
    cbi ucr,txen    ;clear sender bit
  ret

;*****************************************************
TastInt:   cli
    CLR temp1
    CLR temp   ;Das Empfangsbyte leeren
    CLR counter   ;Einen Loop-Counter

RcvLoop:
    RCALL ClkHl   ;Einen Clk-Zyklus abwarten
    CLC     ;Das Carry-Bit leeren.
    SBIC PIND,3   ;Wenn logisch "high" anliegt,
    SEC     ;Carry-Bit setzen
    ROR temp1   ;und Bit ins Register schieben
    INC counter
    CPI counter,7   ;7 Bits empfangen
    BRNE RcvLoop
    ROR temp1   ;nochmal ein Bit nach rechts schieben
    RCALL ClkHl   ;partity Bit abwarten
    RCALL ClkHl   ;Stoppbit abwarten

    mov fbin, temp1 ;temp1 nach fbin kopieren
      rcall bin2bcd8  ;fbin in tBCDL und tBCDH aufteilen
      mov temp, tBCDH ;obere Dezimalstelle
     subi temp, -48  ;48 addieren um in ASCII umzuwandeln
      rcall serout    ;Byte senden
      mov temp, tBCDL ;untere Dezimalstelle
      subi temp, -48  ;48 addieren um in ASCII umzuwandeln
    rcall serout    ;Byte senden
    ldi temp, 10    ;ASCII-Wert für "neue Zeile"
    rcall serout
    ldi temp, 13    ;ASCII-Wert für "Cursor zurück"
    rcall serout

    sei
           reti
;*******************************************************
ClkHl:

LoopClkLow:
    SBIS PIND,2   ;An PIND2 hängt jetzt mal die Clk
    RJMP LoopClkLow
LoopClkHigh:
    SBIC PIND,2
    RJMP LoopClkHigh

    RET
;*******************************************************

von Sebastian Wille (Gast)


Lesenswert?

Hi Leute,

ich mein Programm nun auch mal erweitert. Pro Taste wird nun ein 
bestimmter Code erkannt, leider noch nicht der richtige. Ich werd's 
morgen nochmal checken.

Jornbytes File werde ich auch mal testen. Ich habe jetzt dennoch mal 
versucht, mir das alles selber zu erarbeiten, weil ich a) was dabei 
lernen will und b) ich ja keine fertige Lösung will (so lieb' es ja auch 
gemeint ist!).

Morgen werd' ich mal Jornbytes File und meines vergleichen und 
hoffentlich meinen Fehler finden.

Auf jeden Fall Danke für jede Mithilfe!

Hast Du eigentlich noch was, Matthias?

Grüße,

Sebastian

von Sebastian Wille (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

also mein Programm hat doch funktioniert. Anstatt für die Leertaste 29 
(Hex) bzw. 41 (Dez.) anzuzeigen, zeigt's halt ")" an, was dem ja aber 
laut ASCII entspricht!
:-)
Wer will kann's sich's gerne mal durchschauen, für Tips wäre ich 
natürlich sehr dankbar!!!

Hast Du noch was gemacht, Matthias? Meld' Dich mal wieder!

Grüße,

Sebastian

von Matthias (Gast)


Lesenswert?

Hallo Sebastian,

ich bin schon am Programmieren, aber mein Programm ist noch nicht 
fertig. Wie wandeln wir die Scancodes eigentlich am besten in 
ASCII-Codes um? Vielleicht mit einem LookUp-Table?

Gruß
Matthias

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Sebastian,

ich hab jetzt ein Simpel-Programm geschrieben (ohne Interrupts). 
Allerdings funktioniert es bei mir nicht. Ich hab es trotzdem mal 
angehängt, vielleicht kann mir jemand sagen, wo der Fehler liegt.

Gruß
Matthias

von Uwe (Gast)


Lesenswert?

Hi
Du musst lsr schleiben nicht ror. ror bringt C-Flag nach Bit 7 (bei 0 
wird es ja nicht überschrieben.)
Gruss Uwe

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Danke Uwe! Ich habe das Programm entsprechend geändert, aber leider 
funktioniert es immer noch nicht: Immherhin wird aber bei jedem 
Tastendruck drei mal Byte 127 ausgegebem (außer bei den erweiterten 
Tasten). Was könnte der Grund sein, warum es immer noch nicht 
funktioniert?

Gruß
Matthias

von Uwe (Gast)


Lesenswert?

Hi
Du machst keine saubere Flankenauswertung (nur H und L). Prüfe doch 
mindestens ob es auch wirklich ein Startbit ist
Gruss Uwe

von Jornbyte (Gast)


Angehängte Dateien:

Lesenswert?

Ein Stück weiter. Die Tastatur gibt schon ASCII an RS232 aus.

von Maik Floges (Gast)


Lesenswert?

Hallo, ist vlt. etwas spät aber habt ihr das Projekt beendet? Ist etwas
vorzeigbares entstanden?

Habt ihr noch die Schaltung bzw. das Programm etc. ? Würde mich gerne
interessieren.

mfg -maik-

von Dmitry (Gast)


Lesenswert?

Hi
To write the letter, it is necessary ...

von Michael Dierken (Gast)


Lesenswert?

Guten Tag.

Bin nun seit ca. 3 Wochen dabei nach Feierabend das gleiche zu versuchen 
wie ihr es hier gemacht habt und bin nun soweit das ich
eine Erkennung habe per Interrupt,
Abfrage des Startbit,
Abfrage des Stopbit,
Überprüfung der Parität,
Abbruch bei falschen Daten,
Abbruch bei Abrechendem Datenstrang,
Ignorierung des Codes beim Loslassen einer Taste,
Anzeige der Richtigen Buchstaben auf dem LCD.

Also kann ich bereits richtig Schreiben.

Hinzu kommen sollen nun noch sowas wie Sonderfunktionen auf [Fx] Tasten, 
Zeilensprung bei Return und Sondertasten mit mehr als 1Byte Codelänge.

Warum melde ich mich hier:

Euer Thema hat mir geholfen da ich mit einem Beispielprogramm testen 
konnte ob meine Verkabelung überhaupt richtig ist, sodass ich schonmal 
die Verkabelung/Tastatur als Fehler ausschließen konnte (Key_DDR war 
high ^^).

Mein Problem ist es das ich mich frage warum ich in meiner Tabelle nur 
jedes zweite Byte beschreiben darf und wie ich es hinbekommen würde 
jedes Byte zu beschreiben.

Hier ein Beispiel wie ich es geschrieben habe:
1
ldi      ZL,        LOW(Tabelle-1)
2
ldi      ZH,        HIGH(Tabelle-1)
3
add      ZL,        Data              ; Data = Empfangener Code
4
adc      ZH,        Zero              ; Zero = leeres Register
5
lsl      ZL
6
rol      ZH
7
lpm
8
push     temp1
9
mov      temp1,     r0
10
rcall    lcd_data                     ; Ausgabe von temp1 auf Display
11
pop      temp1
12
13
14
Tabelle:
15
16
.db "* # * * * * * # * * * * t o * # a # # s Q 1 # # # Y S A W 2 # # C X D E 4 3 # #   V F T R 5 # # N B H G Z 6 # # # M J U 7 8 # # , K I O 0 9 # # # - L Ö P ? # # # Ä # Ü ´ # # c s r + # # # # # # # # # # b # # 1 # 4 7 # # # 0 , 2 5 6 8 e n * + 3 - * r +"  ;steht alles in einer Reihe

* Symbolisiert die [Fx] Tasten
# Symbolisiert nicht vorhandene Tasten (nicht belegte Codes)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.