2025-08-04 6:30 AM - edited 2025-08-04 6:51 AM
I'm trying to set up a simple UART debug just for transmission from the the NUCLEO board.
uart.c
#include "uart.h"
#define GPIOAEN (1U<<0)
#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 uart2_set_baudrate(uint32_t periph_clk, uint32_t baudrate);
static uint16_t compute_uart_bd(uint32_t periph_clk, uint32_t baudrate);
static void uart2_write(int ch);
int __io_putchar(int ch)
{
uart2_write(ch);
return ch;
}
void uart2_tx_init(void)
{
/*** Configure UART GPIO pin ***/
/* Enable clock access to GPIOA */
RCC->AHB1ENR |= GPIOAEN;
/* Set PA2 mode to alternate function mode */
GPIOA->MODER &=~ (1U<<4);
GPIOA->MODER |= (1U<<5);
/* Set PA2 alt function 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 the UART ***/
/* Enable clock access to UART2 */
RCC->AHB1ENR |= UART2EN;
/* Configure baudrate */
uart2_set_baudrate(APB1_CLK, UART_BAUDRATE);
/* Configure transfer direction */
USART2->CR1 = CR1_TE;
/* Enable UART module */
USART2->CR1 |= CR1_UE;
}
static void uart2_write(int ch)
{
/* Ensure transmit data register empty */
while(!(USART2->SR & SR_TXE)){}
/* Write to the transmit data register */
USART2->DR = (ch & 0xFF);
}
static void uart2_set_baudrate(uint32_t periph_clk, uint32_t baudrate)
{
USART2->BRR = compute_uart_bd(periph_clk, baudrate);
}
static uint16_t compute_uart_bd(uint32_t periph_clk, uint32_t baudrate)
{
return ((periph_clk + (baudrate / 2U)) / baudrate);
}
uart.h
#ifndef __UART_H__
#define __UART_H__
#include "stm32f4xx.h"
#include <stdint.h>
void uart2_tx_init(void);
#endif
main.c
#include "stm32f4xx.h"
#include <stdio.h>
#include "uart.h"
static void psuedo_delay(int dly);
int main(void)
{
/* Initialize UART2 */
uart2_tx_init();
while(1)
{
printf("hi there!\n\r");
psuedo_delay(9000);
}
}
static void psuedo_delay(int dly)
{
for(int i = 0; i < dly; i++)
{
// DO NOTHING
}
}
If I'm right then PA2 has been set up as a UART TX with a Baud rate of 115200 & this is connected to the USB on the board.
But when I open a TeraTerm window & connect to the board I get nothing just a blank terminal window. What am I missing here?
Solved! Go to Solution.
2025-10-02 2:08 AM - edited 2025-10-02 2:09 AM
I appreciate your insistence on using "official, proven and correct bit masks" but my intention here is to understand how things are working at a register level without abstraction.
As pointed out by @Andrew Neil some posts back now, the issue was actually the use of the drivers (yes user error as I had been blindly cut & pasting code). I was erroneously prototyping the USART configuration function in main() instead of calling it (there was a stray void in there that I was obviously blind to until this morning).
The actual driver itself works as it should even with "custom constants"