Forum: Mikrocontroller und Digitale Elektronik STM32 BSRR Reset


von AndererStudent (Gast)


Lesenswert?

Guten Tag,

Habe folgendes Problem: Möchte in das BSRR Register ein Pin setzen. Nach 
einem kurzen Delay will es wieder rücksetzen. Eigentlich kein Problem.
1
#define EN 0x80     /* PB7 mask for enable */
2
3
GPIOB->BSRRL = EN;               /* pulse E high */
4
delayMs(1);
5
GPIOB->BSRRL = EN << 16;         /* clear E */

Das Bit wird aber nicht zurückgesetzt. Ich schätze mal es liegt an der 
Warnung: "large integer implicitly truncated to unsigned type". Die 
bekomme ich genau bei der Zeile, in der ich das Bit um 16 nach links 
verschiebe. Habe auch schon folgende Definition versucht:
1
#define EN ((uint32_t)0x80)     /* PB7 mask for enable */

Hilft aber auch nicht. Hat jemand eine Idee? Danke

von Bologna Consultant (Gast)


Lesenswert?

Schonmal mit BSRRH versucht?

von AndererStudent (Gast)


Lesenswert?

Bologna Consultant schrieb:
> Schonmal mit BSRRH versucht?

Funktioniert auch nicht. Pin PB7 bleibt auf High. Könnte es was mit dem 
16 bit verschieben zu tun haben?

von Adam P. (adamap)


Lesenswert?

AndererStudent schrieb:
> #define EN ((uint32_t)0x80)

Das geht erst recht nicht...wie willst du eine 32bit Wert um 16 shiften, 
dann wären es 48bit und den in ein 32bit Register schreiben.

Versuch doch mal:
#define EN ((uint16_t)0x80)

Aber eleganter wäre es wohl so:

Bologna Consultant schrieb:
> Schonmal mit BSRRH versucht?

von Metier (Gast)


Lesenswert?

BSRRL für das Setzen des Pins.
BSRRH für das Rücksetzen des Pins.

von AndererStudent (Gast)


Lesenswert?

Metier schrieb:
> BSRRL für das Setzen des Pins.
> BSRRH für das Rücksetzen des Pins.

Mhm funktioniert. Danke. Hab aber im Datenblatt und in den CMSIS Dateien 
nichts gefunden. Wo steht das? Im Datenblatt finde ich nur das BSRR 
Register mit den 32bit.

von leo (Gast)


Lesenswert?

AndererStudent schrieb:
> #define EN 0x80     /* PB7 mask for enable */
>
> GPIOB->BSRRL = EN;               /* pulse E high */
> delayMs(1);
> GPIOB->BSRRL = EN << 16;         /* clear E */
>
> Das Bit wird aber nicht zurückgesetzt.

Du verwendest nur den Lowanteil (16 bit des Registeres.

Probier mal
1
GPIOB->BSRR = (uint32_t)EN << 16U;

HTH leo

von Dr. Sommer (Gast)


Lesenswert?

So viele Antworten und keine ist wirklich vollständig.
BSRR ist ein 32bit-Register welches setzen und löschen kann. Im Header 
ist das zusätzlich aufgeteilt auf BSRRL und BSRRH.

Wenn man Bit i (0 <= i <= 15) in BSRR auf 1 setzt, wird Pin i auf High 
geschaltet. Setzt man Bit i+16 in BSRR auf 1, wird Pin i auf Low 
gesetzt.

BSRRL ist das gleiche wie BSRR, aber als 16bit-Register definiert. Man 
kann also nur Pins setzen.
BSRRH ist ein 16bit-Register mit der selben Adresse wie das obere 
16bit-Word von BSRR. D.h. wenn man Bit i in BSRRH setzt ist das exakt 
identisch zum Setzen von Bit i+16 in BSRR, d.h. Pin i wird auf Low 
gesetzt.

Es geht also entweder
1
GPIOB->BSRRH = EN;
oder
1
GPIOB->BSRR = EN << 16;

Das BSRR ist im Reference Manual definiert. Im Header erkennt man dass 
BSRRL und BSRRH den selben Speicher belegen und somit die Doku vom BSRR 
zutrifft.

Was ist "EN" für ein blöder Name? Da weiß keiner was gemeint ist.

von AndererStudent (Gast)


Lesenswert?

Dr. Sommer schrieb:

> Wenn man Bit i (0 <= i <= 15) in BSRR auf 1 setzt, wird Pin i auf High
> geschaltet. Setzt man Bit i+16 in BSRR auf 1, wird Pin i auf Low
> gesetzt.
>
> BSRRL ist das gleiche wie BSRR, aber als 16bit-Register definiert. Man
> kann also nur Pins setzen.
> BSRRH ist ein 16bit-Register mit der selben Adresse wie das obere
> 16bit-Word von BSRR. D.h. wenn man Bit i in BSRRH setzt ist das exakt
> identisch zum Setzen von Bit i+16 in BSRR, d.h. Pin i wird auf Low
> gesetzt.


Vielen Dank für die Erklärung. Hab den Ausschnitt aus meinem Programm 
rauskopiert. Benutze es als Enable um auf ein LCD Display Daten zu 
schicken. Hätte ich für hier auch ändern können.

von kalrl (Gast)


Lesenswert?

Um 16 bitschieben ist zuviel. Maximal 1 UM 15 BIT...

von Dr. Sommer (Gast)


Lesenswert?

Nein, 16 ist korrekt! Du meinst etwas anderes.

von Bologna Consultant (Gast)


Lesenswert?

Lass dich durch die Kritik nicht draus bringen.
Das weiss doch jeder Nicht-Anfänger das EN Enable heisst. Was soll es 
auch sonst heissen?

von Dr. Sommer (Gast)


Lesenswert?

Bologna Consultant schrieb:
> Das weiss doch jeder Nicht-Anfänger das EN Enable heisst. Was soll es
> auch sonst heissen?

Ja, aber was wird enabled? Das Haupttriebwerk? Die Badezimmer-Radio? Und 
was ist das, ein Parameter-Wert für eine Funktion? Ein Datenfeld für ein 
Protokoll?

Nein, es ist die Pin-Nummer des Enable-Pins des Displays. Da Makros 
sowieso lange Namen haben sollten um Kollisionen zu vermeiden, könnte 
man es z.B. LCD_PINNO_ENABLE nennen. Zusammen mit LCD_PORT_ENABLE für 
GPIOB.

von Nop (Gast)


Lesenswert?

Adam P. schrieb:
> AndererStudent schrieb:
>> #define EN ((uint32_t)0x80)
>
> Das geht erst recht nicht...wie willst du eine 32bit Wert um 16 shiften,
> dann wären es 48bit und den in ein 32bit Register schreiben.

Unsinn. Natürlich geht der Shift auf eine 32bit-Variable, ganz besonders 
bei einem ARM mit 32bit-Registern.

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.