cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with USART on Nucleo-F401RE

david027
Associate II

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.

1 REPLY 1
mƎALLEm
ST Employee

Hello,


@david027 wrote:

Hi, I am pretty new to STM32 MCUs and I am having trouble with USART communication.


As you are a newbie to STM32 MCUs, better to start by using the HAL and inspire from the examples provided in STM32CubeF4 package:

https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM324xG_EVAL/Examples/UART

https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32F401RE-Nucleo/Examples/UART/UART_Printf

Then if you succeed with that you can inspire from the HAL implementation to develop your specific direct access to the registers.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.