www.mikrocontroller.net

Forum: Compiler & IDEs weitere Zeigerfrage


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
typedef struct{
 unsigned char state;
 unsigned char *Port; // kann ich hiermit auf einen Port verweisen???
 unsigned char PinMask;
}Components;

//Globale Variable
Components allComps[20];

...
initComps()
{
  allComps[0].state = 0;
  allComps[0].Port = &PORTB; // ????
  allComps[0].state = 0x01;
}
...
// Anwendung

setComps()
{
 allComps[0].Port |= allComps[0].PinMask;
}


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.

Autor: Falk Brunner (falk)
Datum:

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

Autor: Fred (Gast)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das mit dem
volatile unsigned char* Port;

war es :-)

Danke euch.

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht 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:
typedef struct ti_register_t {
  const volatile uint8_t *Register;
  prog_char Name[TI_REGNAMELEN];
} ti_register_t;

ti_register_t ti_registers[] PROGMEM = {
  {PORTA, "porta"},
  {DDRA, "ddra"},
  {PINA, "pina"}
};

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?

Autor: Andreas K. (a-k)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

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

Autor: Philipp Burch (philipp_burch)
Datum:

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

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.