Tastatureingabe simulieren

Wo du aufpassen musst: das ist ein Open-Collector-Bus, das heißt, du
darfst nie einen Ausgang auf High haben! Meine Empfehlung: PORTx auf
Dauer-0 und DDRx bei Bedarf umschalten (0=Eingang=High,
1=Ausgang=Low).

Geht das schnell genug?
Ich denke schon, dass es schnell genug geht, du hast bei 20KHz und
10MHz-Quartz 500 Takte Zeit dafür. In Assembler überhaupt kein Problem.
Wenn es dir sicherer erscheint (und du genug Platz hast), kannst du aber
natürlich auch die Transistor-Lösung nehmen. Wobei ich mich frage: gibt
es eigentlich AVRs mit OC-Ausgängen?


Gruß,
Arne
 
On Fri, 12 Dec 2003 18:58:32 +0100, "Arne Rossius"
<ArneRossius@despammed.com> wrote:

Hi!

Wo du aufpassen musst: das ist ein Open-Collector-Bus, das heißt, du
darfst nie einen Ausgang auf High haben! Meine Empfehlung: PORTx auf
Dauer-0 und DDRx bei Bedarf umschalten (0=Eingang=High,
1=Ausgang=Low).

Geht das schnell genug?

Ich denke schon, dass es schnell genug geht, du hast bei 20KHz und
10MHz-Quartz 500 Takte Zeit dafür.
Sorry, ich meinte: Schaltet der die Pins elektrisch schnell genug von
Eingang auf Ausgang und zurück?

Gruß,
Michael.
 
Sorry, ich meinte: Schaltet der die Pins elektrisch schnell genug von
Eingang auf Ausgang und zurück?
Ich denke schon, ich glaube der braucht dazu nur 2 Takte oder so. Am
besten aber noch mal im Datenblatt nachlesen.


Gruß,
Arne
 
"Arne Rossius" <ArneRossius@despammed.com> wrote in message news:<breouu$3pu$04$1@news.t-online.com>...

Hi!

Sorry, ich meinte: Schaltet der die Pins elektrisch schnell genug von
Eingang auf Ausgang und zurück?

Ich denke schon, ich glaube der braucht dazu nur 2 Takte oder so. Am
besten aber noch mal im Datenblatt nachlesen.
So, hab mal auf dem Skop geschaut:

DDR:Ausgang, PORT:low/high/low/...
-> ca 10ns Anstiegszeit/Abfallzeit

PORT:low, DDR:Ausgang/Eingang/Ausgang/...
-> ca 50ns Anstiegszeit (DDR:Eingang, 1k pullup extern)
-> ca 10ns Abfallzeit (DDR:Ausgang)

Wie erwartet also langsamer, da nur pullup-Widerstand statt
push-pull-Stufe. Für meinen Zweck aber völlig ausreichend, da 1000x
schneller als der Bit-Takt.

Gruß,
Michael.
 
On Wed, 10 Dec 2003 23:45:55 +0100, Michael Eggert
<m.eggert.nul@web.de> wrote:

Hi!

Update:

Das Tastatursignal durch den Controller zu schleifen kann ich
letztendlich wohl doch knicken, was jedoch an meinen "Sonderwünschen"
liegt. Jedes Bit von der Tastatur braucht 100ľs, bei 10fach
oversampling (direktes, stumpfes Durchschleifen auf Signalebene) und
16MHz Takt (Mega8) macht das 160 Takte pro Durchgang.

Daß Ihr mich nicht falsch versteht - das Durchschleifen an sich ist
kein Problem, frisst rein vom Gefühl etwa 50% CPU-Zeit. Nun möchte ich
aber noch die Daten von der Tastatur auswerten, um bestimmte
Tastendrücke (auf die der PC eh nicht reagiert, wie "Pause") dazu zu
nutzen, im Controller was zu triggern. Dazu kommt noch die Ansteuerung
von ein paar Tastern, und I2C wollt ich ja auch noch (was aber wohl
wesentlich in Hardware läuft).

Kurzum: Es wird wohl alles ein bisschen zuviel, insbesondere die
Datenauswertung bringt den Controller an die Grenzen, so daß das
zeitkritische Durchschleifen nicht mehr so will. Also wird die "V2"
nun doch einen 4066 bekommen, dann gibts Durchschleifen in Hardware,
und der Controller kann sich auf die Gimmicks konzentrieren.

Gruß,
Michael.
 
Michael Eggert wrote:


Daß Ihr mich nicht falsch versteht - das Durchschleifen an sich ist
kein Problem, frisst rein vom Gefühl etwa 50% CPU-Zeit.
Vorsicht! Das Tastaturinterface beim PC ist bidirektional.
Der PC schickt auch Kommandos an die Tastatur (fuer die LEDs
z.B.) das muesstest du auch implementieren.

Gerrit
 
Michael Eggert wrote:
Das Tastatursignal durch den Controller zu schleifen kann ich
letztendlich wohl doch knicken, was jedoch an meinen "Sonderwünschen"
liegt. Jedes Bit von der Tastatur braucht 100ľs, bei 10fach
oversampling (direktes, stumpfes Durchschleifen auf Signalebene) und
16MHz Takt (Mega8) macht das 160 Takte pro Durchgang.
Wozu brauchst Du 10-faches Oversampling? Zur sicheren Auswertung
ist 3-fache Überabtastung mehr als ausreichend.
Mit Interrupts lässt sich die verbratene Rechenzeit noch weiter
drücken, falls das nötig sein sollte.
Dass die Schnittstelle bidirektional ist, hat Gerrit H. ja schon
angemerkt - da wäre dann der im ATmega integrierte Komparator
dann ganz nützlich, mit dem sich über die Vorzeichen zwischen Spannung
und Strom (letzteres gemessen mit dem Komparator an einem Serien-R)
die "Richtung" des Signals bestimmen lässt (ohne dass ich das jedoch
praktisch mal ausprobiert hätte - nur als Idee).

Thomas.

PS: Sorry for eMail - ich habe den falschen Knopf getroffen...
 
On Sat, 20 Dec 2003 23:06:42 +0100, Gerrit Heitsch
<gerrit@laosinh.s.bawue.de> wrote:

Hi!

Vorsicht! Das Tastaturinterface beim PC ist bidirektional.
Der PC schickt auch Kommandos an die Tastatur (fuer die LEDs
z.B.) das muesstest du auch implementieren.
Natürlich ist das so! Andernfalls wärs ja einfach, und es hätte den
ganze Tread (der schon 10 Tage alt ist, und wo das mehrfach diskutiert
wurde) nicht gegeben.

Zur Hardware: Vom Controller gehen 2 Leitungen zur Tastatur und 2 zum
PC. Macht 4 I/O, die auch wechselweise als I oder O genutzt werden,
halt je nachdem, wer gerade sendet. Es sind die niederwertigen 4 Bit
von PortD. Jeder Pin ist im Grundzustand Eingang mit externem PullUp-
Widerstand, soll er die Leitung auf GND ziehen, so wird das
DataDirectionRegister auf Ausgang geschaltet.

Ich schick hier mal die Interrupt-Routine, ist ganz simpel. Kernstück
ist eine Tabelle, die die Zuweisung von "Eingang Data von Keyboard ist
low" zu "Ausgang Data zum PC muss ich low ziehen" macht. Die Tabelle
invertiert, da Eingang low -> DataDirectionRegister high. Durch die
invertierte Logik bedeutet portmap[inport|outport] in der vorletzten
Zeile also "wenn ein Eingang low ist _und_ich_den_nicht_gerade_selber_
_low_ziehe_, dann ziehe den entsprechenden Ausgang".


SIGNAL(SIG_OUTPUT_COMPARE2)
{
static unsigned char //wird nur 1x initialisiert
portmap [] = {0,1,2,3,4,0,6,2, //Tabelle, mappt Eingangs-
8,9,0,1,12,8,4,0}, //signale auf Ausgänge
outport = 0, //Wert für Ausgang
inport; //Wer vom Eingang

inport = (PIN(PORTD) & 0x0f); //Eingänge lesen

outport = portmap[inport | outport]; //Ausgang festlegen..

DDRD = outport; //..und schreiben.
}


Gruß,
Michael.
 
On Sat, 20 Dec 2003 23:32:59 +0100, Thomas Rehm <Th.Rehm@T-Online.de>
wrote:

Hi!

Wozu brauchst Du 10-faches Oversampling? Zur sicheren Auswertung
ist 3-fache Überabtastung mehr als ausreichend.
Weil das Timing ekelig aussieht. Clock und Data wechseln nicht etwa
gleichzeitig den Zustand (wie man sich das so vorstellt), sondern
Clock ist um etwa 90° verschoben.

data
-- ---------------- -------- --
-------- -------- --------

clock
---- ---- ---- ---- ---- ---- ----
---- ---- ---- ---- ---- ----

Mit 10-fach Oversampling meine ich übrigens 10 pro ganzer Periode,
also 10 Abtastungen pro 8 "-". Klar lässt sich das vielleicht etwas
drücken, das ändert aber nichts daran, daß es ziemlich zeitkritisch
ist. Im Übrigen hab ich hier zwar eine Tastatur mit 10kbit/s, aber
wenn ich mich recht entsinne, geht die Spezifikation bis 20kbit/s.


Mit Interrupts lässt sich die verbratene Rechenzeit noch weiter
drücken, falls das nötig sein sollte.
Ich mach das ja mit Interrupts. Bloß mit Interrupts im festen
zeitlichen Raster, nicht mit Interrupts von den Leitungen aus, da ich
sonst 4 Interrupt-Pins bräuchte.


Dass die Schnittstelle bidirektional ist, hat Gerrit H. ja schon
angemerkt
Und das ist auch der Grund, warum das ganze etwas komplizierter wird.
Andernfalls könnte ich ja einfach auf der Leitung "sabbeln", der PC
empfängts, die Tastatur ignorierts.


- da wäre dann der im ATmega integrierte Komparator
dann ganz nützlich, mit dem sich über die Vorzeichen zwischen Spannung
und Strom (letzteres gemessen mit dem Komparator an einem Serien-R)
die "Richtung" des Signals bestimmen lässt (ohne dass ich das jedoch
praktisch mal ausprobiert hätte - nur als Idee).
Hä? Wir sprachen doch die ganze Zeit davon, das Signal _durch_ den
ATmega zu schleifen. Einmal clock+data zum PC, einmal clock+data zum
Keyboard. Da sollte man schon wissen, ob eine Leitung von "außen"
gezogen wurde, oder ob man das grad selber macht.

Gruß,
Michael.
 
Michael Eggert wrote:
Weil das Timing ekelig aussieht. Clock und Data wechseln nicht etwa
gleichzeitig den Zustand (wie man sich das so vorstellt), sondern
Clock ist um etwa 90° verschoben.

data
-- ---------------- -------- --
-------- -------- --------

clock
---- ---- ---- ---- ---- ---- ----
---- ---- ---- ---- ---- ----
Das sieht doch ganz danach aus, als wenn immer die fallende
Flanke von CLK die aktive ist und damit der Zustand von
DATA nur zu diesem Zeitpunkt interessant ist. Also
keine Pegeltriggerung (wie man das normalerweise macht)
sondern eine Flankentriggerung.

Gibts keine Moeglichkeit bei fallender Flanke auf CLK
einen IRQ auszuloesen? Wuerde das ganze Obersampling
ueberfluessig machen.


Ich mach das ja mit Interrupts. Bloß mit Interrupts im festen
zeitlichen Raster, nicht mit Interrupts von den Leitungen aus, da ich
sonst 4 Interrupt-Pins bräuchte.
4? Ich komme hier auf 2 weil ich nur CLK ueberwachen muss.

Irgendwo habe ich noch den Source um eine AT-Tastatur an einen
Amiga anzuschliessen, incl. Steuerung der LEDs usw. Ist
allerdings 8031-Assembler (8031 mit 11.059 MHz Quarz), aber
vielleicht koennte man da Ideen rausziehen?

Gerrit
 
On Sun, 21 Dec 2003 13:14:26 +0100, Gerrit Heitsch
<gerrit@laosinh.s.bawue.de> wrote:

Hi!

Das sieht doch ganz danach aus, als wenn immer die fallende
Flanke von CLK die aktive ist und damit der Zustand von
DATA nur zu diesem Zeitpunkt interessant ist. Also
keine Pegeltriggerung (wie man das normalerweise macht)
sondern eine Flankentriggerung.
Na eben doch. Die clk-Flanke liegt ja _nicht_ mittig zwischen den
data-Änderungen.

Ich mach das ja mit Interrupts. Bloß mit Interrupts im festen
zeitlichen Raster, nicht mit Interrupts von den Leitungen aus, da ich
sonst 4 Interrupt-Pins bräuchte.

4? Ich komme hier auf 2 weil ich nur CLK ueberwachen muss.
Und da sich data zu anderen Zeitpunkten ändert, wird data erst beim
nächsten clk registriert und durchgeleitet, zu einem Zeitpunkt, an dem
der Empfänger es schon längst übernommen haben will.

Schau Dir zum Beispiel an, wie eine Datenübertragung PC->Keyb
eingeleitet wird: PC zieht clk, PC wartet (und zwar länger als ein
normaler clk dauert), PC zieht data, PC lässt clk wieder los (und Keyb
macht ab jetzt den Takt). Wenn ichs recht verstanden hab, ist es dabei
durchaus von Bedeutung, daß eben _erst_ Data gezogen wird und _dann_
clk losgelassen wird - Data dürfte _nicht_ erst mit der clk-Flanke
durchgeleitet werden. Um solche Fälle zu berücksichtigen, brauchts
schon wieder einige Intelligenz im Controller, und Intelligenz kostet
nunmal Rechenzeit.

Irgendwo habe ich noch den Source um eine AT-Tastatur an einen
Amiga anzuschliessen, incl. Steuerung der LEDs usw. Ist
allerdings 8031-Assembler (8031 mit 11.059 MHz Quarz), aber
vielleicht koennte man da Ideen rausziehen?
Hm danke, aber ich machs jetzt mit der brutalen Methode, also 4066.
Das scheint ne verbreitete Lösung zu sein, kommt jedenfalls in
ziemlich vielen ähnlichen Schaltungen vor.

Also: Im Normalbetrieb sind PC und Keyb per 4066 verbunden, und wenn
der Controller was an den PC senden will, wird das Keyb kurz
abgeklemmt, damits sich nicht an den Daten verschluckt.

Gruß,
Michael.
 
Michael Eggert wrote:

Mit Interrupts lässt sich die verbratene Rechenzeit noch weiter
drücken, falls das nötig sein sollte.

(...) da ich sonst 4 Interrupt-Pins bräuchte.
4 normale Eingänge und ein Interrupt-Eingang reichen: Die 4 Signale
können ODER-verknüpft (im einfachsten Falle Diodenverknüpfung) den
Interrupt aktivieren, der dann die 4 Eingänge einliest.

Thomas.
 
On Sun, 21 Dec 2003 19:37:25 +0100, Thomas Rehm <Th.Rehm@T-Online.de>
wrote:

Hi!

4 normale Eingänge und ein Interrupt-Eingang reichen: Die 4 Signale
können ODER-verknüpft (im einfachsten Falle Diodenverknüpfung) den
Interrupt aktivieren, der dann die 4 Eingänge einliest.
Ich dachte, die Idee wäre, bei jeder _Änderung_ eines Eingangssignals
einen Interrupt auszulösen?

Gruß,
Michael.
 
Michael Eggert wrote:
Ich dachte, die Idee wäre, bei jeder _Änderung_ eines Eingangssignals
einen Interrupt auszulösen?
Du hast recht - die ODER-Verknüpfung alleine tut es nicht.

Thomas.
 
Halli-Hallo!

"Michael Eggert" schrieb:
Ich dachte, die Idee wäre, bei jeder _Änderung_ eines
Eingangssignals einen Interrupt auszulösen?
3 XOR (oder eins mit 4 Eingängen), dazu RC-Verzögerer und noch ein XOR
als Impulsglied. Oder so...

Ciao/HaJo
 
On Sun, 21 Dec 2003 22:02:19 +0100, "HaJo Hachtkemper"
<cis.dfn@qsecofr.02368.net> wrote:

Hi!

3 XOR (oder eins mit 4 Eingängen), dazu RC-Verzögerer und noch ein XOR
als Impulsglied. Oder so...
Na wenn ich schon ein zusätzliches IC brauche, dann kanns doch auch
ein 4066 sein und dem ľC einiges an Arbeit abnehmen. Der Reiz der
"durch den ľC durchreichen"-Lösung war ja der, daß sie keine weitere
Hardware erfordert.

Gruß,
Michael.
 
On Sun, 21 Dec 2003 16:27:26 +0100, Michael Eggert
<m.eggert.nul@web.de> wrote:

Hi,
hier das nächste Update:

Hm danke, aber ich machs jetzt mit der brutalen Methode, also 4066.
Das scheint ne verbreitete Lösung zu sein, kommt jedenfalls in
ziemlich vielen ähnlichen Schaltungen vor.

Also: Im Normalbetrieb sind PC und Keyb per 4066 verbunden, und wenn
der Controller was an den PC senden will, wird das Keyb kurz
abgeklemmt, damits sich nicht an den Daten verschluckt.
....funzt prima. Danke nochmal an alle für die links zu Schaltungs-
Vorschlägen und Informationen übers Protokoll.

Gruß,
Michael.
 

Welcome to EDABoard.com

Sponsor

Back
Top