Forum: Mikrocontroller und Digitale Elektronik STM32F0Discovery: BSRR tut nicht das, was es soll.


von Hexheini (Gast)


Lesenswert?

Hallo!

Ich versuche gerade die beiden LEDs auf dem Board über das BSR register 
zum leuchten zu bringen. Dazu benutze ich den folgenden Code:
1
  *((uint32_t*)(0x48000818)) = (1 << 8);
2
  *((uint32_t*)(0x48000818)) = (1 << 9);
Doch leider leuchtet nur die LED PC9. Drehe ich die beiden Zeilen um 
leuchtet hingegen nur die LED PC8. Und jede Zeile allein tut ebenfalls 
was sie soll.

Wenn ich nun in das Reference Manual in Kapitel 8.4.7 auf Seite 135 
schaue, so steht dort folgendes:

> 0: No action on the corresponding ODRx bit

Wenn ich das richtig verstehe, ändert sich bei dem jeweiligen ODR Bit 
nichts, wenn in das dazugehörige BSRR Bit eine Null geschrieben wird.
Doch genau dies schein nicht zu funktionieren, denn in der zweten Zeile 
löscht die Null in Bit 8 das entsprechende Bit in ODR offenbar wieder.
Oder habe ich da was falsch verstanden?

Vielen Dank im Voraus!
Hexheini

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Clock vom Port aktiviert?
Pin als Ausgang parametriert?

von Hexheini (Gast)


Lesenswert?

Markus Müller schrieb:
> Clock vom Port aktiviert?
> Pin als Ausgang parametriert?

Beides gemacht. Wie gesagt funktionieren die Zeilen einzeln ja wunderbar 
und wenn ich sie vertausche leuchtet die andere LED.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich habe gerade die Doku nicht zur Hand. Aber vermutlich nutzt Du die 
falsche Adresse. Nehme doch besser die Deklaration von ST.

von Hexheini (Gast)


Lesenswert?

Die Adressen sind schon richtig, das habe ich mehrmals überprüft. Und 
wie gesagt funktionieren die Zeilen für sich genommen ja.

von Hexheini (Gast)


Lesenswert?

Des Rätsels Lösung ist: Der Compiler hat die erste Zeile wegoptimiert.
Mit einem volatile geht es:
1
  *((volatile uint32_t*)(0x48000818)) = (1 << 8);
2
  *((volatile uint32_t*)(0x48000818)) = (1 << 9);

Die Standard Library von ST werde ich übrigens weiterhin nicht nutzen, 
da sie potthässlich ist:
1
    RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
2
    GPIOC->MODER |= (GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0) ;
3
    GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9);
4
    GPIOC->BSRR = (1 << 8) | (1 << 9);
Ich bastel mir gerade etwas zusammen, das viel einfacher und vor allen 
lesbarer ist:
1
  rcc.ahbenr.iopcen = 1;
2
  gpioc.moder.pin8 = gpo;
3
  gpioc.moder.pin9 = gpo;
4
  gpioc.bsrrbs.pin8 = 1;
5
  gpioc.bsrrbs.pin9 = 1;
:)

von Blub (Gast)


Lesenswert?

Hexheini schrieb:
> Die Standard Library von ST werde ich übrigens weiterhin nicht nutzen,
> da sie potthässlich ist

Das ist Geschmacksache.

Hexheini schrieb:
> (0x48000818)

Für die Adresse gibt es bestimmt ein #define. Wirf ein Blick in den 
Header.

Hexheini schrieb:
> (1 << 8)

Warum schreibt man nicht BIT8 und das #define BIT8  0x00000010?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Blub schrieb:
> Hexheini schrieb:
>> (1 << 8)
>
> Warum schreibt man nicht BIT8 und das #define BIT8  0x00000010?

Weil du damit BIT4 definierst und nicht Bit8. Richtig wäre
eher:
1
#define BIT8 0x00000100
Das ist aber gar nicht nötig, so unelegant ist das alles gar nicht:
1
#define GREEN_LED_PIN                   GPIO_Pin_9
2
#define BLUE_LED_PIN                   GPIO_Pin_8
3
#define LED_GPIO_PORT                   GPIOC
4
/* Turn On the blue LED */
5
LED_GPIO_PORT->BSRR =  BLUE_LED_PIN;
6
/* turn off the blue LED */
7
LED_GPIO_PORT->BRR =  BLUE_LED_PIN;

: Bearbeitet durch User
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.