使用stm32 通过串口对接一款数据采集终端,对终端发送一条指令,串口会返回不定量的数据,
刚开始使用串口接收中断的方式处理数据,发现处理速度较慢,出现丢帧情况。
进而改成回环结构接收数据。
typedef struct
{
short write_point;//写指针
u8 Reader_RX_Buffer_Second[4096];//存储空间
short read_point;//读指针
u8 loop;//如果写指针到末端的时候,重头开始写表示
}READER_UART_REC_STRUCT_T;
串口接收方法:
void DEBUG_Reader_IRQHandler(void)
{
u8_t res;
if(USART_GetITStatus(DEBUG_Reader, USART_IT_RXNE) != RESET)//接收到数据
{
res =USART_ReceiveData(DEBUG_Reader);//;读取接收到的数据USART2->DR
if(reader_uart_rec_t.loop<1 && reader_uart_rec_t.write_point>=reader_uart_rec_t.read_point)
{
reader_uart_rec_t.Reader_RX_Buffer_Second[reader_uart_rec_t.write_point++] = res;
if(reader_uart_rec_t.write_point == 4095)
{
reader_uart_rec_t.write_point = 0;
reader_uart_rec_t.loop = 1;
}
}else if(reader_uart_rec_t.write_point<reader_uart_rec_t.read_point)
{
reader_uart_rec_t.Reader_RX_Buffer_Second[reader_uart_rec_t.write_point++] = res;
}
USART_ClearITPendingBit(DEBUG_Reader, USART_IT_RXNE);
}
}
数据解析方法:
main()
{
//我的协议最小数据长度为6
if(reader_uart_rec_t.write_point>(reader_uart_rec_t.read_point+5) || reader_uart_rec_t.loop>0)
{
//数据处理方法
AnalyData(&reader_uart_rec_t);
}
}
typedef struct
{
u8 head;
u8 len;
u8 address;
u8 cmd;
}RECEIVE_EPC_DATA_HEAD_T;
void AnalyData(READER_UART_REC_STRUCT_T* reader_uart_rec)
{
RECEIVE_DATA_HEAD_T head;
if(reader_uart_rec->loop == 1)
{
len = 4095+reader_uart_rec->write_point - reader_uart_rec->read_point;
}else
{
len = reader_uart_rec->write_point - reader_uart_rec->read_point;
}
while(len>0)
{
len--;
if(reader_uart_rec->read_point >= 4096)
{
reader_uart_rec->read_point = 0;
reader_uart_rec->loop = 0;
}
//0xA0 是协议报头 循环查找报头,报头不对则移动指针,正确则判断符不符合协议头,然后再处理数据
if(reader_uart_rec->Reader_RX_Buffer_Second[reader_uart_rec->read_point] == 0xA0)
{
memcpy(&head,&reader_uart_rec->Reader_RX_Buffer_Second[reader_uart_rec->read_point],sizeof(RECEIVE_DATA_HEAD_T));
switch(head.cmd)
{
case 0x1:
//处理数据
if((reader_uart_rec->read_point+ head.len+2)>4095)
{
reader_uart_rec->read_point = reader_uart_rec->read_point+ head.len+2-4095;
reader_uart_rec->loop = 0;
}else
{
reader_uart_rec->read_point = reader_uart_rec->read_point+ head.len+2;
}
len = len - head.len-1;
break;
default:
reader_uart_rec->read_point++;//如果协议不在处理范围,可能是错误数据或者出现了丢帧,则read下标后移
break;
}
}else
{
//如果数据不符合包头则read下标后移继续找报头
reader_uart_rec->read_point++;
}
}
}
转载:https://blog.csdn.net/yi_tianchou/article/details/102593931