Register ansprechen µC

OP #4247739
Lesenswert?
• ▲
▼
Hallo Community,

ich möchte bei einem Mikrocontroller mittels einer Funktion einige 
Register ansprechen. Z.B. C1CTRL und C2CTRL. Jetzt möchte ich aber nicht 
eine funktion für C1CTRL und eine Funktion für C2CTRL schreiben, sondern 
eine mit Übergabeparameter welches Register ich ansprechen möchte.
Geht das? Wie setzt ich das zusammen das z.B. der Übergabeparameter 
nicht als "Name" gesehen wird.

Gruß Dirk

Beispiel:

bla (wert)
{
    CwertCTRL = 0x1;
}

Wert kann 1 oder 2 sein
Gast #4247767
Lesenswert?
• ▲
▼
Praktisch schaust Du einfach mal nach, wie Identifier wie C1CTRL 
letztlich deklariert und definiert sind.
Das kann unter Umständen über mehrere Preprozessor Makros und weitere 
C-Konstruktionen gehen. Wenn aber für den fraglichen uC der Compiler 
Ausdrücke mit C1CTRL als L-Wert akzeptiert muss am Ende gerade ein Typ 
herauskommen der als L-Wert geeignet ist.
Manchmal ist das ein wenig verwickelt, weil noch Hilfsdefinitionen von 
Makros oder Typen eine Rolle spielen können. CMSIS ist so ein Beispiel. 
Aber für nen AVR führt die Suche ziemlich schnell zum Ziel.

Der Typ ist dann auch der Parameter für die Funktion.
Gast #4247819
Lesenswert?
• ▲
▼
In dem Du die Funktion mit einem Parameter deklarierst, der dem Typ von 
C1CTRL entspricht. Dieser Funktion kannst Du dann "C1CTRL" als Wert 
übergeben.

Nimm an, C1CTRL sei als char * deklariert. Dann wäre die Funktion:
1
funktion (registertyp x) {
2

3
  x = 7;
4
}
#4247955
Lesenswert?
• ▲
▼
Üblicherweise sind solche Registersymbole als "volatile" definiert, und 
benutzen irgendeine Compiler-spezifische Magie, um sie an eine feste 
Adresse zu legen:
1
volatile uint16_t C1CTRL __an_fester_adresse__(0x1234);

Für deinen Zeiger brauchst du die Adresse nicht, aber das "volatile" 
(oder was dort halt benutzt wird):
1
void funktion(volatile uint16_t *reg)
2
{
3
    *reg = 0x1;
4
}
5

6
    ...
7
    funktion(&C1CTRL);
#4248189
Lesenswert?
• ▲
▼
Dirk P. schrieb:

>
> bla (wert)
> {
>     CwertCTRL = 0x1;
> }
>
> Wert kann 1 oder 2 sein


Und was gefällt dir jetzt an
1
void bla( uint8_t wert )
2
{
3
  if( wert == 1 )
4
    C1CTRL = 0x1;
5
  else if( wert == 2 )
6
    C2CTRL = 0x1;
7
}
nicht?

Nein. Du kannst nicht einen Variablennamen zur Laufzeit zusammen setzen 
lassen. Wenn das Programm läuft, existierten Variablennamen nicht mehr.

Normalerweise ist der Versuch so etwas machen zu wollen, ein starker 
Hinweis darauf, dass man eigentlich ein Array einsetzen will
1
registerPointerDatentyp Output[] = { &C1CTRL, &C2CTRL };
2

3
void bla( uint8_t wert )
4
{
5
  Output[wert-1] = 0x1;
6
}
#4248376
Lesenswert?
• ▲
▼
Dirk P. schrieb:
> Und wie ändere ich jetzt das je nach Übergabeparameter das C1 oder C2
> Register anspreche?

bla(&C1CTRL);
bla(&C2CTRL);

Je nach µC gibt es in den Headern statt vieler Einzelregister (z.B. AVR) 
oft Strukturen für die I/O-Module (z.B: ARM). Dann geht das z.B. so

void initUART(UART_REG_BLOCK *ptr)
{
   ptr->CTRL1  = ...;
   ptr->STATUS = ...;
}

und ruft das so auf
   initUART(&UART1);
   initUART(&UART2);

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.