Hallo. Ich habe folgendes Problem: Habe ein Testprogramm welches mit Tasterabfragung läuft. Programm wartet bis 2 Taster zugleich gedrückt sind, soll dann einen Port anschalten oder auschalten. Beim Testen auf dem STK500 lief es perfekt. Auf meiner Platine aber weigert sich der Prozessor auf die Taster zureagieren. Ich bin verwirrt... Wenn die internen Pullups den Pin auf high ziehen, warum funzt das dann auf dem STK500??? Muss man bei internen Pullups die gewünschte Pinbelegung "invertieren"? Ratlose Grüße, mct3
Zeig mal bitte dein Programm und den Schaltplan deiner eigenen Platine. Daran lässt sich das Problem mit Sicherheit erkennen.
Beim STK500 hast du externe Pullups. Hast du bei deinem Board die internen aktiviert? Schalten deine Schalter auch nach Masse? Durch die Pullups hast du immer eine 1 am Pin, beim Tasterdrücken wechselt er dann auf 0. Also musst du auf 0 testen wenn du wissen willst ob ein Taster gedrückt ist.
Habe die erwartete Pinbelegung umgedreht, funktioniert auf dem STK500 genauso wenig, wie auf der Platine. Taster schalten nach ground. auf dem STK500 weiß ich es nicht. Wie kann das Programm eigentlich richtig reagieren, wenn interne Pullups und externe dran sind?
Kopier doch einfach mal das Programm hierein, dann sehen wir, ob die internen Pullups richtig geschalten werden. Interne und externe Pullups zusammen funktionieren im Regelfall ohne Probleme. Aber wenn in deiner Schaltung keine externen Pullups drin sind und die internen nicht richtig aktiviert wurden, dann geht dein Programm auf dem STK500, aber auf deiner Platine nicht. Kannst du den Port auf deiner Platine an- und ausschalten und die Abfrage der Tester mal lassen. Nur um zu schauen, dass der Port richtig angeschlossen ist (LEDs??).
Wenn das mit den internen Pullups nicht geht, kann ich ja auch externe Pulldown Widerstände verwenden. das Programm bleibt das gleiche ohne die internen.
Das Programm ist top secret! Damit will er die Weltherrschaft an sich reißen!
Ich habe das Programm nicht vollständig selber entwickelt. Ich hatte Hilfe, da ich eher C++ kann und in C nicht so. aber bitte: #include <avr/io.h> #include <inttypes.h> #ifndef F_CPU # define F_CPU 4000000UL #endif #include <util/delay.h> /* bei alter avr-libc: #include <avr/delay.h> */ uint8_t debounce(volatile uint8_t *port, uint8_t pins, uint8_t _value) { if ( !(*port & pins & _value)) { _delay_ms(10); // kurze Zeit warten _delay_ms if ( *port & pins & _value) { /* Anwender Zeit zum Loslassen des Tasters geben */ _delay_ms(10); return 1; //wenn alles stimmt, wird die Funktion true } } return 0; } int main(void) { DDRB &= 0x00;//Port B wird als Eingang definiert. PORTB |= 0xff;/* Pullup-Widerstand aktivieren */ DDRA = 0xff;//PortA als Ausgang definieren PORTA = 0x00; while(1) { if (debounce(&PINA, PORTA, 0b00000101))//ist das Ergebnis true? { PORTA = 0xff; } if (debounce(&PINA, PORTA, 0b00000110)) { PORTA = 0x00; } } }
Was'n das
1 | uint8_t debounce(volatile uint8_t *port, uint8_t pins, uint8_t _value) |
2 | {
|
3 | if ( !(*port & pins & _value)) |
4 | ...
|
Ich würde mal sagen, du hast eine Vorlage kaputtprogrammiert. Zurück an den Start und noch mal von vorne (so lernt man) Weiters solltest du dich mit dir selbst einigen, ob deine Taster nun am Port A oder am Port B hängen. > Ich hatte Hilfe, da ich eher C++ kann und in C nicht so. Das macht nichts. Bitmanipulationen funktionieren in C++ auch nicht anders als in C. Bitmanipulation Auch du wirst nicht umhin kommen und dir die Grundlagen aneignen müssen. Entprellung
die grundlagen kenn ich. aber da steht nicht, wie man die Kombination aus zwei Tastern abfragt... so funktioniert das ja. Ach und portb oder porta als eingang ist nicht weiter ernst zunehmen, das war schon geändert, aber nicht in dieser Version.
mc t3 schrieb: > die grundlagen kenn ich. aber da steht nicht, wie man die Kombination > aus zwei Tastern abfragt... eventuell, indem man 2 mal hintereinander debounce aufruft mit der Angabe der jeweiligen Taste? Und dann die beiden Ergebnisse miteinander verknüpft? Man kann natürlich auch analysieren, wie denn dieses debounce eigentlich funktioniert und dann das zweite Argument beim Aufruf so anpassen, dass man beide Tasten in einem Aufwasch abfrägt. Falls das überhaupt möglich ist. Aber das ergibt dann die Analyse ob das geht oder nicht. Letzterer Weg wäre insofern besser, weil man dann seine Fähigkeiten schult anstelle von fertigem Code übernehmen und sich dann fragen warum nichts geht. Und seien wir mal ehrlich: Der debounce Code, von dem du ausgegangen bist ist so kompliziert nun auch wieder nicht. Aber dazu muss man eben mit den Bitoperationen umgehen können. > Ach und portb oder porta als eingang ist nicht weiter ernst zunehmen, > das war schon geändert, aber nicht in dieser Version. Schön. Da stehen wir alle drauf, wenn du Code postest, der nicht dem entspricht, den du auf dem µC laufen lässt.
> Schön. Da stehen wir alle drauf, wenn du Code postest, der nicht dem > entspricht, den du auf dem µC laufen lässt. Was wäre denn eine Suppe ohne Salz? ;)
Ich habe auf die internen Pullups verzichtet und "Pull-Down-Widerstände" angehängt. Es funktioniert nicht!?!?
mc t3 schrieb: > Ich habe auf die internen Pullups verzichtet und "Pull-Down-Widerstände" > angehängt. Da passt jetzt aber dein Debounce nicht mehr dazu. > Es funktioniert nicht!?!? Dann wirst du das Umschreiben müssen. Erst mal das Debounce an deine Tasten anpassen und mit EINER Taste testen. Dann gehts weiter zu mehreren Tasten. Setz dich auf deinen Hintern und analysiere, wie das hier
1 | inline uint8_t debounce(volatile uint8_t *port, uint8_t pin) |
2 | {
|
3 | if ( !(*port & (1 << pin)) ) |
4 | {
|
5 | /* Pin wurde auf Masse gezogen, 100ms warten */
|
6 | _delay_ms(50); // Maximalwert des Parameters an _delay_ms |
7 | _delay_ms(50); // beachten, vgl. Dokumentation der avr-libc |
8 | if ( *port & (1 << pin) ) |
9 | {
|
10 | /* Anwender Zeit zum Loslassen des Tasters geben */
|
11 | _delay_ms(50); |
12 | _delay_ms(50); |
13 | return 1; |
14 | }
|
15 | }
|
16 | return 0; |
17 | }
|
eigentlich funktioniert und dann ist der Rest ein Kinderspiel.
Ich kenne mich wie schon gesagt mit C nicht so aus. Das betrifft vorallem die Logikoperatoren und Bedingungen. Was ist eigentlich gegen meine debounce einzuwenden?
und warum funktioniert das ganze auf dem STK500 mit Pullups, wenn der Controller doch eigentlich auf einen high-pegel wartet???? und warum funktioniert das dann nicht auf meiner platine???
mc t3 schrieb: > Ich kenne mich wie schon gesagt mit C nicht so aus. Das betrifft > vorallem die Logikoperatoren und Bedingungen. Genau aus dem Grund hab ich dir oben die Links gegeben. Nochmal Bitmanipulationen AVR-Tutorial AVR-GCC-Tutorial > Was ist eigentlich gegen meine debounce einzuwenden? Für jemanden der angeblich C++ (also programmieren) kann, ist das eine seltsame Frage.
mc t3 schrieb: > und warum funktioniert das ganze auf dem STK500 mit Pullups, wenn der > Controller doch eigentlich auf einen high-pegel wartet???? > und warum funktioniert das dann nicht auf meiner platine??? Wenn etwas scheinbar funktioniert, heißt das noch lange nicht, dass es richtig ist.
Also. Ich habe überhaupt keine Ahnung was an dieser Funktion nicht gut sein soll. Ich habe die Funktion übernommen von jemandem, der avr programmierung als beruf gemacht hat, von daher bin ich ausgegangen das wäre korrekt. Was soll denn daran nicht funktionieren???
Hallo nochmal. Ich habe mal die Ratschläge befolgt und selber ein Programm geschrieben. Es funktioniert bestens. vielen Dank schon mal. :D
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.