Forum: Mikrocontroller und Digitale Elektronik Funktionszeiger in Menüstruktur


von Ulf (Gast)


Lesenswert?

Hallo!

In Guttenbergscher Anlehnung an die hier
Beitrag "Menüstruktur für Grafikdisplay"
geposteten Erkenntnisse will ich eine Menüstruktur zusammenbasteln, die 
mit einem PIC18f4550 und einem Graphik-Touchdisplay läuft.
1
#define off 0
2
#define on 1
3
4
void menu(void);
5
void leer(void);
6
//typedef void (*action)();
7
8
/*===================================================*/
9
//   Buttonberechnung:
10
//   StartPosition ist immer Textposition
11
//   Rahmen errechnet sich aus Textposition
12
//   Rahmengröße immer gleich, max. 11 Zeichen, 104x24 Pixel
13
//    
14
/*===================================================*/
15
16
17
struct Button
18
{
19
 char Text[12];      // angezeigter Button-Name max. 11 Zeichen
20
  unsigned startx,starty;  // Startpunkt des Buttons als Textposition
21
  unsigned Active;    // Nur aktive B. werden genutzt
22
  void (*action)(void);    // Zeiger auf Funktion beim Drücken
23
}button[10];
24
25
struct Button buttons[] =   // hier sind alle Buttons gespeichert
26
{ 
27
  { "12345678901",26, 17, on,leer },
28
  { "ABC        ",26, 20, on,leer },
29
  { "Werte      ",26, 23, on,leer },
30
  { "Reset      ",26, 26, on ,leer},
31
};
32
33
#define NrAllButtons ( sizeof( buttons ) / sizeof( buttons[0] ) )
34
35
void ShowActiveButtons() //malt die Buttons
36
{
37
 unsigned i;
38
 for( i = 0; i < NrAllButtons; ++i ) {
39
  if( buttons[i].Active ) {
40
   GLCD_Rectangle(buttons[i].startx*8,buttons[i].starty*8,
41
    (buttons[i].startx*8)+104, (  buttons[i].starty*8)+24 );
42
   GLCD_TextGoTo(( buttons[i].startx)+1, (buttons[i].starty)+1);  
43
   GLCD_WriteText(buttons[i].Text );
44
  }
45
 }
46
}
47
48
/********************************************************************
49
* Function:        imButton
50
*  
51
*  true, wenn eingegebene Koordinaten 
52
*  innerhalb von button[i] liegen.
53
 *******************************************************************/
54
unsigned char imButton(unsigned int txpos, unsigned int typos,unsigned char nr)
55
{
56
 if( buttons[nr].Active )
57
  if(((buttons[nr].startx<txpos)&& (txpos<(buttons[nr].startx+104)))&&
58
      (buttons[nr].starty<typos)&& (typos<(buttons[nr].starty*+24 )))
59
    return(1);
60
  else return(0);
61
}
62
63
/********************************************************************
64
* Function:        void leer(void)
65
*  
66
* eine der Menüfunktionen
67
*     
68
 *******************************************************************/
69
void leer(void){
70
  GLCD_TextGoTo(13, 27);
71
  GLCD_WriteTextP("ertappt!");
72
}
73
74
75
/********************************************************************
76
 * Function:        void menuHandler(void)
77
*
78
*  muß in main.c zyklisch aufgerufen werden....
79
*  
80
*  liest die Touch- Koordinaten aus
81
*  und ruft die entsprechenden Funktionen auf.
82
 *******************************************************************/
83
void menuHandler(void){
84
 unsigned char i;
85
 touch_init();//schaltet die Ports
86
  if Finger{//Touch gedrückt? (X-Leitungen mit Y verbunden)
87
   for(i = 0; i < NrAllButtons; i++){          
88
    if((imButton(Touch_x()/8, Touch_y()/8, i))!=0){
89
     button[i].action(); //---->Dieser Aufruf führt zum Absturz
90
     GLCD_TextGoTo(3, 26);GLCD_WriteText(buttons[i].Text );
91
//zeigt den gedrückten Buttontext noch mal an---nur zum Testen-, muß wieder raus!!--
92
   }
93
  }
94
  GLCD_SetPixel(Touch_x(),Touch_y(), 1);//nur zur Kontrolle, wo gedrückt wurde, muß wieder raus!!
95
 }
96
 monitor();//zeigt allerlei Variablen an
97
}

Zur Verzweiflung bringt mich der Aufruf von
button[i].action();
welcher jedesmal zum Absturz und Reset führt. Läßt man statt dessen 
einfach nur den Namen des Buttons anzeigen, läuft alles wie gewollt, nur 
eben der Funktionszeiger scheint irgendwo ins Nirvana zu weisen...
Sieht jemand einen Fehler?


Dank im Voraus!

ulf.
als lausig laienhafter Autodidakt

von Klaus W. (mfgkw)


Lesenswert?

Gibt es auch einen Absturz, wenn du statt button[i].action() direkt 
leer() aufrufst?

von Ben j. (scarab)


Lesenswert?

Setze mal einen Breakpoint in der Zeile und siehe nach was in action 
steht.

Ich persönlich prüfe Funktionszeiger immer ob sie ungleich 0 sind bevor 
ich sie Aufrufe, so viel Zeit muss sein.

von A. S. (telekatz)


Lesenswert?

Ulf schrieb:
> Zur Verzweiflung bringt mich der Aufruf von
> button[i].action();

Du hast zwei Arrays definiert, button und buttons. Initialisiert wurde 
aber nur das Array buttons.

von Ulf (Gast)


Lesenswert?

>Du hast zwei Arrays definiert, button und buttons. Initialisiert wurde
>aber nur das Array buttons.
... das ja verschiedene Varianten von button speichert.
Aber Heureka! Das hat mich auf Umwegen doch auf den Tippfehler gebracht:

button[i].action(); muß heißen:
buttons[i].action();

Man sollte eben differenziertere Namen vergeben und noch öfter alles neu 
tippen...

Danke nochmals!!!

ulf.
nicht mehr verzweifelt.

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.