Forum: Mikrocontroller und Digitale Elektronik Eingangssignal zählen


von Christian P. (christian_p32)


Lesenswert?

Hallo zusammen!

Ich bin neu in der Welt der Mikrocontroller und taste mich gerade an die 
Materie mit einem Atmega 8 heran.

Ich habe folgendes Problem:
Wenn mein Eingang PC0 5 mal betätigt wird soll mein Ausgang PD1 ein 
Signal ausgeben.

Ich hab mir das so vorgestellt:
1
uint8_t i=0;
2
3
4
int main (void)
5
{DDRD = 0b111111; //Port D als Ausgang
6
 DDRC = 0b000000; //Port C als Eingang   
7
while (1){
8
9
if (PINC & (1<<PINC0)) {i++;}
10
11
if (i==5) { PORTD |= (1<<PD1);} //wenn ich (i>=5) schreibe leuchtet meine 
12
                                //mein LED ab dem ersten Signal
13
14
    else {PORTD &=~ (1<<PD1);}
15
}
16
17
  return 0;
Ich verwende externe Pullup Widerstände ich weis nicht ob das genügt um 
Taster Prellen auszuschließen.

Ich bin echt Ratlos nicht mal Dr. Google konnte mir helfen!

Danke im Voraus.

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Was ist denn nun aber Dein Problem? Was Deine Frage?

> Ich verwende externe Pullup Widerstände ich weis
> nicht ob das genügt um  Taster Prellen auszuschließen.
Warum sollten Pull-Up-Widerstände überhaupt auf das Prellen einwirken?
Du brauchst jedenfalls ziemlich sicher eine Entprellung.

von Justus S. (jussa)


Lesenswert?

Bitflüsterer schrieb:
> Was ist denn nun aber Dein Problem?

wohl dass er auf eine Flanke abfragen will aber es nicht tut...

von Bitflüsterer (Gast)


Lesenswert?

Lies am besten mal diesen Artikel hier: 
http://www.mikrocontroller.net/articles/Entprellung

Es ist natürlich ein Problem für einen Anfänger, den Effekt so zu 
benennen, dass man etwas findet, wenn man Prellen von vorneherein 
ausschließt. Aber lass Dir gesagt sein, dass alle Taster prellen, es 
sei denn Du hast extra für prellfreie Taster bezahlt - und das merkst Du 
dann schon im Portemonais.

Da entprellen schon ein Thema für sich ist - Peters berühmte 
Entprellroutine erfordert schon ein wenig Erfahrung - würde ich Dir eine 
Entprellung mit Vorwiderstand und Kondensator empfehlen.

von San L. (zwillingsfreunde)


Lesenswert?

Wenn das der ganze Code sein soll, dürfte er sich nicht einmal 
kompilieren lassen. Da fehlt eine Klammer.

Desweiteren solltest du stark an deiner Darstellung des Codes arbeiten. 
Das ist kein bisschen leserlich. Ungefähr so sollte es aussehen:
1
uint8_t i=0;
2
3
4
int main (void) {
5
   DDRD = 0b111111; //Port D als Ausgang
6
   DDRC = 0b000000; //Port C als Eingang
7
8
 while (1) {
9
10
   if (PINC & (1<<PINC0)) {  
11
     i++;
12
   }
13
14
   if (i==5) { 
15
     PORTD |= (1<<PD1); //wenn ich (i>=5) schreibe leuchtet LED
16
   } 
17
18
   else {
19
     PORTD &=~ (1<<PD1);
20
   }
21
 }
22
  return 0;
23
}

So.
Und der Fehler ist klar. Wenn du PINC0 betätigst, inkrementiert er in 
der Tat die Variable i um 1. Somit steht dann i = 1. Das Problem dabei: 
Du wartest nicht, bis du den Taster wieder loslässt. Da dein Code sehr 
kurz ist und dein uC bestimmt mit merheren MHz läuft, hat der bereits 
nach wenigen Mikrosekunden für i einen Wert der WEIT über 5 ist.

Ganz einfach gesagt:
Schreib einen Code der i nicht dauerhaft inkrementiert, sondern erst 
dann wieder hochzählt, wenn der Taster auch einmal wieder losgelassen 
wurde.
Am einfachste (nicht am besten) wäre da eine simple schleife.
1
   if (PINC & (1<<PINC0)) {  
2
     i++;
3
     while(PINC & (1<<PINC0));
4
   }

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Justus Skorps schrieb:
> Bitflüsterer schrieb:
>> Was ist denn nun aber Dein Problem?
>
> wohl dass er auf eine Flanke abfragen will aber es nicht tut...

Schön. Aber ich wollte nicht das Du das formulierst, sondern er. Oder 
soll er sich daran gewöhnen, dass andere für ihn denken und formulieren?

von Christian P. (christian_p32)


Lesenswert?

Ich weis nicht ob mein Programm überhaut Sinn macht.

wie würdet ihr meine Aufgabe lösen (4 Signale am Eingang dan einen 
Ausgang schalten)?

von Bitflüsterer (Gast)


Lesenswert?

Christian P. schrieb:
> Ich weis nicht ob mein Programm überhaut Sinn macht.

Nichts und niemand kann "Sinn machen". Aber bitte lies die Antworten.

> wie würdet ihr meine Aufgabe lösen (4 Signale am Eingang dan einen
> Ausgang schalten)?

Genau so. (Ich empfehle allerdings eine Spezifikation darüber, was bei 
weiteren Tastendrücken passieren soll.) Und entprellen.

von San L. (zwillingsfreunde)


Lesenswert?

Christian P. schrieb:
> wie würdet ihr meine Aufgabe lösen (4 Signale am Eingang dan einen
> Ausgang schalten)?

So wie mein gepostetr Code oben dürfte es funktionieren.

Ansonsten:
Für dich evt, noch bisschen Neuland, aber mit Interrupts liese sich das 
ganze auch sehr gut lösen. Weiss nicht was da das Stichwort bei Atmel 
wäre, für Microchip's PIC wäre da "Interupt on Change" das Schlagwort 
zum Googlen. ;) Aber wie gesagt, ist dann ein kleines bisschen 
komplizierter... erstmal die Basis lernen. Aber so hast du es immerhin 
shconmal gehört. ;)

von Christian P. (christian_p32)


Lesenswert?

@ San Lue

Danke für die Antwort!

Ich weis aber nicht genau wo ich deinen Code jetzt genau reinpacken soll 
und wie ich zu meinem Ausgang komme!

von San L. (zwillingsfreunde)


Lesenswert?

Christian P. schrieb:
> Ich weis aber nicht genau wo ich deinen Code jetzt genau reinpacken soll
> und wie ich zu meinem Ausgang komme!


Code:
1
uint8_t i=0;
2
3
4
int main (void) {
5
   DDRD = 0b111111; //Port D als Ausgang
6
   DDRC = 0b000000; //Port C als Eingang
7
8
 while (1) {
9
10
   if (PINC & (1<<PINC0)) {  
11
     i++;
12
     while(PINC & (1<<PINC0));
13
   }
14
15
   if (i==5) { 
16
     PORTD |= (1<<PD1); //wenn ich (i>=5) schreibe leuchtet LED
17
   } 
18
19
   else {
20
     PORTD &=~ (1<<PD1);
21
   }
22
 }
23
  return 0;
24
}

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Schade. Eine der ersten Erfahrungen, die man machen kann, nämlich das 
der uC sehr viel schneller ist, als der Anfänger denkt, leider 
vorgedacht.

von oldmax (Gast)


Lesenswert?

Hi
Die Kunst, mit einem Taster Impulse zu zählen ist Flankenbildung. Ich 
kann es dir nicht in C eerklären, aber prinzipiell.
EDu legst zwei Variablen an, eine nennst du neu, die andere alt. bei 
Programmstart sind beide gleich. Nun startest du dein Programm und liest 
in Neu den Port ein. Eine Exclusiv-Oder-Verknüpfung mit der Variablen 
Alt zeigt dir anhand gesetzter Bits, das es eine Änderung gab.
Funktion ist
  Neu    alt   Erg.
   0     0     0
   1     0     1
   0     1     1
   1     1     0
Wenn du im Ergebnis eine 1 findest und nun eine Und - Verknüpung mit Neu 
machst, weist du, das es einSignal gibt, welches von 0 nach 1 gewechselt 
hat. Das ist die steigende Flanke. Machst du hingegten eine 
Und-Verknüpfung Ergebnis mit Alt, erhälst du die fallende Flanke, das 
heißt den Wechsel von 1 nach 0
Diesen Wechsel mekst du dir in einem Flankenmerker. Dann setzt du Alt= 
neu. NAtürlich wird im nächsten Zyklus wieder auf einen Unterschied 
geprüft, aber diesmal findet der Controller nur zwei gleiche Werte vor 
und so gibt es nichts zu tun.
Dieses Flankenbit fragst du im weiteren Programm ab, und wenn es gesetzt 
ist, führst du den Zählvorgang aus und setzt das Bit zu 0. Erst, wenn 
wieder eine Änderung der Eingänge über Exklusiv-Oder erkannt wird gibt 
es wieder eine Flanke und einen erneuten Zählvorgang. Dafür braucht es 
aber eine erneute Betätigung des Tasters. Natürlich ist Voraussetzung, 
das der Eingang vorher entprellt ist. Der Vorgang ist ähnlich. Auch hier 
wird ein alter Wert mit einem neuen Wert verglichen, sind sie gleich, 
wird ein gesetzter Zähler heruntergezählt, ansonsten gesetzt. Danach neu 
nach alt kopiert. Erreicht der Zähler die 0, prellt der Eingang nicht 
mehr und der Wert ist gültig. Es sollte aber klar sein, das Entprellen 
mit aktuellen Eingängen und alt_entprellen und Flankenerfassung mit 
gültigen Eingängen und Alt_Flanken arbeiten.
Gruß oldmax

von Christian P. (christian_p32)


Lesenswert?

Danke für die vielen Antworten!
Mit dem code von San lue hab ich genau das selbe Problem wie mit meinem!

Die Led Flackert kurz beim ersten mal Tasten sonnst tut sich nix!

von Der Meckerer (Gast)


Lesenswert?

Hallo,
jetzt fühle ich mich doch einmal genötigt etwas zu schreiben.
Das kommt jetzt etwas hart rüber aber ich wundere mich hier schon seit 
etlichen Wochen über die Beiträge im Forum.

Aussage: Ich bin neu in der Welt der Mikrocontroller.

In der Regel sieht man dann allerdings an den Fragen, daß anscheinend 
auch nur sehr mangelnde Kenntnisse in C vorhanden sind. Dies ist hier 
auch der Fall, wie man deutlich erkennt. -> Vielleicht erstmal 
einigermaßen vernünftige Programmierkenntnisse aneignen?

@ Christian P.
Da die Variable i nicht von dir im Programm wieder auf 0 gesetzt wird, 
mußt du wohl sooft auf die Taste drücken bis der Wert, dank Überlauf, 
wieder auf 5 kommt.

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


Lesenswert?

Christian P. schrieb:
> Mit dem code von San lue hab ich genau das selbe Problem wie mit meinem!
Und warum?
Die Stichworte wurden genannt (schnell, Flanke, entprellen). Der Weg, 
bis es funktioniert heisst "Lernen". Es wäre Unsinn, wenn man dir jetzt 
das fertige Programm vorlegen würde. Du selbst wüsstest nicht, was da 
passiert...

Nimm den Simulator oder den Debugger und finde den Fehler. Das ist jetzt 
ja noch keine Raketentechnik.

Der Meckerer schrieb:
> @ Christian P.
> Da die Variable i nicht von dir im Programm wieder auf 0 gesetzt wird,
> mußt du wohl sooft auf die Taste drücken bis der Wert, dank Überlauf,
> wieder auf 5 kommt.
Zum Glück hilft hier ein prellender Taster, dass doch nicht ganz so oft 
gedrückt werden muss. Aber genau so ein Fehler ist mit dem Simulator 
nach 10 Minuten gefunden...

: Bearbeitet durch Moderator
von oldmax (Gast)


Lesenswert?

Hi
und ich hatte gedacht, das die Information, wie man Flankenerkennung 
programmiert deutlich war. Mit zeigt das wieder mal, kommt kein fertiger 
Code ist Schicht im Schacht.
Gruß oldmax

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.