Hallo, hier mal eine Lib um eine PC-Tastatur an einen AVR anzuschließen. Kurzdoku ist in der Header-Datei. Stefan
Hi Stefan, ich fand den AVR-Code so praktisch, dass ich ihn für meinen MSP430 portiert habe. Dabei wird ein deutsches Tastatur-Layout unterstützt und alle mit [ALT Gr] erreichbaren Zeichen. Wer lust und Zeit hat, kann sich ja noch etwas für den Nummernblock und die Sondertasten einfallen lassen. konstruktive Kritik ist immer willkommen, Gruß, Kay
Moin, ich habe mal die Tastaturroutine von Stefan Seegel überarbeitet. Jetzt funktionieren auch "Alt Gr"-Zeichen (z.B. €,@,\,}, etc…). Siehe "scancodes.h" Des weiteren kann man nun auch Befehle an die Tastatur schicken und somit die LEDs steuern oder die Anschlaggeschwindigkeit verändern. Ein kleines Demoprogramm ist in der main.c Datei: Das Demoprogramm gibt die aktuell gedrückte Taste über den UART (Baudrate: 19200) aus und reagiert auf die Funktionstasten (F1-F4 siehe main.c). Wenn man die "Break"-Taste drückt, wechselt die Routine in den Bytemodus:
1 | atkeyb.c Line 94: |
2 | else if(data==0xE1) |
3 | {
|
4 | flag.ascii=0; |
5 | return; |
6 | }
|
Über die Zahlen 0-7 steuert das Demoprogramm die LEDs der Tastatur an. Sondertasten können einfach in "scancodes.h" ergänzt bzw. unnötige Tasten gelöscht werden. Siehe: http://www.marjorie.de/ps2/scancode-set1.htm Gruß Gregor
Hallo Gregor, könnte man mit deinem Code auch Zeichen an einen PC senden ? Eine Senderoutine hattest du ja schon eingebaut, allerdings in Richtung Tastatur. Ich suche eine solche Routine. Bei Google und Co habe ich nicht das Richtige gefunden. Immer nur PS2 <-> AVR. Gruß Günter
Tag zusammen, ich bin so langsam am verzweifeln... ich versuche schon seit ner halben ewigkeit ne ps/2 tastatur an meinen atmega8 anzuschliesen aber auch fremde codes(mehrere) die als funktionsfähig beschrieben wurden laufen nicht... Mein schluss daraus war dass es sich wohl um ein hardwareproblem handeln muss. Eigendlich sollte das ja aber kein prob. sein- ist ja open collector alles... das einzige was mir noch einfällt ist dass ich den internen takt des mega8 nutze statt externem quarz ...ist das in diesem zusammenhang (interrupts werden hier mit 10-16 kHz ausgelöst) kritisch?
hallo Gregor ich arbeite gerade mit deinen source für keyboard auslesen. ich schaffe es nicht die tastatur anzusprechen. Led's einschalten reseten . Ansonsten läuft alles prima. Hast due eine Revision Gruß Juppo
Ich weiß nicht, ob Dir das hilft, aber in Bascom gibt es den Befehl "GETATKBD" Damit kann man ohne große Mühe einen Tastaturcode einlesen. MfG Paul
Hi Paul Das auslesen geht wunderbar ,nur das senden zu Tastatur geht nicht. Led's werden nicht angesteuert ,naja .evt. ein Timing Problem. Wenn noch jemmnad einen Source hat zum ansprechen einer at Tastatur ,immer her damit. Wünsche alle Mitlesern FROHE WEIHNACHTEN. Gruß Juppo
Mit dem hier läufts bei mir:
1 | #include <util/parity.h> |
2 | |
3 | void Write_ps2data(unsigned char data) |
4 | {
|
5 | cli(); // disable interrupts . . . . . |
6 | |
7 | PORTD = (1<<PD2) | (1<<PD3); // Set pull-up resistor data and clock, if output then high |
8 | |
9 | DDRD |= (1<<DDD2); // Pin D2 output clock |
10 | DDRD |= (1<<DDD3); // Pin D3 output data |
11 | |
12 | |
13 | _delay_ms(0.25); |
14 | |
15 | PORTD &= ~(1<<PD2); // Pin D2 low, start clock bit |
16 | |
17 | _delay_ms(0.25); |
18 | |
19 | PORTD &= ~(1<<PD3); // Pin D3 low, start data bit |
20 | |
21 | |
22 | PORTD |= (1<<PD2); // Set pull-up resistor clock |
23 | DDRD &= ~(1<<DDD2); // Pin D2 input clock |
24 | |
25 | |
26 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // wait until clock bit is clear |
27 | |
28 | |
29 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 1'st data bit if clock bit is set |
30 | |
31 | if ((data&0x01)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
32 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
33 | |
34 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
35 | |
36 | |
37 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 2'nd data bit |
38 | |
39 | if ((data&0x02)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
40 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
41 | |
42 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
43 | |
44 | |
45 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 3'rd data bit |
46 | |
47 | if ((data&0x04)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
48 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
49 | |
50 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
51 | |
52 | |
53 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 4'th data bit |
54 | |
55 | if ((data&0x08)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
56 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
57 | |
58 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
59 | |
60 | |
61 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 5'th data bit |
62 | |
63 | if ((data&0x10)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
64 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
65 | |
66 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
67 | |
68 | |
69 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 6'th data bit |
70 | |
71 | if ((data&0x20)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
72 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
73 | |
74 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
75 | |
76 | |
77 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 7'th data bit |
78 | |
79 | if ((data&0x40)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
80 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
81 | |
82 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
83 | |
84 | |
85 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send 8'th data bit |
86 | |
87 | if ((data&0x80)==0) { PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
88 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
89 | |
90 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
91 | |
92 | |
93 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); // Send parity data bit |
94 | |
95 | if (parity_even_bit(data)==1){ PORTD &= ~(1<<PD3);} // Pin D3 output data 0 |
96 | else PORTD |= (1<<PD3); // Pin D3 output data 1 |
97 | |
98 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // |
99 | |
100 | |
101 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); |
102 | |
103 | DDRD &= ~(1<<DDD3); // Pin D3 input data |
104 | PORTD |= (1<<PD3); // Set pull-up resistor data |
105 | |
106 | |
107 | do {asm volatile ("nop"::);} while (PIND & _BV(2)); // Ignore acknowledge bit |
108 | do {asm volatile ("nop"::);} while (!(PIND & _BV(2))); |
109 | |
110 | sei(); // enable interrupts . . . . . |
111 | |
112 | }
|
Frohe Weihnachten, Gruß Gerrit
Irgendwann muss ich doch einmal C lernen, das scheint wirklich einfacher zu sein als Assembler.
Hallo zusammen, ich bin auf der Suche nach einer möglichkeit einen Magnetkartenleser mit PS/2 Emulation mit einem Atmega (welcher steht noch offen) auszulesen und auszuwerten. Kurz zum Sinn: Wir benötigen ein Türöffnersystem. Etwas fertiges kostet sehr horrende Preise. Das Ding muss sich anlernen lassen an einen Inhalt der 2. Spur einer LOCO Magnetkarte und anschließend ein Relais schalten für einen Türöffner. Ich habe im Internet Magnetkartenleser gefunden die mit RS232 funktionieren. Programmiertechnisch weniger aufwand, aber dafür hohe Preise für die Leser und schelcht zu bekommen (also immer den gleichen). Ich habe mich also entschlossen einen magnetkartenleser zu nehmen, der eine PS/2 tastaturemulation vorweisen kann. Jetzt ist die Frage, ob es eine fertige lib gibt, die sowas auslesen kann. Überträgt eine Tastatur ASCII-Daten über den Bus oder nur Binärdaten? Ziel ist es das Ding einmalig anzulernen (Sprich den Inhalt der Karte in den EEPROM des µC schreiben) und diesen dann vergleichen mit dem Code auf der Karte und die Tür zu öffnen. Ich wäre über Hilfe sehr sehr Dankbar! Gruss Stefan
Moin Dann teste den Leser erst mal an einem normalen PC. Wenn das geht könnt eman einen Mikrocontroller "Atmega32" nehmen und die ScanCode von dem Leser einlesen. Das sollte dann mit den normalen Sourcen gehen. Gruß Juppo
Moin Ich hab da immer noch Probleme Das auslesen klappt wunder bar. Reseten geht auch. Aber die einzelen LED ansteuern klappt überhaupt nicht. Hardware Schaltung ist bei mir eine direkte Verbindind von CLK und Data zu den Port Pin PIND 2/3. Ist das richtig? Der Befehl besteht aus 2 Byte senden ?? kann es sein das ein Delay dazwischen muss ? Gruß Juppo (Frohes neues Jahr)
Hurra Es läuft. kann es sein das _delay_ms _delay_us aus der AVR Lib nicht vernünftg laufen ? Eigene funktionen für wait geschrieben und zwischen 0xed und 0x01 ein wait non 100 ms gesetzt.
Juppo Nini schrieb: > kann es sein das _delay_ms _delay_us aus der AVR Lib nicht vernünftg > laufen ? Nur bei eingeschalteter Optimierung und bei Aufruf mit einer Konstante!!! als Argument.
Stefan Seegel schrieb: > Hallo, > > hier mal eine Lib um eine PC-Tastatur an einen AVR anzuschließen. > Kurzdoku ist in der Header-Datei. > > Stefan Hallo Stefan Für welchen Controller ist das geschrieben ? Gruß Juppo
Hallo Juppo, Auch bei mir eine direkte Verbindung von CLK und Data zu den Port Pin PIND 2/3. Ich benütze allerdings nur der Caps Lock LED, mit folgendes Programmteil:
1 | case 0x58 : // Caps Lock |
2 | |
3 | if (capslock == 0) |
4 | {
|
5 | capslock = 1; |
6 | Write_ps2data(0xed); // send Cap Lock LED on |
7 | Write_ps2data(0x04); |
8 | }
|
9 | else
|
10 | {
|
11 | capslock = 0; |
12 | Write_ps2data(0xed); // send Cap Lock LED off |
13 | Write_ps2data(0x00); |
14 | }
|
15 | break; |
Also ohne Verzögerung. Ich habe allerdings gemerkt die Tastatur sendet einen Byte mehr zurück als ich laut im Internet gefundene Daten erwartet habe. Offenbar sind nicht alle Tastaturen gleich . . . Es freut mich dass es letztendlich geklappt hat, Gruß Gerrit
Moin Gerrit Das klappt wenn ich ohne Timer arbeite. zB. get_ack() Dort wird bei meinem ATMEGA32 der Timer nicht gestartet. Welchen Prozessor hast du benutzt ? Möchte das alles auf einen ATTINY 2313 zum laufen bringen. Gruß Juppo
Hallo Juppi, Ich benütze einen Atmega8. Ich vermute dein Problem hat zu tun mit deinem Beitrag im Forum: PC Hard- und Software, "PC-Keyboard im XT Modus". Da steht in dein Makefile dass du einen Attiny2313 benützt, der Timer0 von denen unterscheidet sich aber von denen des Atmega32 den du jetzt nennst. Du benützt den Timer um einen Fehlzustand zu testen, aber dass macht die Sache kompliziert, außerdem benützt du der Fehlerrückmeldung (noch) nicht. Ich würde diesen Test auslassen, schick nur den Code zu der Tastatur raus und gut ist ! Gruß Gerrit
Hallo Danke Klappt soweit ganz gut. Ich bin mit dem Umsetzen von scancode2 aud scancode1 zugange. Passe daszu deine Tabelle an. Besten Dank. Juppo
Halt noch eins ,da droht Gefahr. Wenn die "NUM LOCK" Taste betätigt wird dann verändert sich der Ausgabe Code der PC2 Tastatur. Mal wieder lange drann verzweifelt. Gruß Juppo
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.