Platformio cmsis stm32f103 serial print

Can someone help me to code cmsis serial for stm32f103c8. I am writing to the usart->dr register
But i only get NULL in the serial monitor
I have tried arduino framework and there it works fine.

  • What platformio.ini do you have
  • What code have you tried?
[env:genericSTM32F103C8]
platform = ststm32
board = genericSTM32F103C8
framework = cmsis
upload_protocol = serial
board_build.core = stm32
#pragma once
#include <stm32f1xx.h>
#include <stdint.h>
#include "string.h"
#include "stdio.h"
#include <stdarg.h>
void begin()
{
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN;
    GPIOA->CRH |= GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1;
    GPIOA->CRH &= ~GPIO_CRH_CNF9_0;
    USART1->BRR = 0x1D4C;
    USART1->CR1 = 0;
    USART1->CR1 |= USART_CR1_TE;
    USART1->CR1 |= USART_CR1_UE;
    USART2->CR2 = 0;
    USART3->CR3 = 0;
}
void print (char *msg, ...)
{
    char buff[100];
    va_list args;
    va_start(args, msg);
    vsprintf (buff, msg, args);
    for (unsigned int i = 0; i < strlen(msg); i++)
    {
        USART1->DR = msg[i];
        while(!(USART1->SR & USART_SR_TXE));
    }
}
  • Is this a complete reproducable example? Seems like it’s missing the main function with calls to begin and print?
  • Where do you initialize the GPIO pins for TX, RX as output push-pull with alternate functions and input with alternate functions? And which pins are these?
  • Where does the magic number for BRR come from? What are your used and expected settings?

Aside from some minor bugs in print, your baud rate is not what you expect.

For 9,600 baud, use:

USART1->BRR = 8000000 / 9600;

The usart1 has tx = A9 and rx = A10
Since i am only transmitting to my serial monitor i only enabled pin 9 and and configured it to push pull
in the begin function.
In the APB2ENR there is USART1 , IOA, and alternate function enable.
I am trying to use 9600 baud rate.
BRR = 72000000/9600; in hex

Why 8 MHz and not 72 MHz?
Isn’t the frequency of APB2 bus is 72 MHz?

Without any further configuration, most parts of the chip run a 8 MHz. That’s basically a safe value to boot the chip. You can then configure it to use an external clock, configure PLLs etc.

Even if you configure the chip such that the system clock is 72 MHz, the clock relevant for the UART might be different. Different parts of the chip have separate clocks with separate configuration.

But your code doesn’t change the default clock configuration. So it’s a 8 MHz.

I recommend you install STM32cubeMX. It contains an interactive tool to configure the clock.

Here’s the libopencm3 code to configure the STM32F103C8 for 72 MHz (provided an external 8 MHz crystal is connected). It’s not trivial…

Thank You
I have to use the following lines of code:
SystemInit();
SystemCoreClockUpdate();
USART1->BRR = SystemCoreClock / 9600;
This initializes the clock and sets the varaible SystemCoreClock

Meaning it works now?

yes
it works
now i need to set any baud rate at any speed for all frequencies