Forum: Mikrocontroller und Digitale Elektronik AT2313 1 Taster 3 Ausgänge


von Steffen K. (buttonsoft)


Lesenswert?

Hi, ich habe einen Attiny2313 mit einem Taster an PIN2 und 3 Ausgängen 
an Port PD4,PD5,PD6.
Ich bekomm es nicht hin, den Taster hochzuzählen um so die Ausgänge 
anzusteuern.
Die Suche hat mich auch nicht weiter gebracht.
Hat von euch jemand einen Lösungsansatz?
PIN 2 warscheinlich immer irgendwie +1 und ab 3 wieder auf 0 und mit der 
+1 die jeweiligen Ports einschalten
(z.B. 1x drücken PD6 ein, ein zweites mal drücken: PD6 ein und PD5 ein, 
ein drittes mal drücken: PD6, PD5 und PD4 ein, ein viertes mal drücken: 
PD6,PD5 und PD4 aus und wieder von vorn)

1
#include <avr/io.h>
2
3
int main(void) {
4
  DDRD  = 0b01110000;
5
  PORTD = 0x00;
6
7
  short Ausgang1 = 0; //PD6
8
  short Ausgang2 = 0; //PD5
9
  short Ausgang3 = 0; //PD4
10
11
  while(1) {
12
    if(PIND & ((1 << PD2))) {      // ist der Taster gedrückt?
13
      
14
      if(PIND & (1 << PD2)) {      // Taster gedrückt → Ausgang in Warteschlange setzen    
15
        Ausgang1 = 1;
16
      }
17
      
18
    }
19
    else {                // Taster nicht gedrückt → Warteschlange abarbeiten
20
    
21
      if(Ausgang1 == 1) {        // Ausgang in Warteschlange
22
        Ausgang1 = 0;        // Ausgang aus Warteschlange herausnehmen
23
        PORTD ^= (1 << PD6);    // XOR an Ausgang1 anwenden: 1 wenn bisher 0, 0 wenn bisher 1
24
        
25
      }
26
    }
27
  }
28
  return 0;
29
}

: Verschoben durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Steffen K. schrieb:
> Ich bekomm es nicht hin, den Taster hochzuzählen
Wie auch? Man kann Taster nicht hochzählen.

> Ich bekomm es nicht hin, den Taster hochzuzählen um so die Ausgänge
> anzusteuern.
> Hat von euch jemand einen Lösungsansatz?
Du beschreibst mal, was du von deinem Programm eigentlich erwartest und 
was stattdessen passiert.
Und während des Wartens auf eine Antwort denkst du mal über /prellende 
Taster/ nach.

: Bearbeitet durch Moderator
von Georg G. (df2au)


Lesenswert?

Taster gegen Vcc ist keine gute Wahl. Hast du einen Pulldown am Eingang? 
Vermutlich nicht. Also Taster gegen GND, internen Pullup einschalten, 
Auswertung invertieren. Und da Taster selten ideal sind sondern prellen, 
musst du da auch noch was tun.

von pseudo (Gast)


Lesenswert?

Steffen K. schrieb:
> (z.B. 1x drücken PD6 ein, ein zweites mal drücken: PD6 ein und PD5 ein,
> ein drittes mal drücken: PD6, PD5 und PD4 ein, ein viertes mal drücken:
> PD6,PD5 und PD4 aus und wieder von vorn)

1
Taster gedrückt dann check PD4. Wenn PD4 aus, dann PD4 einschalten. Weiter in Hauptschleife mit Taster abfragen
2
                                Wenn PD4 an, dann check PD5. Wenn PD5 aus, dann PD5 einschalten -> Hauptschleife
3
usw
4
Wenn PD6 an, dann alle PD aus.
Schutz vor Tastenprellung nicht vergessen.

von pseudo (Gast)


Lesenswert?

pseudo schrieb:
>
1
> Taster gedrückt dann check PD4. Wenn PD4 aus, dann PD4 einschalten. 
2
> Weiter in Hauptschleife mit Taster abfragen
3
>                                 Wenn PD4 an, dann check PD5. Wenn PD5 
4
> aus, dann PD5 einschalten -> Hauptschleife
5
> usw
6
> Wenn PD6 an, dann alle PD aus.
7
>

oder umgekehrte Reihenfolge ;-)

von Thomas E. (thomase)


Lesenswert?

pseudo schrieb:
> pseudo schrieb:
>>> Taster gedrückt dann check PD4. Wenn PD4 aus, dann PD4 einschalten.
>> Weiter in Hauptschleife mit Taster abfragen
>>                                 Wenn PD4 an, dann check PD5. Wenn PD5
>> aus, dann PD5 einschalten -> Hauptschleife
>> usw
>> Wenn PD6 an, dann alle PD aus.
>>
> oder umgekehrte Reihenfolge ;-)

Gute Idee. Um das Ganze zu entwirren, sollte man aber eine Variable 
hochzählen und entsprechend dem Zählerstand die Ports setzen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Steffen K. schrieb:
> Hat von euch jemand einen Lösungsansatz?

 So etwa ?
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void) {
5
  DDRD  = 0b01110000;
6
  PORTD = 0x00;
7
  uint8_ t tState = 0x00;
8
  
9
  while(1) {
10
//    if !(PIND & ((1 << PD2))) {      // Taster nach GND
11
    if (PIND & ((1 << PD2))) {      // Taster nach PLUS
12
       tState <<= 1;
13
       tState += 0x10;
14
       if (tState > 0x80)  tState = 0x0;
15
       PORTD = tState;       // Ändern, wenn Taster mit Pullups arbeiten ! 
16
//       PORTD = tState | 0x04;       // Etwa so 
17
       _delay_ms(50);        // Hier kommt normallerweise die Routine zum Entprellen
18
    }
19
  }
20
  return 0;
21
}

: Bearbeitet durch User
von Steffen K. (buttonsoft)


Lesenswert?

Das ist ja der Wahnsinn,

Ich versuch das seit Ewigkeiten und hab mich zuletzt in irgendwelchen if 
Anweisungen verhaspelt und dann kommt die perfekte Lösung.

vielen Dank @all und besonders an Marc Vesely ich hab noch das delay 
angepasst und 1-2 Kleinigkeiten behoben, nun äuft es so wie gewollt.

Danke Schön
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void) {
5
  DDRD  = 0b01110000;
6
  PORTD = 0x00;
7
  uint8_t tState = 0x00;
8
  
9
  while(1) {
10
   if (!(PIND & ((1 << PD2)))) {      // Taster nach GND
11
   // if (PIND & ((1 << PD2))) {      // Taster nach PLUS
12
       tState <<= 1;
13
       tState += 0x10;
14
       if (tState > 0x80)  tState = 0x0;
15
      // PORTD = tState;       // Ändern, wenn Taster mit Pullups arbeiten ! 
16
       PORTD = tState | 0x04;       // Etwa so 
17
       _delay_ms(200);        // Hier kommt normallerweise die Routine zum Entprellen
18
    }
19
  }
20
  return 0;
21
}

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Steffen K. schrieb:
> ich hab noch das delay angepasst und ... nun läuft es so wie gewollt.
Ja, tolle Software: entprellen über ein delay_ms. Du hättest da besser 
mal über die mehrmals erwähnte Tasterentprellung nachdenken sollen...

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Steffen K. schrieb:
> Danke Schön

 Bitte Schön.

Lothar M. schrieb:
> Ja, tolle Software: entprellen über ein delay_ms. Du hättest da besser
> mal über die mehrmals erwähnte Tasterentprellung nachdenken sollen...

 Kann er jetzt machen.
 Obwohl, solange sein Programm nur dieses eine Taster abfragt, kommt
 es auf dasselbe hinaus...

 Apropos Prellen:
 Kein Taster/Schalter prellt länger als 50ms, selbst das ist zu viel.
 Sollte dies trotzdem der Fall sein, kannst du ihn ruhig wegschmeissen.

von Steffen K. (buttonsoft)


Lesenswert?

Hey Leute,

es soll legendlich der Taster abgefragt werden. Ich bin froh das es 
überhaupt läuft, denn ich hab schon fast aufgegeben. Wenn es euch 
beruhigt dann entprelle ich über HW und geh doch auf Plus.

von Thomas E. (thomase)


Lesenswert?

Steffen K. schrieb:
> Hey Leute,
>
> es soll legendlich der Taster abgefragt werden. Ich bin froh das es
> überhaupt läuft, denn ich hab schon fast aufgegeben. Wenn es euch
> beruhigt dann entprelle ich über HW und geh doch auf Plus.

Meinetwegen musst du das nicht tun. Mir ist das vollkommen egal.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Steffen K. schrieb:
> es soll legendlich der Taster abgefragt werden. Ich bin froh das es
> überhaupt läuft, denn ich hab schon fast aufgegeben. Wenn es euch
> beruhigt dann entprelle ich über HW und geh doch auf Plus.

 Nö.
 Nimm nur _delay_ms aus der if Abfrage raus (2 Zeilen nach unten)
 und verkürze es auf 50ms.

: Bearbeitet durch User
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.