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/PB7USART2PA2PA3无重映射USART3PB10PB11可重映射到PC10/PC11实际连接时需要注意TTL模块的TX接MCU的RXRX接MCU的TX共地连接必不可少若使用开发板上的LED通常连接在PC13引脚2. 开发环境搭建2.1 工具链配置推荐使用以下开发环境组合Keil MDK-ARM5.23及以上版本STM32CubeMX6.0用于初始化代码生成串口调试助手推荐使用SecureCRT或Putty2.2 工程创建步骤打开STM32CubeMX选择STM32F103C8T6型号配置时钟树将系统时钟设置为72MHz使能三个USART模块USART1异步模式波特率9600USART2异步模式波特率9600USART3异步模式波特率9600生成代码时选择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 串口2LED控制功能串口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-ARM4.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 常见问题排查无法接收数据检查TX/RX接线是否交叉连接确认波特率设置一致测量串口引脚是否有信号数据乱码检查时钟配置是否正确特别是外部晶振设置验证串口初始化参数数据位、停止位、校验位中断不触发确认NVIC中断已使能检查中断优先级设置确保中断服务函数名称正确5. 进阶应用场景5.1 多协议通信方案利用三个串口实现不同的通信协议USART1Modbus RTU协议USART2自定义二进制协议USART3JSON格式数据传输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. 性能优化技巧环形缓冲区应用typedef struct { uint8_t buffer[256]; uint16_t head; uint16_t tail; } RingBuffer;中断优先级管理给关键串口分配更高优先级避免在中断中进行耗时操作低功耗优化空闲时进入STOP模式通过串口唤醒MCU在实际项目中三串口的协同工作能力可以极大扩展STM32的应用场景。我曾在一个工业控制器项目中使用USART1连接HMIUSART2连接PLCUSART3连接无线模块三者各司其职又相互配合实现了稳定可靠的控制系统。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2440624.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!