www.mikrocontroller.net

Forum: Compiler & IDEs Taster abfragen - LED anschalten - Weiterentwicklung


Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

nachdem ich das Prinzip aus meinem ersten Beitrag begriffen habe, wollte 
ich die Schaltung erweitern.

Ziel:
Taste 1 an PORTA Bit 0 gedrückt LED soll leuchten, auch wenn danach die 
Taste losgelassen wird.
Taste 2 an PORTA Bit 1 gedrückt LED soll wieder ausgehen.
Im Prinzip ist das ein Flip-Flop.

Was geht, was geht nicht:
Sofort nach dem Flashen geht die LED an. Wird die Taste 2 gedrückt geht 
sie aus, aber nur solange die Taste 2 gedrückt wird, dann geht sie 
wieder an.

Mein Code:
#include <avr/io.h>

#ifndef F_CPU
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
#endif

#include <util/delay.h>

  uint8_t l1 = 0;
  uint8_t l2 = 0;  

  int main(void)
{  
  DDRA = 0xff;                                         // Port A, alles auf Ausgang
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1));                // bis auf die Tastereingaenge
  PORTA = 0xff;                                        // Port A alle Pullups an
  

  while(1) {

    _delay_ms(0.5); // Verzögerung 

    if (PINA & (1 << PINA0)){
  l1=1;
  l2=0;
  }
    if (PINA & (1 << PINA1)){
  l2=1;
  l1=0;
  }

    if (l1==1){
  PORTA |= ( 1 << PA3 );    // LED an
  l2=0;
  }
    if (l2==1){
  l1=0;
  PORTA &= ~( 1 << PA3 );   // LED aus
  }
    

  }
}


Wo stehe ich denn da wieder auf dem Schlauch?
Ich habe keine else-Zweige verwendet, weil ich von meinem Verständnis 
her keine Notwendigkeit sah.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:

> Wo stehe ich denn da wieder auf dem Schlauch?

Du hast dir mit deinen "vielen" Variablen selbst den Blick aufs 
Wesentliche verstellt.

Hinweis:
  Ein Portpin behält seinen Status so lange, bis er geändert wird.
  Du brauchst keine einzige zusätzliche Variable.
  Die Hauptschleife besteht aus 4 Zeilen


Alternativ:
Gib deinen Variablen 'vernünftige' Namen und nicht ll1, ll2, i1, i2, x, 
y und was man sonst noch so alles sieht.
Bei
   if (l1==1){
muss man nachdenken, nachschauen, was da die Bedeutung ist.

Bei
   if( ledErrorOn == TRUE )
braucht man nicht raten. Da steht schon im Code, was an dieser Stelle 
warum passieren soll. Man verwirrt sich dann viel weniger leicht selber.

ZU deinem aktuellen Programm
> Taste 1 an PORTA Bit 0 gedrückt

Wenn eine Taste gedrückt ist, wie ist dann der Zustand des 
entsprechenden Port-Bits? Ist der 1 oder 0?

Wie sind deine LED angeschlossen?
Muss man eine 1 oder eine 0 an den Ausgang schreiben um die LED 
einzuschalten?

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl Heinz,

wieder einmal danke für die Unterstützung. Programmiert habe ich schon 
in anderen Sprachen, aber C hat es in sich.

Zu den Frage:

Taster schließen auf 0.
LED leuchtet bei 0.

Habe ich so gemacht, weil meistens die Ausgänge des µC bei 0 etwas tun.

Gruß
Dietmar

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:
> Hallo Karl Heinz,
>
> wieder einmal danke für die Unterstützung. Programmiert habe ich schon
> in anderen Sprachen, aber C hat es in sich.
>
> Zu den Frage:
>
> Taster schließen auf 0.
> LED leuchtet bei 0.
>
> Habe ich so gemacht, weil meistens die Ausgänge des µC bei 0 etwas tun.

Ja ist ok.
Muss man nur wissen.

Wenn dein Taster aber bei Betätigung auf 0 schließt, was kann dann an
  if (PINA & (1 << PINA0)){
    mach was wenn der Taster betätigt wurde

nicht stimmen?

( In C ist jeder Ausdruck ungleich 0 auch gleichzeitig ein Ausdruck, der 
als logisch wahr gilt. Mit dem & setzt du alle Bits ausser PINA0 gezielt 
auf 0. Also bleibt nur noch das Bit PINA0 übrig. Ist es 0, dann ist auch 
der ganze Ausdruck und hat damit den Wahrheitswert Falsch. Ist das Bit 
auf 1, dann belibt etws übrig, was nicht 0 ist und damit den 
Wahaheitswert Wahr hat.)

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Mein Code verkürzt:

    if (PINA & (1 << PINA0)){
  PORTA |= ( 1 << PA3 );    // LED an
  }
    if (PINA & (1 << PINA1)){
  PORTA &= ~( 1 << PA3 );   // LED aus
  }

Erhalte aber das gleiche Ergebnis.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn dein Taster aber bei Betätigung auf 0 schließt, was kann dann an
  if (PINA & (1 << PINA0)){
    mach was wenn der Taster betätigt wurde

nicht stimmen?

In C ist jeder Ausdruck auch gleichzeitig ein Ausdruck, der als 
logischer Wahrheitswert fungieren kann. 0 ist dabei der Wahrheitswert 
falsch, alles ungleich 0 ist der Wahrheitswert wahr. Mit dem & setzt du 
alle Bits ausser PINA0 gezielt auf 0. Also bleibt nur noch das Bit PINA0 
übrig. Ist es 0, dann ist auch der ganze Ausdruck 0 und hat damit den 
Wahrheitswert Falsch. Ist das Bit auf 1, dann belibt etwas übrig, was 
nicht 0 ist und damit den Wahrheitswert Wahr hat.

Dein Taster ist im Grundzustand nicht gedrückt, daher hat das Bit an 
PINA0 den Wert 1, und damit ist

  PINA & (1 << PINA0)

logisch wahr, wenn die Taste NICHT gedrückt ist.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du sagst, dass deine Taster beim Drücken eine 0 ergeben, solltest 
du die Bedingungen in den Abfragen invertieren ;-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Dein Taster ist im Grundzustand nicht gedrückt, daher hat das Bit an
> PINA0 den Wert 1, und damit ist
>
>   PINA & (1 << PINA0)
>
> logisch wahr, wenn die Taste NICHT gedrückt ist.

Und damit sollte dein Programm so aussehen
#ifndef F_CPU
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
#endif

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{  
  DDRA = 0xff;                                         // Port A, alles auf Ausgang
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1));                // bis auf die Tastereingaenge
  PORTA = 0xff;                                        // Port A alle Pullups an
  
  while(1) {

    if( ( PINA & (1 << PINA0) ) == 0 )
      PORTA |= ( 1 << PA3 );   // Led ausschalten
 
    if( ( PINA & (1 << PINA1) ) == 0 )
      PORTA &= ( 1 << PA3 );   // Led einschalten
  }
}

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl Heinz,

super, danke.

Deine Lösung ist so gut verständlich.

Gruß
Dietmar

Nachtrag:

Könnte es sein, dass in der letzten Zeile nach &= die Tilde ~ fehlt?

Autor: weißgradnich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Könnte es sein, dass in der letzten Zeile nach &= die Tilde ~ fehlt?
Yepp. Korrigierte Zeile:
      PORTA &= ~( 1 << PA3 );    // Led einschalten
mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:
> Hallo Karl Heinz,
>
> super, danke.
>
> Deine Lösung ist so gut verständlich.
>
> Gruß
> Dietmar
>
> Nachtrag:
>
> Könnte es sein, dass in der letzten Zeile nach &= die Tilde ~ fehlt?

Gut aufgepasst.
Ich seh schon, du erkennst die stehenden C-Phrasen zum Bit setzen und 
löschen selbst dann, wenn ich Fehler mache :-)

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, aber noch mit einiger Unsicherheit.

Es ist toll, dass es solch ein Forum gibt. Ohne das Forum hätte ich wohl 
schon längst aufgegeben.
Ich werde mich mit Sicherheit während meines Projektes "Alarmanlage" 
noch  melden.

Bereits erledigt:

Hard- + Software für Anzeige Status von Leitungen über Mux/Demux auf 
einem  Tableau mit LED's.

In Arbeit:

- Leitungsauswertung für Alarm.
- Verwendung LCD-Display für Leitungsstatus.

Da kommt noch das Thema Tabellenverarbeitung auf mich zu.

Gruß
Dietmar

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darf ich fragen, womit du sonst do sprogrammiert hast? Welche Sprache? 
Und auf welchem Niveau?

Autor: Helmut Lenzen (helmi1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ich seh schon, du erkennst die stehenden C-Phrasen zum Bit setzen und
> löschen selbst dann, wenn ich Fehler mache :-)

Karl heinz  du machst keine Fehler, du willst nur testen ob er aufpasst.

Gruss Helmi

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl Heinz,

ja, gerne.

Angefangen habe ich mal mit etwas Assembler auf dem Großrechner, ist 
aber nur noch wenig vorhanden, dann sehr viel beruflich COBOL mit 
Datenbanken.
Auf dem PC war / ist das Basic und APL. APL gibt es offenbar nicht mehr, 
wurde von IBM getrieben. APL ist eine Programmiersprache, die eigentlich 
nur aus Zeichen aus der Mathematik besteht, ist unheimlich 
leistungsfähig für
Tabellenverarbeitung und sehr schnell, aber der Einstieg ist wohl ebenso 
mühsam, wie jetzt für mich in C.
Mit Tools für rel. Datenbaken wie dBase bzw. heute Open-Office Base 
beschäftige ich mich auch.

Eigentlich wollte ich mit Bascom für die µC's anfangen, habe aber hier 
im Forum den Eindruck gewonnen, dass C besser sei.

Nun ja und nun quäle ich mich halt in C wegen der µC, ist kpl. Neuland 
für mich.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dietmar P. schrieb:

> Assembler auf dem Großrechner, COBOL, APL

Oh. APL kenn ich noch. Hab ich auf der Uni gehabt :-)

Warum ich frage:
Der Hintergedanke ist, dass man dir eventuell weiterhelfen kann, wenn 
man auf dir bereits Bekanntes zurückgreift. Aber da ist nichts dabei, 
was man brauchen könnte. Deine bekannten Sprachen sind ziemlich weit von 
C entfernt, und mein COBOL ist schon sehr rostig :-)

> Nun ja und nun quäle ich mich halt in C wegen der µC, ist kpl. Neuland
> für mich.

Mein Tip:
Hol dir einen Kernighan&Ritchie und arbeite den (zumindest die erste 
Hälfte) auf dem PC durch. Du hast deutlich mehr davon, wenn du die 
Grundlagen systematisch durchgehst. Und auf dem PC lernt es sich 
leichter, weil du eine bessere Entwicklungsumgebung hast. So Dinge wie 
'Ausgabe auf die Konsole' funktionieren dort ganz einfach und damit hast 
du ein mächtiges Werkzeug um dir zb Zwischenergebnisse oder 
'strategische Ausgaben zu Debugzwecken' zu machen. Ganz abgesehen davon, 
dass du einen viel besseren Debugger hast.

Erst dann, wenn du mit Arrays, Strings, Strukturen, Pointern, nicht mehr 
auf Kriegsfuss stehst, macht es Sinn die spezifischen Dingen zur 
µC-Programmierung dazuzunehmen und vom PC auf einen AVR zu wechseln. Du 
betreibst sonst einen Mehrfrontenkrieg, der unnötig mühsam ist.

Und ja: Kauf dir Literatur! C ist voll kleiner Fallen die sich einem mit 
der Methode 'Try&Error' nicht erschliessen.

Autor: Dietmar P. (dietmar2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ich denke das wird der richtige Weg sein.

Hab schon mal gegoogelt wegen Kernighan&Ritchie, werde es mir besorgen.
Wenn man das empfehlen kann, ist es ok. Hatte mir schon Bücher 
angesehen, aber da war nichts dabei was mich wirklich angesprochen hat.

Mit "Try & Error" habe ich doch schon viele Stunden zu gebracht.

Autor: Jakob K. (jaykob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

hat jemand von euch die überarbeite Version des Programms mal 
ausprobiert?
Hat diese bei euch funktioniert.


Bei mir funktioniert da leider gar nichts, ich kann aber einen Fehler an 
der Hardware ausschließen, da ich diese bereits für für andere Programme 
verwendet habe.

Bei dieser überarbeiteten Version habe ich nur die Eingangs- und 
Ausgangspins nach meinen Anforderungen verändert.

Leider geht die LED weder an noch aus.


Kann mir vielleicht jemand sagen, woran das liegt?


Vielen Dank schon mal im Vorraus.

Achja ich besitze einen ATTiny 84V.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jakob K. schrieb:

> Bei dieser überarbeiteten Version habe ich nur die Eingangs- und
> Ausgangspins nach meinen Anforderungen verändert.

Wie sieht dein Programm aus?
Wie sieht deine Schaltung aus?

> Leider geht die LED weder an noch aus.

Hört sich banal an, aber hast du schon mal versucht, die LED ohne Taster 
einzuschalten?

Autor: Jakob K. (jaykob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wie schon gesagt habe die LED schon für andere Schaltungen verwendet
Ich kann Sie sogar schon blinken lassen, das hat einwandfrei 
funktioniert

Und die Schalterpins habe ich auch durchgemessen bei geöffneten wie 
geschlossenem Schalter, die Spannungen passen soweit.


Ich werd mal schnell nen Schaltplan zeichnen und hier hochladen, gib mir 
ca. 20 min

Autor: Jakob K. (jaykob)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So jetzt der Schaltplan und der Quellcode

das Programm ist folgendes:
#include <avr/io.h>                   // hinzufügen der header files
#include <util/delay.h>
#include <stdint.h>
 
int main (void)              // main funktion
{                          
     // Festlegen der Ein- und Ausgänge des Ports A
   DDRA  = ( 1 << DDA0) | (0 << DDA2) | (0 << DDA3) | (0 << DDA4) | (0 << DDA5);                 
     // Aktivieren der internen Pull-Ups für die Eingänge
   PORTA = ( 1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5);

     
 
    while( 1 ) 
  {                // Endlosschleife
       if ( (PINA & (1 << PINA2) == 0))
      PORTA |= (1 << PA0);


       if ( (PINA & (1 << PINA3) == 0))
      PORTA &= ~(1 << PA0);
 
    }
    return 0;
}

Der Schaltplan zeigt meine komplette Schaltung.
Diesen benötige ich noch nachdem dieses Programm läuft.

Der Max 232 und die Kondis hierfür habe ich noch nicht verbaut
Die LED ist über den Jumper deaktivierbar

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Passt eigentlich soweit.

Deine LED ist richtig rum und auch der Jumper gesteckt?

Tetsprogramm
#include <avr/io.h>                   // hinzufügen der header files
#include <util/delay.h>
#include <stdint.h>
 
int main (void)              // main funktion
{                          
   DDRA  = ( 1 << DDA0);
   while( 1 ) 
   {
     PORTA |= (1 << PA0);
     _delay_ms( 1000 );

      PORTA &= ~(1 << PA0);
     _delay_ms( 1000 );
    }
}

LED muss blinken

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aaaaah.
Übersehen

Klammern!

Falsch:
       if ( (PINA & (1 << PINA2) == 0))


Richtig:
       if ( (PINA & (1 << PINA2)) == 0)

Autor: Jakob K. (jaykob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für die schnelle Antwort,
Programm funktioniert jetzt soweit. :-)
Es waren wirklich die falsch gesetzten Klammern! :-(


Ich habe noch eine Frage, wie kann kann ich die LED nur so lang leuchten 
lassen, wie der Schalter gedrückt ist?


Vielen Dank für dieses Forum, ohne dieses hätte ich vermutl. schon 
längst aufgegeben


Jakob

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jakob K. schrieb:

> Ich habe noch eine Frage, wie kann kann ich die LED nur so lang leuchten
> lassen, wie der Schalter gedrückt ist?

Indem du innerhalb der SChleife immer wieder das machst

 für immer {
   wenn   Taster gedrückt
     dann LED an
   else
     LED aus
 }

genau genommen stimmt es nicht ganz, dass die LED nur so lange leuchtet, 
wie die Taste gedrückt ist, aber auf die paar µs kommt es nicht an.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jakob K. schrieb:

> Es waren wirklich die falsch gesetzten Klammern! :-(

Die Hausaufgabe für dich: Warum ist das so?

(Dein Stichwort lautet: Operator Precedence Table  bzw. auf Deutsch: 
Vorrangregeln der Operatoren)

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jakob K. schrieb:
> Ich habe noch eine Frage, wie kann kann ich die LED nur so lang leuchten
> lassen, wie der Schalter gedrückt ist?

Dazu braucht man dann folgendes riesen Programm:
#include "sbit.h"


#define LED     SBIT( PORTB, PB0 )
#define TASTE   SBIT( PINC,  PC1 )


void test( void )
{
  for(;;)
    LED = TASTE;
}


Peter

Autor: Jakob K. (jaykob)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,


danke für die vielen antworten

jetzt funktioniert alles und ich kann mich dem nächsten problem widmen.


vielen dank

jakob

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.