Forum: Mikrocontroller und Digitale Elektronik STM32G431: LPUART1 Baudrate?


von Randy B. (rbrecker)


Lesenswert?

Hallo zusammen,

ich versuche den LPUART1 des G431@170MHz zum Laufen zu bringen (nein: 
HAL und LL sind keine Alternative):

Initialisierung:
1
        RCC->APB1ENR2 |= RCC_APB1ENR2_LPUART1EN;
2
        RCC->CCIPR |= 0x01 << RCC_CCIPR_LPUART1SEL_Pos;                
3
        LPUART1->PRESC = 0x0111; // presc: 16
4
        uint32_t clock = 170'000'000;
5
        clock /= 16;
6
        clock *= 256;
7
        clock /= 9600;
8
        LPUART1->BRR = clock;
9
        LPUART1->CR1 |= USART_CR1_FIFOEN;
10
        LPUART1->CR1 |= USART_CR1_RE;
11
        // LPUART1->CR1 |= USART_CR1_TE;
12
        LPUART1->CR1 |= USART_CR1_UE;

Das BRR bekommt: 283333. Das sollte laut DB alle Anforderungen erfüllen.

Später lese ich in einer Polling-Loop:
1
       if (LPUART1->ISR & USART_ISR_RXNE_RXFNE) {
2
            uint8_t b = LPUART1->RDR;
3
            IO::outl<trace>("LPUART: ", b);
4
       }

Dort lese ich dann:
1
LPUART: 128
2
LPUART: 128
3
LPUART: 0

wenn ich ein '\n' über die ser. Schnittstelle ausgebe (per LA 
verifiziert).

Sende ich mit der 8-fach höheren Baudrate von 76800Baud, so kommen die 
Zeichen korrekt an.

Wo ist mein Fehler?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Lies mal LPUART1->BRR aus. Stimmt der Wert? Gebe den 170 MHz noch den 
Postfix U, damit auch wirklich als unsigned gerechnet wird. GDB 
zumindest macht da einen Unterschied:
$8 = 0x452c5
(gdb) p /x ((170000000U/16 << 8)) / 9600
$9 = 0x452c5
(gdb) p /x ((170000000/16 << 8)) / 9600
$10 = 0xfffd7f25

von Randy B. (rbrecker)


Lesenswert?

Uwe B. schrieb:
> Lies mal LPUART1->BRR aus. Stimmt der Wert?

Ich lese aus dem BRR 283333 zurück. Das sollte doch richtig sein?

von J. S. (jojos)


Lesenswert?

Ein HAL Code ist in wenigen Minuten erstellt und den kann man sich als 
Referenz ansehen. Darin werden die Limits geprüft, die CR richtig 
gesetzt was man evtl. aus mehreren Stellen des DB zusammensuchen muss. 
Es wird auch die tatsächliche Tatkquelle für die Berechnung benutzt, 
nicht einfach angenommen des es die 170 MHz sind. Wenn man auf das alles 
verzichten möchte, dann ist halt Fehlersuchen angesagt.

von Randy B. (rbrecker)


Lesenswert?

J. S. schrieb:
> Ein HAL Code ist in wenigen Minuten erstellt und den kann man sich als
> Referenz ansehen. Darin werden die Limits geprüft, die CR richtig
> gesetzt was man evtl. aus mehreren Stellen des DB zusammensuchen muss.
> Es wird auch die tatsächliche Tatkquelle für die Berechnung benutzt,
> nicht einfach angenommen des es die 170 MHz sind. Wenn man auf das alles
> verzichten möchte, dann ist halt Fehlersuchen angesagt.

Super nutzlose Antwort!

von J. S. (jojos)


Lesenswert?

vielleicht ist deine Ansicht einfach nur superignorant?
Wenn du alles besser weißt, warum fragst du dann hier?

von Randy B. (rbrecker)


Lesenswert?

J. S. schrieb:
> vielleicht ist deine Ansicht einfach nur superignorant?
> Wenn du alles besser weißt, warum fragst du dann hier?

Lies den Eingangspost: da steht eine sehr konkrete Frage mit 
tatsächlichem Code. Wenn Du darauf keine Antwort weißt, dann bleib 
einfach ruhig und spare Dir solche Hinweise, die explizit nicht gefragt 
waren!

von Randy B. (rbrecker)


Lesenswert?

Die Auflösung:
1
  LPUART1->PRESC = 0x0111; // presc: 16

muss natürlich
1
  LPUART1->PRESC = 0b0111; // presc: 16

heißen.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Randy B. schrieb:

> Die Auflösung:
[...]

Solche Tippfehler sind extrem fies. Da liest man leider sehr schnell 
drüber.

Allerdings: spätestens, wenn man den Code im Debugger durchsteppt und 
nach jedem Schreibvorgang in ein SFIOR kontrolliert, ob da das erwartete 
drinsteht, sollte sich das Problem offenbaren.

Nunja, hat es ja wohl letztlich auch.

von Harald K. (kirnbichler)


Lesenswert?

Randy B. schrieb:
> uint32_t clock = 170'000'000;

Welcher Compiler übersetzt das eigentlich?

von Randy B. (rbrecker)


Lesenswert?

Harald K. schrieb:
> Randy B. schrieb:
>> uint32_t clock = 170'000'000;
>
> Welcher Compiler übersetzt das eigentlich?

GCC

von Harald K. (kirnbichler)


Lesenswert?

Ach ja?
1
main.c: In function ‘main’:
2
main.c:15:26: warning: multi-character character constant [-Wmultichar]
3
   15 |     uint32_t  clock = 170'000'000;
4
      |                          ^~~~~
5
main.c:15:26: error: expected ‘,’ or ‘;’ before '\x303030'

von Harry L. (mysth)


Lesenswert?

Harald K. schrieb:
> Ach ja?
>
>
1
> main.c: In function ‘main’:
2
> main.c:15:26: warning: multi-character character constant [-Wmultichar]
3
>    15 |     uint32_t  clock = 170'000'000;
4
>       |                          ^~~~~
5
> main.c:15:26: error: expected ‘,’ or ‘;’ before '\x303030'
6
>

@Harald gebs auf!
Mit ignoranten Klugscheissern, die ihren Ansatz für den einzig Wahren 
halten, diskutiert man nicht!
Die läßt man vor die Wand laufen.

von Randy B. (rbrecker)


Lesenswert?

Harald K. schrieb:
> Ach ja?

Ja.

Als C muss Du auf C2x schalten, in C++ geht das ab C++14.

von Randy B. (rbrecker)


Lesenswert?

Harry L. schrieb:
> Mit ignoranten Klugscheissern, die ihren Ansatz für den einzig Wahren
> halten, diskutiert man nicht!

Habe ich behauptet, das mein Ansatz der einzig wahre ist?

Blödsinn, es war eine simple Frage zu einem recht simplen Problem, und 
es hat sich ja auch herausgestellt, dass die Lösung dafür simpel war.

Aber leider hast Du das gar nicht bemerkt!
Und leider hast Du auch gar nicht bemerkt, dass er obige Code C++ war.

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.