2025-11-26 11:17 AM
I'm writing a UART driver for NUCLEO-F103RB and I followed all steps in the book "Bare-metal embedded C programming" and advices from Gemini but still can't see the receiving output from my PC.
How can I fix this?
Other parts than UART work without problem in this setting.
main.c
#include <stdint.h>
#include <stdio.h>
#include "gpio.h"
#include "uart.h"
#if !defined(__SOFT_FP__) && defined(__ARM_FP)
#warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif
unsigned readBit(unsigned line, unsigned position){
unsigned mask = 1U<<position;
return ((mask & line) >> position);
}
int main(void)
{
RCC_APB2EN_R |= 1U<<2;
RCC_APB2EN_R |= 1U<<4;
//led init
GPIOA_MODE_R &= ~(1U<<20);
GPIOA_MODE_R |= 1U<<21;
GPIOA_MODE_R &= ~(1U<<22);
GPIOA_MODE_R &= ~(1U<<23);
//button init
GPIOC_MODE_R &= ~(1U<<20);
GPIOC_MODE_R &= ~(1U<<21);
GPIOC_MODE_R |= 1U<<22;
GPIOC_MODE_R &= ~(1U<23);
uart_init();
unsigned short button_pressed = 0;
unsigned short led_on = 0;
/* Loop forever */
for(;;){
for(int i = 0; i < 500000; i++);
printf("Hello from STM32...\r\n");
}
}
gpio.h
#define PERIPH_BASE 0x40000000UL
#define GPIOA_OFFSET 0x00010800UL
#define GPIOC_OFFSET 0x00011000UL
#define GPIOA_BASE PERIPH_BASE + GPIOA_OFFSET
#define GPIOC_BASE PERIPH_BASE + GPIOC_OFFSET
#define RCC_OFFSET 0x00021000UL
#define RCC_BASE PERIPH_BASE + RCC_OFFSET
#define APB2EN_R_OFFSET 0x18UL
#define RCC_APB2EN_R *(volatile unsigned int *)(RCC_BASE + APB2EN_R_OFFSET)
#define A_MODE_R_OFFSET 0x00UL
#define C_MODE_R_OFFSET 0x04UL
#define GPIOA_MODE_R *(volatile unsigned int *)(GPIOA_BASE + A_MODE_R_OFFSET)
#define GPIOC_MODE_R *(volatile unsigned int *)(GPIOC_BASE + C_MODE_R_OFFSET)
#define OD_R_OFFSET 0x0CUL
#define GPIOA_OD_R *(volatile unsigned int *)(GPIOA_BASE + OD_R_OFFSET)
#define ID_R_OFFSET 0x08UL
#define GPIOC_ID_R *(volatile unsigned int *)(GPIOC_BASE + ID_R_OFFSET)
#define BSRR_OFFSET 0x10UL
#define GPIOA_BSRR *(volatile unsigned int*)(GPIOA_BASE + BSRR_OFFSET)
uart.h
#define PERIPH_BASE 0x40000000UL
#define GPIOA_OFFSET 0x00010800UL
#define GPIOC_OFFSET 0x00011000UL
#define GPIOA_BASE PERIPH_BASE + GPIOA_OFFSET
#define GPIOC_BASE PERIPH_BASE + GPIOC_OFFSET
#define USART2_BASE PERIPH_BASE + 0x00013800UL
#define RCC_OFFSET 0x00021000UL
#define RCC_BASE PERIPH_BASE + RCC_OFFSET
#define RCC_APB1EN_R *(volatile unsigned int *)(RCC_BASE + 0x1CUL)
#define RCC_APB2EN_R *(volatile unsigned int *)(RCC_BASE + 0x18UL)
#define C_MODE_R_OFFSET 0x04UL
#define GPIOA_MODEL_R *(volatile unsigned int *)(GPIOA_BASE)
#define GPIOC_MODE_R *(volatile unsigned int *)(GPIOC_BASE + C_MODE_R_OFFSET)
#define USART2_BRR_R *(volatile unsigned int *)(USART2_BASE + 0x08UL)
#define USART2_CR1_R *(volatile unsigned int *)(USART2_BASE + 0x0CUL)
#define USART2_SR_R *(volatile unsigned int *)(USART2_BASE + 0x00UL)
#define USART2_DR_R *(volatile unsigned int *)(USART2_BASE + 0x04UL)
#define APB1_CLK 36000000
#define USART_BAUDRATE 115200
void uart_init(void);
uart.c
#include <stdint.h>
#include "uart.h"
void uart_init(void){
RCC_APB2EN_R |= 1U<<2;
RCC_APB1EN_R |= 1U<<17;//UART2 enable
/*GPIOA_MODEH_R &= ~(1U<<4);
GPIOA_MODEH_R |= (1U<<5);
GPIOA_MODEH_R &= ~(1U<<6);
GPIOA_MODEH_R |= (1U<<7);
*/
GPIOA_MODEL_R &= ~(0xFUL << 8);
// Set MODE9[1:0] = 10 (Output mode, max speed 2 MHz)
GPIOA_MODEL_R |= (1U << 9);
// Set CNF9[1:0] = 10 (Alternate function output Push-pull)
GPIOA_MODEL_R |= (1U << 11);
//int uartdiv = APB2_CLK/USART_BAUDRATE;
unsigned uartdiv = APB1_CLK/USART_BAUDRATE;
unsigned mantissa = uartdiv / 16;
unsigned fraction = uartdiv % 16;
USART2_BRR_R = (mantissa << 4) | fraction;
//USART2_BRR_R = (APB1_CLK + (USART_BAUDRATE/2U))/(16U * USART_BAUDRATE);
USART2_CR1_R |= 1U<<3;
USART2_CR1_R |= 1U<<13;
}
int __io_putchar(int ch)
{
while(!(USART2_SR_R & (1U<<7))){}
USART2_DR_R = (ch & 0xFF);
return ch;
}
2025-11-26 11:44 AM
Welcome to the forum.
Please see How to write your question to maximize your chances to find a solution for best results
@Jajang01 wrote:NUCLEO-F103RB
So, presumably, you are using the ST-Link's VCP (Virtual COM Port) to connect to the PC ?
Are you sure that you are using the correct UART pins for that ?
Have you tried one of the ST examples for reference?