Hi, ich habe hier ein kleines Problem. Ich habe ab einem Pin einen Schalter und ein LED hängen. Wenn ich jetzt den Schalter drücke soll er das beim einlesen registrieren und der setzt dann den Port so, das das LED leuchtet. Bei erneuten drücken soll es wieder aus gehen. Der Status ob das Led an ist oder nicht wird in einer Variable gespeichert. Leider hab ich da meine Probleme und es will einfach nicht klappen, hab den folgenden Code: [c] DDRB &= ~(1<<PROGBUTTON); PORTB &= ~(1<<PROGBUTTON); for(i=0;i<5;i++) _NOP(); // check if programming button is pressed if(!(PINB & (1<<PROGBUTTON))) { // wait until button is released while(!(PINB & (1<<PROGBUTTON))); if(mode & (1<<SS_PROG)) { DEBUG_PUTS("Prog Mode off "); mode &= ~(1<<SS_PROG); }else { DEBUG_PUTS("Prog Mode on "); mode |= (1<<SS_PROG); } } // intermediate state, necessary to switch between input/output DDRB &= ~(1<<PROGBUTTON); PORTB |= (1<<PROGBUTTON); // set pin to represent progmode if(mode & (1<<SS_PROG)) PORTB &= ~(1<<PROGBUTTON); else PORTB |= (1<<PROGBUTTON); DDRB |= (1<<PROGBUTTON); [\c] Der Code klappt ganz gut, aber auf einmal kommt der total aus dem Trap (auf dem Kontroller laufen noch einige Interrupt Routinen, Timer und INT0). Hat einer ne Idee wie man das evtl. besser machen könnte? Liebe Grüsse Matthias
>Der Status ob das Led an ist oder nicht wird in einer Variable gespeichert. Schon mal schlecht. Wie hängt dein Schalter und deine LED am Port-Pin? Es handelt sich vermutlich um einen mechanischen Taster. Die haben die Angewohnheit zu prellen, also den Kontakt nicht sofort richtig zu schliessen, sondern über eine gewisse Zeit zwischen den zwei Zuständen hin- und herzuschalten. Eine Entprellroutine würde helfen (gibt's in der Codesammlung). Ich mache solche Sachen so, dass die LED an VCC (über einen Vorwiderstand) und dem Portpin hängt. Der Taster schaltet GND. Den Portpin schaltet ich auf GND (logisch 0). Dann schalte ich nur noch das DDR um. Das ganze passiert in einem Timer-Interrupt, wo dann auch gleich noch der Taster entprellt wird. Dazu ist es aber nötig, den LED-Zustand in einer Variablen zwischenzuspeichern. PORTB &= ~(1<<PROGBUTTON); // Pin auf GND-Pegel sschalten Ablauf in der ISR: DDRB &=~(1<<PROGBUTTON); // Pin als Eingang schalten PINB einlesen und mit vorherigem Zustand vergleichen Ist der Zustand über eine gewisse Dauer stabil und die Taste gedrückt, ändere den Zustand der LED (an/aus...) in ihrer Variablen (ganzer Port ist ganz praktisch, wenn man mehrere Taster und LEDs hat). Merke dir, dass die Taste gedrückt wurde. Ist der Zustand über eine gewisse Dauer stabil und die Taste nicht gedrückt, freue dich...(irgendwie sollte noch erkannt werden, dass die Taste losgelassen wurde...) schreibe den neuen Zustand (kann auch der alte sein) der LED ins DDRB. Die LED arbeitet in diesem Fall auch als Pullup-Widerstand.
Also die Ansteuerung ist die folgende: VCC---R---LED-----Schalter---GND | | PIN MC
mehrfacher STK500-Besitzer wrote:
> Dann geht das so (in etwa) wie ich es geschrieben habe.
super danke dir, dann liegt mein problem wohl wo anders begraben :(
Naja mal weitersuchen wieso es auf einmal nicht mehr geht.
so, es klappt wunderbar, hier eine kurze Zusammenfassung wie es geht. So ist es möglich einen Pin als Eingang und Ausgang gleichzeitig zu nutzen, um z.B. den Kontroller in einen bestimmten Zustand zu bringen und gleichzeitig diesen Zustand mit einem LED am gleichen Port anzuzeigen. Zuerst den Pin als Ausgang definieren: PORTB |= _BV(PROGBUTTON); DDRB |= _BV(PROGBUTTON); Ein define zum warten: #define _NOP() do { _asm__ __volatile_ ("nop"); } while (0) Die Schleife oben scheint den Schalter auch gleich zu entprellen Dann das abfragen: uint8_t i; // switch to input mode DDRB &= ~(1<<PROGBUTTON); for(i=0;i<10;i++) _NOP(); // check if programming button is pressed if(!(PINB & (1<<PROGBUTTON))) { // wait until button is released while(!(PINB & (1<<PROGBUTTON))); if(progmode == 1) { DEBUG_PUTS("PM off "); progmode = 0; }else { DEBUG_PUTS("PM on "); progmode = 1; } } // set pin to represent progmode if(progmode == 1) PORTB &= ~(1<<PROGBUTTON); else PORTB |= (1<<PROGBUTTON); // define port as output DDRB |= (1<<PROGBUTTON); return; Hoffe das hilft dem ein oder anderem. Gruss Matthias
Dein Programm hat aber den Schönheitsfehler, daß die LED nie aus geht, wenn die Taste gedrückt ist. So gehts aber: Beitrag "Taster + LED am selben Draht (4*)" Peter
Hallo Peter, danke für Deinen Tip, hab mir das mal angeschaut und es geht ein bischen weiter als ich gerne hätte, aber ich hab mir es auf jeden Fall mal gebookmarkt, kann vielleicht später mal brauchen. Mit ist vollkommen bewusst wie das Programm sich verhält und ich muss sagen, ich wollte es auch genauso. Und wenn einer den Taster drückt und nicht los lässt geht es nicht weiter, sehe ich aber als absolut nicht kritisch, da es ein Taster und kein Schalter ist und wenn einer den Taster nicht loslassen will, denkt er sich bestimmt was dabei :) Gruss Matthias
Matthias Fechner wrote: > Mit ist vollkommen bewusst wie das Programm sich verhält und ich muss > sagen, ich wollte es auch genauso. Sagen wir mal, Du hast Dich dran gewöhnt. Ein Fremder würde immer die Reaktion beim Betätigen erwarten. Natürlich läßt er irgendwann los und lernt es dann. Ein weiterer Vorteil meiner Lösung ist auch, daß für Taste und LED zusammen nur 2 Leitungen nötig sind. Peter
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.