Hallo, ich habe ein kleines Problem mit dem Zugriff auf den Flash-Speicher: ATMega8 (8 KB Flash) Programm belegt ~4 oder ~5 KB Geht: uint8_t b[22][7] = {...} const uint8_t array[16][100] PROGMEM = {...} pwm_setting[i] = pgm_read_byte (&array[b[i][6]-1][b[i][2]]); Geht nicht: uint8_t b[22][7] = {...} const uint16_t array[16][100] PROGMEM = {...} pwm_setting[i] = pgm_read_word (&array[b[i][6]-1][b[i][2]]); Wenn ich meine Beobachtungen korrekt interpretiere liefert die Funktion häufig "0" statt einen Wert aus "array". Genauer kann ich die eingelesenen Werte frühestens heute Abend angucken wenn ich ein Display an den µC hänge, aber vielleicht sieht ja schon jemand was da kaputt ist, mir sind die Ideen ausgegangen: Habe ich da irgendwas grob falsch gemacht oder benötigt pgm_read_word vielleicht einfach 1000 Zyklen? Grüße, "Rootsquash"
@ Andi M. (rootsquash) >Geht nicht: >uint8_t b[22][7] = {...} >const uint16_t array[16][100] PROGMEM = {...} >pwm_setting[i] = pgm_read_word (&array[b[i][6]-1][b[i][2]]); Spar dir solchen Käse un poste VOLLSTÄNDIGEN, OROIGINALEN Code, am besten als Anhang. >Habe ich da irgendwas grob falsch gemacht Ja, aber in dem Stück Code, das wir nicht sehen. >oder benötigt pgm_read_word >vielleicht einfach 1000 Zyklen? Nö.
So, bin wieder an einem Computer: Original-Quelltext ist im Anhang. Es handelt sich um die Software aus dem Artikel Soft_PWM, aufgebläht auf mehr Auflösung und etwa 20 Kanäle. Die Werte sollen aus einer Tabelle gelesen werde. Ich dachte das hätte ich fertig in der Schublade liegen, bei genauerem Hinsehen zeigen sich aber immer wieder unerwünsche Werte im Ausgangssignal*. Jetzt wollte ich es etwas beschleunigen indem ich nur einen Wert aus dem Flash lese, nicht 2, aber dann flackern die LEDs an den Ausgängen ganz furchtbar, so als gingen sie nur jedes x-te Mal an. Der programmierte Verlauf ist mit etwas gutem Willen aber erkennbar. Es scheint also irgendwas schief zu gehen wenn ich mit pgm_read_word einen Wert aus einem uint16_t array lese. Grüße, "Rootsquash" * Wenn ich "pwm_setting[i] = pgm_read_word (&nichtlinear_array[pwm_setting[i]]); // Benötigte Pulsbreite raussuchen" auskommentiere sind die Verläufe im Prinzip so wie ich es gern möchte, aber linear. Wenn ich die Zeile mit rein nehme bleibt die LED immer mal wieder aus, so als wäre pwm_setting[i] ab und zu einfach 0. Ich habe übers Wochenende leider nur ein HM 312 als Oszilloskop, das ist keine so besonders zuverlässige Informationsquelle bei Digitalsignalen.
:
Bearbeitet durch User
@Andi M. (rootsquash) >Jetzt wollte ich es etwas beschleunigen indem ich nur einen Wert aus dem >Flash lese, nicht 2, aber dann flackern die LEDs an den Ausgängen ganz >furchtbar, so als gingen sie nur jedes x-te Mal an. Der programmierte >Verlauf ist mit etwas gutem Willen aber erkennbar. Naja, da sind glaube ich noch ein paar Bugs drin, auch wenn ich im Moment nicht alles überblicke. portstatus_table[i][0]++; // PWmodulierstes Signal wurde ausgegeben Diese Zeile macht rein gar nichts. portstatus_table[i][2]++; // Aktuellen Wert neu setzen: Wert aus nächster Spalte holen Die auch nicht. Wenn gleich die verschachtelte Indizierung des Arrays etwas furchteinflößend ist, sollte sie denoch funktionieren. Der Fehler liegt eher in deiner Steuertabelle sowie deren Auswertung.
Falk Brunner schrieb: > portstatus_table[i][0]++; // PWmodulierstes Signal wurde > ausgegeben > > Diese Zeile macht rein gar nichts. Die Zeile zählt einen Eintrag hoch, damit ich den Wert mehrfach ausgeben lassen kann bevor der nächste gelesen wird, falls ich die Breite des PWM-Signals nicht alle 10 ms ändern möchte, sondern nur alle n*10 ms. > portstatus_table[i][2]++; // Aktuellen Wert neu setzen: Wert > aus nächster Spalte holen > > Die auch nicht. portstatus_table[i][2] gibt an an welcher Stelle des Signalverlaufs das Programm gerade ist. Sonst, würde ich immer nur den ersten Wert aus meiner Zeile kriegen. In der Tabelle stelle ich ein ob ich einen Sägezahn, einen Sinus oder sonstwas haben möchte usw., wirklich "getan" wird aber tatsächlich erst hier etwas: pwm_setting[i] = pgm_read_byte (&verlaufs_array[portstatus_table[i][6]-1][portstatus_table[i][2]]); // Wert lesen Diese Werte landen dann durch pwm_update via double_buffering auf den Ausgängen. > Wenn gleich die verschachtelte Indizierung des Arrays etwas > furchteinflößend ist, sollte sie denoch funktionieren. Der Fehler liegt > eher in deiner Steuertabelle sowie deren Auswertung. Mh, da werde ich morgen nochmal drüber nachdenken müssen. Vielleicht schreibe ich es auch nochmal neu.. ich weiß blos nicht ob ich dabei dann irgendwas anders machen werde. Vielen Dank für die Antworten und Grüße, "Rootsquash"
Guten Morgen! Die Helligkeitssprünge konnte ich beseitigen: Beim Neuformatieren fand ich ein überschüssiges Komma in meiner Tabelle, jetzt ist das Ausgangssignal schön "glatt". Im Prinzip funktioniert3 es jetzt also, das Problem mit dem pgm_read_word war so aber noch nicht gelöst: Wenn ich direkt den 16 Bit-Wert ausgelesen habe flackerten die LEDs ziemlich wild. Daraufhin habe ich einfach aus Spaß mal #define PWM_STEPS 768 auf 256 gesetzt, schon ging es. Dann habe ich den Wert nach und nach wieder auf 768 erhöht.. und es tut immernoch was es soll. Kann bei der Verwendung von pgm_read_... notwendig werden immer wieder "make clean" aufzurufen? Anders kann ich mir gerade nicht wirklich erklären warum sich das System nicht ordentlich deterministisch verhält.
Andi M. schrieb: > Kann bei der Verwendung von pgm_read_... notwendig werden immer wieder > "make clean" aufzurufen? Falls dein Makefile korrekt ist: Nein. Und anstsatt progmem+pgm_read geht das einfacher mit __flash.
Johann L. schrieb: > Andi M. schrieb: >> Kann bei der Verwendung von pgm_read_... notwendig werden immer wieder >> "make clean" aufzurufen? > > Falls dein Makefile korrekt ist: Nein. Mh, das Ding habe ich nicht selbst gebaut :-/ > Und anstsatt progmem+pgm_read geht das einfacher mit __flash. Oh, schick. Mein Editor versteht __flash leider nicht, aber es natürlich schöner zu schreiben, danke für den Tipp.
Johann L. schrieb: > Andi M. schrieb: >> Kann bei der Verwendung von pgm_read_... notwendig werden immer wieder >> "make clean" aufzurufen? > > Falls dein Makefile korrekt ist: Nein. > > > Und anstsatt progmem+pgm_read geht das einfacher mit __flash. __flash kenn ich noch nich. Gibs beispiele?
Jörg Esser schrieb: > Johann L. schrieb: >> Andi M. schrieb: >>> Kann bei der Verwendung von pgm_read_... notwendig werden immer wieder >>> "make clean" aufzurufen? >> >> Falls dein Makefile korrekt ist: Nein. >> >> >> Und anstsatt progmem+pgm_read geht das einfacher mit __flash. > > __flash kenn ich noch nich. Gibs beispiele? Steht (leicht zu übersehen) in http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial Zitat: __flash und Embedded-C[Bearbeiten] Ab Version 4.7 unterstützt avr-gcc Adress-Spaces gemäß dem Embedded-C Dokument ISO/IEC TR18037. Der geläufigste Adress-Space ist __flash, der im Gegensatz zu progmem kein GCC-Attribut ist, sondern ein Qualifier und damit ähnlich verwendet wird wie const oder volatile. GCC kennt keine eigene Option zum Aktivieren von Embedded-C, es wird als GNU-C Erweiterung behandelt. Daher müssen C-Module, die Address-Spaces verwenden, mit -std=gnu99 compiliert werden. static const __flash int value = 10; int get_value (void) { return value; } Im Gegensatz zu progmem sind keine speziellen Bibliotheksfunktionen oder -makros für den Zugriff mehr notwendig: Der Code zum Lesen der Variable ist "normales" C. Die Variable wird im richtigen Speicherbereich (Flash) angelegt. __flash ist nur zusammen mit read-only Objekten oder Zeigern, d.h. nur zusammen mit const, erlaubt. Zugriffe wie im obigen Beispiel können (weg)optimiert werden. Das Beispiel entspricht einem "return 10". Es besteht keine Notwendigkeit, für value überhaupt Flash-Speicher zu reservieren. Auch Zeiger-Indirektionen sind problemlos möglich. Zu beachten ist, dass __flash auf der richtigen Seite des "*" in der Zeigerdeklaration bzw. -definition steht: Rechts vom *: Der Zeiger selbst liegt im Flash Links vom *: Der Zeiger enthält eine Flash-Adresse // val ist eine Variable im Flash const __flash int val = 42; // pval liegt auch im Flash und enthält die Adresse von val const __flash int* const __flash pval = &val; char get_val (void) { // liest den Wert von val über die in pval abgelegte Adresse return *pval; }
Jaaa jetz endlich 14.2.2 ok. Danke Habe nicht Lang genug gelesen, sorry immer diese Ungeduld.
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.