PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tastereingabe, Probleme...



The_Darkside
03.02.2006, 07:39
int main(void){
init_pwm( 8 );
uint16_t pwm_val = 0;
DDRD = (1<<DDD5) | (1<<DDD6);
PORTD = (1<<DDD6);
OCR1A = pwm_val;
while(1){
* if(PIND & (1<<2)) pwm_val+=10;
* else if(PIND & (1<<3)) pwm_val-=10;
else if(PIND & (1<<4)) pwm_val=250;
//pwm_val = readChannel(0);
OCR1A = pwm_val;
}
}


Genau die Abfrage in den beiden mit * gekennzeichneten Zeilen bereitet Probleme. Gebe ich der Variable da nen Festwert, funkt. das. tu ich es nicht sondern zähle die hoch bzw. runter funkt. es irgendwie nicht so wie ich es erwarte.

Meiner Ansicht nach sollte die LED am Ausgang dann dimmbar sein, aber das tut sie nicht, wird einfach unkontrolliert hell oder dunkel. Also Sprunghaft, vor allem auch beim hochzählen, mal hell, mal dunkel völlig unkontrolliert.
Dacht ich mir, liegt am Tasterprellen, aber der Taster prellt eigentl. gar nicht, zumindest wenn ich meinem Oszi glauben schenken darf.
Nichts destotrotz hab ich eine Routine zum entprellen benutzt, gibt aber den gleichen Effekt.
Hab auch versucht die Tastereingabe per Interrupt zu lösen, aber auch das brachte keinen Erfolg.

Benutze ich aber über meinen Analogeingang nen Poti, ist alles i.O.

Ich hab nun einfach keine Idee mehr, vielleicht hat einer von euch das gleiche Problem schon erfolgreicher gelöst.

Letztendlich möchte ich auch keine LED dimmen, aber das bot sich zum probieren einfach gerade an.

Danke für Tipps... Tobias

SprinterSB
03.02.2006, 08:32
Ich würde dennoch tippen, daß Prellen ein Problem macht.
Evtl sind's auch offene Ports? Vielleicht hilft schon, die Pullups an D2..D4 zu aktivieren. Kommt drauf an, wie die Taster angeschlossen sind.

OCR1A sollte auch nicht über den Maximalwert gehen, den du einstellst für die PWM. Das wäre ein Tastverhältnis von über 100%.

Sternthaler
03.02.2006, 08:53
Hallo The_Darkside,
ich bin der Meinung, dass dein Programm einfach zu schnell ist.
Wenn ich das richtig sehe, dann prüfst du über die "if (PIND.."-Abfragen was denn da passieren soll.
Jedes mal, wenn du also in der whileschleife bist, erhöhst bzw. verringerst du den pwm_val-Wert wenn die jeweilige Bedingung das so will.

Für wie lange sind denn die einzelnen Bits in PIND gesetzt?
Kann es sein, dass deine Schleife so schnell ist, dass du den pwm-Val-Wert innerhalb kürzester Zeit mehrfach hochzählt und somit den Wertebereich wie von SprinterSB schon angekündigt überschreitest?
(Eigendlich überschreitest du den Wertebereich nicht, da von der 16-Bit-Variablen ja nur die letzten 8 Bit in das Register OCR1A übernommen werden. [So weit ich weiss ist das ein 8-Bit-Register])

Du solltest innerhalb der while-Schleife mal ein Sleep einbauen und nach der if-Konstruktion noch die Grenzen für den pwm_val bzw. das Register OCR1A prüfen und bei über- unterschreiten korrigieren.

The_Darkside
03.02.2006, 09:04
Meinem Verständnis nach sind die Bits in PIND solang gesetzt wie ich den Taster drücke.
Ich werde das Programm in den Abfragen mal verzögern und noch eine Bereichsüberprüfung machen

@SprinterSB
Bei externen Pullups, brauch ich doch die internen nicht, oder? Bzw. es würde nicht funktionieren, jedenfalls hab ich das so verstanden, ich hoffe ich irre mich nich?

Sternthaler
03.02.2006, 09:06
Viel Erfolg
Um Antwort wird gebeten ;-)

askazo
03.02.2006, 09:11
Für wie lange sind denn die einzelnen Bits in PIND gesetzt?
Kann es sein, dass deine Schleife so schnell ist, dass du den pwm-Val-Wert innerhalb kürzester Zeit mehrfach hochzählt und somit den Wertebereich wie von SprinterSB schon angekündigt überschreitest?

Das kann nicht nur so sein, das ist auf jeden Fall so.
Du wirst den Taster niemals so kurz betätigen können, dass die if-Abfrage nur einmal ausgeführt wird.

Zur Lösung des Problems könntest Du in der if-Abfrage solange warten, bis der Taster wieder losgelassen wurde:


if(PIND & (1<<2)) {
pwm_val+=10;
OCR1A = pwm_val;
while (PIND & (1 << 2))
; //do nothing
}

SprinterSB
03.02.2006, 09:14
Ja, ist wohl einfach zu flott dein Programm.

Die Taster sind wohl von vcc an den Port gelegt. Sind die offen, brauchst du einen Pulldown nach GND, damit die Ports nicht floaten.

Oder du hängst die Taster zwischen GND und Port. Dann brauchst du Pullups (intern oder extern). Dann dreht sich allerdings die Logik um, weil ein gedrückter Taster ne 0 liefert.

Pascal
03.02.2006, 09:17
(Eigendlich überschreitest du den Wertebereich nicht, da von der 16-Bit-Variablen ja nur die letzten 8 Bit in das Register OCR1A übernommen werden. [So weit ich weiss ist das ein 8-Bit-Register])

OCR1A ist ein 16-Bit-Register und setzt sich aus den beiden 8-Bit-Registern OCR1AH und OCR1AL zusammen.

The_Darkside
03.02.2006, 09:28
Ich probiere das heute Nachmittag/Abend mal aus und gebe dann die Ergebnisse bekannt.

:)

Danke erstmal

Sternthaler
03.02.2006, 19:36
OCR1A ist ein 16-Bit-Register und setzt sich aus den beiden 8-Bit-Registern OCR1AH und OCR1AL zusammen.

Danke für die Info, hatte ich wärend der Arbeit nicht parat. (siehe unten stimmt leider nicht immer)

The_Darkside
04.02.2006, 13:01
Also das war tatsächlich sio, das das Programm zu schnell war. Ich warte jetzt bis der Taster wieder losgelassen ist und es funktioniert perfekt.
Muss man erst mal drafkommen ;). Es war sicher auch nicht meine letzte Frage.

Danke nochmal