windows的WSL2中ubuntu下安装的openclaw与windows文件互通备份
2026/8/22 22:01:06
STM32F103的USART1挂载在APB2总线,USART2/3挂载在APB1总线,核心参数:
初始化是串口通信的基础,需配置GPIO复用、时钟、波特率、帧格式等核心参数。
#include"stm32f10x.h"#include<stdio.h>// USART1初始化函数(9600波特率,8位数据位,1位停止位,无校验)voidUSART1_Init(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 1. 使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);// 2. 配置GPIO(PA9=TX,PA10=RX)// PA9:USART1_TX 复用推挽输出GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);// PA10:USART1_RX 浮空输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);// 3. 配置USART参数USART_InitStructure.USART_BaudRate=9600;// 波特率USART_InitStructure.USART_WordLength=USART_WordLength_8b;// 8位数据位USART_InitStructure.USART_StopBits=USART_StopBits_1;// 1位停止位USART_InitStructure.USART_Parity=USART_Parity_No;// 无校验USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;// 无硬件流控USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;// 收发使能USART_Init(USART1,&USART_InitStructure);// 4. 使能USART1USART_Cmd(USART1,ENABLE);}// 重定向printf到USART1(方便打印字符串)intfputc(intch,FILE*f){// 等待发送数据寄存器为空while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);// 发送字节USART_SendData(USART1,(u8)ch);returnch;}查询模式通过轮询USART状态标志位实现数据收发,逻辑简单,适合低频率数据交互。
// 查询模式:发送单个字节voidUSART1_SendByte(u8 data){// 等待TXE标志位(发送数据寄存器空)while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));USART_SendData(USART1,data);}// 查询模式:发送字符串voidUSART1_SendString(u8*str){while(*str!='\0'){USART1_SendByte(*str);str++;}// 等待发送完成while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}// 查询模式:接收单个字节(阻塞式)u8USART1_ReceiveByte(void){// 等待RXNE标志位(接收数据寄存器非空)while(!USART_GetFlagStatus(USART1,USART_FLAG_RXNE));returnUSART_ReceiveData(USART1);}// 主函数测试intmain(void){u8 recv_data;// 初始化USART1USART1_Init();// 上电发送欢迎信息USART1_SendString((u8*)"STM32 USART1 Test (查询模式)\r\n");USART1_SendString((u8*)"请输入字符:\r\n");while(1){// 接收单个字节recv_data=USART1_ReceiveByte();// 回显接收到的字符USART1_SendByte(recv_data);// 接收到换行符,发送提示if(recv_data=='\r'){USART1_SendString((u8*)"\r\n已接收字符,等待下一次输入...\r\n");}}}查询模式会阻塞主程序,中断模式通过收发中断实现异步通信,适合高频率、实时性要求高的场景。
#include"stm32f10x.h"#include<stdio.h>u8 recv_buf[100];// 接收缓冲区u8 recv_len=0;// 接收数据长度u8 recv_flag=0;// 接收完成标志(回车触发)// USART1初始化(含中断配置)voidUSART1_Init(void){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;// 1. 使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);// 2. GPIO配置GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);// 3. USART参数配置USART_InitStructure.USART_BaudRate=9600;USART_InitStructure.USART_WordLength=USART_WordLength_8b;USART_InitStructure.USART_StopBits=USART_StopBits_1;USART_InitStructure.USART_Parity=USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;USART_Init(USART1,&USART_InitStructure);// 4. 中断配置// 开启接收中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);// NVIC配置NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;// 抢占优先级1NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;// 子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);// 5. 使能USART1USART_Cmd(USART1,ENABLE);}// 重定向printfintfputc(intch,FILE*f){while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);USART_SendData(USART1,(u8)ch);returnch;}// USART1中断服务函数voidUSART1_IRQHandler(void){u8 recv_data;// 接收中断触发if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){recv_data=USART_ReceiveData(USART1);// 读取接收数据if(recv_data!='\r')// 未接收到回车,存入缓冲区{recv_buf[recv_len]=recv_data;recv_len++;// 防止缓冲区溢出if(recv_len>=99)recv_len=0;}else// 接收到回车,标记接收完成{recv_buf[recv_len]='\0';// 字符串结束符recv_flag=1;// 置位完成标志recv_len=0;// 重置长度}USART_ClearITPendingBit(USART1,USART_IT_RXNE);// 清除中断标志}}// 主函数测试intmain(void){USART1_Init();printf("STM32 USART1 Test (中断模式)\r\n");printf("请输入字符串(回车结束):\r\n");while(1){if(recv_flag==1)// 检测到接收完成{// 回显接收到的字符串printf("已接收:%s\r\n",recv_buf);// 重置标志recv_flag=0;printf("请继续输入:\r\n");}// 主循环可执行其他任务(如LED闪烁),不被串口阻塞}}实际开发中115200bps更常用,仅需修改USART_Init中的波特率参数,并重新计算BRR值:
// 波特率改为115200USART_InitStructure.USART_BaudRate=115200;STM32F103 APB2时钟72MHz时,115200波特率的BRR值由硬件自动计算,无需手动配置,仅需同步修改串口调试助手的波特率为115200即可。
recv_flag、recv_len、recv_buf;recv_len随接收字符递增;recv_flag变为1,recv_buf存储完整字符串;实际项目中常需收发结构化数据(如传感器数据、控制指令),可基于中断模式扩展:
// 示例:接收自定义协议(帧头0xAA + 数据 + 校验位 + 帧尾0xFF)voidUSART1_IRQHandler(void){staticu8 protocol_buf[20];staticu8 protocol_len=0;u8 recv_data;if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){recv_data=USART_ReceiveData(USART1);// 帧头检测if(protocol_len==0&&recv_data!=0xAA)return;// 存入协议缓冲区protocol_buf[protocol_len]=recv_data;protocol_len++;// 帧尾检测(假设协议长度固定为8字节)if(protocol_len==8&&protocol_buf[7]==0xFF){// 校验位验证(示例:前6字节和 = 第7字节前的校验位)u8 check_sum=0;for(u8 i=1;i<6;i++)check_sum+=protocol_buf[i];if(check_sum==protocol_buf[6]){// 协议校验通过,处理数据printf("协议接收成功:");for(u8 i=0;i<8;i++)printf("%02X ",protocol_buf[i]);printf("\r\n");}protocol_len=0;// 重置}// 超时/溢出处理if(protocol_len>=19)protocol_len=0;USART_ClearITPendingBit(USART1,USART_IT_RXNE);}}