2022-12-26 05:53 AM
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);
}
2022-12-26 11:54 AM
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.
2022-12-26 12:01 PM
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.
2022-12-26 12:02 PM
You didn't turn on 9 bits did you?
2022-12-26 12:04 PM
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".
2022-12-26 12:07 PM
No no, it works on 8 bits so no need for 9 bits..
2022-12-26 12:08 PM
Ah thanks a lot..!
2022-12-26 12:09 PM
This is one of the things I like about embedded programming, it makes you go crazy but when it works, it feels sooooooo goooddd...!
2022-12-26 12:13 PM
If someone can, please tell me why 8Mhz frequency worked rather than 16Mhz? I see in the reference manual that APB1 runs on 36Mhz.