STM32G431: LPUART1 Baudrate?

OP #7560961
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?

(Firma: TU Darmstadt) #7560990
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

#7561014
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.

OP #7561023
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!

(Firma: 1984now) #7561095
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.

#7561137
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.

OP #7561549
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren