Hi... Ich hab ein Programm, was auf einem ATmega8 einige TLC5941 mit Daten versorgen soll. Das sind Chips mit denen man LEDs treiben kann... Der Controller läuft via externer Clock bei 16MHz (Fuses C9, D0) Er muss mehrere aufgaben erfüllen, damit die LED Treiber arbeiten: - Eingabe neuer Werte via SPI (12bit pro LED) - Generierung eines Takts für Counter in den Treibern - Statusleitungen Treiben Ich verwende avrlib zusätzlich zum WinAVR. Der Code in main.c ist in etliche Funktionen geteilt... Einige davon sind nur zur Initialisierung... Die Funktion "timer1CM" ist handler für das CompareMatch Interrupt des timer1 und sorgt für die generierung des besagten Takts und eines Update Pulses nachdem neue Daten zu den Treibern übertragen wurden. Sie nutzt dazu die beiden globalen Countervariablen "nGSCLKCycles" und "nUpdateTimeout" Die Daten werden in "main" (vorläufig) fortlaufend generiert -> wert hochzählen -> maximum erreicht -> runterzählen. Lange Rede, kurzer Sinn... das ganze geht irgendwie nicht. Es ist folgendes: Zur Generierung der Werte gibt es in main eine lokale Variable "nValue" (deklariert kurz vor der Endlosschleife), Initialwert ist 1. (Ich geb mir einige Debuginfos per UART aus...) Der Wert wird in "transferColorData" ins richtige Format gepackt und übertragen. Allerdings nur beim ersten mal richtig... Der output sieht so aus: init done sending value: schedule update Status: grayscale cycle running Status: grayscale cycle completed sending value: ¼ó¼óó0ó000ó0¼ó¼¼ó¼óó0ó000ó¼¼ó¼óó¼ó00ó0¼0ó¼¼ó¼óó¼ó00ó0¼0ó¼óó¼ó0¼ó0 0ó0¼óó¼ó¼¼ó0¼ó00ó0¼óó¼ó¼¼ó0óó00ó0¼ó¼¼ó¼óó0ó000ó0¼ó¼¼ó¼óó0ó000ó¼¼ó¼óó¼ó00 ó0¼0óôôÇ ZZÿ€j¼óó¼ó0¼ó00ó0¼óó¼ó¼¼ó0¼ó00ó0¼óóó schedule update Status: grayscale cycle running Status: grayscale cycle completed sending value: ó00ó0¼óó¼ó¼¼ó0óó00ó0¼óó¼ó¼¼ó0óó00ó0¼ó¼¼ó¼óó0ó000ó¼¼ó¼¼ó¼óó0ó000ó¼ ¼ó¼óó¼ó00ó0¼0ó¼óó¼ó¼¼ó00ó0¼0ó¼óó¼ó0¼ó00ó0¼óó¼ó¼¼ó0óó00ó0¼óó¼ó¼¼ó0óó00ó0¼ ó¼¼ó¼ôôÇ ZZÿ€aóó0ó000ó¼¼ó¼óó¼ó00ó0¼0ó¼óó¼ó¼¼¼ schedule update Status: grayscale cycle running Status: grayscale cycle completed Die Interruptabfolge ist hier allerdings richtig. Definier ich mir "nValue" als globale Variable im SRAM bleibt das Programm nach dem setzen des ersten Updates stehen (timer1CM funktioniert nicht mehr richtig) oder es kommt nur Matsch raus. Ich dachte mir, es gäbe evtl. ein Timing-Problem mit dem Interrupt und habe mal die Zählvariablen "nGSCLKCycles" und "nUpdateTimeout" als Register global definiert, dann geht aber auch nichts mehr. (Output ist nur noch matsch) Ich verwende SPI normalerweise auch mit Interrupts, es geht aber auch nicht wenn ich es ohne mache. Außerdem hab ich den Code mal testweise auf einen mega16L auf meinem STK500 geladen und da wird zwar kein Datenmatsch auf der UART ausgegeben, aber die Werte in nValue sind plötzlich mal ganz groß und dann ist es wieder der gleiche wie vorher... Könnte sich bitte mal jemand den Code ansehen und mir sagen, ob ich da einen riesen Fehler gemacht hab der mir noch nicht aufgefallen ist? merci, Martin.
Hallo, deklariere alle Variablen, die im Interrupt genutzt werden als volatile. Das verhindert, dass eine Optimierung des Compilers zu Fehlern führen kann. Gruß, Peter
@ Peter Diener (Gast) >deklariere alle Variablen, die im Interrupt genutzt werden als volatile. Nöö, das braucht man nur für die, welche sowohl im Interrupt als auch im Hauptprogramm verwendet werden. MFG Falk
hey ho... danke für den tipp. ich hab das für die betreffenden variablen gemacht und "nValue" endgültig in den globalen bereich verschoben: volatile uint16_t nGSCLKCycles; volatile uint8_t nUpdateTimeout; volatile uint16_t nValue = 1; // only 12bit used volatile struct { unsigned fNeedUpdate:1; unsigned fUp:1; } flags; der punkt ist: auf dem mega16L im STK500 gehts jetzt (mit internem RC oszi). auf meinem ATmega8 hat sich nichts verändert, sowohl nicht mit externer clock als auch nicht mit internem oszillator. ich werd mal versuchen die uart implementation direkt von winavr zu nutzen. theoretisch müsste es ja identisch sein, aber dann hab ich wenigstens die kontrolle über die einstellungen. hat sonst noch jemand eine idee? greets, Martin.
@ Martin Krellmann (mkrelli) >auf dem mega16L im STK500 gehts jetzt (mit internem RC oszi). Und UART? Naja. ABer das diskutiere ich nicht mehr. >auf meinem ATmega8 hat sich nichts verändert, sowohl nicht mit externer >clock als auch nicht mit internem oszillator. >Ich verwende avrlib zusätzlich zum WinAVR. Ich denke mal dass mit der avrlib was nicht stimmt. Falscher Controller eingestellt oder so. Die rprint GEschiten sehen mir verdächtige aus. Und das Kauderwelsch deutet darauf hin, dass Pointer ins Flash an die falsche Stelle zeigen. MFG Falk
Falk Brunner wrote: > Ich denke mal dass mit der avrlib was nicht stimmt. Falscher Controller > eingestellt oder so. die überlegung hatte ich auch. der controller sollte zwar richtig gewesen sein, aber ich habe meinen code erstmal soweit als möglich von der avrlib getrennt... d.h.: - ich hab ein neues makefile mit mfile gebaut - was ich aus der avrlib noch brauchte (timer.c, buffer.c, vt100.c) hab ich in mein eigenes verzeichnis kopiert und etwas abgeändert (typen geändert, z.b. u08 nach uint8_t) - die uart initialisiere und benutze ich komplett unabhängig von der avrlib (und via printf und stdout) - beim spi transfer hab ich auch die interruptnutzung deaktiviert... bis auf die timer läuft jetzt alles ohne interrupts ich stellte dannt fest, dass sich der controler nach dem ersten main-loop zurückgesetzt hat ---> watchdog war an. ich erziel damit jetzt schon wesentlich bessere ergebnisse. die zeichen werden sauber übertragen, nur die ausgabe von "nValue" (dem farbwert) klappt nicht - bzw. nur im ersten loop (auch wenn ich das so mache, wie im avr-gcc tut mit sprintf und nem stringbuffer) was kann da noch sein? greets, Martin. PS: ich hab den neuen code nochmal angehängt
hi leute... okay das problem hat sich erledigt. ich hab mir mal die neueste winavr version geladen und den code damit kompiliert. es geht jetzt. danke für die tipps greets, Martin.
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.