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_ti=0;
2
3
4
intmain(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
return0;
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.
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.
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.
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_ti=0;
2
3
4
intmain(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
return0;
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.
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?
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.
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. ;)
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
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!
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.
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...
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