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
typedefstruct{
2
unsignedcharstate;
3
unsignedchar*Port;// kann ich hiermit auf einen Port verweisen???
4
unsignedcharPinMask;
5
}Components;
6
7
//Globale Variable
8
ComponentsallComps[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.
@ 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
>>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;
> 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.
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
typedefstructti_register_t{
2
constvolatileuint8_t*Register;
3
prog_charName[TI_REGNAMELEN];
4
}ti_register_t;
5
6
ti_register_tti_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?
> 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.
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!