Forum: Compiler & IDEs weitere Zeigerfrage


von Gast (Gast)


Lesenswert?

Hallo,

ich habe folgendes Ziel mit meinem WINAvr für einen Mega16:

Ich möchte mir einen typedef definieren, wo ich zu LEDs den verwendeten 
Port, Pin und Zustand speichere. Das ganze soll zur Laufzeit veränderbar 
sein.

Meine Idee:
1
typedef struct{
2
 unsigned char state;
3
 unsigned char *Port; // kann ich hiermit auf einen Port verweisen???
4
 unsigned char PinMask;
5
}Components;
6
7
//Globale Variable
8
Components allComps[20];
9
10
...
11
initComps()
12
{
13
  allComps[0].state = 0;
14
  allComps[0].Port = &PORTB; // ????
15
  allComps[0].state = 0x01;
16
}
17
...
18
// Anwendung
19
20
setComps()
21
{
22
 allComps[0].Port |= allComps[0].PinMask;
23
}

Bei dem Code handelt es sich um Beispielcode, da mein Programm ncoh am 
Entstehen ist.

Was mich nun genau interessiert ist die Zuweisung des PORTB. Wie muss 
ich diesen definieren?

Danke
Christian.

von Falk B. (falk)


Lesenswert?

@ Gast (Gast)

>Ich möchte mir einen typedef definieren, wo ich zu LEDs den verwendeten
>Port, Pin und Zustand speichere. Das ganze soll zur Laufzeit veränderbar
>sein.


>typedef struct{
> unsigned char state;
> unsigned char *Port; // kann ich hiermit auf einen Port verweisen???

Ja, aber der Zeiger sollte volatile sein, bzw. auf ein volatile zeigen 
(wie macht man das??) um dem Compiler vor irgendwelchen Optimierungen 
abzuhalten.

MfG
Falk

von Fred (Gast)


Lesenswert?

Warum brauchst du denn dafür Pointer? PORTX ist doch nur eine einfache 
Zahl, die kannst du ja auch so für deine finsteren Zwecke 
missbrauchen... ;-)

von Rolf Magnus (Gast)


Lesenswert?

>>typedef struct{
>> unsigned char state;
>> unsigned char *Port; // kann ich hiermit auf einen Port verweisen???
>
> Ja, aber der Zeiger sollte volatile sein, bzw. auf ein volatile zeigen
> (wie macht man das??)

Genauso wie bei const.

volatile unsigned char* Port;

von Johannes M. (johnny-m)


Lesenswert?

Fred wrote:
> PORTX ist doch nur eine einfache Zahl,[...]
So? Dann schau mal in die Header-Datei. Da steht was anderes.

von Rolf Magnus (Gast)


Lesenswert?

> Warum brauchst du denn dafür Pointer?

Warum nicht?

> PORTX ist doch nur eine einfache Zahl,

Es ist eine Speicherstelle bzw. ein in den Adressraum gemaptes Register.

> die kannst du ja auch so für deine finsteren Zwecke missbrauchen... ;-)

Was meinst du mit "so"? Wenn man eine Adresse speichern will, ist ein 
Zeiger die naheliegendste Lösung dafür.

von Gast (Gast)


Lesenswert?

Hallo,

das mit dem
1
volatile unsigned char* Port;

war es :-)

Danke euch.

von Philipp B. (philipp_burch)


Lesenswert?

Da habe ich doch auch gleich noch eine Frage dazu:

Ich möchte in einem Array einige IO-Register ablegen, um über eindeutige 
Strings darauf zugreifen zu können. Das sieht dann etwa so aus:
1
typedef struct ti_register_t {
2
  const volatile uint8_t *Register;
3
  prog_char Name[TI_REGNAMELEN];
4
} ti_register_t;
5
6
ti_register_t ti_registers[] PROGMEM = {
7
  {PORTA, "porta"},
8
  {DDRA, "ddra"},
9
  {PINA, "pina"}
10
};

Der GCC weigert sich aber, das zu kompilieren, da der Initialisierer 
nicht konstant ist ("../src/ti.c:103: error: initializer element is not 
constant"). Der Fehler bezieht sich auf PORTA, DDRA und PINA. Was muss 
ich da angeben, damit das funktioniert? Die Adressen der Register sind 
ja zur Compilezeit bekannt, warum sollte damit keine Initialisierung 
möglich sein?

von Andreas K. (a-k)


Lesenswert?

Du könntest es mal damit versuchen, den Zeiger mit der Adresse des Ports 
anstelle des Inhalts zu initialisieren.

von Rolf Magnus (Gast)


Lesenswert?

> typedef struct ti_register_t {
>  const volatile uint8_t *Register;

Du willst also nur lesend auf das Register zugreifen?

> ti_register_t ti_registers[] PROGMEM = {
>  {PORTA, "porta"},

PORTA ist kein Zeiger.

> Der GCC weigert sich aber, das zu kompilieren, da der Initialisierer
> nicht konstant ist ("../src/ti.c:103: error: initializer element is not
> constant"). Der Fehler bezieht sich auf PORTA, DDRA und PINA. Was muss
> ich da angeben, damit das funktioniert?

&PORTA

> Die Adressen der Register sind ja zur Compilezeit bekannt, warum sollte
> damit keine Initialisierung möglich sein?

Weil du nicht mit der Adresse, sondern mit dem Inhalt des Registers zu 
initialisieren versuchst.

von Philipp B. (philipp_burch)


Lesenswert?

Rolf Magnus wrote:
>> typedef struct ti_register_t {
>>  const volatile uint8_t *Register;
>
> Du willst also nur lesend auf das Register zugreifen?

Eigentlich nicht, das "const" muss da natürlich weg.

>> ti_register_t ti_registers[] PROGMEM = {
>>  {PORTA, "porta"},
>
> PORTA ist kein Zeiger.
>
>> Der GCC weigert sich aber, das zu kompilieren, da der Initialisierer
>> nicht konstant ist ("../src/ti.c:103: error: initializer element is not
>> constant"). Der Fehler bezieht sich auf PORTA, DDRA und PINA. Was muss
>> ich da angeben, damit das funktioniert?
>
> &PORTA

Ach herrje... Ich dachte eigentlich, das hätte ich probiert. War wohl 
nix. Funktioniert jetzt jedenfalls.

Besten Dank euch beiden!

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.