uart-serial-baremetal
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseUART Serial (Bare-Metal)
UART串行通信(裸机)
Purpose
用途
Implement UART/USART for debug console and device communication: baud rate calculation, 8N1 framing, polling and interrupt-driven I/O, overrun handling, and optional DMA basics.
为调试控制台和设备通信实现UART/USART:包括波特率计算、8N1帧格式、轮询与中断驱动I/O、溢出处理,以及可选的DMA基础功能。
When to Use
适用场景
- First /log output on new hardware
printf - Serial protocol to sensor/module
- Replacing blocking HAL_UART with minimal driver
- Fixing garbled or missing characters
- 在新硬件上实现首个/日志输出
printf - 与传感器/模块的串行协议通信
- 用轻量驱动替代阻塞式HAL_UART
- 修复乱码或丢字符问题
Workflow
实现流程
1. Baud rate (STM32)
1. 波特率配置(STM32)
BRR = pclk / (16 * baud) /* oversampling by 16 — check RM for USART */c
void usart2_init(uint32_t pclk, uint32_t baud) {
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
/* GPIO PA2/PA3 AF — see gpio-baremetal */
USART2->BRR = pclk / baud; /* simplified — RM has fractional formula */
USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}Verify from actual clock tree (, APB prescaler).
pclkSystemCoreClockBRR = pclk / (16 * baud) /* oversampling by 16 — check RM for USART */c
void usart2_init(uint32_t pclk, uint32_t baud) {
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
/* GPIO PA2/PA3 AF — see gpio-baremetal */
USART2->BRR = pclk / baud; /* simplified — RM has fractional formula */
USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}从实际时钟树(、APB预分频器)确认的值。
SystemCoreClockpclk2. Polling TX/RX
2. 轮询式TX/RX
c
void uart_putc(USART_TypeDef *u, char c) {
while (!(u->SR & USART_SR_TXE))
;
u->DR = (uint8_t)c;
}
char uart_getc(USART_TypeDef *u) {
while (!(u->SR & USART_SR_RXNE))
;
return (uint8_t)u->DR;
}c
void uart_putc(USART_TypeDef *u, char c) {
while (!(u->SR & USART_SR_TXE))
;
u->DR = (uint8_t)c;
}
char uart_getc(USART_TypeDef *u) {
while (!(u->SR & USART_SR_RXNE))
;
return (uint8_t)u->DR;
}3. Interrupt-driven RX ring buffer
3. 中断驱动的RX环形缓冲区
c
void USART2_IRQHandler(void) {
if (USART2->SR & USART_SR_RXNE) {
uint8_t b = USART2->DR;
rb_push(&rx_rb, b);
}
if (USART2->SR & USART_SR_ORE) {
(void)USART2->DR; /* clear overrun — required on STM32 */
}
}c
void USART2_IRQHandler(void) {
if (USART2->SR & USART_SR_RXNE) {
uint8_t b = USART2->DR;
rb_push(&rx_rb, b);
}
if (USART2->SR & USART_SR_ORE) {
(void)USART2->DR; /* clear overrun — required on STM32 */
}
}4. retarget printf
(newlib)
printf4. 重定向printf
(newlib)
printfc
int _write(int fd, char *ptr, int len) {
(void)fd;
for (int i = 0; i < len; i++)
uart_putc(USART2, ptr[i]);
return len;
}Link with or provide full syscalls.
--specs=nosys.specsc
int _write(int fd, char *ptr, int len) {
(void)fd;
for (int i = 0; i < len; i++)
uart_putc(USART2, ptr[i]);
return len;
}链接时使用,或提供完整的系统调用。
--specs=nosys.specs5. Agent usage
5. Agent使用方式
/uart-serial-baremetal Calculate USART BRR for 115200 at 84 MHz PCLK/uart-serial-baremetal Calculate USART BRR for 115200 at 84 MHz PCLKCommon Problems
常见问题
| Symptom | Cause | Fix |
|---|---|---|
| Garbage chars | Wrong baud/PCLK | Recompute BRR; check APB divider |
| Lost bytes | ORE not cleared | Read DR on ORE; use IRQ + ringbuf |
| No output | TX pin not AF | GPIO alternate function |
| | Implement retarget |
| 症状 | 原因 | 解决方案 |
|---|---|---|
| 乱码 | 波特率/PCLK错误 | 重新计算BRR;检查APB分频器 |
| 丢字节 | 未清除ORE标志 | 发生ORE时读取DR;使用IRQ+环形缓冲区 |
| 无输出 | TX引脚未配置为AF | 设置GPIO复用功能 |
| 缺少 | 完成重定向实现 |
Related Skills
相关技能
- — TX/RX pin mux
skills/baremetal/gpio-baremetal - — USART IRQ
skills/baremetal/interrupts-and-exceptions-baremetal - — UART RX DMA
skills/baremetal/dma-baremetal - — semihosting alternative
skills/embedded/openocd-jtag
- — TX/RX引脚复用配置
skills/baremetal/gpio-baremetal - — USART中断
skills/baremetal/interrupts-and-exceptions-baremetal - — UART RX DMA
skills/baremetal/dma-baremetal - — semihosting替代方案
skills/embedded/openocd-jtag