cancel
Showing results for 
Search instead for 
Did you mean: 

Need help in making USART2 work on STM32F303RE

SKhan.7
Associate II

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);

}

17 REPLIES 17
SKhan.7
Associate II

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.

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
Up vote any posts that you find helpful, it shows what's working..
SKhan.7
Associate II

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

Go to debug mode and manually plau woth jart registere

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

SKhan.7
Associate II

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
Lead III

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.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

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
Lead III

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?

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.