hallo, ich stehe bei einem Programmierproblem total auf dem Schlauch. In einem C Programm (Atmega 328P über ISP mit AtmelStudio 6) speichert mir mein Programm einfache Arraywerte falsch und ich find den Fehler nicht! eigentlich lasse ich nur über diese Billo-Funktion: void fill_pwm_values() { for (uint8_t j = 0; j < 16; j++) { pwm_values[j] = 100; } } ein array beschreiben, welches global so uint16_t pwm_values[16]; definiert ist. Genutzt wird das Array dann so: void create_pwm_values_for_spi() { uint8_t counter = 0; fill_pwm_values(); for (uint8_t i = 0; i < 16; i += 2) { pwm_values_for_spi[counter] = ((pwm_values[i] & 0x0ff) >> 4); pwm_values_for_spi[counter+1] = ((pwm_values[i] & 0x0f) << 4) | (pwm_values[i+1] >> 8); pwm_values_for_spi[counter+2] = (pwm_values[i+1]) << 8; counter += 3; } } Lasse ich mir jetzt über die watch die Werte anzeigen, zeigt er mir irgendwelche 16bit Werte an (pwm_value[0] = 50197, pwm_value[1] = 287, pwm_value[2] = 8224, pwm_value[3] = 0, pwm_value[4] = 7876 ...) Wenn ich meine Funktion einzeln in ATMEL-Studio teste, zeigt mir die watch die richtigen Werte an. Was ist denn da los? Die Werte ändern sich auch dauernd. Im Anhang mein Test-Code, es muss irgendwie an dem liegen, aber ich find den Fehler nicht. Ist bisher nur Testcode, es speichert eigentlich nur ein 16-bit-Array, zerlegt die 16bit-Werte SPI-kompatibel in 8bit und sendet diese an den TLC. Über den Timer wird ein Takt erzeugt und mitgezählt, brauch ich für die Ansteuerung des TLC5940. Ob das alles schon so funktioniert weiß ich nicht, weil ich ja schon vorher stecken bleibe... Danke für etwaige Hilfe, c.
blinksdinks schrieb: > pwm_values_for_spi[counter] = ((pwm_values[i] & 0x0ff) >> 4); > pwm_values_for_spi[counter+1] = ((pwm_values[i] & 0x0f) << 4) | > (pwm_values[i+1] >> 8); > pwm_values_for_spi[counter+2] = (pwm_values[i+1]) << 8; Was machst Du da? Was soll das bewirken?
blinksdinks schrieb: > pwm_values_for_spi[counter+2] = (pwm_values[i+1]) << 8; Mit pwm_values[i+1] greift Du bei i == 15 hinter Dein Array, was schon mal nicht stimmen kann. Edit: OK, sehe gerade, dass Du in der Schleife immer um 2 hochzählst und die Schleife somit nur bis 14 zählt.
:
Bearbeitet durch User
sorry fürdie blöde formatierung oben, hier besser: void create_pwm_values_for_spi() { uint8_t counter = 0; fill_pwm_values(); for (uint8_t i = 0; i < 16; i += 2) { pwm_values_for_spi[counter] = ((pwm_values[i] & 0x0ff) >> 4); pwm_values_for_spi[counter+1] = ((pwm_values[i] & 0x0f) << 4) | (pwm_values[i+1] >> 8); pwm_values_for_spi[counter+2] = (pwm_values[i+1]) << 8; counter += 3; } } Der TLC5940 ist ein 16Kanal-PWM-IC, er hat 16 12-bit-PWM-Kanäle. Ich zerlege mit dieser Funktion meine 12bit-Werte (gespeichert als 16bit) in 8-bit-Werte und sende diese Über SPI. Diese Zerlegefunktion funktioniert auch im Test. Olly T. schrieb: > Mit pwm_values[i+1] greift Du bei i == 15 hinter Dein Array, was schon > mal nicht stimmen kann. deswegen läuft i aber nur bis 14...
1 | pwm_values_for_spi[counter+2] = (pwm_values[i+1]) << 8; |
Was glaubst Du das diese Zeile macht? Die ist falsch, Du wolltest hier vermutlich
1 | pwm_values_for_spi[counter+2] = (pwm_values[i+1]) & 0xFF; |
schreiben. Ich würde zu Testzwecken das 16-bittige Array auch mit verschiedenen Werten füllen, z.B. 100+i, sonst sieht man einige Fehler nicht.
:
Bearbeitet durch User
Problem gelöst! Jim M. schrieb: > Was glaubst Du das diese Zeile macht? Die ist falsch, Du wolltest hier > vermutlich > pwm_values_for_spi[counter+2] = (pwm_values[i+1]) & 0xFF; > > schreiben. Danke für den Hinweis, vielleicht wollte ich das wirklich so schreiben ;-) War aber nicht die Ursache. Dieter F. schrieb: > "schwurbelst" Du da hin: > > https://de.wikipedia.org/wiki/Byte-Reihenfolge An sowas dachte ich auch, aber es ist eine ISR, die mir dazwischenfunkt. Oder der Timer. Würde mich freuen, wenn mir jemand erklären könnte, warum dem so ist: Ich erzeuge mir einen Takt über Timer0 für den TLC5940. Der braucht nen Takt für die Erzeugung seiner PWM; Nach 4096 Takten muß man den IC einmal toggeln. Eigentlich wollte ich den Takt über Compare Match Mode machen, habs dann aber über Fast-PWM gemacht. Ich lege TOP und Compare Match fest und krieg so meinen 50%Duty-Cycle. In einer ISR zähle ich den Takt mit. Ich wollte den Tak so schnell wie möglich machen und hab deswegen als TOP einfach mal 15 und Compare Match auf 7 gesetzt. Und das zerhaut mir die Speicherung meiner Variablen. Lege ich den Top-Wert auf 63 und Compare Match auf 31, läuft alles wie gewünscht, also in meinem Array sind meine Werte und nicht irgendein Quatsch. Oder hab ich da nen Programmierschnitzer? Bin noch recht neu auf dem Gebiet, teste gerade mit den Timern rum und es bereitet mir schon auch Probleme, dass alles zu verstehen - und umzusetzen! Also falls es eher mit meinen Code als mit einer Überforderung des Atmegas zu tun hat, würde ich mich freuen, wenn sich jemand nochmal den Code anschaut, ob der Timer oder die ISR irgendwie blöd sind. Habe ihn deswegen nochmal überarbeitet angehängt. Ob die Ansteuerung des TLC5940 jetzt funktioniert kann ich grad nicht testen, weil Aufbau nicht hier, aber ist für die Frage mit dem wirren Speichern der Variablen ja auch egal. Danke für die ganzen Hinweise bisher! Schöne Nacht euch allen!
blinksdinks schrieb: > Ich wollte den Tak so schnell wie möglich machen und hab deswegen als > TOP einfach mal 15 und Compare Match auf 7 gesetzt. Und das zerhaut mir > die Speicherung meiner Variablen. Dürfte das sei im zusammenhang mit dem zu knappen Timing sein. Das enabled den Interrupt bevor die Aufräumarbeiten des Stacks fertich sind -> Stack overflow. Man sollte auch daran denken dass da signifikant Zyklen zum Sichern und Wiederherstellen von Registern nötig sind - 15 Clocks sind für die ISR deutlich zuwenig.
Danke Jim für die Erläuterung... Es freut mich immer sehr, wenn Leute dieses Forum sich die Zeit für sowas nehmen. Ach, diese Mikrocontroller. Es ist zwar -wenn man sich alles selbst beibringt - saukompliziert, aber es macht auch dolle Spaß sich die Architektur der kleinen Biester zu erarbeiten! Als nächstes kommt dann jetzt wohl der stack, dann weiß ich bald endlich was der berühmte stack overflow ist! Und mit dem Timing und der Antsteuerung des TLC hab ich grad auch noch zu kämpfen, aber diese Geschichte wird in einem Extrathread weitergeschrieben. Schönen Sonntag euch allen!
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.