Hallo Leute,
ich beutze zur Entprellung meiner taster den genialen Code von Peter
Dannegger. Ich habe u.a. gestern den ganzen Tag hier im Forum verbracht
um mich nochmal in den Code einzuarbeiten.
Ich habe nun bei mir Taster an unterschiedlichen Ports (Port C und Port
B). Jetzt versuche ich die beiden Ports in den Code von PD zu
verbasteln. Ich bin sicher das ich das hier mal gelesen habe, aber ich
finde es nicht mehr.
Ich muss irgendwie die unterschiedlichen Ports mit den entsprechenden
Pins mit "KEY_PIN" verheiraten. Aber ich weiß nicht mehr wie das geht.
Vielleicht hilft mir mal jemand auf die Sprünge oder gibt mir den Link
zum entsprechendem Thema.
1
/* C-Code für ATmega 88 */
2
3
[...]
4
//#define KEY_PIN PINB // Version PD
5
#define KEY_PINB PINB
6
#define KEY_PINC PINC
7
8
#define _Taster1 0x01 //PB0
9
#define _Taster2 0x02 //PC1
10
11
[...]
12
13
ISR(TIMER2_OVF_vect)
14
{
15
staticuint8_tct0,ct1;
16
uint8_ti;
17
18
TCNT2=(uint8_t)(int16_t)-(F_CPU/1024*10e-3+0.5);// preload for 10ms
19
20
// i = key_state ^ ~KEY_PIN; // key changed ? PD's Version
Hallo, hab das mal so gelöst (Codeteile hängen zusammen als Teil der
Interrupt-Service-Routine, hier nur vereinzelt zum Kommentieren):
Erstmal Portrichtung für die Taster setzen. Bei mir in der
Interrupt-Service-Routine selber, da die Port-Pins auch als
LCD-Datenausgang genutzt werden, das delay ist dann nötig für stabile
Verhältnisse beim Einlesen:
1
KEY_DIR_RS&=~ALL_KEYS;// Portrichtung setzen auf Eingang
2
KEY_PORT_RS|=ALL_KEYS;// PullUp's Ein
3
KEY_PORT_RS&=~KEY_PIN_RS;// Tasten an RS abfragen: RS auf low ziehen
4
_delay_us(2);//2us
Als nächstes 3 Digitale Inputs einlesen (DIN), liegen auf anderem Port
als die Tasten, Portrichtung ist anderswo gesetzt:
1
din_state=(~DIN_PIN_C)&14;// DIN Bits 1,2,3 einlesen, ~ da Optokoppler gegen GND und interner Pull-Up-Widerstand ein, Rest rausmaskieren
Hier noch ne kleine Notaus-Abfrage, die direkt ohne Entprellung aus der
ISR heraus die Maschine abstellt:
1
if(din_state&(D_IN_2)){// wenn D_IN_2 (NOTAUS) gesetzt,
2
D_OUT_1_off;
3
}
Jetzt die eingelesenen DIN-Zustände mit den Taster-Zuständen in ein Bit
verheiraten (hier liegen die einzelnen Bits günstig, falls nicht, dann
noch zurechtschieben):
1
i=key_state^(din_state|((~KEY_PIN)&240));// key changed ? ~ da Signal gegen GND und interner Pull-Up-Widerstand ein,
2
// DIN sind Bits 1,2,3, Tasten sind Bits 4,5,6,7, dort Rest rausmaskieren
dann der "normale" Peter Dannegger Code (4-fach Entprellung, hier mit
10ms Takt):
1
ct0=~(ct0&i);// reset or count ct0, Signale CT0 und CT1 sind invertiert
Das müsste so funktionieren. An Stelle eines EingangsPorts setzte du dir
das Byte aus zwei Ports zusammen. Vorassetzung ist natürlich, das deine
Tasten an "aufeinanderfolgenden" Bist hängen - mit jeweisl einer Taste
an Bit 0 von PORTB und PORTC ginge das nicht so einfach.
????
Damit komme ich nicht klar. Dazu finde ich auch keine Entsprechung im
Originalcode, zumindest nicht in dem hier:
http://www.mikrocontroller.net/attachment/highlight/36986
Abgesehen davon hasse ich solche Kontruktionen mit Zuweiseungen
innerhalb der rechten Seite eines Ausdrucks. Das ist eher was für den
Obfuscated C Contest.
Oliver
Oliver schrieb:
> ????>> Damit komme ich nicht klar. Dazu finde ich auch keine Entsprechung im> Originalcode, zumindest nicht in dem hier:> http://www.mikrocontroller.net/attachment/highlight/36986
Ist doch simpel.
Das Einlesen des kompletten Tastenports geschieht im Originalcode hier
1
i=key_state^~KEY_PIN;// key changed ?
Anstatt das Pin Register direkt auszulesen, kannst du das auch so machen
1
tmp=KEY_PIN;
2
i=key_state^~tmp;
3
...
Noch hat sich nichts geändert.
Jetzt sagt aber kein Mensch, dass du tmp als ganzes von KEY_PIN befüllen
musst. Du kannst das auch nach Lust und Laune aus mehreren Pin Registern
zusammensetzen ... komplette Pins nehmen ... einzelne Bits ausmaskieren,
was immer du willst. Hauptsache jeder Taster hat in tmp sein eigenes Bit
1
tmp=(PINB&0x01)|(PINC&0x02)|(PINC&0x01)<<2;
2
i=key_state^~tmp;
3
...
Wenn man es hochgestochen ausdrücken will, dann baust du dir damit ein
'virtuelles Pin Register' zusammen, in dem jedes Bit einem Taster
entspricht.
>> Abgesehen davon hasse ich solche Kontruktionen mit Zuweiseungen> innerhalb der rechten Seite eines Ausdrucks.
Dann machs ganz einfach nicht :-)
Beides nacheinander, so wie es oben wörtlich steht, macht es eben keinen
Sinn.
>> Abgesehen davon hasse ich solche Kontruktionen mit Zuweiseungen>> innerhalb der rechten Seite eines Ausdrucks.>Dann machs ganz einfach nicht :-)
Tue ich auch nicht :-)
Oliver
Hallo nochmal,
das mit den nicht "aufeinanderfolgenden" Bits lässt sich leicht durch
Bit-Schieben (>>) lösen.
Bei mir habe ich das Zusammenführen über eine Zwischenvariable din_state
gelöst, da ich noch eine Notaus-Funktion brauche, die direkt reagiert.
Ihr müsst darauf achten, alle nicht relevanten Bits rauszumaskieren (die
werden ja sonst wie gedrückte Tasten interpretiert), also definierte
Zustände zu schaffen. Und genau aufpassen, welche Bits/Bytes wann
negiert (~) sein wollen.
Das Konstrukt KEY_PIN_neu = ... funktioniert so daher nicht.
hier noch meine Defines zu obigem Code:
1
//D-IN Ports
2
#define DIN_PORT_C PORTC
3
#define DIN_DIR_C DDRC
4
#define DIN_PIN_C PINC
5
#define D_IN_0 (1 << PC3)
6
#define D_IN_1 (1 << PC2)
7
#define D_IN_2 (1 << PC1) // NOTAUS
8
9
// KEY-Ports
10
#define KEY_PIN PIND
11
#define KEY1 (1 << PD4)
12
#define KEY2 (1 << PD5)
13
#define KEY7 (1 << PD6)
14
#define KEY8 (1 << PD7)
15
16
#define KEY_PORT_RS PORTD
17
#define KEY_DIR_RS DDRD
18
#define KEY_PIN_RS (1 << PD3) // LCD_RS_PD3
19
20
#define ALL_KEYS (KEY1 | KEY2 | KEY7 | KEY8)
Den KEY_..._RS setze ich, da wie geschrieben die Tasten mit der
LCD-Anzeige gemultiplext sind. Ich habe eigentlich noch eine
Repeat-Funktion für einzelne Taster eingebaut, die ich hier im Code
weggelassen habe.
Gruß!
>> Oliver wrote:>> Abgesehen davon hasse ich solche Kontruktionen mit Zuweisungen>> innerhalb der rechten Seite eines Ausdrucks.
Du musst es ja nicht übernehmen. Es hat halt jeder seinen eigenen
Programmierstil. ich arbeite gerne mit "sprechenden Variablen" In diesem
Fall muss man aber wissen was man tut: nicht das die beiden Taster auf
dem gleichen Bit liegen.
Viele Grüße und Danke nochmal
@ M.B. (Gast)
>ich beutze zur Entprellung meiner taster den genialen Code von Peter>Dannegger.
Sorry mal, bin hier noch relativ neu, wo finde ich den Code?
@ Ahnungslos_0815 (Gast)
Schau mal hier:
[[Beitrag "Universelle Tastenabfrage"]]
@ Oliver
Sollte natürlich PINB und PINC heißen und nicht PORT
Sorry, hatte mich vertippselt
ziegel schrieb:
> Hier noch ne kleine Notaus-Abfrage, die direkt ohne Entprellung aus der> ISR heraus die Maschine abstellt:
Du bist sicher, daß der Notaus auch darauf reagieren muß, wenn jemand
elektrostatisch aufgeladen dem Taster näher kommt oder bei sonstigen
Störungen?
Du bist sicher, daß ein Notaus 30ms später wirklich eine Rolle spielt?
Peter
Hallo,
@ Peter, das kommt natürlich auf die Anwendung an. Es handelt sich hier
um einen schnell laufenden Antrieb, der µC realisiert über eine Rampe
und Frequenzumrichter das langsame anlaufen und abbremsen. Notaus ist
ein Öffner-Stromkreis gegen GND, der durch verschiedene Bedingungen
unterbrochen wird. Prellen und statische Ladung sind hier also
uninteressant. Es ist außerdem völlig egal, ob der Notaus zu oft
Auftritt, wichtig ist, daß der Antrieb schellstmöglich gebremst wird, um
Schäden zu vermeiden. Außerdem, um die Entprell-Diskussion anzuheizen,
ich habe immerhin die Info, daß der Zustand aufgetreten ist, und das zu
einem diskreten Zeitpunkt.
Mir ging es hier aber primär ums Prinzip, vor der "Entprellung" noch
eine zusätzliche Abfrage zu realisieren. Sonst brauchts auch keine
Zwischenvariable.
Und Vielen Dank für die hervorragende Entprell-Routine! Gruß!
Hallo,
ist zwar ein bischen her, aber habe ein Problem das diese Routine auf
Unterschiedlichen Ports nicht funzt. Habe soweit auch verstanden, wie
das mit dem Maskieren der unterschiedlichen Ports funzt. Problem ist
noch das in getkeypress() nur die variable des PINs (1 oder 2) an
Keypress übergeben wird. Wenn jetzt aber gleiche >PINs aus
unterschiedlichen Ports abgefragt werden sollen ( PINC1 oder PINB1 ),
wie wird das dann in der getkeypress gemacht. Muss man dann nicht zwei
variblen übergeben?
East schrieb:> Wenn jetzt aber gleiche >PINs aus> unterschiedlichen Ports abgefragt werden sollen
Dann schiebe den einen Wert auf freie Bits oder nimm 16Bit Variablen:
Könntest Du vielleicht mal einen Blick drauf werfen. Habe es zwar zum
laufen gebracht. Aber das Programm macht faxen. Heisst wenn ich mit der
Hand ohne Berührung über den MC fahre, löst das immerwieder einen
Eingang aus.
Nach erfolgreicher Fehlersuche, habe ich vielleicht noch eine Frage.
Wie sieht nach der beschaltung der unterschiedlichen Ports, die Übergabe
in getkeypress(x) aus?
Wird einfach nur wie zuvor, der Wert des Pins übergeben? Oder reicht
einfach nur Name der Deklaration (_taster1) aus.?