cancel
Showing results for 
Search instead for 
Did you mean: 

Not getting output via USART2 of STM32F401RE nucleo board

Lalit26
Associate

Hi All,

I have written a baremetal code to initialize the USART2 of STM32F401RE and print HELLO WORLD. The code does not use HAL and rather accesses and writes to USART2 peripheral registers using the C pointers. I have cross verified the code multiple times and have tried multiple methods to get the print, but I am not seeing any output on the teraterm/puTTY. 

I even used USB-TTL cable for this purpose by connecting the PA2 and PA3 (on the ST-Morpho connector) to TTL's cable Rx and Tx pin respectively. But there is no output. What can be the reason? Below is my code:

#include "stdint.h"
#include "stm32f4xx.h"
#include "string.h"

typedef struct{
	volatile uint32_t REG_MODER;
	volatile uint32_t REG_OTYPER;
	volatile uint32_t REG_PUPDR;
	volatile uint32_t REG_IDR;
	volatile uint32_t REG_ODR;
	volatile uint32_t REG_AFR[2];
}GPIO_REG_DEF;

typedef struct{
	volatile uint32_t REG_SR;
	volatile uint32_t REG_DR;
	volatile uint32_t REG_BRR;
	volatile uint32_t REG_CR1;
	volatile uint32_t REG_CR2;
	volatile uint32_t REG_CR3;
}USART_REG_DEF;

/*Create a pointer of type GPIO_REG_DEF pointing to base address of GPIOA*/
#define GPIO_BASE_ADDR 0x40020000
#define GPIO_A ((GPIO_REG_DEF *)GPIO_BASE_ADDR)

/*Create pointers of type volatile uint32_t to point to respective registers in the RCC*/
#define AHB1_ADDR (*(volatile uint32_t *)(0x40023800+0x30))
#define APB1_ADDR (*(volatile uint32_t *)(0x40023800+0x40))

/*Create pointers of type USART_REG_DEF pointing to base address of USART2*/
#define USART_BASE_ADDR 0x40004400
#define USART_2 ((USART_REG_DEF *)USART_BASE_ADDR)

/*Create an alias for USART pins*/
#define USART_TX_PIN								2
#define USART_RX_PIN								3

/*Create an alias for USART registers' bits*/
#define USART_EN 										(1<<13)
#define USART_OVER8 								(1<<15)
#define USART_STOP_BITS 						(0x3<<12)
#define USART_WORD_LEN 							(1<<12)
#define USART_PARITY_CTRL 					(1<<10)
#define USART_PARITY_TYPE 					(1<<9)
#define USART_TX_EN 								(1<<3)
#define USART_RX_EN 								(1<<2)
#define USART_BR										((0x16<<4) | (0xD & 0xFF))
#define TXE													(1<<7)
#define TC													(1<<6)
#define RXNE												(1<<5)

#define SEND_MSG 										"HELLO WORLD" 

/*Function to set up the clock for GPIOA and USART2*/
void clockSet(){
	AHB1_ADDR |= 1;
	APB1_ADDR |= (1<<17);
}

/*Function to initialize the UART Tx and Rx pins*/
void gpioConfig(){
	/*Configure GPIOA pin2 and pin3 in alternate function mode to use it as an UART*/
	GPIO_A->REG_MODER &= ~(0x3<<(2*USART_TX_PIN) | 0x3<<(2*USART_RX_PIN));
	GPIO_A->REG_MODER |= (0x2<<(2*USART_TX_PIN) | 0x2<<(2*USART_RX_PIN));
	GPIO_A->REG_AFR[0] |= (7<<(4*USART_TX_PIN)| 7<<(4*USART_RX_PIN));
	GPIO_A->REG_OTYPER &= ~(0x1<<USART_TX_PIN | 0x1<<USART_RX_PIN);
	GPIO_A->REG_PUPDR &= ~(0x3<<(2*USART_TX_PIN) | 0x3<<(2*USART_RX_PIN));
}

/*Function to initialize the USART*/
void usart_init(){
	USART_2->REG_CR1 &= ~USART_EN;
	USART_2->REG_CR1 &= ~USART_OVER8;									//RESET the OVER8 bit in CR1 for oversampling=16
	USART_2->REG_CR2 &= ~USART_STOP_BITS;							//Configure number of stop bits=1
	USART_2->REG_CR1 &= ~USART_WORD_LEN;							//Configure the word length (1 start bit+8 data bits+1 stop bits)
	USART_2->REG_CR1 &= ~USART_PARITY_CTRL;						//Disable parity control		
	USART_2->REG_CR1 |= USART_TX_EN;									//enable the transmit driver path
	USART_2->REG_CR1 |= USART_RX_EN; 									//ENABLE the receive driver path
	USART_2->REG_BRR = USART_BR;											//SET the baud rate to 115200
	USART_2->REG_CR1 |= USART_EN; 										//Enable the USART2
}

void send_data(){
	unsigned char ch;
	int i=0;
	while(i != strlen(SEND_MSG)){
		ch = SEND_MSG[i];
		while(!(USART_2->REG_SR & TXE));
		USART_2->REG_DR = ch;
		i++;
	}
	while(!(USART_2->REG_SR & TC));
}

int main(){
	clockSet();
	gpioConfig();
	usart_init();
	send_data();
	while(1);
}

Can anyone please help me to get this working?

Thanks,

Lalit.

1 REPLY 1

Sanity test with HAL, even if you choose to do it this way. There's a LOT of non-optimal code in your example

Have you checked signal with scope?

Baud rate looks wrong. What was the goal?

Default HSI clock is 8 MHz for F401

#define USART_BR (8000000 / 9600)

#define USART_BR (HSI_VALUE / 9600)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..