Forum: Mikrocontroller und Digitale Elektronik Neu in Microchips SAM D21. Frage zu Arrow Operator ->


von Aleko (Gast)


Lesenswert?

Hi,

Ich spiele mit dem Gedanken, mich näher mit dem SAM D21 von Microchip zu 
beschäftigen. Genauer gesagt, geht es um den ATSAMD21G18:
https://www.microchip.com/wwwproducts/en/ATsamd21g18

Entwicklungsumgebung ist im ersten Anlauf Keil.

Bei einer Google Suche über den SAM D21 bin ich mehrfach auf folgenden 
Code gestoßen, um auf die einzelnen Bits in Registern zuzugreifen. 
Beigefügt zwei Beispiele, die den internen 8MHz Oszillator 
initialisieren:
1
 SYSCTRL->OSC8M.bit.PRESC = 0;
2
    SYSCTRL->OSC8M.bit.ONDEMAND = 1;
3
    SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
4
    SYSCTRL->OSC8M.bit.ENABLE = 1;
Quelle:
https://archives.plil.fr/elopes/PFE15/raw/a752c7abc15410f36f02a6e750e6ef3f7b940a40/RIOT/cpu/samd21/cpu.c
Oder aber auch:
1
/* OSC8M Internal 8MHz Oscillator */
2
SYSCTRL->OSC8M.bit.PRESC = SYSTEM_OSC8M_DIV_1;
3
SYSCTRL->OSC8M.bit.ONDEMAND = CONF_CLOCK_OSC8M_ON_DEMAND;
4
SYSCTRL->OSC8M.bit.RUNSTDBY = CONF_CLOCK_OSC8M_RUN_IN_STANDBY;
5
6
/* Enable OSC8M */
7
SYSCTRL->OSC8M.reg |= SYSCTRL_OSC8M_ENABLE;
Quelle:
https://stackoverflow.com/questions/42025662/samd21-clock-configuration

Ich weiß, dass der -> Operator verwendet wird, wenn eine Pointervariable 
auf ein Member eines Structs zugreift. Allerdings habe ich 
Verständnisschwierigkeiten, den dahinter liegenden Sinn bei der 
Anwendung von uC Initialisierungen zu verstehen (Da reichen meine 
C-Kenntnisse noch nicht aus). Was würde passieren, wenn man anstelle von
1
    SYSCTRL->OSC8M.bit.ENABLE = 1;
nun
1
    OSC8M.bit.ENABLE = 1;
schreibt?

Das Datenblatt schreibt in Kapitel 17.6.6 vor:
> In order to enable OSC8M, the Oscillator Enable bit in the OSC8M Control > 
register (OSC8M.ENABLE)
> must be written to one. OSC8M will not be enabled until OSC8M.ENABLE is > set. 
In order to disable
> OSC8M, OSC8M.ENABLE must be written to zero. OSC8M will not be disabled > until 
OSC8M is cleared.

Meine Frage:
Weshalb verwendet man den Arrow operator -> in den o.g. Beispielen, wenn 
man auf OSC8M.bit.ENABLE ein Bit setzen oder löschen will? Irgendwas hat 
da bei mir noch nicht ganz Klick gemacht.

Danke.

Gruß,

von holger (Gast)


Lesenswert?

>Was würde passieren, wenn man anstelle von
>
>    SYSCTRL->OSC8M.bit.ENABLE = 1;
>
>nun
>
>    OSC8M.bit.ENABLE = 1;
>
>schreibt?

Du bekommst einen Compiler Fehler. Ein Bit hat keine Adresse.
Das Register in dem das Bit sitzt schon. Und das ist nun mal SYSCTRL.

von leo (Gast)


Lesenswert?

Aleko schrieb:
> Was würde passieren, wenn man anstelle von    SYSCTRL->OSC8M.bit.ENABLE
> = 1;nun    OSC8M.bit.ENABLE = 1;schreibt?

Vergleich es mit:
a[2][3][4] = 1
vs.
[2][3][4] = 1

Zweiteres macht keinen Sinn.

leo

von Aleko (Gast)


Lesenswert?

Hi,
vielen Dank. Ich muss mir das noch mal durch den Kopf gehen lassen und 
mir das mit Pointern und Structs verinnerlichen. Was mich wundert, ist, 
dass bei einem alten Projekt mit einem TI DSP (F28335), das wie folgt 
gehandhabt wurde:
1
   EALLOW;
2
   
3
/* Enable internal pull-up for the selected pins */
4
// Pull-ups can be enabled or disabled by the user. 
5
// This will enable the pullups for the specified pins.
6
// Comment out other unwanted lines.
7
8
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;    // Enable pull-up on GPIO0 (EPWM1A)
9
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;    // Enable pull-up on GPIO1 (EPWM1B)   
10
   
11
/* Configure ePWM-1 pins using GPIO regs*/
12
// This specifies which of the possible GPIO pins will be ePWM1 functional pins.
13
// Comment out other unwanted lines.
14
15
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
16
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B
17
   
18
    EDIS;

Das ist doch ebenfalls ein Struct - genau so wie im Anfangspost. Oder 
liegt es daran, dass der Datentyp des Struct Members (im jetzigen 
Beispiel GPIO0 und GPIO1) ein anderer sein kann (Habe Code Composer 
Studio im Moment nicht auf meinem Laptop installiert, kann also nicht in 
die Header files einsehen)?

Danke und Gruß,

von foobar (Gast)


Lesenswert?

Wie die IO-Register angesprochen werden legt der Designer der API fest - 
die einen machen es per "struct an Adresse" (werden dann per "." 
angesprochen), die anderen per "Pointer auf struct" (werden dann per 
"->" angesprochen).  Beide Varianten haben Vor- und Nachteile.  Nicht 
dran festbeißen, einfach als gegeben hinnehmen.

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.