2025-03-25 7:28 AM - last edited on 2025-03-25 7:37 AM by Andrew Neil
Hi, I am pretty new to STM32 MCUs and I am having trouble with USART communication. I would like to send a message from Nucleo-F401RE to raspberry pi 3b+, and then to display that message in terminal on raspberry. I have tried to use USART2 for this but it didn't work, then i read that USART2 is used when i connect Nucleo to the laptop so i changed the code to use USART1 and it still doesn't work.
I have tested the USART2 with the advanced serial monitor on the laptop and it works properly.
Bellow are the functions in main.c and uart.c that i am currently using
This is the function uart.c, for some reason i couldn't post it as the attachment:
#include "moduli/uart.h"
#include "stm32f401xe.h"
#define BUFFER_SIZE 64
static uint8_t ring_buffer[BUFFER_SIZE];
static uint8_t rb_write;
static uint8_t rb_read;
void uart1_init() {
/*
* PA9 --> USART1 TX (AF7)
* PA10 --> USART1 RX (AF7)
*/
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
// Init GPIO
GPIOA->MODER &= ~(0b11 << (9 * 2) | 0b11 << (10 * 2));
GPIOA->MODER |= (0b10 << (9 * 2) | 0b10 << (10 * 2));
GPIOA->AFR[1] &= ~(0xF << ((9 - * 4) | 0xF << ((10 - * 4));
GPIOA->AFR[1] |= (7 << ((9 - * 4) | 7 << ((10 - * 4));
// Init USART1
USART1->CR1 &= ~(1 << 15); // OVER8 = 0 (16 samples)
USART1->CR1 &= ~(1 << 12); // 8 data bits
USART1->CR1 &= ~(1 << 10); // no parity
USART1->CR1 |= (1 << 5); // RXNE interrupt enable
USART1->CR1 |= (1 << 3); // TE
USART1->CR1 |= (1 << 2); // RE
// Baudrate: 9600 @ 42 MHz
USART1->BRR = (273 << 4) | 7;
USART1->CR1 |= (1 << 13); // USART enable
NVIC->ISER[1] |= (1 << (37 - 32)); // USART1 IRQ
}
void uart1_send_data(unsigned char data) {
while (!(USART1->SR & (1 << 6))); // TXE
USART1->DR = data;
}
void uart1_send_data_array(unsigned char *data, unsigned int size) {
for (int i = 0; i < size; i++) {
uart1_send_data(*data++);
}
}
void uart1_echo() {
if (rb_read == rb_write)
return;
while (ring_buffer[rb_read] != '\0') {
uart1_send_data(ring_buffer[rb_read]);
rb_read = (rb_read + 1) % BUFFER_SIZE;
}
}
void USART1_IRQHandler(void) {
if ((USART1->SR & (1 << 5)) != 0) { // RXNE
ring_buffer[rb_write] = USART1->DR;
rb_write = (rb_write + 1) % BUFFER_SIZE;
ring_buffer[rb_write] = '\0';
}
}
Can somebody help me with this?
Thanks in advance.
Code formatting applied - please see How to insert source code for future reference.