Taster abfragen - LED anschalten - Weiterentwicklung

OP #1695425
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.
#1695435
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?
#1695526
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.)
#1695533
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.
#1695542
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
}
OP #1696089
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
OP #1696137
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.
#1696149
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.
OP #1696241
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.
#1796999
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.
#1797014
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
#1797130
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
Angehängte Dateien:
#1797234
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
#1797795
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
#1797894
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.
#1797922
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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren