news 2026/6/10 20:34:52

STM32F103C8T6三串口实战:从LED控制到数据回传(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F103C8T6三串口实战:从LED控制到数据回传(附完整代码)

STM32F103C8T6三串口实战:从LED控制到数据回传(附完整代码)

在嵌入式开发中,串口通信是最基础也最实用的功能之一。STM32F103C8T6作为一款性价比极高的Cortex-M3内核微控制器,内置了三个独立的USART模块,能够同时处理多路串口通信任务。本文将带你从硬件连接到代码实现,完整掌握如何利用这三个串口实现LED控制和数据回传功能。

1. 硬件准备与连接

1.1 所需材料清单

  • STM32F103C8T6最小系统板(蓝色药丸开发板)
  • USB转TTL模块(建议准备2-3个)
  • LED灯及限流电阻(或直接使用开发板上的用户LED)
  • 杜邦线若干
  • ST-Link下载器(用于程序烧录)

1.2 引脚连接说明

STM32F103C8T6的三个串口对应引脚如下:

串口TX引脚RX引脚复用功能重映射
USART1PA9PA10可重映射到PB6/PB7
USART2PA2PA3无重映射
USART3PB10PB11可重映射到PC10/PC11

实际连接时,需要注意:

  • TTL模块的TX接MCU的RX,RX接MCU的TX
  • 共地连接必不可少
  • 若使用开发板上的LED,通常连接在PC13引脚

2. 开发环境搭建

2.1 工具链配置

推荐使用以下开发环境组合:

  • Keil MDK-ARM:5.23及以上版本
  • STM32CubeMX:6.0+用于初始化代码生成
  • 串口调试助手:推荐使用SecureCRT或Putty

2.2 工程创建步骤

  1. 打开STM32CubeMX,选择STM32F103C8T6型号
  2. 配置时钟树,将系统时钟设置为72MHz
  3. 使能三个USART模块:
    • USART1:异步模式,波特率9600
    • USART2:异步模式,波特率9600
    • USART3:异步模式,波特率9600
  4. 生成代码时选择MDK-ARM工具链
// 示例:CubeMX生成的USART初始化代码片段 void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; 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. 三串口功能实现

3.1 串口1:数据回显功能

串口1将实现最基本的回显功能,即接收到什么数据就原样返回。我们使用中断方式接收数据。

// 串口1中断回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1){ // 将接收到的字符发回 HAL_UART_Transmit(&huart1, &rx_data, 1, 100); // 重新开启接收中断 HAL_UART_Receive_IT(&huart1, &rx_data, 1); } }

提示:在实际项目中,建议添加接收超时处理和缓冲区管理,避免数据丢失。

3.2 串口2:LED控制功能

串口2将接收特定指令控制LED状态。我们定义以下协议:

  • 发送"ON":打开LED
  • 发送"OFF":关闭LED
  • 其他指令:返回"Invalid Command"
// 串口2命令处理函数 void ProcessUSART2Command(uint8_t *cmd) { if(strcmp((char*)cmd, "ON") == 0){ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); HAL_UART_Transmit(&huart2, (uint8_t*)"LED ON\r\n", 8, 100); } else if(strcmp((char*)cmd, "OFF") == 0){ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); HAL_UART_Transmit(&huart2, (uint8_t*)"LED OFF\r\n", 9, 100); } else{ HAL_UART_Transmit(&huart2, (uint8_t*)"Invalid Command\r\n", 16, 100); } }

3.3 串口3:数据采集与传输

串口3将模拟一个数据采集终端,定期发送传感器数据(这里用ADC值模拟)。

// 模拟数据采集任务 void DataAcquisitionTask(void) { static uint32_t adcValue = 0; char buffer[50]; adcValue = HAL_ADC_GetValue(&hadc1); // 假设已配置ADC int len = sprintf(buffer, "ADC Value: %lu\r\n", adcValue); HAL_UART_Transmit(&huart3, (uint8_t*)buffer, len, 100); HAL_Delay(1000); // 每秒发送一次 }

4. 完整代码实现与优化

4.1 工程文件结构

├── Core │ ├── Src │ │ ├── main.c │ │ ├── stm32f1xx_it.c │ │ ├── usart.c │ ├── Inc │ │ ├── main.h │ │ ├── stm32f1xx_it.h │ │ ├── usart.h ├── Drivers ├── MDK-ARM

4.2 关键代码片段

主循环中整合三个串口的功能:

int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_USART3_UART_Init(); MX_ADC1_Init(); // 启动串口接收中断 HAL_UART_Receive_IT(&huart1, &usart1_rx_data, 1); HAL_UART_Receive_IT(&huart2, &usart2_rx_data, 1); while (1) { DataAcquisitionTask(); // 串口3数据发送 ProcessSerialCommands(); // 处理串口1和2的命令 HAL_Delay(100); } }

4.3 常见问题排查

  1. 无法接收数据

    • 检查TX/RX接线是否交叉连接
    • 确认波特率设置一致
    • 测量串口引脚是否有信号
  2. 数据乱码

    • 检查时钟配置是否正确(特别是外部晶振设置)
    • 验证串口初始化参数(数据位、停止位、校验位)
  3. 中断不触发

    • 确认NVIC中断已使能
    • 检查中断优先级设置
    • 确保中断服务函数名称正确

5. 进阶应用场景

5.1 多协议通信方案

利用三个串口实现不同的通信协议:

  • USART1:Modbus RTU协议
  • USART2:自定义二进制协议
  • USART3:JSON格式数据传输

5.2 数据分流处理

通过DMA实现高效数据传输,减轻CPU负担:

// DMA串口接收配置 HAL_UART_Receive_DMA(&huart1, usart1_rx_buffer, BUFFER_SIZE); HAL_UART_Receive_DMA(&huart2, usart2_rx_buffer, BUFFER_SIZE);

5.3 硬件流控制

当传输速率较高(如115200以上)或距离较远时,建议启用硬件流控制:

huart1.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;

6. 性能优化技巧

  1. 环形缓冲区应用

    typedef struct { uint8_t buffer[256]; uint16_t head; uint16_t tail; } RingBuffer;
  2. 中断优先级管理

    • 给关键串口分配更高优先级
    • 避免在中断中进行耗时操作
  3. 低功耗优化

    • 空闲时进入STOP模式
    • 通过串口唤醒MCU

在实际项目中,三串口的协同工作能力可以极大扩展STM32的应用场景。我曾在一个工业控制器项目中使用USART1连接HMI,USART2连接PLC,USART3连接无线模块,三者各司其职又相互配合,实现了稳定可靠的控制系统。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 5:19:29

如何成为渗透测试工程师?从零到入门的完整指南

如何成为渗透测试工程师?从零到入门的完整指南 一、渗透测试工程师的核心职责 渗透测试工程师通过模拟黑客攻击的方式,对目标系统(如网站、APP、网络设备等)进行安全测试,发现漏洞并提供修复建议。具体工作包括&#…

作者头像 李华
网站建设 2026/6/8 15:31:14

如何为PocketMine-MP编写高性能插件:10个最佳实践技巧

如何为PocketMine-MP编写高性能插件:10个最佳实践技巧 【免费下载链接】PocketMine-MP A server software for Minecraft: Bedrock Edition in PHP 项目地址: https://gitcode.com/gh_mirrors/po/PocketMine-MP PocketMine-MP是一款基于PHP的Minecraft: Bedr…

作者头像 李华
网站建设 2026/6/9 4:01:47

Lighthouse实战:从零到99分的首屏优化指南

1. 为什么首屏优化如此重要? 想象一下你打开一个网站,等了3秒还是白屏,你会怎么做?大多数人会选择直接关闭。数据显示,页面加载时间每增加1秒,用户流失率就增加7%。首屏加载速度直接影响用户体验、转化率甚…

作者头像 李华
网站建设 2026/6/9 2:28:15

OpenTabletDriver在艺术创作中的应用:数字绘画最佳实践

OpenTabletDriver在艺术创作中的应用:数字绘画最佳实践 【免费下载链接】OpenTabletDriver Open source, cross-platform, user-mode tablet driver 项目地址: https://gitcode.com/gh_mirrors/op/OpenTabletDriver OpenTabletDriver是一款开源、跨平台的用户…

作者头像 李华
网站建设 2026/6/9 3:25:55

用fakeIP插件玩转BurpSuite Intruder:实现随机IP绕过WAF的暴力破解实战

用fakeIP插件玩转BurpSuite Intruder:实现随机IP绕过WAF的暴力破解实战 在渗透测试中,Web应用防火墙(WAF)和基于IP的速率限制常常成为安全研究人员面临的主要障碍。传统的暴力破解尝试往往因为单一IP的频繁请求而被迅速封禁&#…

作者头像 李华