mikrocontroller.net

Forum: Compiler & IDEs mehrdimensionales Array aus Flash an Funktion übergeben


Autor: Neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Ich bräuchte mal ein wenig Hilfe und zwar würde ich gerne ein 
mehrdimensionales Array das ich per PROGMEM im Flash abgelegt habe an 
eine Funktion übergeben:

Mein Array wird wie flogt im Flash abgelegt:
const uint8_t image_1[128][6] PROGMEM = {
  {0x00, 0x00, 0x3F, 0x00, 0x00, 0x00},
  ...
}
soweit auch erstmal kein problem.

Wenn ich das jetzt richtig verstanden ist image_1 jetzt ein Array aus 
Zeigern die auf den Flash zeigen? Auf deren Inhalt ich per
pgm_read_byte(&image_1[0][0])
zugreifen kann. Das funktioniert soweit auch...

Aber wie bekomme ich jetzt mein image_1 an eine Funktion übergeben? So 
das ich aus der Funktion per pgm_read_byte auf den Inhalt von image_1 
zugreifen kann?
Ich komm einfach nicht drauf...

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber wie bekomme ich jetzt mein image_1 an eine Funktion übergeben?

einefunktion(image_1);

Das war jetzt leicht ;-)

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neo schrieb:
> Aber wie bekomme ich jetzt mein image_1 an eine Funktion übergeben?

Im Normalfall übergibt man der Funktion den Zeiger auf den ersten Wert 
(hier image_1) und die Dimensionen des Arrays, falls im Unterprogramm 
benötigt.

Autor: Neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wollte ich's auch machen... klappt nur leider nicht:

Bekomme da erstmal eine Warnung bei der Übergabe:
warning: passing arg 1 of `G_DRAW_IMAGE' makes integer from pointer 
without a cast

und dann in der Funktion folgenden Error:
error: subscripted value is neither array nor pointer

So schaut meine Funktion aus an die ich das gange gerne übergeben würde:
void G_DRAW_IMAGE(uint16_t image, uint8_t x, uint8_t y, uint8_t color) {
    for (uint8_t byte_x=0; byte_x<image_w; byte_x++) {
      for (uint8_t byte_y=0; byte_y<(neobator_h-(image_h&0x07)); byte_y=byte_y+8) {
        DOG128_SET_BYTE(pgm_read_byte(&image[byte_x][byte_y/8]), byte_x+x, byte_y+y, color);
      }
    }   
  }

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
image ist kein uint16_t sonder ein uint8_t*;

Autor: Neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Floh schrieb:
> Im Normalfall übergibt man der Funktion den Zeiger auf den ersten Wert
> (hier image_1) und die Dimensionen des Arrays, falls im Unterprogramm
> benötigt.

Also würde ich meiner Funktion einfach image_1[0][0] übergeben und dann, 
innerhalb der Dimensionen, image_1[x][y] hochzählen?
werd ich gleich mal probieren :)

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neo schrieb:
> Also würde ich meiner Funktion einfach image_1[0][0] übergeben und dann,
> innerhalb der Dimensionen, image_1[x][y] hochzählen?

Ne. image[0][0] ist ein uint8_t.
Du brauchst die Adresse des Arrays, also entweder &image_1[0][0] oder 
image_1 .

Autor: Neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
g457 schrieb:
> image ist kein uint16_t sonder ein uint8_t*;

gleiches Problem auch wenn ich's so mach:
void G_DRAW_IMAGE(uint8_t* image, uint8_t x, uint8_t y, uint8_t color)

außerdem dachte ich das Zeiger auf im Flash abgelegte Variabeln immer 
uint16_t sind?

Autor: Neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh fein so klapts:
G_DRAW_IMAGE(&image_1[0][0] ,0,0,1);



void G_DRAW_IMAGE(uint16_t image, uint8_t x, uint8_t y, uint8_t color) {
    
    for (uint8_t byte_x=0; byte_x<neobator_w; byte_x++) {
      for (uint8_t byte_y=0; byte_y<(neobator_h-(neobator_h&0x07)); byte_y=byte_y+8) {
        DOG128_SET_BYTE(pgm_read_byte(image), byte_x+x, byte_y+y, color);
        image++;
      }
    }
    
  }
allerdings doch uint16_t sonst bekomm ich nur 1/4 des bildes und der 
Rest ist naja... nenen wir es mal "rauschen"...

bekomme allerdings immernoch folgende Warnung:
main.c:153: warning: passing arg 1 of `G_DRAW_IMAGE' makes integer from 
pointer without a cast

wie bekomm ich die jetzt noch weg?

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
$ cat main.c 
#include <avr/pgmspace.h>
#include <inttypes.h>

const uint8_t image_1[2][6] PROGMEM = {
  {0x00, 0x00, 0x3F, 0x00, 0x00, 0x00},
  {0x00, 0x00, 0x3F, 0x00, 0x00, 0x00}
};

uint8_t funktion(const uint8_t* const pData, uint8_t x, uint8_t y, uint8_t resX)
{
        return pgm_read_byte(&(pData[y *resX +x]));
}

int main()
{
        return funktion(&(image_1[0][0]), 1, 2, 6);
}
$ avr-gcc -mmcu=atmega8 -Wall -o main main.c
$ file main
main: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped

HTHundichhoffichhabmirnichtindenadressenverhauen

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> main.c:153: warning: passing arg 1 of `G_DRAW_IMAGE' makes integer from
> pointer without a cast

wie schon geschrubt (und oben inzwischen auch im Beispielcode 
vorgeschrubt): der formale Parameter 'image' ist ein POINTER, kein 
uint16_t (bzw. hat es der Einfachheit halber zu sein).

Autor: Neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jupp, klappt jetzt. dickes Danke euch beiden :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.