mikrocontroller.net

Forum: Compiler & IDEs Pointerproblem


Autor: Volker Kattoll (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);


};

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

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Volker Kattoll (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);
        };
};

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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sourcecode bitte das nächste Mal in den Anhang.

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Volker Kattoll (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Volker Kattoll (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.