代码拉取完成,页面将自动刷新
/************************************版权申明********************************************
**-----------------------------------文件信息--------------------------------------------
** 文件名称: cmd_queue.c
** 修改时间: 2018-05-18
** 文件说明: 用户MCU串口驱动函数库
--------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------*/
#include "cmd_queue.h"
QUEUE que = {0,0,0,0,0,0}; //指令队列
static qsize cmd_pos = 0; //当前指令指针位置
//计算数组中的 XOR8 校验
/*
* \brief 计算数组中的 XOR8 校验
* \detial 串口接收的数据,通过此函数计算校验码
* \param buffer 指令数据
* \param buffer 指令数据长度
* \return 计算得到的校验码
*/
uint8_t Number_XOR8(uint8_t *buffer,uint8_t size)
{
uint8_t result = 0;
uint8_t xor_cnt= 0x00;
uint8_t i;
xor_cnt = buffer[2] + 3 ;
if(size > 7){
for(i = 2; i < xor_cnt; i++){ //从第2位开始 到最后第三位
result ^= *(buffer+i);
}
return result;
}
return 0;
}
//校验 数组中的 XOR8
/*!
* \brief 校验 数组中的 XOR8
* \detial 串口接收的数据,通过此函数计算校验码
* \param buffer 指令数据
* \param buffer 指令数据长度
* \return 匹配是否成功 0:失败 1:成功
*/
uint8_t Check_XOR8(uint8_t *buffer,uint8_t size)
{
uint8_t XOR8_tmep = 0xFF;
uint8_t result = 0x00;
uint8_t xor_cnt= 0x00;
uint8_t i;
if(size > 7)
{
XOR8_tmep = buffer[buffer[2]+3]; //缓存校验码
result = Number_XOR8(buffer,size); //计算xor校验
}
return (result == XOR8_tmep);
}
/*!
* \brief 清空指令数据
*/
void queue_reset(QUEUE * queue)
{
queue->_head = queue->_tail = 0;
cmd_pos = queue->tail_state[0] = queue->head_state[0]= 0;
}
/*!
* \brief 添加指令数据
* \detial 串口接收的数据,通过此函数放入指令队列
* \param _data 指令数据
*/
void queue_push(QUEUE * queue,qdata _data)
{
qsize pos = (queue->_head+1)%QUEUE_MAX_SIZE;
if(pos!=queue->_tail) //非满状态
{
queue->_data[queue->_head] = _data;
queue->_head = pos;
}
}
//从队列中取一个数据
static void queue_pop(QUEUE * queue,qdata* _data)
{
if(queue->_tail != queue->_head) //非空状态
{
*_data = queue->_data[queue->_tail];
queue->_tail = (queue->_tail+1)%QUEUE_MAX_SIZE;
}
}
//获取队列中有效数据个数
static qdata queue_size(QUEUE * queue)
{
return ((queue->_head+QUEUE_MAX_SIZE-queue->_tail)%QUEUE_MAX_SIZE);
}
/*!
* \brief 从指令队列中取出一条完整的指令
* \param cmd 指令接收缓存区
* \param buf_len 指令接收缓存区大小
* \return 指令长度,0表示队列中无完整指令
*/
qdata lock_queue_find_cmd(qdata *buffer,qdata buf_len)
{
qdata _data = 0;
qdata cmd_size = 0;
while(queue_size(&que)>0)
{
//取一个数据
queue_pop(&que,&_data);
if(cmd_pos==0) //指令第一个字节必须是帧头,否则跳过
{
que.head_state[1] = que.head_state[0];
que.head_state[0] = ( _data );
if( que.head_state[1] != 0x5C && que.head_state[0] != 0xC5){
continue;
}
buffer[cmd_pos++] = que.head_state[1];
}
if(cmd_pos < buf_len){ //防止缓冲区溢出
buffer[cmd_pos++] = _data;
}
que.tail_state[1] = que.tail_state[0];
que.tail_state[0] = ( _data );
if( (que.tail_state[1] == 0x0D && que.tail_state[0] == 0x0A ) //最后2个字节与帧尾匹配,得到完整帧
||( buffer[2] + 3 == cmd_pos-1 && buffer[2] >= 5 )) //数据长度达到指令需求
{
cmd_size = cmd_pos ;
que.head_state[0] = 0; //重新检测帧头
que.head_state[1] = 0; //重新检测帧头
que.tail_state[0] = 0; //重新检测帧尾
que.tail_state[1] = 0; //重新检测帧尾
cmd_pos = 0; //复位指令指针
if(!Check_XOR8(buffer,cmd_size)){ return 0; } //XOR8校验
return cmd_size;
}
}
return 0; //没有形成完整的一帧
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。