STM32 串口通信

引言

在嵌入式系统开发中,串口通信是最基础且重要的通信方式之一。无论是设备调试、模块对接还是远程通信,串口都扮演着关键角色。本文将从通信协议原理出发,结合STM32F4系列MCU,深入讲解串口通信的硬件实现和软件配置,并通过实战案例展示其应用。

一、串口通信协议深度解析

1.1 串口通信核心概念

串行接口(Serial Port)采用逐位顺序传输方式,其优势在于:

  • 硬件成本低(仅需2根信号线)
  • 传输距离远(RS485可达千米级)
  • 抗干扰能力强
  • 协议简单易实现

常见串口类型对比:

类型 电平标准 传输距离 通信方式
TTL 0-3.3V/5V <3m 全双工
RS232 ±3-15V 15m 全双工
RS485 ±1.5-6V 1200m 半双工

1.2 通信协议分层模型

物理层规范

  • 接口类型:DB9、RJ45、端子排
  • 电平标准:RS232使用负逻辑(逻辑1=-3-15V,逻辑0=+3+15V)
  • 连接拓扑:点对点、总线型

协议层规范

  • 数据帧格式
  • 波特率精度(误差<2%)
  • 校验机制
  • 流控协议(硬件RTS/CTS,软件XON/XOFF)

1.3 数据帧结构详解

标准异步串行数据帧构成:

复制代码
[Start Bit][Data Bits][Parity Bit][Stop Bits]

典型参数配置示例:

c

Copy

c 复制代码
/* 8位数据位,无校验,1位停止位 */
UART_InitStructure.WordLength = UART_WORDLENGTH_8B;
UART_InitStructure.StopBits = UART_STOPBITS_1;
UART_InitStructure.Parity = UART_PARITY_NONE;

校验方式性能对比:

校验类型 错误检测能力 数据开销
奇校验 单比特错误 +1 bit
偶校验 单比特错误 +1 bit
CRC校验 多比特错误 +1-4字节

二、STM32F4串口硬件架构剖析

2.1 USART功能框图

https://example.com/stm32-usart-block-diagram.png

关键功能模块:

  1. 波特率发生器:BRR寄存器实现分数波特率生成
  2. 数据寄存器(TDR/RDR)
  3. 校验控制单元
  4. 中断控制器
  5. DMA接口

2.2 时钟系统配置

时钟树路径:

APBx总线时钟 → USARTDIV分频器 → 生成比特周期

波特率计算公式:

复制代码
波特率 = fCK / (16 * USARTDIV)

其中USARTDIV为16位浮点数(高12位整数,低4位小数)

配置示例(72MHz时钟,115200波特率):

c

Copy

c 复制代码
// USARTDIV = 72000000/(16 * 115200) = 39.0625
USART1->BRR = (39 << 4) | 0x1; // 0x271

2.3 GPIO映射配置

STM32F407 USART1引脚映射:

功能 引脚 复用功能
TX PA9 AF7
RX PA10 AF7
CTS PA11 AF7
RTS PA12 AF7

配置代码示例:

c

Copy

c 复制代码
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

三、STM32串口编程实战

3.1 基础通信实现

初始化流程:

c

Copy

c 复制代码
UART_HandleTypeDef huart1;

void USART1_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;
  HAL_UART_Init(&huart1);
}

数据收发函数:

c

Copy

c 复制代码
// 阻塞式发送
HAL_UART_Transmit(&huart1, (uint8_t*)"Hello", 5, 1000);

// 中断接收
HAL_UART_Receive_IT(&huart1, &rx_data, 1);

3.2 中断处理机制

中断服务函数示例:

c

Copy

c 复制代码
void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart1);
}

// 回调函数实现
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart->Instance == USART1){
    // 处理接收数据
    process_data(rx_data);
    // 重新使能接收
    HAL_UART_Receive_IT(huart, &rx_data, 1);
  }
}

3.3 DMA高效传输

DMA配置示例:

c

Copy

c 复制代码
// 发送DMA配置
hdma_usart1_tx.Instance = DMA2_Stream7;
hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart_tx.Init.Mode = DMA_NORMAL;
HAL_DMA_Init(&hdma_usart_tx);

// 启动DMA传输
HAL_UART_Transmit_DMA(&huart1, tx_buffer, BUFFER_SIZE);

四、典型应用案例

4.1 串口调试终端实现

重定向printf函数:

c

Copy

c 复制代码
int __io_putchar(int ch)
{
  HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 1000);
  return ch;
}

使用示例:

c

Copy

c 复制代码
printf("System Clock: %ld Hz\r\n", HAL_RCC_GetSysClockFreq());

4.2 MODBUS协议实现

协议帧结构:

复制代码
[地址][功能码][数据][CRC校验]

CRC16校验实现:

c

Copy

c 复制代码
uint16_t CRC16(uint8_t *buf, int len)
{
  uint16_t crc = 0xFFFF;
  for(int pos=0; pos<len; pos++){
    crc ^= (uint16_t)buf[pos];
    for(int i=8; i!=0; i--){
      if((crc & 0x0001) != 0){
        crc >>= 1;
        crc ^= 0xA001;
      }
      else
        crc >>= 1;
    }
  }
  return crc;
}

五、调试技巧与常见问题

5.1 故障排查指南

  1. 无数据收发
    • 检查物理连接
    • 验证波特率设置
    • 确认GPIO复用配置
  2. 数据错乱
    • 校验时钟精度
    • 检查电磁干扰
    • 验证电平匹配
  3. 接收数据不完整
    • 调整缓冲区大小
    • 优化中断优先级
    • 启用硬件流控

5.2 性能优化建议

  • 使用DMA进行大数据传输
  • 合理设置FIFO阈值
  • 采用环形缓冲区管理
  • 启用硬件校验功能

结语

通过本文的系统讲解,我们不仅深入理解了串口通信的协议原理,还掌握了STM32平台下的硬件配置和软件开发技巧。在实际项目中,建议根据具体需求选择合适的通信模式(轮询/中断/DMA),并注意做好电磁兼容设计。随着对串口技术的深入掌握,开发者可以更高效地实现各种工业通信需求。

相关推荐
许有杨1 小时前
STM32 的 GPIO和中断
stm32·单片机·嵌入式硬件
轩辰~1 小时前
STM32F103系列单片机寄存器操作和标准库操作
stm32·单片机·嵌入式硬件
小禾苗_2 小时前
32单片机——外部中断
单片机·嵌入式硬件
昊昊昊昊昊明3 小时前
10天学会嵌入式技术之51单片机-day-8
单片机·嵌入式硬件
昊昊昊昊昊明3 小时前
10天学会嵌入式技术之51单片机-day-6
单片机·物联网·51单片机
电鱼智能的电小鱼3 小时前
SAIL-RK3588协作机器人运动控制器技术方案
linux·嵌入式硬件·数码相机·机器人·无人机·边缘计算
优信电子3 小时前
GC9A01-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)
单片机
鸿蒙布道师3 小时前
AI硬件遭遇“关税风暴“:中国科技企业如何破局?
人工智能·科技·嵌入式硬件·深度学习·神经网络·opencv·机器人
二块烧肉4 小时前
STM32 串口USART
stm32·单片机·嵌入式硬件
Bardb4 小时前
04-stm32的标准外设库
stm32·c#