PROGMEN Array in Schleife verarbeiten

Gast #1360977
Lesenswert?

Habe ein Array im Speicher hinterlegt, mit dem ich später in einer 
Schleife arbeiten möchte. Je nach dem, welchen Wert ich wähle, sollen 
alle vorherigen Werte aufaddiert werden.

Wähle ich also Wert 1 soll 7+3=10 raus kommen. s.u.
1
const uint8_t MENUSTR[] PROGMEM ={
2
3, 
3
7, 
4
3, 
5
0, 
6
};

...
main:
1
uint8_t sub=0;
2

3
//Schleife, die nicht funktioniert:
4
for(uint8_t j=0; j==1; j++){
5
sub= &MENUSTR[j] + sub);
6
}

1
//soll das gleiche machen:
2
    
3
uint8_t j=0;
4
sub= &MENUSTR[j] + sub;
5
j++;
6
sub= &MENUSTR[j] + sub;
7
//funktioniert

Ich habe nun einfach mit einem festen Wert gearbeitet. Anscheinend kommt 
allerdings bei der Schleife immer der Initialwert von sub heraus. Also 
im Beispiel 0.
Wenn ich direkt hintereinander Schreibe, was die Schleife machen soll, 
funktioniert es allerdings.

Woran denke ich nicht?

Würde mich über Hilfe freuen.

Gruß
Alex
#1360987
Lesenswert?

Auf Werte im Flash kannst du nicht direkt zugreifen. Du musst sie mit 
den dafür vorgesehenen Funktionen aus dem Flash lesen. Das die eine 
Variante auch mit direktem Zugriff zu funktionieren scheint, liegt 
daran, dass der Optimierer hier gleich die Zugriffe durch die 
entsprechenden Werte ersetzt.
Gast #1361077
Lesenswert?

Hab dann mal noch angepasst. Die Beiträge habe ich leider erst etwas 
später gesehen.
1
const uint8_t MENUSTR[] PROGMEM ={
2
3, 
3
7, 
4
3, 
5
0, 
6
};
7

8
const uint8_t *PTMENUSTR PROGMEM = MENUSTR;

und bei der Schleife
1
for(uint8_t j=0; j<=1; j++){
2
    sub= PTMENUSTR+j + sub;
3
    }

War es so gemeint wegen der automatischen Optimierung?

Gruß
Alex
Gast #1361121
Lesenswert?

wenn du

const char buffer[] PROGMEM = { 1,2,3,4]};

hast


must du mit

char wert=0;
for( char i=0; i<=3 , i++)
  {
    wert += pgm_read_byte( &buffer[i]);
  }


zugreifen


oder so ähnlich ^^ kein plan ob das gehen würde
Gast #1361479
Lesenswert?

pgm_read_byte klappt allerdings nicht und mit dem Geschriebenen wird 
genau auf die Werte im Array zugegriffen.
Also meine Frage:
Wie wird dieses wegoptimiert, was ich geschrieben habe. Bzw. wie sollte 
der Code aussehen? Aus dem Tutorial konnte ich leider nicht mehr 
gewinnen.
#1361484
Lesenswert?

Alex schrieb:
> pgm_read_byte klappt allerdings nicht

Dann hast du es falsch benutzt.
Wie sieht dein Code dazu aus?

Und ich verstehe nicht, was du jetzt die ganze Zeit mit dem "Optimieren" 
meinst. Der Optimierer hat nur unbeabsichtigterweise dafür gesorgt, dass 
ein Teil deines Codes zufällig funktioniert hat, obwohl er eigentlich 
fehlerhaft war.
Gast #1361781
Lesenswert?

Es wird nicht der Wert an der Stelle j benutzt sondern irgendwas 
anderes.

In meinem Beispiel:
1
const uint8_t MENUSTR[] PROGMEM ={
2
3, 
3
7, 
4
3, 
5
0, 
6
};

sollte dann an der Stelle j=0 der Wert 3 benutzt werden. Wird er aber 
nicht. Bekomme dann nur komisches Zeug raus. Wenn ich allerdings 
pgm_read_byte weg lasse kommt alles richtig heraus.

Hatte es vorher ja auch mit pgm_read_byte versucht aber dann einfach mal 
weg gelassen. Und es ging.

Gruß
Alex
Gast #1362535
Lesenswert?

Steht nicht so viel mehr drin:
1
#include <stdio.h>
2
#include <string.h>
3

4
// AVR include files
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <avr/pgmspace.h>
8

9
//P.Fleury
10
#include "lcd.h"
11

12
uint8_t sub=0;
13

14
const uint8_t MENUSTR[] PROGMEM ={
15
3, 
16
7, 
17
3, 
18
0, 
19
};
20

21

22
int  main()
23
{  
24
DDRG &=(1<<PG2);
25
DDRA &=(1<<PA4) & (1<<PA5) & (1<<PA6) & (1<<PA7);
26

27

28
//Werden noch nicht benötigt
29
PORTG |= (1<<PG2);  // Taster Pullups
30
PORTA |= (1<<PA4) | (1<<PA5) | (1<<PA6) | (1<<PA7); // Taster Pullups
31

32

33

34

35
//   LCD Initialisierung
36
  lcd_init (LCD_DISP_ON);
37
        lcd_clrscr();
38

39
for(uint8_t j=0; j<=1; j++){
40
    sub= &MENUSTR[j] + sub;
41
    }
42

43
lcd_gotoxy(1,1);
44

45
//Hier kann ich die Ergebnisse mit LCD Ausgabe prüfen
46

47
if(sub==10){
48
  lcd_puts("ok");
49
}else{
50
  lcd_puts("nicht ok");
51
}
52

53
  for (;;){}
54
}
#1362553
Lesenswert?

Tja.
Und aus der Ausgabe 'OK' bzw. 'Nicht OK' kann man so wunderbare 
Rückschlüsse darauf ziehen, was denn das Problem ist. :-)

Warum lässt du dir denn nicht einfach mal sub ausgeben!
Aus dem Zahlenwert sieht man doch viel mehr als aus einer OK/Nicht OK 
Meldung.


for(uint8_t j=0; j<=1; j++){
    sub= &MENUSTR[j] + sub;
    }

Das ist Unsinn!
Du MUSST über pgm_read_byte gehen.
Alles andere kann ev. das Richtige ergeben (weil ja immer an jeder 
Speicherstelle irgendetwas drinnen steht und jedes Teil eine Adresse 
hat), aber das ist dann Zufall!

Und achte ein bischen auf die äußere Form deines Programmes. 
Interessanterweise sind es nämlich meistens die 
Hässlichen-Kraut-und-Rüben Programme, die solch seltsame sporadische 
Fehler aufweisen.

1
#include <stdio.h>
2
#include <string.h>
3

4
// AVR include files
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <avr/pgmspace.h>
8

9
//P.Fleury
10
#include "lcd.h"
11

12
uint8_t sub=0;
13

14
const uint8_t MENUSTR[] PROGMEM ={
15
  3, 
16
  7, 
17
  3, 
18
  0, 
19
};
20

21
void lcd_puti( int number )
22
{
23
  char buffer[10];
24

25
  itoa( number, buffer, 10 );
26
  lcd_puts( buffer );
27
}
28

29
int  main()
30
{  
31
  DDRG &=(1<<PG2);
32
  DDRA &=(1<<PA4) & (1<<PA5) & (1<<PA6) & (1<<PA7);
33

34
  //Werden noch nicht benötigt
35
  PORTG |= (1<<PG2);  // Taster Pullups
36
  PORTA |= (1<<PA4) | (1<<PA5) | (1<<PA6) | (1<<PA7); // Taster Pullups
37

38
  //   LCD Initialisierung
39
  lcd_init (LCD_DISP_ON);
40
  lcd_clrscr();
41

42
  sub = 0;
43
  for( uint8_t j = 0; j <= 1; j++ ) {
44
    sub = sub + pgm_read_byte( &MENUSTR[j] );
45
  }
46

47
  lcd_gotoxy( 1, 1 );
48
  lcd_puti( sub );
49

50
  if( sub == 10 ) {
51
    lcd_puts("ok");
52
  }
53
  else {
54
    lcd_puts("nicht ok");
55
  }
56

57
  for (;;)
58
  {
59
  }
60
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren