Forum: Mikrocontroller und Digitale Elektronik Problem: Compiler beschreibt variable nicht korrekt


von Raphael F. (erdbewohner)


Lesenswert?

Hallo!
Ich habe ein Menu programmiert, das ich mit structs definieren kann. 
Jetzt sitze ich schon den ganzen Tag an einem Problem: bei dem 
Programmteil, wo alle structs beschrieben werden (ich kann das nicht im 
header machen, weil ich querverweise habe), soll ein element eines 
structs mit vier beschrieben werden, der Compiler schreibt aber 0x37 
hinein (ich habe auch im Disassembly geschaut, er schreibt wirklich 
direkt 0x37 anstatt 4 hinein). Einzig im Optimier-Modus 0 schreibt er 4.
Ich habe alle interrupts deaktiviert und den programmteil komplett 
isoliert. Es funkt also nichts von "aussen" herein. Ich habe aber 
festgestellt, dass wenn ich die Zeilen, wo der Pointer der Text-Arrays 
in die structs geschrieben wird, auskommentiere, es funktionniert. Wenn 
ich einige wieder aktiviere, besteht das problem wieder. Ich habe aber 
kein System dahinter entdecken können, bei welchen das Problem noch 
auftritt und bei welchen nicht mehr.
Ich benutze AVRStudio 6.0.1843 und einen ATXmega256A3.

Ich wäre für Hilfe sehr dankbar!
Viele Grüsse
Erdbewohner

Hier ist noch der Code, ...
...wo die einzelnen structs definiert werden:
1
struct MenuGeneralInfo  //Description see above
2
{
3
  void (*topMenuFunc) (struct MenuGeneralInfo*);
4
  struct MenuGeneralInfo *topMenuPnt;
5
  void (*rightMenuFunc) (struct MenuGeneralInfo*);
6
  struct MenuGeneralInfo *rightMenuPnt;
7
  void (*leftMenuFunc) (struct MenuGeneralInfo*);
8
  struct MenuGeneralInfo *leftMenuPnt;
9
  char (*textList)[LARGEST_MENU][17];      //Has to be in the flash
10
  struct MenuItemInfo (*menuItemsInfo);    //Pointer to an array
11
  uint8_t menuLength;              //Number of Menu Items WITHOUT the Title
12
};
13
14
enum VarType  //Description see above
15
{
16
  NONE,
17
  U_BYTE,
18
  S_BYTE,
19
  U_WORD,
20
  S_WORD,
21
  DOUBLE
22
};
23
24
struct MenuItemInfo  //Description see above
25
{
26
  void (*menuFunc) (struct MenuGeneralInfo*);
27
  struct MenuGeneralInfo *menuPnt;
28
  uint16_t adress;
29
  enum VarType varType;
30
  void (*valueSetFunc) (void);
31
  double smallStep;  //change of the variable when up/down pressed
32
  double bigStep;    //change of the variable when right/left pressed
33
  double lowerLimit;
34
  double upperLimit;
35
  uint8_t precision;
36
};




...wo die menus definiert werden:
1
void emptyFunc1(struct MenuGeneralInfo*);
2
void emptyFunc2(void);
3
void initMenus(void);
4
5
//**Home menu**
6
char const homeTextList[][17] PROGMEM =
7
{"HOME            ",
8
 " Fliegen        ",
9
 " Einstellungen  ",
10
 " U Akku =       "};
11
struct MenuItemInfo homeItemInfos[3];
12
struct MenuGeneralInfo homeGenInf;
13
14
15
//**pid settings menu**
16
char const pidSetTextList[][17] PROGMEM =
17
{"PID             ",
18
 " X/Roll         ",
19
 " Y/Nick         ",
20
 " Z/Yaw          ",
21
 " Sonar          "};
22
struct MenuItemInfo pidSetItemInfos[4];
23
struct MenuGeneralInfo pidSetGenInf;
24
25
  //**pid X settings menu**
26
  char const pidX_SetTextList[][17] PROGMEM =
27
  {"PID X/ROLL      ",
28
   " P              ",
29
   " I              ",
30
   " D              "};
31
  struct MenuItemInfo pidX_SetItemInfos[3];
32
  struct MenuGeneralInfo pidX_SetGenInf;
33
34
  //**pid Y settings menu**
35
  char const pidY_SetTextList[][17] PROGMEM =
36
  {"PID Y/NICK      ",
37
   " P              ",
38
   " I              ",
39
   " D              "};
40
  struct MenuItemInfo pidY_SetItemInfos[3];
41
  struct MenuGeneralInfo pidY_SetGenInf;
42
43
  //**pid Z settings menu**
44
  char const pidZ_SetTextList[][17] PROGMEM =
45
  {"PID Z/YAW       ",
46
   " P              ",
47
   " I              ",
48
   " D              "};
49
  struct MenuItemInfo pidZ_SetItemInfos[3];
50
  struct MenuGeneralInfo pidZ_SetGenInf;
51
52
  //**pid Sonar settings menu**
53
  char const pidSonarSetTextList[][17] PROGMEM =
54
  {"PID SONAR       ",
55
   " P              ",
56
   " I              ",
57
   " D              "};
58
  struct MenuItemInfo pidSonarSetItemInfos[3];
59
  struct MenuGeneralInfo pidSonarSetGenInf;
60
61
//**IMU settings menu**
62
char const imuTextList[][17] PROGMEM =
63
{"IMU             ",
64
 " periodA,G      ",
65
 " periodC,B      ",
66
 " of.GX          ",
67
 " of.GY          ",
68
 " of.GZ          ",
69
 " of.CX          ",
70
 " of.CY          ",
71
 " of.CZ          "};
72
struct MenuItemInfo imuItemInfos[8];
73
struct MenuGeneralInfo imuGenInf;
74
  
75
//**Ultrasonic position finding Settings menu**
76
char const usPositionTextList[][17] PROGMEM =
77
{"US POSITION     ",
78
 " RecK X         ",
79
 " RecJ Y         ",
80
 " RecL X         ",
81
 " RecL Y         ",
82
 " RecL Z         ",
83
 " Vref ACs       "};
84
struct MenuItemInfo usPositionItemInfos[6];
85
struct MenuGeneralInfo usPositionGenInf;
86
87
//**other settings menu**
88
char const otherSetTextList[][17] PROGMEM =
89
{"SONSTIGES       ",
90
 " prog. Regler   ",
91
 " Servos         ",
92
 " Akkulimit      ",
93
 " Kontrast LCD   "};
94
struct MenuItemInfo otherSetItemInfos[4];
95
struct MenuGeneralInfo otherSetGenInf;
96
97
  //**servo settings menu**
98
  char const servoTextList[][17] PROGMEM =
99
  {"SERVOS          ",
100
   " 0 pos 0        ",
101
   " 0 pos 1        ",
102
   " 1 pos 0        ",
103
   " 1 pos 1        "};
104
  struct MenuItemInfo servoItemInfos[4];
105
  struct MenuGeneralInfo servoGenInf;



...wo die menus beschrieben werden:
1
void emptyFunc1(struct MenuGeneralInfo *menuInfo)
2
{
3
  return;
4
}
5
void emptyFunc2(void)
6
{
7
  return;
8
}
9
10
void initMenus(void)
11
{
12
//**Home Menu**
13
  homeItemInfos[0].menuFunc=flyingCall; homeItemInfos[0].varType=NONE;
14
  homeItemInfos[1].menuFunc=menuDisplayerInit; homeItemInfos[1].menuPnt=&pidSetGenInf; homeItemInfos[1].varType=NONE;
15
  homeItemInfos[2].adress=&accuV;  homeItemInfos[2].varType=DOUBLE; homeItemInfos[2].valueSetFunc=emptyFunc2;  homeItemInfos[2].smallStep = 0;  homeItemInfos[2].bigStep = 0;  homeItemInfos[2].lowerLimit = 0; homeItemInfos[2].upperLimit = 200;  homeItemInfos[2].precision = 1;
16
  
17
  homeGenInf.topMenuFunc=emptyFunc1;
18
  homeGenInf.rightMenuFunc=emptyFunc1;
19
  homeGenInf.leftMenuFunc=emptyFunc1;
20
  homeGenInf.textList = &homeTextList;
21
  homeGenInf.menuItemsInfo = &homeItemInfos;
22
  homeGenInf.menuLength = 3;
23
  
24
//**IMU Settings**  
25
  imuItemInfos[0].adress=&imuRefresh;      imuItemInfos[0].varType=U_WORD; imuItemInfos[0].valueSetFunc=setImuRefreshRate;    imuItemInfos[0].smallStep = 10;  imuItemInfos[0].bigStep = 100;  imuItemInfos[0].lowerLimit = 0;    imuItemInfos[0].upperLimit = 65530;
26
  imuItemInfos[1].adress=&baroCompRefresh;  imuItemInfos[1].varType=U_WORD; imuItemInfos[1].valueSetFunc=setImuRefreshRate;    imuItemInfos[1].smallStep = 10;  imuItemInfos[1].bigStep = 500;  imuItemInfos[1].lowerLimit = 0;    imuItemInfos[1].upperLimit = 65530;
27
  imuItemInfos[2].adress=&offsetGyroX;    imuItemInfos[2].varType=DOUBLE; imuItemInfos[2].valueSetFunc=emptyFunc2;      imuItemInfos[2].smallStep = 1;  imuItemInfos[2].bigStep = 10;  imuItemInfos[2].lowerLimit = -500;  imuItemInfos[2].upperLimit = 500;  imuItemInfos[2].precision = 0;
28
  imuItemInfos[3].adress=&offsetGyroY;    imuItemInfos[3].varType=DOUBLE; imuItemInfos[3].valueSetFunc=emptyFunc2;      imuItemInfos[3].smallStep = 1;  imuItemInfos[3].bigStep = 10;  imuItemInfos[3].lowerLimit = -500;  imuItemInfos[3].upperLimit = 500;  imuItemInfos[3].precision = 0;
29
  imuItemInfos[4].adress=&offsetGyroZ;    imuItemInfos[4].varType=DOUBLE; imuItemInfos[4].valueSetFunc=emptyFunc2;      imuItemInfos[4].smallStep = 1;  imuItemInfos[4].bigStep = 10;  imuItemInfos[4].lowerLimit = -500;  imuItemInfos[4].upperLimit = 500;  imuItemInfos[4].precision = 0;
30
  imuItemInfos[5].adress=&offsetCompassX;    imuItemInfos[5].varType=S_WORD; imuItemInfos[5].valueSetFunc=emptyFunc2;      imuItemInfos[5].smallStep = 1;  imuItemInfos[5].bigStep = 10;  imuItemInfos[5].lowerLimit = -300;  imuItemInfos[5].upperLimit = 300;
31
  imuItemInfos[6].adress=&offsetCompassY;    imuItemInfos[6].varType=S_WORD; imuItemInfos[6].valueSetFunc=emptyFunc2;      imuItemInfos[6].smallStep = 1;  imuItemInfos[6].bigStep = 10;  imuItemInfos[6].lowerLimit = -300;  imuItemInfos[6].upperLimit = 300;
32
  imuItemInfos[7].adress=&offsetCompassZ;    imuItemInfos[7].varType=S_WORD; imuItemInfos[7].valueSetFunc=emptyFunc2;      imuItemInfos[7].smallStep = 1;  imuItemInfos[7].bigStep = 10;  imuItemInfos[7].lowerLimit = -300;  imuItemInfos[7].upperLimit = 300;
33
  
34
  imuGenInf.topMenuFunc=menuDisplayerInit;
35
  imuGenInf.topMenuPnt=&homeGenInf;
36
  imuGenInf.rightMenuFunc=menuDisplayerInit;
37
  imuGenInf.rightMenuPnt=&usPositionGenInf;
38
  imuGenInf.leftMenuFunc=menuDisplayerInit;
39
  imuGenInf.leftMenuPnt=&pidSetGenInf;
40
  imuGenInf.textList = &imuTextList;
41
  imuGenInf.menuItemsInfo = &imuItemInfos;
42
  imuGenInf.menuLength = 8;
43
  
44
//**Ultrasonic positioning Settings
45
  usPositionItemInfos[0].adress=&usRecK_x;  usPositionItemInfos[0].varType=DOUBLE; usPositionItemInfos[0].valueSetFunc=emptyFunc2;  usPositionItemInfos[0].smallStep = 0.001;  usPositionItemInfos[0].bigStep = 0.05;  usPositionItemInfos[0].lowerLimit = -0.5;  usPositionItemInfos[0].upperLimit = 0.5;  usPositionItemInfos[0].precision = 3;
46
  usPositionItemInfos[1].adress=&usRecJ_y;  usPositionItemInfos[1].varType=DOUBLE; usPositionItemInfos[1].valueSetFunc=emptyFunc2;  usPositionItemInfos[1].smallStep = 0.001;  usPositionItemInfos[1].bigStep = 0.05;  usPositionItemInfos[1].lowerLimit = -0.5;  usPositionItemInfos[1].upperLimit = 0.5;  usPositionItemInfos[1].precision = 3;
47
  usPositionItemInfos[2].adress=&usRecL_x;  usPositionItemInfos[2].varType=DOUBLE; usPositionItemInfos[2].valueSetFunc=emptyFunc2;  usPositionItemInfos[2].smallStep = 0.001;  usPositionItemInfos[2].bigStep = 0.05;  usPositionItemInfos[2].lowerLimit = -0.5;  usPositionItemInfos[2].upperLimit = 0.5;  usPositionItemInfos[2].precision = 3;
48
  usPositionItemInfos[3].adress=&usRecL_y;  usPositionItemInfos[3].varType=DOUBLE; usPositionItemInfos[3].valueSetFunc=emptyFunc2;  usPositionItemInfos[3].smallStep = 0.001;  usPositionItemInfos[3].bigStep = 0.05;  usPositionItemInfos[3].lowerLimit = -0.5;  usPositionItemInfos[3].upperLimit = 0.5;  usPositionItemInfos[3].precision = 3;
49
  usPositionItemInfos[4].adress=&usRecL_z;  usPositionItemInfos[4].varType=DOUBLE; usPositionItemInfos[4].valueSetFunc=emptyFunc2;  usPositionItemInfos[4].smallStep = 0.001;  usPositionItemInfos[4].bigStep = 0.05;  usPositionItemInfos[4].lowerLimit = -0.5;  usPositionItemInfos[4].upperLimit = 0.5;  usPositionItemInfos[4].precision = 3;
50
  usPositionItemInfos[5].adress=&VRefACs;    usPositionItemInfos[5].varType=U_WORD; usPositionItemInfos[5].valueSetFunc=setVRefACs;  usPositionItemInfos[5].smallStep = 1;    usPositionItemInfos[5].bigStep = 50;  usPositionItemInfos[5].lowerLimit = 0;    usPositionItemInfos[5].upperLimit = 4096;
51
52
  usPositionGenInf.topMenuFunc=menuDisplayerInit;
53
  usPositionGenInf.topMenuPnt=&homeGenInf;
54
  usPositionGenInf.rightMenuFunc=menuDisplayerInit;
55
  usPositionGenInf.rightMenuPnt=&otherSetGenInf;
56
  usPositionGenInf.leftMenuFunc=menuDisplayerInit;
57
  usPositionGenInf.leftMenuPnt=&imuGenInf;
58
  usPositionGenInf.textList = &usPositionTextList;
59
  usPositionGenInf.menuItemsInfo = &usPositionItemInfos;
60
  usPositionGenInf.menuLength = 6;
61
  
62
//**Other Settings Menu**
63
  otherSetItemInfos[0].adress=&programMotCtrl;  otherSetItemInfos[0].varType=U_BYTE; otherSetItemInfos[0].valueSetFunc=emptyFunc2;    otherSetItemInfos[0].smallStep = 1;    otherSetItemInfos[0].bigStep = 1;  otherSetItemInfos[0].lowerLimit = 0; otherSetItemInfos[0].upperLimit = 1;
64
  otherSetItemInfos[2].adress=&batteryV_Compare;  otherSetItemInfos[2].varType=DOUBLE; otherSetItemInfos[2].valueSetFunc=setBatCompare;  otherSetItemInfos[2].smallStep = 0.1;  otherSetItemInfos[2].bigStep = 1;  otherSetItemInfos[2].lowerLimit = 0; otherSetItemInfos[2].upperLimit = 20;  otherSetItemInfos[2].precision = 1;
65
  otherSetItemInfos[3].adress=&eeContrast;    otherSetItemInfos[3].varType=U_BYTE; otherSetItemInfos[3].valueSetFunc=lcdSetContrast;  otherSetItemInfos[3].smallStep = 1;    otherSetItemInfos[3].bigStep = 10;  otherSetItemInfos[3].lowerLimit = 0; otherSetItemInfos[3].upperLimit = 63;
66
  otherSetItemInfos[1].menuFunc=menuDisplayerInit; otherSetItemInfos[1].menuPnt=&servoGenInf; otherSetItemInfos[1].varType=LIST;
67
  
68
  otherSetGenInf.topMenuFunc=menuDisplayerInit;
69
  otherSetGenInf.topMenuPnt=&homeGenInf;
70
  otherSetGenInf.rightMenuFunc=menuDisplayerInit;
71
  otherSetGenInf.rightMenuPnt=&pidSetGenInf;
72
  otherSetGenInf.leftMenuFunc=menuDisplayerInit;
73
  otherSetGenInf.leftMenuPnt=&usPositionGenInf;
74
  otherSetGenInf.textList = &otherSetTextList;
75
  otherSetGenInf.menuItemsInfo = &otherSetItemInfos;
76
  otherSetGenInf.menuLength = 4;
77
78
  //**Servo Settings Menu**
79
    servoItemInfos[0].adress=&servo0pos0;  servoItemInfos[0].varType=U_WORD; servoItemInfos[0].valueSetFunc=emptyFunc2;  servoItemInfos[0].smallStep = 1;  servoItemInfos[0].bigStep = 20;  servoItemInfos[0].lowerLimit = 400;  servoItemInfos[0].upperLimit = 1100;
80
    servoItemInfos[1].adress=&servo0pos1;  servoItemInfos[1].varType=U_WORD; servoItemInfos[1].valueSetFunc=emptyFunc2;  servoItemInfos[1].smallStep = 1;  servoItemInfos[1].bigStep = 20;  servoItemInfos[1].lowerLimit = 400;  servoItemInfos[1].upperLimit = 1100;
81
    servoItemInfos[2].adress=&servo1pos0;  servoItemInfos[2].varType=U_WORD; servoItemInfos[2].valueSetFunc=emptyFunc2;  servoItemInfos[2].smallStep = 1;  servoItemInfos[2].bigStep = 20;  servoItemInfos[2].lowerLimit = 400;  servoItemInfos[2].upperLimit = 1100;
82
    servoItemInfos[3].adress=&servo1pos1;  servoItemInfos[3].varType=U_WORD; servoItemInfos[3].valueSetFunc=emptyFunc2;  servoItemInfos[3].smallStep = 1;  servoItemInfos[3].bigStep = 20;  servoItemInfos[3].lowerLimit = 400;  servoItemInfos[3].upperLimit = 1100;
83
84
    servoGenInf.topMenuFunc=menuDisplayerInit;
85
    servoGenInf.topMenuPnt=&otherSetGenInf;
86
    servoGenInf.rightMenuFunc=emptyFunc1;
87
    servoGenInf.leftMenuFunc=emptyFunc1;
88
    servoGenInf.textList = &servoTextList;
89
    servoGenInf.menuItemsInfo = &servoItemInfos;
90
    servoGenInf.menuLength = 4;
91
92
//**PID Settings Menu**
93
  pidSetItemInfos[0].menuFunc=menuDisplayerInit; pidSetItemInfos[0].menuPnt=&pidX_SetGenInf; pidSetItemInfos[0].varType=NONE;
94
  pidSetItemInfos[1].menuFunc=menuDisplayerInit; pidSetItemInfos[1].menuPnt=&pidY_SetGenInf; pidSetItemInfos[1].varType=NONE;
95
  pidSetItemInfos[2].menuFunc=menuDisplayerInit; pidSetItemInfos[2].menuPnt=&pidZ_SetGenInf; pidSetItemInfos[2].varType=NONE;
96
  pidSetItemInfos[3].menuFunc=menuDisplayerInit; pidSetItemInfos[3].menuPnt=&pidSonarSetGenInf; pidSetItemInfos[3].varType=NONE;
97
  
98
  pidSetGenInf.topMenuFunc=menuDisplayerInit;
99
  pidSetGenInf.topMenuPnt=&homeGenInf;
100
  pidSetGenInf.rightMenuFunc=menuDisplayerInit;
101
  pidSetGenInf.rightMenuPnt=&imuGenInf;
102
  pidSetGenInf.leftMenuFunc=menuDisplayerInit;
103
  pidSetGenInf.leftMenuPnt=&otherSetGenInf;
104
  pidSetGenInf.textList = &pidSetTextList;
105
  pidSetGenInf.menuItemsInfo = &pidSetItemInfos;
106
  pidSetGenInf.menuLength = 4;
107
108
  //**PID X Settings Menu**
109
    pidX_SetItemInfos[0].adress=&pidX_P;  pidX_SetItemInfos[0].varType=DOUBLE; pidX_SetItemInfos[0].valueSetFunc=emptyFunc2;  pidX_SetItemInfos[0].smallStep = 0.5;  pidX_SetItemInfos[0].bigStep = 10;  pidX_SetItemInfos[0].lowerLimit = 0; pidX_SetItemInfos[0].upperLimit = 1000;  pidX_SetItemInfos[0].precision = 1;
110
    pidX_SetItemInfos[1].adress=&pidX_I;  pidX_SetItemInfos[1].varType=DOUBLE; pidX_SetItemInfos[1].valueSetFunc=emptyFunc2;  pidX_SetItemInfos[1].smallStep = 0.5;  pidX_SetItemInfos[1].bigStep = 10;  pidX_SetItemInfos[1].lowerLimit = 0; pidX_SetItemInfos[1].upperLimit = 1000;  pidX_SetItemInfos[1].precision = 1;
111
    pidX_SetItemInfos[2].adress=&pidX_D;  pidX_SetItemInfos[2].varType=DOUBLE; pidX_SetItemInfos[2].valueSetFunc=emptyFunc2;  pidX_SetItemInfos[2].smallStep = 0.1;  pidX_SetItemInfos[2].bigStep = 5;  pidX_SetItemInfos[2].lowerLimit = 0; pidX_SetItemInfos[2].upperLimit = 1000;  pidX_SetItemInfos[2].precision = 1;
112
  
113
    pidX_SetGenInf.topMenuFunc=menuDisplayerInit;
114
    pidX_SetGenInf.topMenuPnt=&pidSetGenInf;
115
    pidX_SetGenInf.rightMenuFunc=menuDisplayerInit;
116
    pidX_SetGenInf.rightMenuPnt=&pidY_SetGenInf;
117
    pidX_SetGenInf.leftMenuFunc=menuDisplayerInit;
118
    pidX_SetGenInf.leftMenuPnt=&pidSonarSetGenInf;
119
    pidX_SetGenInf.textList = &pidX_SetTextList;
120
    pidX_SetGenInf.menuItemsInfo = &pidX_SetItemInfos;
121
    pidX_SetGenInf.menuLength = 3;
122
123
  //**PID Y Settings Menu**
124
    pidY_SetItemInfos[0].adress=&pidY_P;  pidY_SetItemInfos[0].varType=DOUBLE; pidY_SetItemInfos[0].valueSetFunc=emptyFunc2;  pidY_SetItemInfos[0].smallStep = 0.5;  pidY_SetItemInfos[0].bigStep = 10;  pidY_SetItemInfos[0].lowerLimit = 0; pidY_SetItemInfos[0].upperLimit = 1000;  pidY_SetItemInfos[0].precision = 1;
125
    pidY_SetItemInfos[1].adress=&pidY_I;  pidY_SetItemInfos[1].varType=DOUBLE; pidY_SetItemInfos[1].valueSetFunc=emptyFunc2;  pidY_SetItemInfos[1].smallStep = 0.5;  pidY_SetItemInfos[1].bigStep = 10;  pidY_SetItemInfos[1].lowerLimit = 0; pidY_SetItemInfos[1].upperLimit = 1000;  pidY_SetItemInfos[1].precision = 1;
126
    pidY_SetItemInfos[2].adress=&pidY_D;  pidY_SetItemInfos[2].varType=DOUBLE; pidY_SetItemInfos[2].valueSetFunc=emptyFunc2;  pidY_SetItemInfos[2].smallStep = 0.1;  pidY_SetItemInfos[2].bigStep = 5;  pidY_SetItemInfos[2].lowerLimit = 0; pidY_SetItemInfos[2].upperLimit = 1000;  pidY_SetItemInfos[2].precision = 1;
127
  
128
    pidY_SetGenInf.topMenuFunc=menuDisplayerInit;
129
    pidY_SetGenInf.topMenuPnt=&pidSetGenInf;
130
    pidY_SetGenInf.rightMenuFunc=menuDisplayerInit;
131
    pidY_SetGenInf.rightMenuPnt=&pidZ_SetGenInf;
132
    pidY_SetGenInf.leftMenuFunc=menuDisplayerInit;
133
    pidY_SetGenInf.leftMenuPnt=&pidX_SetGenInf;
134
    pidY_SetGenInf.textList = &pidY_SetTextList;
135
    pidY_SetGenInf.menuItemsInfo = &pidY_SetItemInfos;
136
    pidY_SetGenInf.menuLength = 3;
137
138
  //**PID Z Settings Menu**
139
    pidZ_SetItemInfos[0].adress=&pidZ_P;  pidZ_SetItemInfos[0].varType=DOUBLE; pidZ_SetItemInfos[0].valueSetFunc=emptyFunc2;  pidZ_SetItemInfos[0].smallStep = 0.5;  pidZ_SetItemInfos[0].bigStep = 5;  pidZ_SetItemInfos[0].lowerLimit = 0; pidZ_SetItemInfos[0].upperLimit = 200;  pidZ_SetItemInfos[0].precision = 1;
140
    pidZ_SetItemInfos[1].adress=&pidZ_I;  pidZ_SetItemInfos[1].varType=DOUBLE; pidZ_SetItemInfos[1].valueSetFunc=emptyFunc2;  pidZ_SetItemInfos[1].smallStep = 0.5;  pidZ_SetItemInfos[1].bigStep = 5;  pidZ_SetItemInfos[1].lowerLimit = 0; pidZ_SetItemInfos[1].upperLimit = 200;  pidZ_SetItemInfos[1].precision = 1;
141
    pidZ_SetItemInfos[2].adress=&pidZ_D;  pidZ_SetItemInfos[2].varType=DOUBLE; pidZ_SetItemInfos[2].valueSetFunc=emptyFunc2;  pidZ_SetItemInfos[2].smallStep = 0.5;  pidZ_SetItemInfos[2].bigStep = 5;  pidZ_SetItemInfos[2].lowerLimit = 0; pidZ_SetItemInfos[2].upperLimit = 200;  pidZ_SetItemInfos[2].precision = 1;
142
  
143
    pidZ_SetGenInf.topMenuFunc=menuDisplayerInit;
144
    pidZ_SetGenInf.topMenuPnt=&pidSetGenInf;
145
    pidZ_SetGenInf.rightMenuFunc=menuDisplayerInit;
146
    pidZ_SetGenInf.rightMenuPnt=&pidSonarSetGenInf;
147
    pidZ_SetGenInf.leftMenuFunc=menuDisplayerInit;
148
    pidZ_SetGenInf.leftMenuPnt=&pidY_SetGenInf;
149
    pidZ_SetGenInf.textList = &pidZ_SetTextList;
150
    pidZ_SetGenInf.menuItemsInfo = &pidZ_SetItemInfos;
151
    pidZ_SetGenInf.menuLength = 3;
152
153
  //**PID Sonar Settings Menu**
154
    pidSonarSetItemInfos[0].adress=&pidSonarP;  pidSonarSetItemInfos[0].varType=DOUBLE; pidSonarSetItemInfos[0].valueSetFunc=emptyFunc2;  pidSonarSetItemInfos[0].smallStep = 0.5;  pidSonarSetItemInfos[0].bigStep = 5;  pidSonarSetItemInfos[0].lowerLimit = 0; pidSonarSetItemInfos[0].upperLimit = 200;  pidSonarSetItemInfos[0].precision = 1;
155
    pidSonarSetItemInfos[1].adress=&pidSonarI;  pidSonarSetItemInfos[1].varType=DOUBLE; pidSonarSetItemInfos[1].valueSetFunc=emptyFunc2;  pidSonarSetItemInfos[1].smallStep = 0.5;  pidSonarSetItemInfos[1].bigStep = 5;  pidSonarSetItemInfos[1].lowerLimit = 0; pidSonarSetItemInfos[1].upperLimit = 200;  pidSonarSetItemInfos[1].precision = 1;
156
    pidSonarSetItemInfos[2].adress=&pidSonarD;  pidSonarSetItemInfos[2].varType=DOUBLE; pidSonarSetItemInfos[2].valueSetFunc=emptyFunc2;  pidSonarSetItemInfos[2].smallStep = 0.5;  pidSonarSetItemInfos[2].bigStep = 5;  pidSonarSetItemInfos[2].lowerLimit = 0; pidSonarSetItemInfos[2].upperLimit = 200;  pidSonarSetItemInfos[2].precision = 1;
157
  
158
    pidSonarSetGenInf.topMenuFunc=menuDisplayerInit;
159
    pidSonarSetGenInf.topMenuPnt=&pidSetGenInf;
160
    pidSonarSetGenInf.rightMenuFunc=menuDisplayerInit;
161
    pidSonarSetGenInf.rightMenuPnt=&pidX_SetGenInf;
162
    pidSonarSetGenInf.leftMenuFunc=menuDisplayerInit;
163
    pidSonarSetGenInf.leftMenuPnt=&pidZ_SetGenInf;
164
    pidSonarSetGenInf.textList = &pidSonarSetTextList;
165
    pidSonarSetGenInf.menuItemsInfo = &pidSonarSetItemInfos;
166
    pidSonarSetGenInf.menuLength = 3;
167
}

von Raphael F. (erdbewohner)


Lesenswert?

Weiss hier niemand eine Lösung? Es sind auch die gleichen Symptome, wenn 
ich jeweils das PROGMEM weglasse, die Arrays also nicht im Flash, 
sondern normal im SRAM liegen.

von Rene H. (Gast)


Lesenswert?

Du erwartest allen ernstes das sich einer durch diese Orgie denkt? 
Kreise das Problem ein, zeige im Code wo Du das Problem siehst.

Grüsse,
René

von Detlef K. (adenin)


Lesenswert?

Ja, und wo genau kommentiest Du da was aus?
Welche Zeile(n)?

von Raphael F. (erdbewohner)


Lesenswert?

Ähm ja, ihr habt natürlich recht. Ich habe euch da etwas viel Code an 
den Kopf geworfen und nicht alles erklärt.
Ich habe den Code jetzt soweit wie möglich gekürzt, dass der Fehler 
immer noch auftritt und die eigentliche Problemzeile markiert. Dort wird 
in die Variable nicht 4 sondern 0x23.
Nun gibt es ein paar recht merkwürdige Sachen: Wenn ich den Inhalt der 
Funktion initMenus() in die main()-Funktion kopiere und die Funktion 
initMenus() lösche, gibt es den Fehler nicht mehr. Ich kann auch fast 
jede Zeile in der Funktion auskommentieren, und der Fehler tritt nicht 
mehr auf. Oder ich kann die leere Funktion menuDisplayerInit durch die 
genau gleiche Funktion emptyFunc1 ersetzen, und der Fehler tritt auch 
nicht mehr auf.
1
#define F_CPU 32000000UL
2
3
#include <avr/pgmspace.h>
4
#include <string.h>
5
#include <avr/eeprom.h>
6
7
#define LARGEST_MENU 9
8
9
struct MenuGeneralInfo
10
{
11
  void (*topMenuFunc) (struct MenuGeneralInfo*);
12
  struct MenuGeneralInfo *topMenuPnt;
13
  void (*rightMenuFunc) (struct MenuGeneralInfo*);
14
  struct MenuGeneralInfo *rightMenuPnt;
15
  void (*leftMenuFunc) (struct MenuGeneralInfo*);
16
  struct MenuGeneralInfo *leftMenuPnt;
17
  char (*textList)[LARGEST_MENU][17];      //Has to be in the flash
18
  struct MenuItemInfo (*menuItemsInfo);    //Pointer to an array
19
  uint8_t menuLength;              //Number of Menu Items WITHOUT the Title
20
};
21
enum VarType
22
{
23
  NONE,
24
  U_BYTE,
25
  S_BYTE,
26
  U_WORD,
27
  S_WORD,
28
  DOUBLE
29
};
30
struct MenuItemInfo
31
{
32
  void (*menuFunc) (struct MenuGeneralInfo*);
33
  struct MenuGeneralInfo *menuPnt;
34
  uint16_t adress;
35
  enum VarType varType;
36
  void (*valueSetFunc) (void);
37
  double smallStep;
38
  double bigStep;
39
  double lowerLimit;
40
  double upperLimit;
41
  uint8_t precision;
42
};
43
44
void menuDisplayerInit(struct MenuGeneralInfo*);
45
void emptyFunc1(struct MenuGeneralInfo*);
46
void emptyFunc2(void);
47
void initMenus(void);
48
49
volatile double accuV;
50
51
uint8_t eeContrast __attribute__ ((section("EEPROM_P1")));
52
double batteryV_Compare __attribute__ ((section("EEPROM_P0")));
53
double usRecK_x __attribute__ ((section("EEPROM_P0")));
54
double usRecJ_y __attribute__ ((section("EEPROM_P0")));
55
double usRecL_x __attribute__ ((section("EEPROM_P0")));
56
double usRecL_y __attribute__ ((section("EEPROM_P0")));
57
double usRecL_z __attribute__ ((section("EEPROM_P0")));
58
uint16_t VRefACs __attribute__ ((section("EEPROM_P1")));
59
uint16_t imuRefresh __attribute__ ((section("EEPROM_P1")));
60
uint16_t baroCompRefresh __attribute__ ((section("EEPROM_P1")));
61
uint8_t programMotCtrl __attribute__ ((section("EEPROM_P1")));
62
double offsetGyroX __attribute__ ((section("EEPROM_P1")));
63
double offsetGyroY __attribute__ ((section("EEPROM_P1")));
64
double offsetGyroZ __attribute__ ((section("EEPROM_P1")));
65
int16_t offsetCompassX __attribute__ ((section("EEPROM_P1")));
66
int16_t offsetCompassY __attribute__ ((section("EEPROM_P1")));
67
int16_t offsetCompassZ __attribute__ ((section("EEPROM_P1")));
68
double pidX_P __attribute__ ((section("EEPROM_P2")));
69
double pidX_I __attribute__ ((section("EEPROM_P2")));
70
double pidX_D __attribute__ ((section("EEPROM_P2")));
71
double pidY_P __attribute__ ((section("EEPROM_P2")));
72
double pidY_I __attribute__ ((section("EEPROM_P2")));
73
double pidY_D __attribute__ ((section("EEPROM_P2")));
74
double pidZ_P __attribute__ ((section("EEPROM_P2")));
75
double pidZ_I __attribute__ ((section("EEPROM_P2")));
76
double pidZ_D __attribute__ ((section("EEPROM_P3")));
77
78
char const homeTextList[][17] PROGMEM =
79
{"HOME            ",
80
 " Fliegen        ",
81
 " Einstellungen  ",
82
 " U Akku =       "};
83
struct MenuItemInfo homeItemInfos[3];
84
struct MenuGeneralInfo homeGenInf;
85
86
char const pidSetTextList[][17] PROGMEM =
87
{"PID             ",
88
 " X/Roll         ",
89
 " Y/Nick         ",
90
 " Z/Yaw          ",
91
 " Sonar          "};
92
struct MenuItemInfo pidSetItemInfos[4];
93
struct MenuGeneralInfo pidSetGenInf;
94
95
char const pidX_SetTextList[][17] PROGMEM =
96
{"PID X/ROLL      ",
97
  " P              ",
98
  " I              ",
99
  " D              "};
100
struct MenuItemInfo pidX_SetItemInfos[3];
101
struct MenuGeneralInfo pidX_SetGenInf;
102
103
char const pidY_SetTextList[][17] PROGMEM =
104
{"PID Y/NICK      ",
105
  " P              ",
106
  " I              ",
107
  " D              "};
108
struct MenuItemInfo pidY_SetItemInfos[3];
109
struct MenuGeneralInfo pidY_SetGenInf;
110
111
  char const pidZ_SetTextList[][17] PROGMEM =
112
{"PID Z/YAW       ",
113
  " P              ",
114
  " I              ",
115
  " D              "};
116
struct MenuItemInfo pidZ_SetItemInfos[3];
117
struct MenuGeneralInfo pidZ_SetGenInf;
118
119
char const pidSonarSetTextList[][17] PROGMEM =
120
{"PID SONAR       ",
121
  " P              ",
122
  " I              ",
123
  " D              "};
124
struct MenuItemInfo pidSonarSetItemInfos[3];
125
struct MenuGeneralInfo pidSonarSetGenInf;
126
127
char const imuTextList[][17] PROGMEM =
128
{"IMU             ",
129
 " periodA,G      ",
130
 " periodC,B      ",
131
 " of.GX          ",
132
 " of.GY          ",
133
 " of.GZ          ",
134
 " of.CX          ",
135
 " of.CY          ",
136
 " of.CZ          "};
137
struct MenuItemInfo imuItemInfos[8];
138
struct MenuGeneralInfo imuGenInf;
139
  
140
char const usPositionTextList[][17] PROGMEM =
141
{"US POSITION     ",
142
 " RecK X         ",
143
 " RecJ Y         ",
144
 " RecL X         ",
145
 " RecL Y         ",
146
 " RecL Z         ",
147
 " Vref ACs       "};
148
struct MenuItemInfo usPositionItemInfos[6];
149
struct MenuGeneralInfo usPositionGenInf;
150
151
char const otherSetTextList[][17] PROGMEM =
152
{"SONSTIGES       ",
153
 " prog. Regler   ",
154
 " Servos         ",
155
 " Akkulimit      ",
156
 " Kontrast LCD   "};
157
struct MenuItemInfo otherSetItemInfos[4];
158
struct MenuGeneralInfo otherSetGenInf;
159
160
void menuDisplayerInit(struct MenuGeneralInfo *menuInfo){}
161
162
void emptyFunc1(struct MenuGeneralInfo *menuInfo){}
163
void emptyFunc2(void){}
164
165
void initMenus(void)
166
{
167
  homeItemInfos[2].adress=&accuV;  homeItemInfos[2].varType=DOUBLE; homeItemInfos[2].valueSetFunc=emptyFunc2;  homeItemInfos[2].smallStep = 0;  homeItemInfos[2].bigStep = 0;  homeItemInfos[2].lowerLimit = 0; homeItemInfos[2].upperLimit = 200;  homeItemInfos[2].precision = 1;
168
  
169
//**IMU Settings**  
170
  imuItemInfos[0].adress=&imuRefresh;      imuItemInfos[0].varType=U_WORD;  imuItemInfos[0].valueSetFunc=emptyFunc2;    imuItemInfos[0].smallStep = 10;  imuItemInfos[0].bigStep = 100;  imuItemInfos[0].lowerLimit = 0;    imuItemInfos[0].upperLimit = 65530;
171
  imuItemInfos[1].adress=&baroCompRefresh;  imuItemInfos[1].varType=U_WORD;  imuItemInfos[1].valueSetFunc=emptyFunc2;    imuItemInfos[1].smallStep = 10;  imuItemInfos[1].bigStep = 500;  imuItemInfos[1].lowerLimit = 0;    imuItemInfos[1].upperLimit = 65530;
172
  imuItemInfos[2].adress=&offsetGyroX;    imuItemInfos[2].varType=DOUBLE; imuItemInfos[2].valueSetFunc=emptyFunc2;    imuItemInfos[2].smallStep = 1;  imuItemInfos[2].bigStep = 10;  imuItemInfos[2].lowerLimit = -500;  imuItemInfos[2].upperLimit = 500;  imuItemInfos[2].precision = 0;
173
  imuItemInfos[3].adress=&offsetGyroY;    imuItemInfos[3].varType=DOUBLE; imuItemInfos[3].valueSetFunc=emptyFunc2;    imuItemInfos[3].smallStep = 1;  imuItemInfos[3].bigStep = 10;  imuItemInfos[3].lowerLimit = -500;  imuItemInfos[3].upperLimit = 500;  imuItemInfos[3].precision = 0;
174
  imuItemInfos[4].adress=&offsetGyroZ;    imuItemInfos[4].varType=DOUBLE; imuItemInfos[4].valueSetFunc=emptyFunc2;    imuItemInfos[4].smallStep = 1;  imuItemInfos[4].bigStep = 10;  imuItemInfos[4].lowerLimit = -500;  imuItemInfos[4].upperLimit = 500;  imuItemInfos[4].precision = 0;
175
  imuItemInfos[5].adress=&offsetCompassX;    imuItemInfos[5].varType=S_WORD; imuItemInfos[5].valueSetFunc=emptyFunc2;    imuItemInfos[5].smallStep = 1;  imuItemInfos[5].bigStep = 10;  imuItemInfos[5].lowerLimit = -300;  imuItemInfos[5].upperLimit = 300;
176
  imuItemInfos[6].adress=&offsetCompassY;    imuItemInfos[6].varType=S_WORD; imuItemInfos[6].valueSetFunc=emptyFunc2;    imuItemInfos[6].smallStep = 1;  imuItemInfos[6].bigStep = 10;  imuItemInfos[6].lowerLimit = -300;  imuItemInfos[6].upperLimit = 300;
177
  imuItemInfos[7].adress=&offsetCompassZ;    imuItemInfos[7].varType=S_WORD; imuItemInfos[7].valueSetFunc=emptyFunc2;    imuItemInfos[7].smallStep = 1;  imuItemInfos[7].bigStep = 10;  imuItemInfos[7].lowerLimit = -300;  imuItemInfos[7].upperLimit = 300;
178
  
179
//**Ultrasonic positioning Settings
180
  usPositionItemInfos[0].adress=&usRecK_x;  usPositionItemInfos[0].varType=DOUBLE; usPositionItemInfos[0].valueSetFunc=emptyFunc2;  usPositionItemInfos[0].smallStep = 0.001;  usPositionItemInfos[0].bigStep = 0.05;  usPositionItemInfos[0].lowerLimit = -0.5;  usPositionItemInfos[0].upperLimit = 0.5;  usPositionItemInfos[0].precision = 3;
181
  usPositionItemInfos[1].adress=&usRecJ_y;  usPositionItemInfos[1].varType=DOUBLE; usPositionItemInfos[1].valueSetFunc=emptyFunc2;  usPositionItemInfos[1].smallStep = 0.001;  usPositionItemInfos[1].bigStep = 0.05;  usPositionItemInfos[1].lowerLimit = -0.5;  usPositionItemInfos[1].upperLimit = 0.5;  usPositionItemInfos[1].precision = 3;
182
  usPositionItemInfos[2].adress=&usRecL_x;  usPositionItemInfos[2].varType=DOUBLE; usPositionItemInfos[2].valueSetFunc=emptyFunc2;  usPositionItemInfos[2].smallStep = 0.001;  usPositionItemInfos[2].bigStep = 0.05;  usPositionItemInfos[2].lowerLimit = -0.5;  usPositionItemInfos[2].upperLimit = 0.5;  usPositionItemInfos[2].precision = 3;
183
  usPositionItemInfos[3].adress=&usRecL_y;  usPositionItemInfos[3].varType=DOUBLE; usPositionItemInfos[3].valueSetFunc=emptyFunc2;  usPositionItemInfos[3].smallStep = 0.001;  usPositionItemInfos[3].bigStep = 0.05;  usPositionItemInfos[3].lowerLimit = -0.5;  usPositionItemInfos[3].upperLimit = 0.5;  usPositionItemInfos[3].precision = 3;
184
  usPositionItemInfos[4].adress=&usRecL_z;  usPositionItemInfos[4].varType=DOUBLE; usPositionItemInfos[4].valueSetFunc=emptyFunc2;  usPositionItemInfos[4].smallStep = 0.001;  usPositionItemInfos[4].bigStep = 0.05;  usPositionItemInfos[4].lowerLimit = -0.5;  usPositionItemInfos[4].upperLimit = 0.5;  usPositionItemInfos[4].precision = 3;
185
  usPositionItemInfos[5].adress=&VRefACs;    usPositionItemInfos[5].varType=U_WORD; usPositionItemInfos[5].valueSetFunc=emptyFunc2;  usPositionItemInfos[5].smallStep = 1;    usPositionItemInfos[5].bigStep = 50;  usPositionItemInfos[5].lowerLimit = 0;    usPositionItemInfos[5].upperLimit = 4096;
186
187
  usPositionGenInf.topMenuFunc=menuDisplayerInit;
188
  usPositionGenInf.topMenuPnt=&homeGenInf;
189
  usPositionGenInf.rightMenuFunc=menuDisplayerInit;
190
  usPositionGenInf.rightMenuPnt=&otherSetGenInf;
191
  usPositionGenInf.leftMenuFunc=menuDisplayerInit;
192
  usPositionGenInf.leftMenuPnt=&imuGenInf;
193
  usPositionGenInf.textList = &usPositionTextList;
194
  usPositionGenInf.menuItemsInfo = &usPositionItemInfos;
195
  usPositionGenInf.menuLength = 6;
196
  
197
//**Other Settings Menu**
198
  otherSetItemInfos[0].adress=&programMotCtrl;  otherSetItemInfos[0].varType=U_BYTE; otherSetItemInfos[0].valueSetFunc=emptyFunc2;    otherSetItemInfos[0].smallStep = 1;    otherSetItemInfos[0].bigStep = 1;  otherSetItemInfos[0].lowerLimit = 0; otherSetItemInfos[0].upperLimit = 1;
199
  otherSetItemInfos[2].adress=&batteryV_Compare;  otherSetItemInfos[2].varType=DOUBLE; otherSetItemInfos[2].valueSetFunc=emptyFunc2;  otherSetItemInfos[2].smallStep = 0.1;  otherSetItemInfos[2].bigStep = 1;  otherSetItemInfos[2].lowerLimit = 0; otherSetItemInfos[2].upperLimit = 20;  otherSetItemInfos[2].precision = 1;
200
  otherSetItemInfos[3].adress=&eeContrast;    otherSetItemInfos[3].varType=U_BYTE; otherSetItemInfos[3].valueSetFunc=emptyFunc2;  otherSetItemInfos[3].smallStep = 1;    otherSetItemInfos[3].bigStep = 10;  otherSetItemInfos[3].lowerLimit = 0; otherSetItemInfos[3].upperLimit = 63;
201
  
202
  otherSetGenInf.topMenuFunc=menuDisplayerInit;
203
  otherSetGenInf.topMenuPnt=&homeGenInf;
204
  otherSetGenInf.rightMenuFunc=menuDisplayerInit;
205
  otherSetGenInf.rightMenuPnt=&pidSetGenInf;
206
  otherSetGenInf.leftMenuFunc=menuDisplayerInit;
207
  otherSetGenInf.leftMenuPnt=&usPositionGenInf;
208
  otherSetGenInf.textList = &otherSetTextList;
209
  otherSetGenInf.menuItemsInfo = &otherSetItemInfos;
210
  otherSetGenInf.menuLength = 4;
211
212
//**PID Settings Menu**
213
  pidSetItemInfos[0].menuFunc=menuDisplayerInit; pidSetItemInfos[0].menuPnt=&pidX_SetGenInf; pidSetItemInfos[0].varType=NONE;
214
  pidSetItemInfos[1].menuFunc=menuDisplayerInit; pidSetItemInfos[1].menuPnt=&pidY_SetGenInf; pidSetItemInfos[1].varType=NONE;
215
  pidSetItemInfos[2].menuFunc=menuDisplayerInit; pidSetItemInfos[2].menuPnt=&pidZ_SetGenInf; pidSetItemInfos[2].varType=NONE;
216
  pidSetItemInfos[3].menuFunc=menuDisplayerInit; pidSetItemInfos[3].menuPnt=&pidSonarSetGenInf; pidSetItemInfos[3].varType=NONE;
217
  
218
  pidSetGenInf.topMenuFunc=menuDisplayerInit;
219
  pidSetGenInf.topMenuPnt=&homeGenInf;
220
  pidSetGenInf.rightMenuFunc=menuDisplayerInit;
221
  pidSetGenInf.rightMenuPnt=&imuGenInf;
222
  pidSetGenInf.leftMenuFunc=menuDisplayerInit;
223
  pidSetGenInf.leftMenuPnt=&otherSetGenInf;
224
  pidSetGenInf.textList = &pidSetTextList;
225
  pidSetGenInf.menuItemsInfo = &pidSetItemInfos;
226
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
227
/*>>>>*/pidSetGenInf.menuLength = 4;//<<<<<<<< Hier ist der Fehler. Die Variable wird nicht korrekt beschrieben
228
229
  //**PID X Settings Menu**
230
  pidX_SetItemInfos[0].adress=&pidX_P;  pidX_SetItemInfos[0].varType=DOUBLE; pidX_SetItemInfos[0].valueSetFunc=emptyFunc2;  pidX_SetItemInfos[0].smallStep = 0.5;  pidX_SetItemInfos[0].bigStep = 10;  pidX_SetItemInfos[0].lowerLimit = 0; pidX_SetItemInfos[0].upperLimit = 1000;  pidX_SetItemInfos[0].precision = 1;
231
  pidX_SetItemInfos[1].adress=&pidX_I;  pidX_SetItemInfos[1].varType=DOUBLE; pidX_SetItemInfos[1].valueSetFunc=emptyFunc2;  pidX_SetItemInfos[1].smallStep = 0.5;  pidX_SetItemInfos[1].bigStep = 10;  pidX_SetItemInfos[1].lowerLimit = 0; pidX_SetItemInfos[1].upperLimit = 1000;  pidX_SetItemInfos[1].precision = 1;
232
  pidX_SetItemInfos[2].adress=&pidX_D;  pidX_SetItemInfos[2].varType=DOUBLE; pidX_SetItemInfos[2].valueSetFunc=emptyFunc2;  pidX_SetItemInfos[2].smallStep = 0.1;  pidX_SetItemInfos[2].bigStep = 5;  pidX_SetItemInfos[2].lowerLimit = 0; pidX_SetItemInfos[2].upperLimit = 1000;  pidX_SetItemInfos[2].precision = 1;
233
  
234
  pidX_SetGenInf.topMenuFunc=menuDisplayerInit;
235
  pidX_SetGenInf.topMenuPnt=&pidSetGenInf;
236
  pidX_SetGenInf.rightMenuFunc=menuDisplayerInit;
237
  pidX_SetGenInf.rightMenuPnt=&pidY_SetGenInf;
238
  pidX_SetGenInf.leftMenuFunc=menuDisplayerInit;
239
  pidX_SetGenInf.leftMenuPnt=&pidSonarSetGenInf;
240
  pidX_SetGenInf.textList = &pidX_SetTextList;
241
  pidX_SetGenInf.menuItemsInfo = &pidX_SetItemInfos;
242
  pidX_SetGenInf.menuLength = 3;
243
244
//**PID Y Settings Menu**
245
  pidY_SetItemInfos[0].adress=&pidY_P;  pidY_SetItemInfos[0].varType=DOUBLE; pidY_SetItemInfos[0].valueSetFunc=emptyFunc2;  pidY_SetItemInfos[0].smallStep = 0.5;  pidY_SetItemInfos[0].bigStep = 10;  pidY_SetItemInfos[0].lowerLimit = 0; pidY_SetItemInfos[0].upperLimit = 1000;  pidY_SetItemInfos[0].precision = 1;
246
  pidY_SetItemInfos[1].adress=&pidY_I;  pidY_SetItemInfos[1].varType=DOUBLE; pidY_SetItemInfos[1].valueSetFunc=emptyFunc2;  pidY_SetItemInfos[1].smallStep = 0.5;  pidY_SetItemInfos[1].bigStep = 10;  pidY_SetItemInfos[1].lowerLimit = 0; pidY_SetItemInfos[1].upperLimit = 1000;  pidY_SetItemInfos[1].precision = 1;
247
  pidY_SetItemInfos[2].adress=&pidY_D;  pidY_SetItemInfos[2].varType=DOUBLE; pidY_SetItemInfos[2].valueSetFunc=emptyFunc2;  pidY_SetItemInfos[2].smallStep = 0.1;  pidY_SetItemInfos[2].bigStep = 5;  pidY_SetItemInfos[2].lowerLimit = 0; pidY_SetItemInfos[2].upperLimit = 1000;  pidY_SetItemInfos[2].precision = 1;
248
  
249
  pidY_SetGenInf.topMenuFunc=menuDisplayerInit;
250
  pidY_SetGenInf.topMenuPnt=&pidSetGenInf;
251
  pidY_SetGenInf.rightMenuFunc=menuDisplayerInit;
252
  pidY_SetGenInf.rightMenuPnt=&pidZ_SetGenInf;
253
  pidY_SetGenInf.leftMenuFunc=menuDisplayerInit;
254
  pidY_SetGenInf.leftMenuPnt=&pidX_SetGenInf;
255
  pidY_SetGenInf.textList = &pidY_SetTextList;
256
  pidY_SetGenInf.menuItemsInfo = &pidY_SetItemInfos;
257
  pidY_SetGenInf.menuLength = 3;
258
259
//**PID Z Settings Menu**
260
  pidZ_SetItemInfos[0].adress=&pidZ_P;  pidZ_SetItemInfos[0].varType=DOUBLE; pidZ_SetItemInfos[0].valueSetFunc=emptyFunc2;  //pidZ_SetItemInfos[0].smallStep = 0.5;  pidZ_SetItemInfos[0].bigStep = 5;  pidZ_SetItemInfos[0].lowerLimit = 0; pidZ_SetItemInfos[0].upperLimit = 200;  pidZ_SetItemInfos[0].precision = 1;
261
  pidZ_SetItemInfos[1].adress=&pidZ_I;  pidZ_SetItemInfos[1].varType=DOUBLE; pidZ_SetItemInfos[1].valueSetFunc=emptyFunc2;  //pidZ_SetItemInfos[1].smallStep = 0.5;  pidZ_SetItemInfos[1].bigStep = 5;  pidZ_SetItemInfos[1].lowerLimit = 0; pidZ_SetItemInfos[1].upperLimit = 200;  pidZ_SetItemInfos[1].precision = 1;
262
  pidZ_SetItemInfos[2].adress=&pidZ_D;  pidZ_SetItemInfos[2].varType=DOUBLE; pidZ_SetItemInfos[2].valueSetFunc=emptyFunc2;  //pidZ_SetItemInfos[2].smallStep = 0.5;  pidZ_SetItemInfos[2].bigStep = 5;  pidZ_SetItemInfos[2].lowerLimit = 0; pidZ_SetItemInfos[2].upperLimit = 200;  pidZ_SetItemInfos[2].precision = 1;
263
  
264
  pidZ_SetGenInf.topMenuFunc=menuDisplayerInit;
265
  pidZ_SetGenInf.topMenuPnt=&pidSetGenInf;
266
  pidZ_SetGenInf.rightMenuFunc=menuDisplayerInit;
267
  pidZ_SetGenInf.rightMenuPnt=&pidSonarSetGenInf;
268
  pidZ_SetGenInf.leftMenuFunc=menuDisplayerInit;
269
  pidZ_SetGenInf.leftMenuPnt=&pidY_SetGenInf;
270
  pidZ_SetGenInf.textList = &pidZ_SetTextList;
271
  pidZ_SetGenInf.menuItemsInfo = &pidZ_SetItemInfos;
272
  pidZ_SetGenInf.menuLength = 3;
273
}
274
275
int main(void)
276
{
277
  initMenus();
278
  
279
  while(1)
280
  {
281
    ;
282
  }
283
}

von Bernhard S. (b_spitzer)


Lesenswert?

Hast Du mal im Listing geschaut, ob Dir bei den vielen Strukturen nicht 
so langsam der verfügbare Speicherplatz ausgeht? Eventuell überschreibst 
Du dir einfach eine Page im EEPROM.
Ist für die ganzen Parameter wirklich DOUBLE notwendig? Selbst Float hat 
24Bit in der Mantisse, so genau dürfte deine Analogberechnung kaum sein.

von Raphael F. (erdbewohner)


Lesenswert?

Ich habe ja den ATXmega256A3 mit 16kB RAM. Beim Compilieren sagt er 
auch, es seien nur 7.4% verbraucht. Auch für die EEPROM-Pages habe ich 
eine Tabelle erstellt. Es müsste aufgehen. Übrigens habe ich gedacht, 
dass double und float in AVR-C genau das gleiche sind.

von Georg G. (df2au)


Lesenswert?

Raphael F. schrieb:
> double und float in AVR-C genau das gleiche sind

Richtig, so ist es. Double in AVR-GCC ist etwas abweichend von der Norm, 
ist aber so auch in der Doku vermerkt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Zugriff auf PROGMEM-Variablen geschieht über pgm_read-Funktionen.

Alternativ nimm __flash (ab avr-gcc 4.7).

von Raphael F. (erdbewohner)


Lesenswert?

Ich habe mir eine eigene funktion programmiert, die auch funktioniert. 
Aber das spielt ja hier keine Rolle.
Ich kann doch schon einen normalen Pointer mit einer flash-adresse 
laden, wenn ich ihn nachher auch entsprechend behandle, oder?

von Raphael F. (erdbewohner)


Lesenswert?

Wenn ich in die .map-Datei schaue, passen die flash-pointer gut in ein 
16-bit-pointer:
1
 
2
.progmem.data  0x000001e8      0x30e test.o
3
                0x000001e8                otherSetTextList
4
                0x0000023d                usPositionTextList
5
                0x000002b4                imuTextList
6
                0x0000034d                pidSonarSetTextList
7
                0x00000391                pidZ_SetTextList
8
                0x000003d5                pidY_SetTextList
9
                0x00000419                pidX_SetTextList
10
                0x0000045d                pidSetTextList
11
                0x000004b2                homeTextList
12
                0x000004f6                . = ALIGN (0x2)
13
                0x000004f6                __trampolines_start = .
Allerdings sollte ich, wenn mein Programm wächst, wohl 
uint32_t-Variablen nehmen.
Aber all das erklärt dieses merkwürdige Problem leider nicht...

von MWS (Gast)


Lesenswert?

Raphael F. schrieb:
> Ich kann doch schon einen normalen Pointer mit einer flash-adresse
> laden, wenn ich ihn nachher auch entsprechend behandle, oder?

Wie sorgst Du dafür dass der µC das RAMPZ-Register setzt und damit das 
Flash auf der richtigen Page adressiert? Es können 4 Pages sein, ein 
16Bit-Pointer kann die nicht abdecken.

Der Programmcode kann im Flash beispielsweise auf Page1 ausgeführt 
werden und müsste dann wissen, dass er RAMPZ auf 0 setzen muss, damit 
der Pointer wieder auf Page 0, laut der .map, zeigt. Wie stellst Du das 
sicher?

Was passiert übrigens, wenn Du otherSetItemInfos[1] mit Defaults 
belegst?

von Raphael F. (erdbewohner)


Lesenswert?

MWS schrieb:
> Wie sorgst Du dafür dass der µC das RAMPZ-Register setzt und damit das
> Flash auf der richtigen Page adressiert? Es können 4 Pages sein, ein
> 16Bit-Pointer kann die nicht abdecken.
Dafür habe ich eben die eigene Flash-Lese-Funktion geschrieben:
1
uint8_t readFlashByte(uint32_t adress)//reads a byte from the flash memory
2
{
3
  eepromWaitUntilReady();  //wait until the NVM controller is not busy
4
  uint8_t byte;      //this variable will get filled with the read byte
5
  NVM_CMD = NVM_CMD_NO_OPERATION_gc;  //No-Operation-Command for reading via lpm
6
  CPU_RAMPZ  = (uint8_t)(adress>>16);  //The highest byte of the 24-bit-adress has to be stored in the z-pointer-extension register
7
  asm("elpm %0, Z"  "\n\t"      //Call "elpm" which loads the byte of the adress in the z-pointer into byte
8
    :"=r" (byte)
9
    :"z" ((uint16_t)adress));
10
  return byte;  //return the read value
11
}

Die Zeile, wo otherSetItemInfos[1] beschrieben wird habe ich gelöscht, 
da ich gemerkt habe, dass das Problem dann immer noch auftritt und ich 
den Code für ins Forum möglichst kurz und übersichtlich halten wollte.

von Raphael F. (erdbewohner)


Lesenswert?

Ich habe es gerade mal ausprobiert und den Pointer, der mit der 
flash-Adresse geladen wird, in eine uint32_t-Variable umbenannt (kein 
Pointer): Es bringt nichts. :(

von Georg G. (df2au)


Lesenswert?

Kann es sein, dass du EEPROM und Flash durcheinander würfelst?

>uint8_t readFlashByte(uint32_t adress)//reads a byte from the flash memory
{
>  eepromWaitUntilReady();  //wait until the NVM controller is not busy

Versuch doch bitte das Code Monstrum auf die 10 Zeilen zu reduzieren, 
die den Fehler verursachen. So ist es nervig, sich da durch zu wühlen.

von MWS (Gast)


Lesenswert?

Raphael F. schrieb:
> Ich habe es gerade mal ausprobiert und den Pointer, der mit der
> flash-Adresse geladen wird,

Bei pgm_read_... gibt's sowohl near, als far Versionen. Da würde ich 
jetzt annehmen, dass der Compiler bei Übergabe einer Pgmem-Konstanten 
über die entsprechende Länge der übergebenen Adresse entscheidet. Nur 
seh' ich nicht, wie der Compiler bei Deinem Code wissen soll, welchen 
Typ Adresse 16/32Bit Du willst. Wenn Du nur 16Bit bekommst, kann 
readFlashByte auch nicht mehr draus machen.

Aber das scheint erstmal nicht das Problem, wenn Du das Byte bereits 
falsch im Flash wiederfindest. Wäre dagegen nur das Leseergebnis falsch, 
könnt's so ein Adressproblem sein.

An welcher Adresse absolut im Flash befindet sich denn das fehlerhafte 
Byte?

von Raphael F. (erdbewohner)


Lesenswert?

Georg G. schrieb:
> Kann es sein, dass du EEPROM und Flash durcheinander würfelst?
>
>>uint8_t readFlashByte(uint32_t adress)//reads a byte from the flash memory
> {
>>  eepromWaitUntilReady();  //wait until the NVM controller is not busy

Nein, das stimmt schon. Nur die Bezeichnungen sind verwirrend. 
eepromWaitUntilReady() wartet, bis der NVM-Controller fertig ist. Dieser 
ist für Eeprom und Flash zuständig.

Das mit dem langen Code tut mir leid, aber ich habe ihn schon so weit 
wie möglich gekürzt. Sobald ich ihn noch mehr kürze, besteht der Fehler 
nicht mehr:

Raphael F. schrieb:
> Nun gibt es ein paar recht merkwürdige Sachen: Wenn ich den Inhalt der
> Funktion initMenus() in die main()-Funktion kopiere und die Funktion
> initMenus() lösche, gibt es den Fehler nicht mehr. Ich kann auch fast
> jede Zeile in der Funktion auskommentieren, und der Fehler tritt nicht
> mehr auf. Oder ich kann die leere Funktion menuDisplayerInit durch die
> genau gleiche Funktion emptyFunc1 ersetzen, und der Fehler tritt auch
> nicht mehr auf.

von Raphael F. (erdbewohner)


Lesenswert?

MWS schrieb:
> Aber das scheint erstmal nicht das Problem, wenn Du das Byte bereits
> falsch im Flash wiederfindest. Wäre dagegen nur das Leseergebnis falsch,
> könnt's so ein Adressproblem sein.
>
> An welcher Adresse absolut im Flash befindet sich denn das fehlerhafte
> Byte?

Ich bin nicht sicher, ob wir uns richtig verstehen. Das Problem liegt 
nicht bei einer PROGMEM-Variable, sondern dass
1
pidSetGenInf.menuLength = 4;
nicht funktioniert. Wenn ich im debugging-Modus nach dieser Zeile 
anhalte, sehe ich immer, dass die Variable den Wert 0x23 (anfänglich mal 
0x37) hat. Meine Vermutung ist, dass ich durch falsches adressieren 
später diese Variable mit besagtem Wert überschreibe und dass der 
Compiler dieses doppelte Überschreiben wegoptimiert.
Denn bei Optimisazion 0 tritt der Fehler gar nicht auf (sie wird auch 
nicht später mit 0x23 geladen).

von MWS (Gast)


Lesenswert?

Raphael F. schrieb:
> Ich bin nicht sicher, ob wir uns richtig verstehen.

Ich habe noch um etwas Anderes rumtheoretisiert, aber das schrieb ich ja 
;-)

> Wenn ich im debugging-Modus nach dieser Zeile
> anhalte, sehe ich immer, dass die Variable den Wert 0x23

Du mischt das Menü aus Flash und SRam? Welchen Sinn macht das? Du hast 
doch kein dynamisches Menü, welches solcherart erweiter-/veränderbar 
sein soll.

So wie sich's anfänglich las:
Raphael F. schrieb:
> (ich habe auch im Disassembly geschaut, er schreibt wirklich
> direkt 0x37 anstatt 4 hinein)

und auch weil man ein statisches Menü komplett in den Flash packen 
würde, nahm ich an, dass sich die 0x23 an einer Stelle im Flash befindet 
und es dort eben Probleme mit einer Page-Grenze gäbe.

Das scheint jedoch nicht der Fall zu sein, denn wär's im Flash, könntest 
Du an dieser Stelle gar nicht debuggen, da der Wert zur Kompilierzeit 
in's Flash geschrieben würde und die Zeile
1
pidSetGenInf.menuLength = 4;
damit nicht mehr ausführ-/debugbar wäre.

Man konnte in Studio 4 Haltepunkte auf SRam-Zellen legen und eine 
Änderung überwachen, probier' doch mal, ob das in Studio 6 auch geht. 
Dann könntest Du die Optimierung auf 0 setzen und testen, woher auf 
diese Zelle zugegriffen wird.

von Raphael F. (erdbewohner)


Lesenswert?

MWS schrieb:
> Du mischt das Menü aus Flash und SRam? Welchen Sinn macht das? Du hast
> doch kein dynamisches Menü, welches solcherart erweiter-/veränderbar
> sein soll.

Der Sinn ist, dass es mir zu kompliziert war, alles ins flash zu tun, da 
ich auf die anderen beiden structs recht oft zugreife, während ich den 
text-array beim aufrufen eines Menus in den ram lade und gut ist.

Databreakpoints gibts im 6 leider nicht mehr, aber es hätte ja auch gar 
nichts gebracht, da bei Optimierung 0 der Wert gar nicht auf 0x23 
gesetzt wird, sondern auf 4 bleibt.
Könnte es an einer Makefile-Einstellung liegen? Ich habe eigentlich 
überall die Standart-Einstellungen verwendet.

von MWS (Gast)


Lesenswert?

Also wenn mal die 39 Warnings wegen missbräuchlicher Pointerumwandlung 
außer acht lässt, dann kompiliert (-Os) Dein Code hier:

Beitrag "Re: Problem: Compiler beschreibt variable nicht korrekt"

bei mir einwandfrei und in der Zelle steht drin, was soll, auch nach 
Ausführung der kompletten Funktion.

Hier wird 0x04 geladen:
1
00000351  LDI R29,0x04    Load immediate
Und hier abgelegt:
1
/*>>>>*/pidSetGenInf.menuLength = 4;//<<<<<<<< Hier ist der Fehler. Die Variable wird nicht korrekt beschrieben
2
00000668  STS 0x22EB,R29    Store direct to data space

von Raphael F. (erdbewohner)


Lesenswert?

Hm, ok. Könntest du mir mal dein Makefile schicken?
Welche Programmierumgebung hast du?
Vielen Dank übrigens für die ganzen Mühen!

von MWS (Gast)


Angehängte Dateien:

Lesenswert?

AVRStudio 6.1.2562, Makefile anhängend, Pfade sind gegen ... ersetzt.
Das ist meine Debug-Konfiguration, nur war die Optimierung auf -Os 
gesetzt.

Hab's auch noch mit der Release-Konfiguration laufen lassen. Ist zwar 
schwieriger ohne Debug-Information, man muss über's Assembler-Listing 
gehen.

Hab' die Speicherzelle nach Ausführung der Funktion abgefragt, war ok, 
enthielt 4. Kann natürlich sein, dass unter einer anderen 
Konfiguration ein Fehler woanders existiert.

Kein Problem ;-)

von Arno (Gast)


Lesenswert?

Dito hier:

-O3, -O2 und -Os
1
 1205 0892 44E0                 ldi r20,lo8(4)
2
 1206 0894 B42E                 mov r11,r20
3
4
 [...]
5
6
 1294 095a B092 0000            sts pidSetGenInf+16,r11

-O1
1
 1252 08f0 6894                 set
2
 1253 08f2 BB24                 clr r11
3
 1254 08f4 B2F8                 bld r11,2
4
5
 [...]
6
7
 1342 09ba B092 0000            sts pidSetGenInf+16,r11

-O0
1
 1764 0b2c 84E0                 ldi r24,lo8(4)
2
 1765 0b2e 8093 0000            sts pidSetGenInf+16,r24

Jeweils erstellt mit:

avr-gcc -O$irgendwas -mmcu=atxmega256a3 /tmp/test.c -pedantic -Wall -g 
-Wa,-adhlns

Version ist avr-gcc 4.7.1.

MfG, Arno

von Raphael F. (erdbewohner)


Lesenswert?

Ich habe jetzt auf AVRStudio 6.1.2730 upgedated und es scheint nun auch 
bei mir zu funktionieren...

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.