一、前言
记录在使用stm32的usb虚拟串口通讯时,无法接收0x0d字节,并且后续数据断包问题。
二、环境
stm32/GD32系列,使用标准USB_CORE和USB_CONFIG库文件
三、正文
usb库
使用虚拟串口时,main函数初始化部分如下所示
int main(void)
{
u32 len;
u8 usbstatus=0;
//初始化系统
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
delay_ms(500);
USB_Port_Set(0); //USB先断开
delay_ms(200);
USB_Port_Set(1); //USB再次连接
Set_USBClock();
USB_Interrupts_Config();
USB_Init();
while(1)
{
/**************************USB虚拟串口部分*************************/
//检测usb热插拔状态
if(usbstatus!=bDeviceState){//USB连接状态发生了改变.
usbstatus=bDeviceState;//记录新的状态
//if(usbstatus==CONFIGURED)printf("USB连接成功\r\n");//提示USB连接成功
//else printf("USB连接断开\r\n");//提示USB断开
}
//终端接收usb虚拟串口数据
if(USB_USART_RX_STA&0x8000){
len=USB_USART_RX_STA&0x3FFF;//得到此次接收到的数据长度
USB_USART_RX_STA=0;
if(USB_USART_RX_BUF[0]==0x5A&&USB_USART_RX_BUF[1]==0xA5){//头
}
memset(USB_USART_RX_BUF,0,sizeof(USB_USART_RX_BUF));//缓存清零
}
if(usbstatus==CONFIGURED){//判断USB已经连接
}
else{//USB未连接
}
/**************************USB虚拟串口部分end*************************/
}
}
当定义的协议中有0x0d字节时,接收USB_USART_RX_BUF就会不全,这是我们跳转到原函数写法那里查看代码
//void USB_To_USART_Send_Data(u8* data_buffer, u8 Nb_bytes)
//{
// u8 i;
// u8 res;
// for(i=0;i<Nb_bytes;i++)
// {
// res=data_buffer[i];
// if((USB_USART_RX_STA&0x8000)==0) //接收未完成
// {
// if(USB_USART_RX_STA&0x4000) //接收到了0x0d
// {
// if(res!=0x0a)USB_USART_RX_STA=0;//接收错误,重新开始
// else USB_USART_RX_STA|=0x8000; //接收完成了
// }else //还没收到0X0D
// {
// if(res==0x0d)USB_USART_RX_STA|=0x4000;
// else
// {
// USB_USART_RX_BUF[USB_USART_RX_STA&0X3FFF]=res;
// USB_USART_RX_STA++;
// if(USB_USART_RX_STA>(USB_USART_REC_LEN-1))USB_USART_RX_STA=0;//接收数据错误,重新开始接收
// }
// }
// }
// }
//}
这是原函数写法,我全部注释了,没有打开,其中就是判断0x0d在判断0x0a去获取数据发送完毕,这里缺点就很明显了,也不是我们想要的方式,因为数据中万一出现0x0d,就会接收处理异常,还有就是发送还必须得加上0x0d和0x0a,比较麻烦
将接收函数改成如下方式:
void USB_To_USART_Send_Data(u8* data_buffer, u8 Nb_bytes)
{
u8 i;
u8 res;
for(i=0;i<Nb_bytes;i++)
{
res=data_buffer[i];
if((USB_USART_RX_STA&0x8000)==0) //接收未完成
{
USB_USART_RX_BUF[USB_USART_RX_STA&0X3FFF]=res;
USB_USART_RX_STA++;
if(USB_USART_RX_STA>(USB_USART_REC_LEN-1))USB_USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
USB_USART_RX_STA|=0x8000; //接收完成了
}
这样发送数据完毕之后同样会进入主循环的判断条件中,并且在发送数据时不用必须发送0x0d和0x0a字节。
四、结语
本文到此结束,快去试试吧,祝君成功!
评论(0)
您还未登录,请登录后发表或查看评论