Skip to main content
SKhan.7
Associate
December 26, 2022
Question

Need help in making USART2 work on STM32F303RE

Hi, I am doing a MOOC for learning STM32 programming, in the UART topic, we are supposed to implement UART. The course follows STM32F4 but I have an STM32F303RE and I tried to adapt it to my board but it is still not showing anything on the serial monitor (I tried CuteCom and Arduino Serial Monitors as I use a Mac). Can you please tell me what is wrong with the code below? I tried to input various values directly into the BRR register as I had doubts about the baud rate formula in the course.

#include <stdio.h>

#include <stdint.h>

#include "stm32f303xe.h"

#define IOPAEN (1U<<17)

#define UART2EN (1U<<17)

#define CR1_TE (1U<<3)

#define CR1_UE (1U<<13)

#define SR_TXE (1U<<7)

#define SYS_FREQ 16000000

#define APB1_CLK SYS_FREQ

#define UART_BAUDRATE 115200

static void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t BaudRate);

static uint16_t compute_uart_bd(uint32_t PeriphClk, uint32_t BaudRate);

void uart2_tx_init(void);

void uart2_write (int ch);

int main (void){

uart2_tx_init();

while(1){

uart2_write('Y');

}

}

void uart2_tx_init(void){

//Configure UART GPIO pin

// Enable clock access to GPIOA

RCC->AHBENR |= IOPAEN;

// Set PA2 to Alternate Function Mode

GPIOA->MODER &= ~(1U<<4);

GPIOA->MODER |= (1U<<5);

// Set PA2 Alternate Function type to UART_TX (AF07)

GPIOA->AFR[0] |= (1U<<8);

GPIOA->AFR[0] |= (1U<<9);

GPIOA->AFR[0] |= (1U<<10);

GPIOA->AFR[0] &= ~(1U<<11);

//Configure UART Module

// Enable clock access to UART2

RCC->APB1ENR |= UART2EN;

// Configure baud rate

uart_set_baudrate(USART2, APB1_CLK, UART_BAUDRATE);

// Configure the transfer direction

USART2->CR1 = CR1_TE;

// Enable UART module

USART2->CR1 |= CR1_UE;

}

void uart2_write (int ch){

//Make sure transmit data register is empty

while (!(USART2->ISR & SR_TXE)){}

//Write to transmit data register

USART2->TDR = (ch & 0xFF);

}

static void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t BaudRate){

USARTx->BRR = compute_uart_bd(PeriphClk,BaudRate);

}

static uint16_t compute_uart_bd(uint32_t PeriphClk, uint32_t BaudRate){

return ((PeriphClk + (BaudRate/2U))/BaudRate);

}

This topic has been closed for replies.

17 replies

SKhan.7
SKhan.7Author
Associate
December 26, 2022

One thing I have found is that APB1 frequency is 36Mhz, I tried various values with the formula 36000000/(16*115200) but even that does not work with the BRR register.

Tesla DeLorean
Guru
December 26, 2022

Perhaps send a stream of U characters and use a scope?

​

BRR = 36000000 / 115200 is probably a better formula.

​

S​ome of the code is also very inefficient. The compiler can't optimize or fold them.

​

I​ would enable the clocks first, so you have a slight dwell time before using the registers they clock.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
SKhan.7
SKhan.7Author
Associate
December 26, 2022

Unfortunately I don't have a scope so checking it on a serial monitor on my laptop. I used the formula you suggested and things still don't work. Optimisation is turned off for the compiler. Yes, the clocks are enabled in the init function.

S.Ma
Principal
December 26, 2022

Go to debug mode and manually plau woth jart registere

SKhan.7
SKhan.7Author
Associate
December 26, 2022

Unfortunately I find the debug mode quite complicated but I will try..

SKhan.7
SKhan.7Author
Associate
December 26, 2022

Another thing I am suspecting is that the course made us configure word length as 8 but my microcontroller's Transmit Data Register has space for 9 bits.. I will try changing the code to adjust for a 9 bit word length.

Karl Yamashita
Principal
December 26, 2022

The CR1 register is 0 on POR. You've only enabled CR1_UE and CR1_TE bits. The M bit should be zero so your word length is 8 bits.

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
SKhan.7
SKhan.7Author
Associate
December 26, 2022

Yes, but the thing is it 8 bits word length alright or should I change it to 9 bits as the TDR has a space for 9 bits.

Karl Yamashita
Principal
December 26, 2022

Unless the course says to change to 9 bits, leave it as 8 bits. How is the UART communicating to the serial program? USB to Serial adapter (TTL level) and hopefully not a USB to RS232 adapter?

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
SKhan.7
SKhan.7Author
Associate
December 26, 2022

So I found one mistake in my code, what an idiot I am. The CR1_UE is supposed to be (1U<<0). Now I am getting something on serial but it is a weird character instead of capital Y, I am getting ÿ repeatedly.

Karl Yamashita
Principal
December 26, 2022

Good catch. I've actually grabbed the first reference data sheet available and it so happen to be for a STM32F407, lol. Now that I grabbed the correct data sheet, the STM32F303RE CR1_UE bit is bit 0.

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
SKhan.7
SKhan.7Author
Associate
December 26, 2022

Ah thanks a lot..!

Karl Yamashita
Principal
December 26, 2022

You didn't turn on 9 bits did you?

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
SKhan.7
SKhan.7Author
Associate
December 26, 2022

No no, it works on 8 bits so no need for 9 bits..

SKhan.7
SKhan.7Author
Associate
December 26, 2022

Ah finally, got it working. So the problems were:

#define CR1_UE (1U<<0) // This has been corrected from bit 13 to 0

#define SYS_FREQ 8000000 // This has been changed from 16000000 to 8000000 (But I don't know why, APB1 is supposed to be on 36Mhz?)

Thanks for the help, I guess I will continue with the course and "be careful".