Hallo
Ich wollte mir ein Board bauen auf dem ungefähr ind er Mitte ein LCD ist
und drumherum 32 Leds, einzeln über 2 16er Multiplexer ansteuerbar.
Gesteuert werden sollte das ganze mit einem AtMega8 der mit 12 Mhz
läuft. Über Taster sollte jetzt nun entweder der derzeitige Effekt der
Leds festgestellt werden oder der Text der über das Display läuft
geändert werden. Ich habe noch einen Weiteren Taster für eine eventuelle
andere Erweiterung eingebaut. Mit den Effekten der Leds und dem
Ansteuern vom Lcd hat alles funktioniert. Ich muss dazu sagen dass das
mein erstes richtiges Programm in C ist allerdings mein Bruder etwas C
kann und mir deswegen geholfen hat. Mein Problem ist nun, dass wenn ich
den entsprechenden Taster drücke nichts passiert, im Gegenteil sogar, da
ich den ersten Taster dafür verwenden wollte um den Text zu ändern hab
ich mit dem auch angefangen. Nun ändert sich der Text allerdings auch
wenn ich den Taster garnicht drücke. Aber auch wenn ich ihn drücke
passiert nicht anderes. ICh hab schon ein paar andere Sachen probiert,
vorher hatte ich die Textänderung auch nicht in einem Unterprogramm
sondern in Main stehen. Kann mir Jemand bitte helfen???? Ich weiß
nichtmehr weiter und bin am verzweifeln.
Liebe Grüße
Nils
Deine Taster schalten nach Masse?
Hast du einen externen Pullup Widerstand?
Wahrscheinlich nicht. Das heißt du musst zumindest den internen Pullup
Widerstand einschalten. Ansonsten hast du einen Eingang der buchstäblich
bei nicht gedrücktem Taster in der Luft hängt und nur Gott alleine weiß,
welchen Zustand der dann annimmt, aber der sagt nichts.
Das ist das eine.
Das andere ist:
if (!(PINB & (1<<PINB1)));
{
Textaenderung();
}
Dir muss klar sein, dass das keine Abfrage ist: Wenn eine Taste gedrückt
wird.
Das ist eine Abfrage, ob eine Taste gedrückt ist!
Der UNterschied ist in etwa so, wie der Unterschied von deiner
TV-Fernbedienung, bei der ein Tastendruck um 1 Kanal weiterschaltet und
einer Rollosteuerung bei der das Rollo rauf/runter fährt solange die
Taste gedrückt ist und stehen bleibt, wenn du die Taster wieder
loslässt.
Du willst ersteres, hast aber letzteres programmiert.
PS.
Dein Programm ist ein Kraut und Rüben Sammelsurium von Testcode. Du
solltest mit einem neuen Testprogramm anfangen. Schön langsam wirds
unübersichtlich.
Denn: Deine neu gewünschte Funktionalität (Tastendruck erkennen) ist gar
nicht so einfach zu realisieren.
Habe 10k Pulllup Widerstände udn auch nachgemessen, wenn taster nicht
gedrückt wird, 5V und wenn er gedrückt wird bin ich bei 0V also masse.
Habe vorher in Assembler programmiert bin aber jetzt umgestiegen weil
mir jemand gesagt hätte C wäre bei diesem Projekt einfacher, da ich auch
noch niicht sehr viel in Asm gemacht hatte. Wie könnte ich das denn mit
"TV-Fernbedienungseffekt" programmieren? dann müsste der doch am besten
warten wenn ein taster gedrück wird und ert umschalten wenn der wieder
losgelassen wird oder? aber wie mache ich das denn denn wenn ich mache 1 | if (!(PINB & (1<<PINB1)));
| 2 | {
| 3 | if (PINB&(1<<PINB1));
| 4 | {
| 5 | Textaenderung();
| 6 | }
| 7 | }
|
dann springt der doch sofort wieder weg wenn ich den Taster nicht
innerhalb kürzester Zeit wieder loslasse oder?
Nils Wiechert schrieb:
> Habe 10k Pulllup Widerstände udn auch nachgemessen, wenn taster nicht
> gedrückt wird, 5V und wenn er gedrückt wird bin ich bei 0V also masse.
OK.
Dann brauchst du natürlich keinen internen Pullup
> losgelassen wird oder? aber wie mache ich das denn denn wenn ich mache
> 1 | > if (!(PINB & (1<<PINB1)));
| 2 | > {
| 3 | > if (PINB&(1<<PINB1));
| 4 | > {
| 5 | > Textaenderung();
| 6 | > }
| 7 | > }
| 8 | >
|
> dann springt der doch sofort wieder weg wenn ich den Taster nicht
> innerhalb kürzester Zeit wieder loslasse oder?
Richtig.
So schnell kannst du nicht drücken und loslassen.
Ich ignoriere jetzt erst mal etwas, was das ganze zu Fall bringen wird:
Die while Schleife ist schon erfunden!
Wenn in der Hauptschleife festgestellt wird, dass eine Taste gedrückt
ist, dann gehts in das if hinein. Und dort wartest du in einer Schleife
solange, bis die Taste wieder losgelassen wird
1 | if (!(PINB & (1<<PINB1)));
| 2 | {
| 3 | while( !(PINB&(1<<PINB1))
| 4 | ;
| 5 | Textaenderung();
| 6 | }
|
Probiers ruhig aus.
Wie gesagt, ich hab hier etwas ignoriert, welches dieses Vorgehen
(abgesehen vom Warten) zu Fall bringt: Tasten prellen.
Eine saubere Entprellung, die auch gleich noch die anderen Schwachpunkte
der Einfachstlösung behebt, findet sich hier.
http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
DIckes fettes danke werde ich gleich ausprobieren
Zum Prellen: Im tutorial steht, dass man einfach eine Pause von 100ms
oder so einfügen soll... Hab ich bisher aber nicht gemacht, weil mir 100
ms etwas lange vorkommen und ich beim ausprobieren eigentlich nicht
wollte dass 100ms lang etwas nicht normal funktioniert und ich jedesmal
nen schock bekomme bis mir einfällt dass das die Pause wegen dem
entprellen ist. Oder gibt es eine besere Methode?
Liebe Grüße:
Nils
Nils Wiechert schrieb:
> DIckes fettes danke werde ich gleich ausprobieren
> Zum Prellen: Im tutorial steht, dass man einfach eine Pause von 100ms
> oder so einfügen soll... Hab ich bisher aber nicht gemacht, weil mir 100
> ms etwas lange vorkommen
100ms sind etwas lang. 20ms sollten auch reichen. Muss man aber
ausprobieren. Hängt von den Tastern ab.
> und ich beim ausprobieren eigentlich nicht
> wollte dass 100ms lang etwas nicht normal funktioniert
100ms ist eine Zehntelskunde. Auch wenn diese Zeit aus µC Sicht ziemlich
kurz ist, aus Benutzersicht wird es wohl kaum jemand bemerken, der es
nicht weiß.
> und ich jedesmal
> nen schock bekomme bis mir einfällt dass das die Pause wegen dem
> entprellen ist. Oder gibt es eine besere Methode?
http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
Ist aber schon etwas anspuchsvoll. Allerdings ist das Code von dem du
als Einsteiger nicht wissen musst wie er funktioniert. Wichtig ist nur,
dass er funktioniert. Und das tut er erstklassig.
Habe erst jetzt den Link gesehen^^
Aber jetzt ist immer noch nicht das Problem behoben, dass mein
Controlelr wie verrückt zwischen den Texten wechselt... aber das kann
doch eigentlich garnicht sein...
Ich versteh die Welt nichtmehr...
Naja, statt den Taster zu pollen, wäre ein Interrupt die sinnvollere
Methode um nicht Rechenzeit zu vergeuden.
Nils Wiechert schrieb:
> Aber jetzt ist immer noch nicht das Problem behoben, dass mein
> Controlelr wie verrückt zwischen den Texten wechselt... aber das kann
> doch eigentlich garnicht sein...
Dein Programm sieht jetzt wie aus?
(Wie gesagt: Fang ein frisches Programm an. Dein jetziges ist schon
Kraut und Rüben. Da blickt keiner mehr durch, ob es nicht irgendwelche
Nebeneffekte gibt)
Hatte ich auch schon überlegt aber so wie ich das dann gesehen habe
können nur bestimmte Pins am uC nen interrupt auslösen und die sind
leider schon belegt...
Habe mich vertan, es passiert etwas, aber immernoch falsch, wenn ich den
Taster drücke machen die Leds nichtsehr und dann erst scrollt der Text
durch.
Und auch einmaliges Drücken des Tasters bringt nichts.
Nils Wiechert schrieb:
> Hatte ich auch schon überlegt aber so wie ich das dann gesehen habe
> können nur bestimmte Pins am uC nen interrupt auslösen und die sind
> leider schon belegt...
Pssst.
Man nimmt auch keine Interrupts für Tasten her. Das bringt mehr Ärger
als es wert ist. Einzige Ausnahme: wenn man den µC mit einer Taste aus
dem Tiefschlaf aufwecken muss.
Nils Wiechert schrieb:
> Habe mich vertan, es passiert etwas, aber immernoch falsch, wenn ich den
> Taster drücke machen die Leds nichtsehr und dann erst scrollt der Text
> durch.
> Und auch einmaliges Drücken des Tasters bringt nichts.
Ich kann mich nur wiederholen:
Mach ein neues Testprogramm. Deines ist schon extrem unübersichtlich.
Und tu dir selbst einen Gefallen und verwende sprechende Variablennamen.
Alles klar mach ich. Darf ich mich dann nochmal melden? :P
SOll ich die UNterprogramme dann vor oder nach Main amchen?
Nils Wiechert schrieb:
> Alles klar mach ich. Darf ich mich dann nochmal melden? :P
> SOll ich die UNterprogramme dann vor oder nach Main amchen?
Davor. Ist einfachen.
Dein erstes Programm mit einer Taste könnte sein:
Eine (!) LED mit einem Tastendruck einschalten.
Dieselbe LED mit dem nächsten Tastendruck wieder ausschalten.
Nicht mehr. Das reicht schon, damit du eine Tastenauswertung in Aktion
siehst.
Dein Fokus in diesem Testprogramm liegt ja auf der Auswertung eines
Tastendrucks und nicht darauf, was dann alles passieren soll.
Alles klar dann kram cih mein atmega16 lernboard mal wieder raus :P
Nils Wiechert schrieb:
> Alles klar dann kram cih mein atmega16 lernboard mal wieder raus :P
Wozu?
Du hast doch ein Board auf dem 1 Taster und mindestens 1 Led sitzt.
Ignorier doch einfach den Rest :-)
Hm so wie ich das sehen sollte das jetzt bei nem Tastendruck die
Variable Leddefinition ändern. und danach die Led entweder ein oder
ausschalten... aber irgendwie hab ich was falsch gemacht. Hängt das
irgendwie damit zusammen dass das ein/ausschalten in nem eigenen
Unterprogramm ist?
LG
Nils
Nur kurz drübergeschaut
if (!(PINB&(1<<PINB0)));
was macht der Strichpunkt da am Ende?
fehl am platze sein :D
Aber auch ohne wills net richtig funktionieren
1 | void zustandaendern (void)
| 2 | {
| 3 | if (Leddefinition == 0)
| 4 | {
| 5 | Leddefinition = 1;
| 6 | }
| 7 | else
| 8 | {
| 9 | Leddefinition = 1;
| 10 | }
| 11 | ledschalten();
| 12 |
| 13 | }
|
Du setzt in beiden Fällen Leddefinition auf 1.
Schreibs so: 1 | void zustandaendern (void)
| 2 | {
| 3 | Leddefinition = 1 - Leddefinition;
| 4 | ledschalten();
| 5 | }
|
oder so 1 | void zustandaendern (void)
| 2 | {
| 3 | Leddefinition ^= 0x01;
| 4 | ledschalten();
| 5 | }
|
dann passiert dir sowas nicht mehr. Du hast für eine einfache
Funktionalität ( 1 Bit toggeln ) zu viel Code produziert, so das du die
Übersicht verloren hast. Ansonsten wär dir der Copy&Paste Fehler selbst
aufgefallen :-)
hab grad ma mein Programm bei Avrstudio simuliert... unglaublich dass
ich mit sowas simplem wie einer Tasterabfrage nen ganzen Tag
verbringe... naja egal... ich habe jetzt den code: 1 | int main (void)
| 2 | {
| 3 | while (1)
| 4 | {
| 5 | if (!(PINB&(1<<PINB0)));
| 6 | {
| 7 | while (!(PINB&(1<<PINB0)));
| 8 | {
| 9 | }
| 10 | zustandaendern();
| 11 | }
| 12 | }
| 13 | return 0;
| 14 | }
|
also nur die main... der kommt aber nie weiter als bis zum while... also
wenn ich PINB0 im Simulator auf 1 setzt dann wechselt der immer zwischen
if und while, aber eigentlich soll der ja bei einer 1 aus der while
schleife rausspringen und zustandaendern ausführen.
Oder sehen ich das mal wieder falsch???????
Ich bin echt am verzweifeln...
Lg
Nils
Du hast
if (!(PINB&(1<<PINB0)));
den Strichpunkt immer noch drinnen.
Sei ein bischen sorgfältiger
PS: Hier
while (!(PINB&(1<<PINB0)));
ist ebenfalls ein überflüssiger ;
In deinem jetzigen Programm wirkt er sich aber nicht aus, insofern hast
du Glück gehabt.
Mann ich Idiot...
aber jetzt springt der wenn ich das Bit an PINB setzte trotzdem wieder
zum IF und nicht zur Zustandsänderung
Nils Wiechert schrieb:
> Mann ich Idiot...
> aber jetzt springt der wenn ich das Bit an PINB setzte trotzdem wieder
> zum IF und nicht zur Zustandsänderung
Kein Wunder: Du fragst ja auch ab, ob der Pin zu 0 wird.
Dein Ruhezustand ist: Pin ist 1
Wenn du eine Taste drückst, wird der Pin zu 0.
Du musst im Simulator schon das nachstellen, was auch in Wirklichkeit
passiert, wenn du eine Taste drückst.
Schon vergessen?
<Zitat>
Habe 10k Pulllup Widerstände udn auch nachgemessen, wenn taster nicht
gedrückt wird, 5V und wenn er gedrückt wird bin ich bei 0V also masse.
</Zitat>
Das ist mir klar... Ich kann ja im SImulator bei PINB die Kästtchen
füllen... aber wenn ich das kästchen leer mache bleibt er beim while und
wenn ich es dann wieder fülle (also die 1) dann springt er wieder zum if
und nicht zur Zustandsaenderung... DAS ist mein Problem im Moment.
Nils Wiechert schrieb:
> unglaublich dass
> ich mit sowas simplem wie einer Tasterabfrage nen ganzen Tag
> verbringe...
Diesen Fehler machen leider auch viele Profis, sie halten Tastenabfrage
für simpel, einer ordentlichen Programmierung nicht würdig.
Daher sieht man leider auch so viele kommerzielle Geräte mit Problemen,
z.B. Prellen, Drücke gehen verloren, Reaktion ohne Drücken
(elektrostatische Störungen), Programm hängt bei langem Drücken und
vieles ander mehr.
Es gibt aber bereits ausgereifte fertige Lösungen. Daher sollte man
nicht versuchen, das Fahrrad nochmal zu erfinden. Weder die
Funktionssicherheit noch die Effizienz wird man nicht in unter 2 Wochen
erreichen.
Beitrag "Universelle Tastenabfrage"
Peter
Nils Wiechert schrieb:
> Das ist mir klar... Ich kann ja im SImulator bei PINB die Kästtchen
> füllen... aber wenn ich das kästchen leer mache bleibt er beim while und
> wenn ich es dann wieder fülle (also die 1) dann springt er wieder zum if
> und nicht zur Zustandsaenderung... DAS ist mein Problem im Moment.
Dann hast du noch irgendwo einen Fehler in der Schreibweise.
(Den Optimizer hast du ausgeschaltet?)
Peter Dannegger schrieb:
> Nils Wiechert schrieb:
>> unglaublich dass
>> ich mit sowas simplem wie einer Tasterabfrage nen ganzen Tag
>> verbringe...
>
> Diesen Fehler machen leider auch viele Profis, sie halten Tastenabfrage
> für simpel, einer ordentlichen Programmierung nicht würdig.
Ich bin grundsätzlich 100% bei dir.
Sein Problem ist aber, dass er als Neuling noch zu schlampig arbeitet
und dann natürlich eine Menge Zeit darauf draufgeht, die selbst
eingebauten Schlampigkeitsfehler zu finden.
> Es gibt aber bereits ausgereifte fertige Lösungen. Daher sollte man
> nicht versuchen, das Fahrrad nochmal zu erfinden. Weder die
> Funktionssicherheit noch die Effizienz wird man nicht in unter 2 Wochen
> erreichen.
Da'cor (oder wie das heisst)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|