单片机接收一帧数据被分成几包发送的方法
程序员文章站
2024-03-26 08:12:29
...
在工作中发现,有的设备串口会出现这种问题:一帧数据也就10个字节,却被随意的分成好几包数据进行发送。这种数据单片机该如何接受数据呢?
1、编写固定格式的通信协议。通信协议中应该带有固定的帧头、帧尾。如果协议携带的数据区有可能会出现与帧头和帧尾相同的字节,必须将该字节进行转义,而且还要在协议中数据长度,方便接收端判断。
2、如果协议中对上面的内容包含不完整,则可以通过设定接收数据超时来判断是否接收完一帧完整的数据。
(1)串口初始化配置函数
/***************************************************************************
**@USART3的功能设置,用于串口通讯
****************************************************************************/
/***************************************************
**函数名称:USART3_Configuration
**函数共能:初始换USART3串口功能
**输入变量:无
**输出变量:无
****************************************************/
void USART3_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
/* Configure USART3 Tx (PB.10) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure USART3 Rx (PB.11) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#if 1
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
USART_ClockInit(USART3, &USART_ClockInitStructure);
#endif
USART_InitStructure.USART_BaudRate = 115200 ;
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_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
// USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //20190703
// USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); //20190705
USART_Cmd(USART3, ENABLE);
}
(2)协议只有帧头,没有帧尾 接收中断函数
void USART3_IRQHandler(void)
{
u8 c,clear;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
clear=USART_ReceiveData(USART3);
if(Start_Rec==0 && clear=='5')
{
tcounter=0;
Counter_USART++;
Start_Rec=1;
Buf_USART3[0]=clear;//(u8)(clear);
}
else if(Start_Rec==1 && clear=='5')
{
tcounter=0;
Counter_USART++;
Start_Rec=2;
Buf_USART3[1]=clear;//(u8)(clear);
}
else if(Start_Rec==2 && clear=='a')
{
tcounter=0;
Counter_USART++;
Start_Rec=3;
Buf_USART3[2]=clear;//(u8)(clear);
}
else if(Start_Rec==3 && clear=='a')
{
tcounter=0;
Counter_USART++;
Start_Rec=4;
Buf_USART3[3]=clear;//(u8)(clear);
}
else if(Start_Rec==4)
{
tcounter=0;
Buf_USART3[Counter_USART++]=clear;//(u8)(clear);
}
else
{
Start_Rec=0;
Counter_USART=0;
memset( Buf_USART3, 0, 40);
}
if(Counter_USART>34)
{
Start_Rec=0;
Counter_USART=0;
memset( Buf_USART3, 0, 40);
}
}
(3)定时器初始化函数
/******************************************************************
函数名称:TIM5_Init
输入参数:无
输出参数:无
函数功能:设置定时中断 0.5s 定时器时间T=(TIM_Period+1)*(TIM_Prescaler+1)/TIMxCLK 1
实际测试大概3mS中断一次 20190807
******************************************************************/
void TIM5_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 9;//3599; //(10000 - 1);
// 这个就是预分频系数,当由于为0时表示不分频所以要减1
TIM_TimeBaseStructure.TIM_Prescaler =36000-1;// 499;
// 使用的采样频率之间的分频比例
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
//向上计数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//初始化定时器
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
/* Clear TIM5 update pending flag[清除TIM5溢出中断标志] */
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
//打开溢出中断
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM5, ENABLE); //计数器使能,开始工作20170520
}
(4)定时器中断函数
void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
tcounter++;
if(Start_Rec)
{
if(tcounter>=3)
{
Start_Rec=0;
Finish_Rec=1;
Counter_USART=0;
}
}
}
}
上一篇: 基于“帧差分法”的运动目标检测
推荐阅读