当前位置: 首页 > news >正文

嵌入式硬件篇---UART


文章目录

  • 前言
  • 1. UART协议基础
    • 1.1 物理层特性
      • 两根信号线
      • 无时钟信号
      • 电平标准
        • TTL UART
        • RS-232
    • 1.2 数据帧格式
    • 1.3 波特率计算
      • 波特率
  • 2. STM32F103RCT6的UART配置
    • 2.1 硬件连接
    • 2.2 CubeMX配置
      • 启用USART1
      • 引脚分配
      • 中断启用(可选)
  • 3. HAL库代码实现
    • 3.1 UART初始化
    • 3.2 发送数据(阻塞模式)
    • 3.3 接收数据(中断模式)
    • 3.4 DMA传输(高效大数据量)
  • 4. 自定义协议设计
    • 4.1 帧格式示例
    • 4.2 帧解析代码
  • 5. 常见问题与调试
    • 5.1 通信失败原因
      • 波特率不匹配
      • 电平不兼容
      • 接线错误
      • 中断为启用
    • 5.2 逻辑分析仪抓包
  • 6. 完整示例:与PC通信
    • STM32代码
    • PC端(Python脚本)
  • 7.总结
    • 基本配置
    • 通信模式
    • 协议设计
    • 调试工具


前言

UART(Universal Asynchronous Receiver/Transmitter)是一种异步串行通信协议,广泛应用于嵌入式设备与传感器、蓝牙模块、GPS等外设的通信。以下是UART协议的详细解析及在STM32F103RCT6上的完整代码实现。


1. UART协议基础

1.1 物理层特性

两根信号线

TX(Transmit):数据发送线(输出)。
RX(Receive):数据接收线(输入)。

无时钟信号

无时钟信号:依赖预定义的波特率(Baud Rate)同步。

电平标准

TTL UART

TTL UART:0V(逻辑0),3.3V/5V(逻辑1)。

RS-232

RS-232:±12V(需电平转换芯片如MAX232)。

1.2 数据帧格式

[起始位] [数据位(5-9位)] [校验位(可选)] [停止位(1-2位)]
起始位:1位低电平(逻辑0)。
数据位:通常8位(如ASCII字符)。
校验位(可选):
奇校验:数据位中1的个数为奇数时置1。
偶校验:数据位中1的个数为偶数时置1。
停止位:1或2位高电平(逻辑1)。

1.3 波特率计算

波特率

波特率(Baud Rate)表示每秒传输的符号数(1符号=1位)。
常见波特率:9600、115200等。
STM32的UART时钟源为APB2(默认72MHz),波特率计算公式:
波特率=APB2时钟USARTDIV
其中USARTDIV是一个16位寄存器值(整数部分 + 小数部分)。

2. STM32F103RCT6的UART配置

2.1 硬件连接

UART信号 STM32引脚 说明
USART1_TX PA9 发送数据
USART1_RX PA10 接收数据
GND 共地 确保电平参考一致

2.2 CubeMX配置

启用USART1

模式:Asynchronous(异步模式)。
波特率:115200。
数据位:8位。
校验位:None。
停止位:1位。

引脚分配

PA9 → USART1_TX
PA10 → USART1_RX

中断启用(可选)

接收中断(RXNE)。

3. HAL库代码实现

3.1 UART初始化

#include "stm32f1xx_hal.h"UART_HandleTypeDef huart1;void MX_USART1_UART_Init(void) {huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK) {Error_Handler();}
}

3.2 发送数据(阻塞模式)

void UART_SendString(uint8_t *str) {HAL_UART_Transmit(&huart1, str, strlen((char *)str), 100); // 阻塞式发送
}// 示例:发送"Hello World!"
UART_SendString((uint8_t *)"Hello World!\r\n");

3.3 接收数据(中断模式)

uint8_t rx_data;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if (huart == &huart1) {// 处理接收到的数据(如回显)HAL_UART_Transmit(&huart1, &rx_data, 1, 100);HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 重新启用接收中断}
}// 主函数中启用接收中断
int main(void) {HAL_Init();MX_USART1_UART_Init();HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 启动接收中断while (1) { /* 其他任务 */ }
}

3.4 DMA传输(高效大数据量)

uint8_t dma_tx_buffer[] = "DMA Transmission Test!\r\n";// 初始化DMA
void MX_DMA_Init(void) {__HAL_RCC_DMA1_CLK_ENABLE();
}// 通过DMA发送数据
HAL_UART_Transmit_DMA(&huart1, dma_tx_buffer, sizeof(dma_tx_buffer));

4. 自定义协议设计

4.1 帧格式示例

字段 长度 说明
帧头 2字节 0xAA 0x55
数据长度 1字节 后续数据长度(N)
数据 N字节 有效载荷
CRC校验 1字节 校验和(数据字节累加和)

4.2 帧解析代码

uint8_t rx_buffer[64];
uint8_t frame_state = 0;
uint8_t data_len = 0;
uint8_t crc = 0;void Process_UART_Byte(uint8_t byte) {static uint8_t idx = 0;switch (frame_state) {case 0: // 等待帧头1if (byte == 0xAA) frame_state = 1;break;case 1: // 等待帧头2if (byte == 0x55) frame_state = 2;else frame_state = 0;break;case 2: // 读取数据长度data_len = byte;idx = 0;crc = byte;frame_state = 3;break;case 3: // 读取数据rx_buffer[idx++] = byte;crc += byte;if (idx >= data_len) frame_state = 4;break;case 4: // 校验CRCif (crc == byte) {// 帧处理(如控制LED)if (rx_buffer[0] == 0x01) HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);}frame_state = 0;break;}
}// 在中断回调中调用
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {Process_UART_Byte(rx_data);HAL_UART_Receive_IT(&huart1, &rx_data, 1);
}

5. 常见问题与调试

5.1 通信失败原因

波特率不匹配

波特率不匹配:确保双方波特率一致(如115200)。

电平不兼容

电平不兼容:TTL UART不能直接接RS-232设备。

接线错误

接线错误:检查TX/RX是否交叉连接。

中断为启用

中断未启用:若使用中断接收,需调用HAL_UART_Receive_IT()。

5.2 逻辑分析仪抓包

使用工具(如Saleae Logic)观察:

  1. 起始位是否为低电平?
  2. 数据位是否符合预期?
  3. 停止位是否为高电平?

6. 完整示例:与PC通信

STM32代码

int main(void) {HAL_Init();MX_USART1_UART_Init();HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 启用接收中断while (1) {// 每隔1秒发送数据UART_SendString((uint8_t *)"STM32 UART Test\r\n");HAL_Delay(1000);}
}

PC端(Python脚本)

import serial
ser = serial.Serial('COM3', 115200, timeout=1)  # 根据实际端口修改
while True:if ser.in_waiting:data = ser.readline().decode('utf-8').strip()print("Received:", data)

7.总结

基本配置

基本配置:波特率、数据位、停止位需匹配。

通信模式

通信模式:阻塞、中断、DMA按需选择

协议设计

协议设计:自定义帧格式提升可靠性

调试工具

调试工具:逻辑分析仪、串口助手是关键。
通过上述代码,STM32F103RCT6可实现稳定的UART通信,适用于传感器数据采集、无线模块控制等场景。


相关文章:

  • 5java集合框架
  • 虚幻引擎5-Unreal Engine笔记之UE编辑器退出时的保存弹框
  • Level1.5算数运算符与赋值运算符
  • 时钟晶振锁相环pll方向技术要点和大厂题目解析
  • nvme Unable to change power state from D3cold to D0, device inaccessible
  • DS18B20温度传感器
  • [思维模式-25]:《本质思考力》-6- 马克思主义哲学的五对基本哲学范畴,以及在计算机领域的体现
  • Linux系统之----模拟实现shell
  • 技嘉主板BIOS升级
  • 单片机-STM32部分:10-2、逻辑分析仪
  • Android开发-Activity启停
  • JAVA练习题(2) 找素数
  • 【Bootstrap V4系列】学习入门教程之 组件-输入组(Input group)
  • (2025)图文解锁RAG从原理到代码实操,代码保证可运行
  • 【基于 LangChain 的异步天气查询2】GeoNames实现地区实时气温查询
  • 棒球裁判员学习指南·棒球1号位
  • dify插件接入fastmcp示例
  • Satori:元动作 + 内建搜索机制,让大模型实现超级推理能力
  • 一文理解扩散模型(生成式AI模型)(1)
  • 初等数论--莫比乌斯函数
  • 网站建设 青岛/微信推广文案
  • 个体户做网站去哪里做/百度地图导航网页版
  • 嘉兴平湖网站建设/一个网站可以优化多少关键词
  • 昆明网站建设云集创/南昌百度推广公司
  • 网站规划书的内容有哪些/知乎关键词排名
  • 黄岐建网站/网络快速排名优化方法