Forum: Compiler & IDEs Pointerproblem


von Volker Kattoll (Gast)


Lesenswert?

Moin, Moin,
in der Funktion void show_dcf_big(void) will ich einen Pointer auf
einen String setzen. Den Pointer p1.

Nutze ich eine Konstante, funktioniert es.
Verwende ich die Variable L, so bekomme ich das gewünschte Ergebnis
nicht zurück. Warum ??


PS: Fallt nicht gleich über mich her, ich bin C/AVR-Anfänger.

Volker Kattoll


/*********************************************************************** 
*****
 Title  :   Allgemeines Testprg
 Author:    Volker Kattoll
 Date:      22/11/2003
 Software:  AVR-GCC with AVR-AS
 Target:    AVR Mega32
 Comments:

************************************************************************ 
*****/
#include "test.h"


#include "lcd_io.h"
//wird benötigt !! Ohne werden keine Interrupts verarbeitet ka031026
#include <avr/interrupt.h>
#include <avr/signal.h>

//---------------- Software-Switches -----------------------
//         0 = Aus,  1 = Ein
#define IRQ0        0
// Schalter haben hier keinen Einfluss auf eine Steuerung in den
Headerdateien
#define DCF77       1

// ----------------- Menu -----------------------------------
//static const unsigned char bar1[8]__attribute__((progmem)) =
{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
static  unsigned char
eeprom_menu1[]__attribute__((section(".eeprom")))={" Uhrzeit
"};//," Uhrzeit       Aus  "};
static  unsigned char
eeprom_menu2[]__attribute__((section(".eeprom")))={" Zeitstatus
"};
static  unsigned char
eeprom_menu3[]__attribute__((section(".eeprom")))={" Tastenstatus
"};
static  unsigned char
eeprom_menu4[]__attribute__((section(".eeprom")))={" zurueck
->INFO "};

static unsigned char m_an[]__attribute__((section(".eeprom")))={"An
"};
static unsigned char
m_aus[]__attribute__((section(".eeprom")))={"Aus  "};

//--------------- Module -----------------------------------
#include "delay.h"

#include "dcf.h"

#include "irq.h"

#include "strg_form.h"

//----------------------------------------------------------

// ---------- Eigene Variablen die im Prg genutzt werden
----------------
#define PrgVers "0.2o"
#define PrgDate "06.12.03"
static  unsigned char
prog_vers1[]__attribute__((section(".eeprom")))={" Program - Version
 "};
static  unsigned char
prog_vers2[]__attribute__((section(".eeprom")))={"Vers: "PrgVers"
"PrgDate};

// Anlegen Hauptmenu-Strings
static  unsigned char
m1s1[]__attribute__((section(".eeprom")))={"Menu1 Punkt1"};
static  unsigned char
m1s2[]__attribute__((section(".eeprom")))={"Menu1 Punkt2"};
static  unsigned char
m1s3[]__attribute__((section(".eeprom")))={"Menu1 Punkt3"};
static  unsigned char
m1s4[]__attribute__((section(".eeprom")))={"Menu1 Punkt4"};
static  unsigned char
m1s5[]__attribute__((section(".eeprom")))={"Menu1 Punkt5"};
static  unsigned char
m1s6[]__attribute__((section(".eeprom")))={"Menu1 Punkt6"};

// Pointer-Array auf Hauptmenu-Strings
static const unsigned char* m1[6]__attribute__((progmem)) =
{m1s1,m1s2,m1s3,m1s4,m1s5,m1s6};


// Für grosse DCF-Anzeige
static  unsigned char z0s1[]__attribute__((section(".eeprom")))={"
00 "};
static  unsigned char z0s2[]__attribute__((section(".eeprom")))={"0
0"};
static  unsigned char z0s3[]__attribute__((section(".eeprom")))={"0
0"};
static  unsigned char z0s4[]__attribute__((section(".eeprom")))={"
00 "};

static  unsigned char z1s1[]__attribute__((section(".eeprom")))={"
00"};
static  unsigned char z1s2[]__attribute__((section(".eeprom")))={" 0
0"};
static  unsigned char z1s3[]__attribute__((section(".eeprom")))={"
0"};
static  unsigned char z1s4[]__attribute__((section(".eeprom")))={"
0"};

static  unsigned char z2s1[]__attribute__((section(".eeprom")))={"
00 "};
static  unsigned char z2s2[]__attribute__((section(".eeprom")))={"0
0"};
static  unsigned char z2s3[]__attribute__((section(".eeprom")))={"
0"};
static  unsigned char
z2s4[]__attribute__((section(".eeprom")))={"0000"};

static  unsigned char z3s1[]__attribute__((section(".eeprom")))={"
00 "};
static  unsigned char z3s2[]__attribute__((section(".eeprom")))={"
_0"};
static  unsigned char z3s3[]__attribute__((section(".eeprom")))={"
0"};
static  unsigned char z3s4[]__attribute__((section(".eeprom")))={"
00 "};

//          Pointer auf die Zahlentabellen
static const unsigned char* z0[4]__attribute__((progmem)) =
{z0s1,z0s2,z0s3,z0s4};
static const unsigned char* z1[4]__attribute__((progmem)) =
{z1s1,z1s2,z1s3,z1s4};
static const unsigned char* z2[4]__attribute__((progmem)) =
{z2s1,z2s2,z2s3,z2s4};
static const unsigned char* z3[4]__attribute__((progmem)) =
{z3s1,z3s2,z3s3,z3s4};

//               Pointer auf die Zahlen 0-9
//static unsigned * zahl[10]__attribute__((progmem)) =
{z0[0],z1[0],z2,z3,z3,z3,z3,z3,z3,z3};


//static const unsigned char* s[]__attribute__((".eeprom")) =
{s1,s2};

// ---------- Globale Variablen ---------------------------
// ----------------- Variablen anlegen
--------------------------------
#define Del_Cnt_Start 9
int Del_Cnt = Del_Cnt_Start;
//------------------ Tastatur
-----------------------------------------
#define TASTENVERZOEGERUNG  20
/*  Richtige Tastenbelegung
#define T_OBEN    1
#define T_RECHTS  2
#define T_MITTE   4
#define T_UNTEN   8
#define T_LINKS  16
*/
#define T_OBEN    10
#define T_RECHTS  9
#define T_MITTE   12
#define T_UNTEN   24
#define T_LINKS   24

uint8_t Taste;      // gedrückte Taste
uint8_t Taste_letzte;  // vorletzte Taste
// Tastencounter:  wird bei jedem Durchlauf decrementiert, wenn 0,
// dann ist die Taste gültig
uint8_t Taste_Cnt;
uint8_t t1;        // Verzögerung in den Menues


  //unsigned
  int Cnt1;
  //unsigned
  int BarCnt;
#if IRQ0 == 1
    //unsigned
    int IRQ0Cnt;
#endif
//  int Cnt;
//  int temp;

  //unsigned char DCF_ntime[4]__attribute__((progmem)) =
{0x00,0x00,0x00,0x00};
//---------------------------------------------------------------------- 
-
  // USER DEFINED CHARS ARRAY's   // nur 8 Chars sind möglich
static const unsigned char bar1[8]__attribute__((progmem)) =
{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
static const unsigned char bar2[8]__attribute__((progmem)) =
{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02};
static const unsigned char bar3[8]__attribute__((progmem)) =
{0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04};
static const unsigned char bar4[8]__attribute__((progmem)) =
{0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08};

static const unsigned char bar5[8]__attribute__((progmem)) =
{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};

static const unsigned char bar6[8]__attribute__((progmem)) =
{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11};
static const unsigned char bar7[8]__attribute__((progmem)) =
{0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12};
static const unsigned char bar8[8]__attribute__((progmem)) =
{0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14};

/*
You could also define a char array like this:
static const unsigned char user_chars[2][8]__attribute__((progmem))={

{0x0E,0x11,0x0E,0x04,0x1F,0x04,0x0A,0x11},

{0x11,0x0A,0x04,0x1F,0x04,0x0E,0x11,0x0E}
                                                                    };
or

static const unsigned char user_chars[]__attribute__((progmem))={

0x0E,0x11,0x0E,0x04,0x1F,0x04,0x0A,0x11,

0x11,0x0A,0x04,0x1F,0x04,0x0E,0x11,0x0E
                                                                };

    and use the macro "lcd_fill_cgram(user_chars);"  instead of
uploading each char separately.
    The array can have from 1 up to 8 used defined chars (max 64 bytes)
but the macro will upload only
    as much as the array size so in the above example it will fill user
defined char positions 0 and 1
    and will not overwrite user defined chars that might exist located
at position 2 to 7.
    However it will always start uploading at position 0.

*/
/*###################################################################### 
################################*/
/*###################################################################### 
################################*/

void show_dcf_big(void)
{
  volatile uint8_t L;
  unsigned char* p1;
  unsigned char* p2;
  unsigned char* p3;
  unsigned char* p4;
  int L1;
  volatile uint8_t versatz;
  versatz = 0;

      // Nutze ich die Variable L, so zeigt p1 nicht auf den String 
z2[0]
          L = 1;
            p1 = (unsigned char*) z2[(int) L];
      // mit dieser Zeile funktioniert es, warum ??
            //p1 = (unsigned char*) z2[(int) 0];

            p2 = (unsigned char*) z2[(int) 1];
            p3 = (unsigned char*) z2[(int) 2];
            p4 = (unsigned char*) z2[(int) 3];
        lcd_gotoxy(versatz,0);
        lcd_puts_e(p1);
        lcd_gotoxy(versatz,1);
        lcd_puts_e(p2);
        lcd_gotoxy(versatz,2);
        lcd_puts_e(p3);
        lcd_gotoxy(versatz,3);
        lcd_puts_e(p4);


};

/*###################################################################### 
################################*/

von Florian Pfanner (Gast)


Lesenswert?

Wenn ich das richtig gelesen habe, dann must du pointer auf Arrays so
vernküpfen:

unsigned char *pointer;
unsigned char array[]="abc...";

pointer =& array[2];        //Pointer auf 3.Arrayfeld


Müsste gehen.

Gruß, Florian

von Volker Kattoll (Gast)


Lesenswert?

Hallo Florian,

das ist leider nicht die Lösung des Problems.

Im Anhang habe ich noch einmal einen Programmausschnitt angefügt.

Der Ablauf ist folgender:

Im EEProm werden mehrere char-arrays angelegt.
(Im Beispiel: z2s1 .. z2s4. Das ist OK)
Im Prog-Memory wird ein Array von Pointern auf diese Strings angelegt.
(Im Beispiel: z2[1] bis z2[4]  Ist auch OKay)

In der Funktion show_dcf_big soll mit den Pointer p1 über das
Pointerarray z2[1..4] auf die im EEProm liegender Char zugegriffen
werden.

Verwende ich eine Konstante als z2[Index] bekomme ich den korrekten
Pointer zurück.
      p1 = z2[1];
Jetzt zeigt p1 auf den entsprechen String im EEProm.

Verwende ich die Schleifenvariable L
      p1 = (z2[(int)L]);
so klappt es nicht.

Warum? Ich kann mir dieses nicht erklären.

Gruss
Volker

/*********************************************************************** 
*****
 Title  :   Allgemeines Testprg
 Author:    Volker Kattoll
 Date:      22/11/2003
 Software:  AVR-GCC with AVR-AS
 Target:    AVR Mega32
 Comments:

************************************************************************ 
*****/
#include "test.h"


#include "lcd_io.h"
//wird benötigt !! Ohne werden keine Interrupts verarbeitet ka031026
#include <avr/interrupt.h>
#include <avr/signal.h>

//---------------- Software-Switches -----------------------
//         0 = Aus,  1 = Ein
#define IRQ0        0
// Schalter haben hier keinen Einfluss auf eine Steuerung in den
Headerdateien
#define DCF77       1

//  ...

//--------------- Module -----------------------------------
#include "delay.h"

#include "dcf.h"

#include "irq.h"

#include "strg_form.h"

//----------------------------------------------------------

// ---------- Eigene Variablen die im Prg genutzt werden
----------------
#define PrgVers "0.2o"
#define PrgDate "06.12.03"
static  unsigned char
prog_vers1[]__attribute__((section(".eeprom")))={" Program - Version
 "};
static  unsigned char
prog_vers2[]__attribute__((section(".eeprom")))={"Vers: "PrgVers"
"PrgDate};

//      ...

// Für grosse DCF-Anzeige


//  Hier werden  4 Char-Arrays im EEProm angelegt.

//      ...

static  unsigned char z2s1[]__attribute__((section(".eeprom")))={"
00 "};
static  unsigned char z2s2[]__attribute__((section(".eeprom")))={"0
0"};
static  unsigned char z2s3[]__attribute__((section(".eeprom")))={"
0"};
static  unsigned char
z2s4[]__attribute__((section(".eeprom")))={"0000"};

//      ...

//  Pointer auf die Anfangs-Adressen der einzelnen Zeilen im EEProm
static const unsigned char* z2[4]__attribute__((progmem)) = { z2s1,
z2s2, z2s3, z2s4};

//      ...


/*###################################################################### 
################################*/
/*###################################################################### 
################################*/

void show_dcf_big(void)
{
  volatile uint8_t L;
  unsigned char p1;

  unsigned char* p2;
  unsigned char* p3;
  unsigned char* p4;
  int L1;
  volatile uint8_t versatz;
  versatz = 0;

          L = 0;
      for (L = 0; L < 5; L ++)
      {
              // Diese Zeile liefert einen Pointer über z2[1] auf den
String z2s2 zurück
//---> ist IO
            p1 = z2[1];
        // Wenn L = 1, so sollte diese Zeile ein identisches Ergebnis
liefern
        // das macht sie aber nicht.
        // Warum?
//---> funktioniert nicht
              p1 = (z2[(int)L]);
        lcd_gotoxy(versatz, L);
          lcd_puts_e(p1);
        };
};

/*###################################################################### 
################################*/
/*###################################################################### 
################################*/

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Sourcecode bitte das nächste Mal in den Anhang.

von Florian Pfanner (Gast)


Lesenswert?

Hallo,

kannst du mal dein gesammtes Projekt (alle Dateien) hier Posten evt.
als Zip-Datei. Ich hab gerade versucht deinen Code zu Compeilieren aber
das klappt irgendwie nicht. Vielleicht finde ich dann was.

Gruß, Florian

von Volker Kattoll (Gast)


Angehängte Dateien:

Lesenswert?

Hey Florian,

als Anhang den gesamten Prg-Code.
Er ist ausgelegt für einen Mega32.

Die Problemstelle ist in dem Modul Test.c (Hauptprog.) in den Zeilen
171 - 200.

Dort ist auch in dem Kommentar das Problem beschrieben.

Gesamtfunktion:
Abfrage eines DCF77-Moduls (von Conrad), Darstellung der Zeit auf einem
LCD-Display, sowie erste Integrationsversuche eines Menue.

In der Subroutine show_dcf_big probiere ich über den Pointer p1 auf
Pointer aus dem Pointerarray z2 zu setzen.
Die Pointer in dem Pointerarray z2 zeigen auf 4 Char-Arrays im EEProm,
welche ich auslesen und an die Anzeigeroutine füre das LCD übergebe.

Nutze ich als Index eine Konstante, so ist alles Okay.
Damit kann ich aber nichts anfangen, ich brauche eine Variable um auf
das nächste Element zugreifen zu können.

Will sagen:
In einer Schleife sollen die Char-Arrays aus dem EEProm auf dem
LCD-Display ausgegeben werden.

Gruss, Volker

von Florian Pfanner (Gast)


Lesenswert?

Hallo Volker,

ich hab mal ein bischen rumporbiert. Ich vermute, dass das Problem im
Pointerarray ligt. Wenn ich einen festen index verwende, so wird der
inhalt des Pointers schon zu laufzeit in das Programm geschrieben. Also
das ist dann keine Variable mehr sondern direkt eine Konstante. Es wird
nichts vom Programmspeicher gelesen. Wenn Ich jetzt eine Variable
einsetzte, so wird zwar etwas gelesen, aber das ist immer FFFF. Ich hab
mal ein bischen mit pgm_read_word probiert, bin aber noch nicht auf
einen grünen Zweig gekommen.

Gruß, Florian

von Volker Kattoll (Gast)


Lesenswert?

Hallo Florian,
also hatte ich das Problem zumindest soweit auch lokalisiert.
Ich vermute, das es damit zusammenhaengt, das das Pointerarray im
ProgMem liegt und die CharArrays im EEProm.

Aber einen konkreten Loesungsansatz habe ich einfach nicht. Pointer
waren noch nie meine Staerke. Aber ich probiere weiter.

Gruss, Volker

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.