Forum: Mikrocontroller und Digitale Elektronik Zugriff auf Register über Pointer


von Julius K. (julius-krebs)


Lesenswert?

Ich möchte auf beide UART Schnittstellen eines Atmega64 zugreifen. Dabei 
wäre es sehr praktisch, wenn der Registerzugriff über einen Pointer 
geschieht.

z.B. wie folgt
1
void SerialEnRc(unsigned char Value)
2
{
3
    if (Value == ON) {
4
        SerialGetCurrUCSRB() |= (1<<RXEN);
5
    } else {
6
        SerialGetCurrUCSRB() &= ~(1<<RXEN);
7
    }
8
}

Ist dies möglich?

von Sven P. (Gast)


Lesenswert?

Die Registerdefinitionen (PORTA...) sind Zeiger. Guck mal in die 
Header...

von Julius K. (julius-krebs)


Lesenswert?

es werden "_SFR_" Makros verwendet.
Nun bleibt es bei der Frage wie ich dieses Zeiger variabel einsetzen 
kann.

von dummy (Gast)


Lesenswert?

>wäre es sehr praktisch, wenn der Registerzugriff über einen Pointer
>geschieht.
>z.B. wie folgt

>void SerialEnRc(unsigned char Value)
>{
>    if (Value == ON) {
>        SerialGetCurrUCSRB() |= (1<<RXEN);
>    } else {
>        SerialGetCurrUCSRB() &= ~(1<<RXEN);
>    }
>}


Ich sehe hier keinen Pointer.

von Julius K. (julius-krebs)


Lesenswert?

Der Rückgabewert von SerialGetCurrUCSRB wäre ein Pointer. Der Inhalt 
dieser Funktion könnte wie folgt aussehen;
1
unsigned char *SerialGetCurrUCSRB()
2
{
3
    switch (Serial->CurrPort){
4
        case 1:
5
            return UCSR1B;
6
        default:
7
            return UCSR0B;
8
    }
9
}

von Stefan E. (sternst)


Lesenswert?

unsigned char *SerialGetCurrUCSRB()
->
volatile unsigned char *SerialGetCurrUCSRB()

return UCSR1B;
->
return &UCSR1B;

SerialGetCurrUCSRB() |= (1<<RXEN);
->
*(SerialGetCurrUCSRB()) |= (1<<RXEN);

von Julius K. (julius-krebs)


Lesenswert?

Dankeschön. Funktioniert auf Anhieb!

von Julius K. (julius-krebs)


Lesenswert?

Doch noch eine weitere Frage, wenn auch nahe an "Off-Topic":

Funktionen wie folgende werde ich nun eine ganze Reihe haben (je nach 
dem viele Register in ansprechen möchte). Mir fällt leider nicht ein, 
wie ich das Ganze noch ein wenig EINDAMPFEN/VEREINFACHEN könnte. 
Werkzeuge wie "##" kann ich in Echtzeit nun mal nicht nutzen.
1
volatile unsigned char *SerialGetCurrUCSRA()
2
{
3
    switch (Serial->CurrChannel){
4
        case 1:
5
            return &UCSR1A;
6
        default:
7
            return &UCSR0A;
8
    }
9
}
10
volatile unsigned char *SerialGetCurrUCSRB()
11
{
12
    switch (Serial->CurrChannel){
13
        case 1:
14
            return &UCSR1B;
15
        default:
16
            return &UCSR0B;
17
    }
18
}
19
volatile unsigned char *SerialGetCurrUCSRC()
20
{
21
    switch (Serial->CurrChannel){
22
        case 1:
23
            return &UCSR1C;
24
        default:
25
            return &UCSR0C;
26
    }
27
}
28
...

von Stefan E. (sternst)


Lesenswert?

Du könntest z.B. mit 3 globalen Pointern arbeiten.
Also statt Serial->CurrChannel dann:
Serial->CurrUCSRA
Serial->CurrUCSRB
Serial->CurrUCSRC
und dann:
*Serial->CurrUCSRB |= (1<<RXEN);

Das erspart beim Zugriff den "Umweg" über die Funktion. Dafür ist der 
Channelwechsel dann aber aufwändiger. Ist halt eine Abwägungssache.

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.