PROGMEM Array an Funktion übergeben

Gast #4416887
Lesenswert?
• ▲
▼
Hallo,

ich hab ein Led-Pattern

const uint8_t pattern PROGMEM = {0, 255, 255, 0, 255, 255, 0, 0};

welches ich an einer Funktion übergeben möchte. Angesteuert werden damit 
2 Leds. Bekomme das irgendwie nicht hin.
1
func(pattern);
2

3
void func(const uint8_t *pattern)
4
{
5
static uint8_t step = 0;
6

7
// falls ein pattern nicht ausreicehnd groß ist
8
if(sizeof(pattern) > step) step = 0;
9

10
ledvalue1 = pgm_read_byte(&pattern[step]);
11
ledvalue2 = pgm_read_byte(&pattern[(step+1);
12

13
step++;
14
}
Gast #4416896
Lesenswert?
• ▲
▼
>Bekomme das irgendwie nicht hin.

Das ist höchst bedauerlich.

Wenn Du allerdings Hilfe erwartest, solltest Du das Ist- und 
Sollverhalten genauer beschreiben.

Wolltest Du vielleicht statt

>step++;

nicht eher

step += 2;

schreiben?
Gast #4416907
Lesenswert?
• ▲
▼
So, hab noch ein bisschen getüfftelt.
Jedoch habe ich noch ein paar Probleme. Zum einen meckert der Compiler
'__progmem__' attribute ignored
Des weiteren kann ich mit sizeof(pattern) nicht die Größe auslesen. 
Ergebnis ist immer 1.
1
const uint8_t pattern PROGMEM = {0, 255, 255, 0, 255, 255, 0, 0};
2

3
func(pattern);
4

5
void func(const uint8_t *pattern)
6
{
7
static uint8_t step = 0;
8
uint8_t sizePattern = sizeof(pattern)/sizeof(pattern[0]);
9
ledValue1 = pgm_read_byte(patter[step]);
10
step++;
11
}
Gast #4416962
Lesenswert?
• ▲
▼
Heribert B schrieb:
> Des weiteren kann ich mit sizeof(pattern) nicht die Größe auslesen.
> Ergebnis ist immer 1.

Das sind absolute C-Grundlagen. Wenn das in deinem Tutorial/Buch nicht 
drin steht, dann entsorge dies und bedenke, dass da noch mehr 
Fehlinformationen drin sind.

Heribert B schrieb:
> func(pattern);
>
> void func(const uint8_t *pattern)

Bei der Deklaration sollte der Rückgabetyp mit angegeben werden, da 
sonst implizit int angenommen wird.
Desweiteren ist der Paramtername egal. Der Typ ist wichtig.
(Der Name hilft aber etwas als Dokumentation (wenn er gut gewählt ist)

void func(const uint8_t *pattern);
(Firma: DC3AX) #4417099
Lesenswert?
• ▲
▼
Das Problem sind die Grundlagen...

Zuerst beschreibe doch, was Du erreichen willst:
1
typedef struct {
2
  uint8_t pattern;
3
  uint8_t value;
4
} tPATTERN;

Jetzt kennt der Compiler auch die Größe eines Elements Deines Arrays. 
Damit legst Du ein Array aus vielen Elementen dieser Art an:
1
const tPATTERN pattern[] = { 
2
  { 0, 255 },
3
  { 255, 0 },
4
... };

Nun, da der Compiler weiß, wie ein Element aussieht, kann er auch die 
Anzahl der Elemente bestimmen, ganz dynamisch zur Compile-Zeit:
1
#define PATTERNS (sizeof(pattern) / sizeof(pattern[0]))

Da Du Deiner Funktion nun einen Pointer auf ein Element bekannter Größe 
übergeben kannst, kann innerhalb der Funktion auch der Compiler selbst 
die korrekte Schrittweite der Pointer bestimmen:
1
void blubb( const tPATTERN *pattern) {
2
  static npat = 0;
3
  
4
  ledvalue1 = pgm_read_byte(&pattern[step]->pattern);
5
  ledvalue2 = pgm_read_byte(&pattern[step]->value);
6

7
  step++;
8
  if (step == PATTERNS) step = 0;
9
}

Ich persönlich finde, dass man gerade als Anfänger erst einmal 
ausführliche structe ausdenken und diese dann konsequent verwenden 
sollte, bevor man Assembler-artigen Code schreibt, den man selbst nach 
ein paar Tagen Pause nicht mehr versteht.
Außerdem bitte hier im Wiki noch mal nachlesen, einige dieser 
pgm_read_byte sind eventuell nicht mehr nötig, weil moderne AVRGCC 
Versionen das im Hintergrund erledigen können.
#4417162
Lesenswert?
• ▲
▼
Heribert B schrieb:
>
1
> const uint8_t pattern PROGMEM = {0, 255, 255, 0, 255, 255, 0, 0};
2
> 
3
> func(pattern);
4
> 
5
> void func(const uint8_t *pattern)
6
> {
7
> static uint8_t step = 0;
8
> uint8_t sizePattern = sizeof(pattern)/sizeof(pattern[0]);
9
> ledValue1 = pgm_read_byte(patter[step]);
10
> step++;
11
> }
12
>

Das grundlegendste Problem an diesem Stück Code ist, daß dem Array die 
[] fehlen.

> Des weiteren kann ich mit sizeof(pattern) nicht die Größe auslesen.
> Ergebnis ist immer 1.

Siehe oben.
#4417260
Lesenswert?
• ▲
▼
@  Heribert B (Gast)


>const uint8_t pattern PROGMEM = {0, 255, 255, 0, 255, 255, 0, 0};

>welches ich an einer Funktion übergeben möchte. Angesteuert werden damit
>2 Leds. Bekomme das irgendwie nicht hin.

Wenn man schon einen aktuellen Compiler hat (Atmelstudio mit avr gcc?), 
dann kann man es auch ein wenig komfortabler machen.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C
1
const __flash uint8_t pattern= {0, 255, 255, 0, 255, 255, 0, 0};
2

3
void func(const __flash uint8_t *pattern);
4

5

6
void func(const __flash uint8_t *pattern) {
7
  static uint8_t step = 0;
8

9
  if(step >= sizeof(pattern) ) step = 0;
10
  ledvalue1 = pattern[step];
11
  ledvalue2 = pattern[step+1];
12
  step++;
13
}
#4417275
Lesenswert?
• ▲
▼
Warum nicht einfach mal so versuchen:
1
const __flash uint8_t pattern[] = {0, 255, 255, 0, 255, 255, 0, 0};
2

3
void func(const __flash uint8_t *pattern);
4

5

6
void func(const __flash uint8_t *pattern) {
7
  static uint8_t step = 0;
8

9
  if(step >= sizeof(pattern) ) step = 0;
10
  ledvalue1 = pattern[step];
11
  ledvalue2 = pattern[step+1];
12
  step++;
13
}
mit Array!

Hat eigentlich der GCC sich nie über die Initialisierung von pattern 
beschwert?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.