dede网站迁移phpcms移动端网站怎么做
2026/1/5 12:58:06 网站建设 项目流程
dede网站迁移,phpcms移动端网站怎么做,龙江网站建设公司,类似12306网站开发STM32F103 串口通信实现全指南本文以 STM32F103C8T6#xff08;最小系统板#xff09;为例#xff0c;详细讲解串口通信的硬件连接、软件配置、代码实现及调试问题解决方案#xff0c;分别覆盖标准外设库#xff08;STM32F10x_StdPeriph_Driver#xff09; 和HAL 库两种主…STM32F103 串口通信实现全指南本文以 STM32F103C8T6最小系统板为例详细讲解串口通信的硬件连接、软件配置、代码实现及调试问题解决方案分别覆盖标准外设库STM32F10x_StdPeriph_Driver和HAL 库两种主流开发方式同时包含轮询 / 中断两种数据收发模式。一、硬件连接1. 核心硬件主控STM32F103C8T6默认使用 USART1也可选择 USART2/3外设USB 转 TTL 模块CH340/PL2303、杜邦线、电源5V/3.3V2. 引脚对应USART1 为例STM32F103 的 USART1 引脚为复用功能需注意引脚定义STM32 引脚功能USB 转 TTL 模块引脚说明PA9USART1_TXRXD单片机发送→模块接收PA10USART1_RXTXD单片机接收→模块发送GND地GND共地必须连接否则乱码可选VCC电源3.3V给单片机供电也可单独供注意STM32 为 3.3V 电平USB 转 TTL 模块若为 5V 输出需串接 1kΩ 电阻分压避免烧毁单片机引脚。3. 硬件连接示意图plaintextSTM32F103C8T6 USB转TTL模块 PA9 (TX) ────────→ RXD PA10 (RX) ────────→ TXD GND ────────→ GND 3.3V ────────→ 3.3V可选二、时钟配置基础串口通信依赖时钟源STM32F103 的 USART 时钟由 APB 总线提供USART1 挂载在 APB2 总线最大时钟 72MHzUSART2/3 挂载在 APB1 总线最大时钟 36MHz串口波特率计算公式USART_BRR APBx时钟 / 波特率例APB272MHz波特率 9600 → BRR72000000/960075000x1D4C三、标准外设库实现STM32F10x_StdPeriph_Lib_V3.5.01. 工程配置引入标准外设库核心文件stm32f10x_usart.c、stm32f10x_rcc.c、stm32f10x_gpio.c定义时钟宏#define SYSCLK_FREQ_72MHz 720000002. 串口初始化USART19600 波特率8 位数据1 位停止无校验c运行#include stm32f10x.h // 串口初始化函数USART1轮询模式基础配置 void USART1_Init(uint32_t baudrate) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; // 中断模式需配置 /************************** 1. 使能时钟 **************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); /************************** 2. 配置GPIO引脚 **************************/ // PA9 (TX)复用推挽输出 GPIO_InitStruct.GPIO_Pin GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; // 复用推挽 GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStruct); // PA10 (RX)浮空输入或上拉输入 GPIO_InitStruct.GPIO_Pin GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode GPIO_Mode_IN_FLOATING; // 浮空输入 GPIO_Init(GPIOA, GPIO_InitStruct); /************************** 3. 配置USART参数 **************************/ USART_InitStruct.USART_BaudRate baudrate; // 波特率 USART_InitStruct.USART_WordLength USART_WordLength_8b; // 8位数据 USART_InitStruct.USART_StopBits USART_StopBits_1; // 1位停止位 USART_InitStruct.USART_Parity USART_Parity_No; // 无校验 USART_InitStruct.USART_HardwareFlowControl USART_HardwareFlowControl_None; // 无硬件流控 USART_InitStruct.USART_Mode USART_Mode_Tx | USART_Mode_Rx; // 收发使能 USART_Init(USART1, USART_InitStruct); /************************** 4. 中断配置可选中断模式需开启 **************************/ // 使能接收中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // RXNE接收缓冲区非空中断 // 配置NVIC NVIC_InitStruct.NVIC_IRQChannel USART1_IRQn; // USART1中断通道 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 1; // 抢占优先级1需根据系统调整 NVIC_InitStruct.NVIC_IRQChannelSubPriority 0; // 子优先级0 NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE; // 使能通道 NVIC_Init(NVIC_InitStruct); /************************** 5. 使能USART **************************/ USART_Cmd(USART1, ENABLE); }3. 轮询模式数据收发1发送单个字符c运行// 轮询发送单个字符等待发送缓冲区为空 void USART1_SendChar(uint8_t ch) { // 等待TXE位置1发送数据寄存器为空 while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET); USART_SendData(USART1, ch); // 发送字符 // 可选等待发送完成TC位确保数据完全发送 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) RESET); }2发送字符串c运行// 轮询发送字符串 void USART1_SendString(uint8_t *str) { while (*str ! \0) // 遍历字符串直到结束符 { USART1_SendChar(*str); str; } }3轮询接收单个字符c运行// 轮询接收单个字符阻塞式 uint8_t USART1_ReceiveChar(void) { // 等待RXNE位置1接收缓冲区非空 while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) RESET); return USART_ReceiveData(USART1); // 读取接收数据 }4. 中断模式数据接收1中断服务函数c运行uint8_t USART1_RxBuffer; // 接收缓冲区全局变量 uint8_t USART1_RxFlag 0; // 接收完成标志 // USART1中断服务函数 void USART1_IRQHandler(void) { uint32_t temp_flag 0; uint32_t temp_data 0; /************************** 1. 检查接收中断标志 **************************/ if (USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { USART_ClearITPendingBit(USART1, USART_IT_RXNE); // 清除中断标志 USART1_RxBuffer USART_ReceiveData(USART1); // 读取数据 USART1_RxFlag 1; // 设置接收完成标志 } /************************** 2. 处理溢出错误可选 **************************/ if (USART_GetITStatus(USART1, USART_IT_ORE) ! RESET) { temp_flag USART1-SR; // 读SR寄存器 temp_data USART1-DR; // 读DR寄存器清除ORE标志 (void)temp_flag; // 避免未使用变量警告 (void)temp_data; } }2中断接收处理示例c运行// 主函数中处理接收数据 int main(void) { USART1_Init(9600); // 初始化USART19600波特率 while (1) { if (USART1_RxFlag 1) // 检测到接收完成 { USART1_SendChar(USART1_RxBuffer); // 回显接收到的字符 USART1_RxFlag 0; // 清除标志 } } }四、HAL 库实现STM32CubeMX HAL 库1. STM32CubeMX 配置步骤1基础配置选择芯片STM32F103C8T6配置 RCCHSE 外部晶振8MHz系统时钟 72MHz配置 SYSDebug 选择 SWD方便调试2串口配置USART1模式Asynchronous异步模式参数Baud Rate9600Word Length8bitStop Bits1ParityNoneFlow ControlNoneGPIOPA9 (TX)、PA10 (RX)自动配置为复用功能中断NVIC Settings → 勾选 USART1 global interrupt开启全局中断3生成代码工具链MDK-ARM生成初始化代码自动生成 HAL 库底层配置2. 核心代码实现1串口初始化CubeMX 自动生成关键代码c运行UART_HandleTypeDef huart1; // USART1初始化函数CubeMX自动生成 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(); // 初始化失败处理 } } // HAL_UART_Init回调函数配置GPIO和中断 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct {0}; if(uartHandle-InstanceUSART1) { // 1. 使能时钟 __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); // 2. 配置GPIO /* PA9 TX */ GPIO_InitStruct.Pin GPIO_PIN_9; GPIO_InitStruct.Mode GPIO_MODE_AF_PP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); /* PA10 RX */ GPIO_InitStruct.Pin GPIO_PIN_10; GPIO_InitStruct.Mode GPIO_MODE_INPUT; GPIO_InitStruct.Pull GPIO_NOPULL; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); // 3. 配置中断 HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); } }3. 轮询模式收发1发送字符 / 字符串c运行// 轮询发送单个字符 HAL_StatusTypeDef UART1_SendChar(uint8_t ch) { // HAL_UART_Transmit阻塞发送参数句柄、数据指针、长度、超时时间 return HAL_UART_Transmit(huart1, ch, 1, 100); // 超时100ms } // 轮询发送字符串 HAL_StatusTypeDef UART1_SendString(uint8_t *str) { uint16_t len 0; while (str[len] ! \0) len; // 计算字符串长度 return HAL_UART_Transmit(huart1, str, len, 100); }2轮询接收字符c运行// 轮询接收单个字符阻塞式 HAL_StatusTypeDef UART1_ReceiveChar(uint8_t *ch) { // HAL_UART_Receive阻塞接收参数句柄、数据指针、长度、超时时间 return HAL_UART_Receive(huart1, ch, 1, 1000); // 超时1s }4. 中断模式收发1接收中断配置与实现c运行uint8_t UART1_RxBuffer; // 接收缓冲区 uint8_t UART1_RxFlag 0; // 接收完成标志 // 主函数中开启接收中断 HAL_UART_Receive_IT(huart1, UART1_RxBuffer, 1); // 开启单次接收中断 // 接收中断回调函数HAL库自动调用 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART1) { UART1_RxFlag 1; // 设置接收完成标志 // 重新开启接收中断HAL库中断接收为单次需手动重启 HAL_UART_Receive_IT(huart1, UART1_RxBuffer, 1); } } // USART1中断服务函数CubeMX自动生成 void USART1_IRQHandler(void) { HAL_UART_IRQHandler(huart1); // 调用HAL库中断处理函数 } // 主函数处理接收数据 int main(void) { HAL_Init(); SystemClock_Config(); MX_USART1_UART_Init(); HAL_UART_Receive_IT(huart1, UART1_RxBuffer, 1); // 开启首次接收中断 while (1) { if (UART1_RxFlag 1) { HAL_UART_Transmit(huart1, UART1_RxBuffer, 1, 100); // 回显 UART1_RxFlag 0; // 清除标志 } } }五、调试常见问题及解决方案1. 串口乱码原因波特率不匹配单片机配置与串口助手不一致时钟配置错误APB 总线时钟计算错误硬件未共地电平不匹配5V→3.3V 未分压晶振未起振系统时钟错误解决方案核对串口助手波特率 / 数据位 / 停止位 / 校验位与代码一致重新计算时钟确认 SYSCLK72MHzAPB272MHzUSART1APB136MHzUSART2/3确保 STM32 与 USB 转 TTL 模块共地5V TTL 模块串接 1kΩ 电阻到 STM32 RX 引脚检查外部晶振电路8MHz确认 RCC 配置正确。2. 无法接收数据原因RX 引脚配置错误如配置为输出而非输入中断未开启中断模式NVIC 优先级配置错误接收缓冲区溢出ORE 错误未处理USB 转 TTL 模块 TX 引脚损坏解决方案确认 RX 引脚为浮空 / 上拉输入模式中断模式下检查USART_ITConfig和 NVIC 配置处理 ORE 错误读 SR 和 DR 寄存器清除标志更换 USB 转 TTL 模块测试。3. 中断不触发原因全局中断未开启__enable_irq()USART 全局中断未使能NVIC 通道未使能中断优先级配置冲突解决方案确保主函数中开启全局中断HAL 库自动开启标准库需手动__enable_irq()检查USART_Cmd(USART1, ENABLE)已执行核对 NVIC 配置确保NVIC_IRQChannelCmd ENABLE调整中断优先级避免被高优先级中断抢占。4. HAL 库中断接收仅触发一次原因HAL 库的HAL_UART_Receive_IT为单次中断触发后需手动重启。解决方案在HAL_UART_RxCpltCallback回调函数中重新调用HAL_UART_Receive_IT。5. 发送数据丢失原因发送前未等待 TXE 位置 1轮询模式波特率过高超过硬件支持范围电源不稳定解决方案轮询模式下等待USART_FLAG_TXE或USART_FLAG_TC降低波特率如 9600→4800测试增加电源滤波电容100nF10μF。六、总结STM32F103 串口通信实现的核心步骤为硬件正确连接 TX/RX/GND注意电平匹配时钟使能 USART 和 GPIO 对应总线时钟GPIOTX 配置为复用推挽输出RX 配置为浮空 / 上拉输入USART配置波特率、数据位、停止位等参数使能收发收发轮询模式简单易实现阻塞中断模式适合非阻塞场景调试重点排查波特率、共地、引脚配置、中断使能四大问题。两种库的选择标准外设库更接近底层适合深入理解原理HAL 库简化开发适配 STM32Cube 生态适合快速开发。实际项目中可根据需求选择同时注意处理串口错误如溢出、帧错误提升通信稳定性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询