Forum: Mikrocontroller und Digitale Elektronik Variablen im Flash (PROGMEM) übergeben


von Matthias F. (frank91)


Lesenswert?

Hallo alle miteinander :P

Ich arbeite gerade zum ersten mal mit PROGMEM.
Hier komme ich an einer stelle nicht weiter.

Bild_Fahrrad.c
1
const uint8_t cYCLO_Bitmaps[] PROGMEM=
2
{
3
0b11111111, 0b11111111... //wurde zum Verständnis gekürzt.
4
}
5
6
const uint8_t cYCLO_WidthPixels PROGMEM= 128;
7
const uint8_t cYCLO_HeightPixels PROGMEM= 64;

Bild_Fahrrad.h
1
extern const uint8_t cYCLO_Bitmaps[];
2
extern const uint8_t cYCLO_WidthPixels;
3
extern const uint8_t cYCLO_HeightPixels;

main.c
1
grafik_LCD_bild(0, 0, cYCLO_Bitmaps, cYCLO_WidthPixels, cYCLO_HeightPixels);

grafik_lcd.c
1
void grafik_LCD_bild (uint8_t x, uint8_t y, const uint8_t bitmap[], const uint8_t widthPixels, const uint8_t heightPixels)
2
{
3
lcd_string(dtostrf(pgm_read_byte(&cYCLO_WidthPixels), 3, 0, wert)); //128. Also Richtig.
4
  
5
  lcd_string(dtostrf(pgm_read_byte(&cYCLO_HeightPixels), 3, 0, wert)); //64. Also Richtig.
6
7
8
  lcd_string(dtostrf(pgm_read_byte(&widthPixels), 3, 0, wert)); //ergibt 255. Also falsch.
9
  lcd_string(dtostrf(pgm_read_byte(&heightPixels), 3, 0, wert)); //ergibt 255. Also falsch.
10
}

Wieso kann ich in "grafik_LCD_bild" nicht widthPixels und heightPixels 
auslesen?
Verwende ich im selben Unterprogramm "pgm_read_byte (&bitmap[zahler])" 
kann ich das Array erfolgreich auslesen.

Mir ist bewusst, dass es nicht viel Sinn macht zwei einzelne kleinen 
Variablen im Flash abzulegen. Da sie aber zu "cYCLO_Bitmaps[] PROGMEM" 
gehören hätte ich aber gerne die 2 zugehörigen Variablen ebenfalls im 
Flash.

Was mache ich hier falsch?

von Falk B. (falk)


Lesenswert?

@ Matthias Frank (frank91)

>void grafik_LCD_bild (uint8_t x, uint8_t y, const uint8_t bitmap[], const 
>uint8_t widthPixels, const uint8_t heightPixels)


>{
>lcd_string(dtostrf(pgm_read_byte(&cYCLO_WidthPixels), 3, 0, wert)); >//128. Also 
Richtig.

>  lcd_string(dtostrf(pgm_read_byte(&cYCLO_HeightPixels), 3, 0, wert)); >//64. 
Also Richtig.

Direkter Zugriff. Passt.


>  lcd_string(dtostrf(pgm_read_byte(&widthPixels), 3, 0, wert)); //ergibt >255. 
Also falsch.
>  lcd_string(dtostrf(pgm_read_byte(&heightPixels), 3, 0, wert)); //ergibt >255. 
Also falsch.
>}

Geht so nicht. Das muss man anders machen. Entweder mit der Erweiterung 
__flash oder Old school mit PGM_P pointern.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C

progmem Version


main.c
1
grafik_LCD_bild(0, 0, cYCLO_Bitmaps, &cYCLO_WidthPixels, &cYCLO_HeightPixels);


grafik_lcd.c
1
void grafik_LCD_bild (uint8_t x, uint8_t y, PGM_P bitmap, PGM_P widthPixels, PGM_P heightPixels)
2
{
3
  lcd_string(dtostrf(pgm_read_byte(widthPixels), 3, 0, wert));
4
  lcd_string(dtostrf(pgm_read_byte(heightPixels), 3, 0, wert));
5
}

__flash Version


Bild_Fahrrad.c
1
const __flash uint8_t cYCLO_Bitmaps[] PROGMEM=
2
{
3
0b11111111, 0b11111111... //wurde zum Verständnis gekürzt.
4
}
5
6
const __flash uint8_t cYCLO_WidthPixels PROGMEM= 128;
7
const __flash uint8_t cYCLO_HeightPixels PROGMEM= 64;

Bild_Fahrrad.h
1
extern const __flash uint8_t cYCLO_Bitmaps[];
2
extern const __flash uint8_t cYCLO_WidthPixels;
3
extern const __flash uint8_t cYCLO_HeightPixels;


main.c
1
grafik_LCD_bild(0, 0, cYCLO_Bitmaps, cYCLO_WidthPixels, cYCLO_HeightPixels);


grafik_lcd.c
1
void grafik_LCD_bild (uint8_t x, uint8_t y, const __flash uint8_t *bitmap, uint8_t widthPixels, uint8_t heightPixels)
2
{
3
  lcd_string(dtostrf(widthPixels), 3, 0, wert));
4
  lcd_string(dtostrf(heightPixels), 3, 0, wert));
5
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk B. schrieb:
> __flash Version
> const __flash uint8_t cYCLO_Bitmaps[] PROGMEM=

PROGMEM ist da überflüssig und verwirrend.

von Falk B. (falk)


Lesenswert?

Mist, Copy&Paste Fehler

von Falk B. (falk)


Lesenswert?

Hier nochmal korrigiert.


__flash Version


Bild_Fahrrad.c
1
const __flash uint8_t cYCLO_Bitmaps[]=
2
{
3
0b11111111, 0b11111111... //wurde zum Verständnis gekürzt.
4
}
5
6
const __flash uint8_t cYCLO_WidthPixels = 128;
7
const __flash uint8_t cYCLO_HeightPixels = 64;

Bild_Fahrrad.h
1
extern const __flash uint8_t cYCLO_Bitmaps[];
2
extern const __flash uint8_t cYCLO_WidthPixels;
3
extern const __flash uint8_t cYCLO_HeightPixels;


main.c
1
grafik_LCD_bild(0, 0, cYCLO_Bitmaps, cYCLO_WidthPixels, cYCLO_HeightPixels);


grafik_lcd.c
1
void grafik_LCD_bild (uint8_t x, uint8_t y, const __flash uint8_t *bitmap, uint8_t widthPixels, uint8_t heightPixels)
2
{
3
  lcd_string(dtostrf(widthPixels), 3, 0, wert));
4
  lcd_string(dtostrf(heightPixels), 3, 0, wert));
5
  lcd_string(dtostrf(bitmap[0]), 3, 0, wert));
6
}

von Matthias F. (frank91)


Lesenswert?

Ich hab das mit dem flash jetzt ausprobiert, weil ich dann das 
pgm_read_byte nicht mehr benötige und es das ganze übersichtlicher 
macht.

Das ganze hat dank deiner Hilfe sofort funktioniert :P
Danke :-D

Bei:
1
void grafik_LCD_bild (uint8_t x, uint8_t y, const __flash uint8_t *bitmap, uint8_t widthPixels, uint8_t heightPixels)

hast du das __flash nur bei dem Array mit angegeben. Brauche ich das bei 
widthPixels und heightPixels nicht?

von Falk B. (falk)


Lesenswert?

@ Matthias Frank (frank91)

>Bei:

>void grafik_LCD_bild (uint8_t x, uint8_t y, const __flash uint8_t *bitmap, 
>uint8_t widthPixels, uint8_t heightPixels)

>hast du das __flash nur bei dem Array mit angegeben. Brauche ich das bei
>widthPixels und heightPixels nicht?

Nein, weil beim Funktionsaufruf die __flash Variablen gelesen und als 
normale Parameter übergeben werden. Die Arbeit des Flash-Zugriffs 
geschieht dort. Beim Pointer ist das anders, dort muss ja auch innerhalb 
der Funktion bekannt sein, dass es kein normaler Pointer ist sondern ein 
__flash Pointer.

von Matthias F. (frank91)


Lesenswert?

ah ok, ich hab es verstanden :P

Danke :-D

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
Noch kein Account? Hier anmelden.