AVR-Butterfly: Mysteriöses Problem

Ich werde gerade wahnsinnig, weil es mir beim AVR Butterfly einfach nicht gelingt, den Joystick korrekt zu verwenden. Hoch, Runter und Knöpfchen drücken funktioniert einwandfrei, aber die Bits für Rechts und Links werden immer als '0' gelesen, verhalten sich also so, als wären die entsprechenden Richtungen dauerhaft betätigt.

Hier ein simpler Programmcode:

int main(void) { DDRE = 0; PORTE = _BV(PE2)|_BV(PE3); DDRB = _BV(DDB5);

while(1) { if ( (PINE & _BV(PINE3)) == 0 ) { PORTB ^= _BV(PB5); _delay_ms(1); } } }

Nach der Logik müßte aus dem Piezo ein Ton erklingen, sobald der Joystick nach rechts bewegt wird. Wenn ich statt PIN3 und PINE3 z.B. PINB und PINB4 einsetze (Knopfdruck) funktioniert es auch entsprechend. Bei obiger Variante erklingt der Ton aber konstant.

Irgendne Idee? Ich verzweifele.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt
Loading thread data ...

Hallo,

ich kenn mich jetzt beim Butterfly zwar nicht aus, aber hat es einen Grund, dass du einmal _BV(PE2) und _BV(PE3) benutzt und weiter unten dann _BV(PINE3)?

Mfg Thomas Pototschnig

formatting link

Reply to
Thomas Pototschnig

Ach ja wie dumm .. vermutlich ist PE3 einfach für'n PORTE und PINE3 von PINE

Sorry - dann kann ich dir auch nicht helfen :-)

Mfg Thomas Pototschnig

formatting link

Reply to
Thomas Pototschnig

Richtig. Wobei sowieso PE3 == PINE3 == 3.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Michael Holzt schrieb:

Musst Du eventuell noch den internen Pullup aktivieren? Weiss jetzt nicht wie der Joystick angebunden ist...

Gerald

Reply to
Gerald Oppen

Was hängt denn dran und wie sind die Ports initialisiert? Pullup/down Widerstände dran? Messwerte?

Gruss

Robert

--
'Vom Standpunkt eines Beamtenrechtlers aus betrachtet ist der Tod die 
schärfstwirkenste aller bekannten, langfristig wirkenden Formen der 
 Click to see the full signature
Reply to
R.Freitag

Wie dem Sourcecode zu entnehmen war, wird der Pullup aktiviert. Es kann am entsprechenden Anschluß des Joysticks auch eine Spannung von 2.7 Volt gemessen werden, dennoch wird ein '0' Signal gelesen. Übrigens bleibt die Spannung auch, wenn man Pullup ausschaltet. Ich begreifs nicht.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Moin!

PINE = Adresse von Port INput E.

PINE3 = keine Ahnung was der Compiler draus macht.

Bit 3 an Port E wäre PE3!

Gruß, Michael.

Reply to
Michael Eggert

Unsinn. PINE3 == PE3 == DDE3 = 3. Sind alles von der avr-libc mitgebrachte Makros. Auch wenn man die Bezeichnungen mischen kann - also z.B. PINE mit PE3, ist sauber eigentlich PINx mit PINxy, PORTx mit Pxy und DDRx mit DDxy.

Das ist auf jeden Fall nicht das Problem.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Hi!

Is ja gut, bin jetzt auch aufgewacht. :-)

Hätte noch vermutet, daß der Compiler schon bei PINE anspringt und erstmal das übersetzt, aber es kommt tatsächlich das gleiche bei raus.

Ansonsten wär noch möglich gewesen, daß Du die Pullups erst zu kurz vor der Abfrage aktivierst, ist in diesem Beispiel aber wohl auch nicht der Fall.

Gruß, Michael.

Reply to
Michael Eggert

Michael Holzt schrieb:

Hast Du auch den passenden uC ausgewählt?

Was macht den _BV(PINE3)? Eine 1 um drei stellen nach links schieben?

Gerald

Reply to
Gerald Oppen

Ja. Es sieht auch im Assemblercode sauber aus.

Ja. Makro im avr-gcc.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Ja. Es sieht auch im Assemblercode sauber aus.

Ja. Makro in der avr-libc.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Michael Holzt schrieb:

Warum hast Du eigentlich ein "int" vor dem Main stehen?

Gerald

Reply to
Gerald Oppen

Gerald Oppen schrieb:

Weil das in C so ist. Gültige Prototypen für main() sind:

int main(void); int main(int, char **);

Alles andere ist kein C.

OK, genaugenommen gilt das nur für eine hosted application. Man könnte sich auf den Standpunkt stellen, dass man es bei einem Controller ja mit einer freestanding application zu tun hätte... Aaaber, ganz so einfach ist das nicht. Erstens ist main() dann überhaupt nicht mehr gesondert zu behandeln (hmm, man müsste theoretisch erstmal dem Compiler sagen, wo er anfangen soll), zweitens haben wohl alle Microcontroller-C-Umgebungen einen guten Anteil der Standardbibliothek mit dabei, und *da* fängt natürlich die Grenze wieder an zu verschwimmen. Fazit: man tut ganz gut daran, sich auch bei einem Controller an die Regeln für eine hosted application zu halten. Dann kann der Compiler nämlich auch aus sowas:

#include #include

uint8_t a, b; ... memcpy(a, b, sizeof(a));

statt eines Funktionsaufrufes direkt den Code generieren und ähnliche Optimierungen durchziehen, die er nur in einer hosted application aufgrund seiner internen Kenntnis der Standardbibliothek machen darf.

(Obiges hat es mir vor zwei Tagen erspart, in einem umfänglichen switch statement, das sich automatisch generieren ließ, eine Sonderbehandlung für die einzelnen vorkommenden Datentypen zu bauen, memcpy() genügt, der Compiler sucht sich die für den jeweiligen Typ effektivste Implementierung aus.)

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
 Click to see the full signature
Reply to
Joerg Wunsch

Richtig, wobei prinzipiell bei einer uC-Anwendung ein Rückgabewert nicht wirklich Sinn macht. Aber ANSI-C fordert es, und der Compiler meckert über ein fehlendes return auch nicht - außer man hat versehentlich das Programm so gestaltet, daß es sich doch beenden kann - was es nicht sollte.

Allerdings wäre ich viel mehr an einer Erklärung (und Lösung) für mein Problem interessiert. Ich kann so langsam nicht mehr erkennen, woran es liegt. Mysteriöse Umstände: Pull-Up bleibt an, auch wenn er abgeschaltet wird. Obwohl Pull-Up an, und physikalisch 2.7V zu messen sind, wird im Register nur eine '0' zurückgeliefert. Ich begreifs nicht.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Michael Holzt schrieb [...]

Hmm,

soweit ich weiß und mehr nicht, gips für die Ports vier Möglichkeiten:

Input / mit oder ohne Pullup Output ohne Pullup / Gegentaktausgang log 1 oder 0

Hast Du das mal durchgehechelt?

Gruß Peter

Reply to
Peter Thoms

Wie dem von mir geposteten Code zu entnehmen ist, wird der Betriebsmodus der entsprechenden Pins korrekt auf Eingang und aktivierten Pull-Up programmiert.

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Ich habe eine Lösung für mein Problem gefunden, aber ich verstehe sie nicht. Und zwar werden zwei Zeilen wie folgt einfügt:

PCMSK0 = _BV(PINE2); EIMSK = _BV(PCIE0);

Nach meinem Verständnis schalten diese den Pin-Change-Interrupt ein. Ich verwende diesen aber überhaupt nicht, und es hilft auch, wenn die Interrupts mit cli() abgeschaltet wurden. Dem Datenblatt konnte ich keine Seiteneffekt entnehmen, die dies begründen könnten, aber es muß offenbar welche geben. Irgendjemand eine Idee?

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

Ok, ich habs.

Kann ersetzt werden durch DIDR1=0;

Offenbar werden um vermeintlich Energie zu sparen im Original-Bootloader des Butterfly die digitalen Eingabe-Buffer von AIN0 und AIN1 (also eben genau die zwei Port-Pins an denen die Joystick-Richtungen links und rechts hängen) abgeschaltet. Diese Abschaltung ist aber totaler Schwachsinn, weil sowohl im Bootloader wie in der Original-Applikation für diese beiden Pins der Pin Change Interrupt eingeschaltet wird, der just die digitalen Eingabe-Buffer wieder einschaltet.

Daher lässt sich mein Problem lösen, in dem ich entweder eben die Pin Change Interrupts aktiviere, oder alternativ die völlig blödsinnige Programmierung von DIDR1 korrigiere. Schlußendlich ist also Atmel Schuld, weil sie Quatsch im Bootloader programmiert haben :-)

--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit 
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Reply to
Michael Holzt

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.