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


von Dietmar P. (dietmar2)


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:
1
#include <avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
5
#endif
6
7
#include <util/delay.h>
8
9
  uint8_t l1 = 0;
10
  uint8_t l2 = 0;  
11
12
  int main(void)
13
{  
14
  DDRA = 0xff;                                         // Port A, alles auf Ausgang
15
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1));                // bis auf die Tastereingaenge
16
  PORTA = 0xff;                                        // Port A alle Pullups an
17
  
18
19
  while(1) {
20
21
    _delay_ms(0.5); // Verzögerung 
22
23
    if (PINA & (1 << PINA0)){
24
  l1=1;
25
  l2=0;
26
  }
27
    if (PINA & (1 << PINA1)){
28
  l2=1;
29
  l1=0;
30
  }
31
32
    if (l1==1){
33
  PORTA |= ( 1 << PA3 );    // LED an
34
  l2=0;
35
  }
36
    if (l2==1){
37
  l1=0;
38
  PORTA &= ~( 1 << PA3 );   // LED aus
39
  }
40
    
41
42
  }
43
}

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.

von Karl H. (kbuchegg)


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?

von Dietmar P. (dietmar2)


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

von Karl H. (kbuchegg)


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
1
  if (PINA & (1 << PINA0)){
2
    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.)

von Dietmar P. (dietmar2)


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.

von Karl H. (kbuchegg)


Lesenswert?

Wenn dein Taster aber bei Betätigung auf 0 schließt, was kann dann an
1
  if (PINA & (1 << PINA0)){
2
    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.

von Flo (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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
1
#ifndef F_CPU
2
#define F_CPU 1000000UL     // Takt CPU wird gesetzt
3
#endif
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
int main(void)
9
{  
10
  DDRA = 0xff;                                         // Port A, alles auf Ausgang
11
  DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1));                // bis auf die Tastereingaenge
12
  PORTA = 0xff;                                        // Port A alle Pullups an
13
  
14
  while(1) {
15
16
    if( ( PINA & (1 << PINA0) ) == 0 )
17
      PORTA |= ( 1 << PA3 );   // Led ausschalten
18
 
19
    if( ( PINA & (1 << PINA1) ) == 0 )
20
      PORTA &= ( 1 << PA3 );   // Led einschalten
21
  }
22
}

von Dietmar P. (dietmar2)


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?

von weißgradnich (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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

von Dietmar P. (dietmar2)


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

von Karl H. (kbuchegg)


Lesenswert?

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

von Helmut L. (helmi1)


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

von Dietmar P. (dietmar2)


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.

von Karl H. (kbuchegg)


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.

von Dietmar P. (dietmar2)


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.

von Jakob K. (jaykob)


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.

von Karl H. (kbuchegg)


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?

von Jakob K. (jaykob)


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

von Jakob K. (jaykob)


Angehängte Dateien:

Lesenswert?

So jetzt der Schaltplan und der Quellcode

das Programm ist folgendes:
1
#include <avr/io.h>                   // hinzufügen der header files
2
#include <util/delay.h>
3
#include <stdint.h>
4
 
5
int main (void)              // main funktion
6
{                          
7
     // Festlegen der Ein- und Ausgänge des Ports A
8
   DDRA  = ( 1 << DDA0) | (0 << DDA2) | (0 << DDA3) | (0 << DDA4) | (0 << DDA5);                 
9
     // Aktivieren der internen Pull-Ups für die Eingänge
10
   PORTA = ( 1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5);
11
12
     
13
 
14
    while( 1 ) 
15
  {                // Endlosschleife
16
       if ( (PINA & (1 << PINA2) == 0))
17
      PORTA |= (1 << PA0);
18
19
20
       if ( (PINA & (1 << PINA3) == 0))
21
      PORTA &= ~(1 << PA0);
22
 
23
    }
24
    return 0;
25
}

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

von Karl H. (kbuchegg)


Lesenswert?

Passt eigentlich soweit.

Deine LED ist richtig rum und auch der Jumper gesteckt?

Tetsprogramm
1
#include <avr/io.h>                   // hinzufügen der header files
2
#include <util/delay.h>
3
#include <stdint.h>
4
 
5
int main (void)              // main funktion
6
{                          
7
   DDRA  = ( 1 << DDA0);
8
   while( 1 ) 
9
   {
10
     PORTA |= (1 << PA0);
11
     _delay_ms( 1000 );
12
13
      PORTA &= ~(1 << PA0);
14
     _delay_ms( 1000 );
15
    }
16
}

LED muss blinken

von Karl H. (kbuchegg)


Lesenswert?

Aaaaah.
Übersehen

Klammern!

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


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

von Jakob K. (jaykob)


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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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)

von Peter D. (peda)


Angehängte Dateien:

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:
1
#include "sbit.h"
2
3
4
#define LED     SBIT( PORTB, PB0 )
5
#define TASTE   SBIT( PINC,  PC1 )
6
7
8
void test( void )
9
{
10
  for(;;)
11
    LED = TASTE;
12
}


Peter

von Jakob K. (jaykob)


Lesenswert?

hallo,


danke für die vielen antworten

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


vielen dank

jakob

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.