Hallo, ich bin noch ein absoluter Anfänger was AVRs angeht und habe schon alle Blinkschaltungen durch. Jetzt möchte ich unbedingt eine LED mit nur einem Taster ein- und ausschalten. Ich habe aber irgendwie keine richtige Idee, alles was ich bis jetzt probiert habe schaltet immer nur für die dauer des Tastendrucks ein. Wäre sehr nett, wenn mir wer helfen könnte..... Danke !
Hallo! also ich würd das jetzt erst mal so lösen: Wenn du den Taster drückst, lasse dein Programm in eine Schleife springen in der du die LED anschaltest und warte dann einfach auf den nächsten Tastendruck, den du in dieser Schleife gesondert abfängst und schalte sie dann wieder aus. Also ungefähr so: Schleife 1: Taster gedrückt? wenn ja, zu Schleife 2, wenn nein, zu 1 Schleife 2: LED an, warten ob Taster gedrückt. Wenn nein, schleife 2, wenn ja, LED aus und schleife 1. Ist jetzt nicht die eleganteste Lösung, aber um das erstmal hinzubekommen sollte es reichen ;-).
Wenn Deine Taste entprellt ist, kannst Du einfach die XOR Funktion nutzen, exclusive Oder. Damit schaltest Du ein PortPin ein fach um. Grüße Lothar
hier mal die oben genannte idee ganz simpel (ohne entprellung), keine wirklich gute technik aber damit geht es schonmal (oder sollte ;)). #define CONTROL PORTC #define TASTER PC0 #define DISPLAY PORTB #define LED 0 volatile int cnt=0; int main..... { while(1) { if ((CONTROL & (1 << TASTER))) cnt++; if(cnt>10) { PORTX ^= _BV(PXx); cnt=0; } }
#define TASTER PC0 sollte doch besser #define TASTER 0 heißen oder?
Super, vielen Dank - das hört sich gut an. Ich werde das gleich mal testen. lg Boriza
Tja also irgendwie ist das alles nicht so dolle.... hat jemand eine Idee, wie man das richtig hinbekommt ? was mache ich falsch ? Sind die Ports zur ein-/ausgabe richtig definiert ? Danke !!! #include <inttypes.h> #include <avr/io.h> #include <avr/delay.h> // definiert _delay_ms() void main() { DDRB = (1 << DDB0); // PB0 als Ausgang DDRB &= ~(1 << DDB1); // PB1 als Eingang { if (PINB & (1 << PB1)) // wenn PB1 geschlossen (HIGH) do { PORTB = PINB ^ ( 1 << PB0 ); // LED an PB0 umschalten PORTB = PORTB | (1 << DDB0); // LED an PB0 ein } while (PINB & (1 << PB1)) // wenn PB1 geschlossen (HIGH) PORTB = PORTB & ~(1 << DDB0); // LED aus } }
Was für eine Hardware hast Du? Bei den meisten Anwendungsboards sind Taster Low-Side angeschlossen, also wenn man drückt, gibts nen Low-Pegel. LEDs hingegen sind meist High-Side angeschlossen (High-Pegel am Pin -> LED aus).
Ich habe das STK500-Board mit einem Tiny45 bestückt und ich habe das dumme Gefühl, das ich auf dem absolut falschen Weg bin. Ich bin mir auch noch nicht sicher ob ich besser in Assembler oder C programmieren soll. Ist Bascom wirklich soviel besser als AVR-Studio ???
Boriza L. wrote: > Ich habe das STK500-Board mit einem Tiny45 bestückt und ich habe das > dumme Gefühl, das ich auf dem absolut falschen Weg bin. Ja. Beim STK500 ist nämlich genau das der Fall, was ich oben angesprochen habe: LEDs sind High-Side und Taster Low-Side angeschlossen. > Ich bin mir auch > noch nicht sicher ob ich besser in Assembler oder C programmieren soll. > Ist Bascom wirklich soviel besser als AVR-Studio ??? Bascom ist mit Sicherheit nicht "besser" als "AVRStudio" (wobei ich mal vermute, dass Du mit "AVRStudio" C meinst, was aber gar nicht zu AVRStudio gehört, sondern nur in Form des AVR-GCC-Plugins in die IDE integriert werden kann). Was von beiden Dir eher liegt, musst Du selbst entscheiden. Aber die Hardware ist davon unabhängig. Auch in BASCOM musst Du einen Pin auf Low schalten, um eine LED am STK500 ans Leuchten zu bringen. Für die Taster gilt entsprechendes...
Boriza L. wrote: > Tja also irgendwie ist das alles nicht so dolle.... definier doch mal 'nicht so dolle....' > hat jemand eine Idee, wie man das richtig hinbekommt ? > was mache ich falsch ? > DDRB = (1 << DDB0); // PB0 als Ausgang > DDRB &= ~(1 << DDB1); // PB1 als Eingang OK > > { > if (PINB & (1 << PB1)) // wenn PB1 geschlossen (HIGH) Bist du ganz sicher, dass vom Port eine 1 kommt, wenn der Taster gedrückt wird? Wie Johannes schon schrieb: Normalerweise ist es umgekehrt. Der Grundzustand ist 1 und nur wenn ein Taster gedrückt wird, wechselt der Pin auf 0 > > do > { > PORTB = PINB ^ ( 1 << PB0 ); // LED an PB0 umschalten > PORTB = PORTB | (1 << DDB0); // LED an PB0 ein > } > while (PINB & (1 << PB1)) // wenn PB1 geschlossen (HIGH) Du willst wirklich die ganze Zeit, während ein Taster geschlossen (=gedrückt) ist, den Ausgangsport umschalten? Das wird aber dann eher ein Zufallsgenerator. Dir ist schon klar, dass dein AVR je nach Taktfrequenz, die obige Schleife bei gedrückter Taste ein paar 100-tausendmal in der Sekunde abarbeitet? Auch: PINx verwendet man, um den Zustand eines Port-Pins einzulesen, wenn dieser Pin als Eingang konfiguriert ist PORTx verwendxet man, um den Zustand eines Port-Pins zu verändern oder auch den zuletzt ausgegebenen Zustand wieder einzulesen, wenn dieser Pin auf Ausgang konfiguriert ist. PORTx wird weiterhin verwendet, um die Pullup Widerstände zu konfigurieren, wenn ein Pin auf Eingang konfiguriert ist. Sieh dir nochmal deine Verwendung von PORT und PIN in obiger Schleife dahingehend durch. Auch: Für die normalen Port-Operationen Ausgabe und Eingabe werden die Pxn (zb. PB0) Makros benutzt um einen bestimmten Pin anzusprechen. Nur wenn man auf das entsprechende Konfigurationsregister DDRx zugreift, verwendet man die DDxn (zb. DDB0) Makros. Macht zwar keinen wirklichen Unterschied, da PB0 denselben Zahlenwert wie DDB0 aufweist (nämlich 0), ist aber eine Frage der Konsistenz und Sorgfalt. Was du machen willst ist was anderes: mache ewig { warte darauf, dass die Taste gedrückt wird Schalte den Ausgangsport um warte darauf, dass die Taste wieder losgelassen wird. } aber auch das wird 'nicht so dolle' funktionieren, weil Tasten nun mal prellen. Im allereinfachsten Fall, kann man das Prellen loswerden, indem nach dem Erkennen des Umschaltens des Tasters eine kleine Wartezeit eingelegt wird. Für Profi-Anwendungen ist diese Warterei so meist nicht zu gebrauchen, aber für deine ersten Schritte ist das schon ok.
Schau Dir mal das hier an: Beitrag "Universelle Tastenabfrage" Dann probier es aus, nimm Dir 1-2 Tage Zeit und versuche es zu verstehen. Und wenn Du es verstanden hast, dann bist Du froh, fürderhin ein derart mächtiges Werkzeug zur Verfügung zu haben. Peter P.S.: Du kannst dazu ruhig Fragen stellen.
Ja,das ist schonmal der erste Akt (LEDs sind High-Side und Taster Low-Side), am liebsten schreibe ich das in C (AVR-GCC-Plugins) hat jemand eine Idee wie man das richtig hinbekommt ? was mache ich falsch ? Sind die Ports zur ein-/ausgabe richtig definiert ? Danke !!!
Vielen Dank, nur verstehe ich leider nur sehr wenig davon. Also, wie definiere ich in C einen bestimmten Ausgang und einen Eingang ? Ich benötige von Port B einen Eingang und einen Ausgang, da der Tiny45 nur Port B besitzt.
Boriza L. wrote: > Vielen Dank, nur verstehe ich leider nur sehr wenig davon. > Also, wie definiere ich in C einen bestimmten Ausgang und einen Eingang > ? Dann schau dir mal das Tutorium auf dieser Site an. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_Ports
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.