Forum: Mikrocontroller und Digitale Elektronik LED mit einem Taster ein- auschalten


von Boris L. (dr-unheil)


Lesenswert?

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 !

von Julian R. (julian83)


Lesenswert?

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 ;-).

von Lothar (Gast)


Lesenswert?

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

von Philipp Karbach (Gast)


Lesenswert?

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;
  }
}

von hubert (Gast)


Lesenswert?

#define TASTER  PC0
sollte doch besser
#define TASTER  0
heißen oder?

von Boris L. (dr-unheil)


Lesenswert?

Super, vielen Dank - das hört sich gut an. Ich werde das gleich mal 
testen.
lg Boriza

von Boris L. (dr-unheil)


Lesenswert?

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
}
}

von Johannes M. (johnny-m)


Lesenswert?

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).

von Boris L. (dr-unheil)


Lesenswert?

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 ???

von Johannes M. (johnny-m)


Lesenswert?

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...

von Gast (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Boris L. (dr-unheil)


Lesenswert?

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 !!!

von Boris L. (dr-unheil)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.