1、解决串口分包问题。即本来接收串口数“1122334455”,被分成了112233和4455两帧数据。
2、解决串口数据长度不固定,且没有规律,没有包头,没有包尾等。
3、发送两帧数据的间隔必须超过设置的超时时间。我一般用5ms的超时时间,所以只要两帧数据发送间隔超过5ms,都能被解析出来。
4、主要是交流学习,如果有什么疑问一起讨论学习,看完有帮助,请点赞,我会分享更多的东西。
解决思路:
当串口数据来了,会触发一个接收中断函数。我们再接收函数里面将数据接收下来,并在这个启动一个定时器,并刷新定时器。
如果定时时间到了,说明数据接收完毕了。
代码理解:(主要是为了更好的理解思路,就列出主要代码,思路还是比较简单的。但是这个确实解决了一件令你头疼的事情)
//stm32f1代码
#define dataLength 255 //串口数据最大长度
struct usartData
{
unsigned char data[dataLength]; //串口数据
unsigned char count; //数据计数
unsigned char flag; //接收完毕一帧数据
unsigned char overtime; //计时
};
void main(void)
{
USART_Config();
TIM5_Configuration(); //1ms定时器
while(1)
{
msgDebug(); //消息处理
}
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
{
//这样就ok了,设置time 接收数据,接下来看 定时器中断处理
usart1_UP.overtime =1;
usart1_UP.data[usart1_UP.count++] = USART_ReceiveData(USART1);
if(usart1_UP.count > 255)
{
usart1_UP.count =0;
usart1_UP.overtime =0;
}
}
}
void TIM5_IRQHandler(void) //1ms
{
if ( TIM_GetITStatus(TIM5 , TIM_IT_Update) != RESET )
{
TIM_ClearITPendingBit(TIM5 , TIM_FLAG_Update);
if(usart1_UP.overtime)
{
if(usart1_UP.overtime++ > 5)
{
usart1_UP.overtime =0;
usart1_UP.flag =1;
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
}
}
}
}
void msgDebug(void)
{
if(usart1_UP.flag)
{
usart1_UP.flag =0;
//这里处理数据吧usart1_UP.data
//清除数据
memset(usart1_UP.data,0,usart1_UP.count);
usart1_UP.count =0;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
}
51代码
//串口初始化
void Uart1_Init(void);
//配置一个1ms的定时器
void Timer2Init(void);
/*usart
串口接收结构体
rxFlag: 1 表示接收到一帧数据
rxTime;超时变量
rxCount 接收数据的长度最多如果数据大于255重新定义
rxBuff[255] 接收到的数据
*/
struct usart_s
{
unsigned char rxFlag;
unsigned char rxTime;
unsigned char rxCount;
unsigned char rxBuff[30];
};
//串口接收中断
void Uart1() interrupt UART1_VECTOR using 1
{
ES =0;
if(RI)
{
//这样就ok了,设置time 接收数据,接下来看 定时器中断处理
myUat1.rxTime =1;
myUat1.rxBuff[myUat1.rxCount++] = SBUF;
}
else
{
}
if(TI)
{
TI = 0;
}
ES =1;
}
//1ms定时器中断函数
void TIM2_IRQHandler() interrupt TIMER2_VECTOR using 1
{
if(myUat1.rxTime)
{
if(myUat1.rxTime++ > 5)
{
myUat1.rxTime =0;
myUat1.rxFlag =1; //接收完毕一帧数据
}
}
}
//主函数
void main(void)
{
Uart1_Init();
Timer2Init();
while(1)
{
if(myUat1.rxFlag)
{
myUat1.rxFlag=0;
//这里就可以处理接收的数据myUat1.rxBuff,最后记得清除数据
}
}
}
//QT部分代码
QByteArray myBuf; //接收的数据
void QtWeight3::Read_Data()
{
QByteArray buf;
buf = serial->readAll();
myBuf += buf;
myTimer2->start(50);
qDebug() << "shoudao";
}
//定时器时间50ms到了会执行该函数
void QtWeight3::TimerUpdate_COM()
{
myTimer2->stop();
qDebug() << myBuf;
//这里处理接收完整的数据myBuf
myBuf.clear();//处理完毕了记得情况buf
qDebug() << "timeout";
}