开发时需要接受一串如下格式的数据
0xAA cmd data 0x0D 0x0A
其中头,和两个尾巴是固定的,cmd是区别不同的命令,data是数据域(数据长度是已知的)
#ifndef QUE_H
#define QUE_H
#include "stdio.h"
#define LEN 255//定义缓存队列的长度
typedef struct
{
unsigned char Rx_data[LEN];
unsigned char front;
unsigned char rear;
}Que;//定义缓存队列
typedef struct
{
const unsigned char data_len;//数据域的长度
const unsigned char TdeCmd;//指向命令的指针(数组的头)
void(*Fun)();//当前命令需要执行的动作
}tde_t;
//判断队列是否为空
unsigned char IsEmpty(void);
//入队
void InQue(unsigned char val);
//出队
unsigned char OutQue(unsigned char *val);
void TDE(tde_t tde_arr[], unsigned char tde_num);
#endif
#include "que.h"
#define HEAD 0xAA
#define END1 0x0D
#define END2 0x0A
Que queue = {0};
//判断队列是否为空
unsigned char IsEmpty(void)
{
if (queue.front == queue.rear)
{
return 1;
}
return 0;
}
//入队
void InQue(unsigned char val)
{
if (queue.front == (queue.rear + 1) % LEN)
{
queue.Rx_data[queue.rear] = val;
queue.rear = queue.front;
queue.front = (queue.front + 1) % LEN;
}
else
{
queue.Rx_data[queue.rear] = val;
queue.rear = (queue.rear + 1) % LEN;
}
}
//出队
unsigned char OutQue(unsigned char *val)
{
if (IsEmpty())
{
return 0;
}
else
{
*val = queue.Rx_data[queue.front];
queue.front = (queue.front + 1) % LEN;
}
return 1;
}
//假设TDE命令每隔1ms轮询一次
void TDE(tde_t tde_arr[], unsigned char tde_num)
{
static unsigned char stage = 0;
static unsigned char delay_count = 0;//等待10ms,如果队列为空,则退出每次处理
static unsigned char record_front = 0;//记录头指针的位置
static unsigned char record_data_len = 0;//记录该指令数据域的长度
static unsigned char record_cmd_index = 0;//记录命令在数组中的下标
static unsigned char record_data[20] = {0};//记录数据域
static unsigned char record_data_index = 0;
unsigned char val = 0, i = 0;
switch(stage)
{
case 0://头
if(OutQue(&val) == 1)//出队成功
{
if(val == HEAD)
{
stage = 1;
}
}
break;
case 1://命令
if(OutQue(&val) == 1)//出队成功
{
for(i = 0; i < tde_num; i++)//轮询tde中所有的命令
{
if(val == tde_arr[i].TdeCmd)
{
stage = 2;
delay_count = 0;
record_data_len = tde_arr[i].data_len;
record_cmd_index = i;
record_front = queue.front;//记录当前队尾位置
return;
}
}
if(val == HEAD)//如果找到头
{
stage = 1;
delay_count = 0;
break;
}
delay_count = 0;
stage = 0;//未找到则复位
}
else
{
delay_count++;
if(delay_count >= 10)
{
delay_count = 0;
stage = 0;
}
}
break;
case 2://数据域
if(record_data_len == 0)
{
delay_count = 0;
record_data_index = 0;
stage = 3;
break;
}
else
{
if(IsEmpty() == 0)//当前队列是否为空
{
OutQue(&val);
//记录出队的数据
record_data[record_data_index] = val;
record_data_index++;
record_data_len--;
}
else
{
delay_count++;
if(delay_count >= 10)
{
delay_count = 0;
record_data_index = 0;
stage = 0;
}
}
}
break;
case 3://END1
if(OutQue(&val) == 1)//出队成功
{
if(val == END1)
{
stage = 4;
delay_count = 0;
break;
}
else
{
queue.front = record_front;//指针复位,如果找到头和命令,但是END1错误,则要从数据域开始找头
delay_count = 0;
stage = 0;//未找到则复位
}
}
else
{
delay_count++;
if(delay_count >= 10)
{
delay_count = 0;
stage = 0;
}
}
break;
case 4:
if(OutQue(&val) == 1)//出队成功
{
if(val == END2)
{
stage = 0;
delay_count = 0;
tde_arr[record_cmd_index].Fun();
break;
}
else
{
queue.front = record_front;//指针复位,如果找到头和命令,但是END2错误,则要从数据域开始找头
stage = 0;//未找到则复位
delay_count = 0;
}
}
else
{
delay_count++;
if(delay_count >= 10)
{
delay_count = 0;
stage = 0;
}
}
break;
}
}
测试:
#include "stdio.h"
#include "que.h"
void f1(void)
{
printf("f1执行");
}
void f2(void)
{
printf("f2执行");
}
tde_t tde_arr[] =
{
{1, 2, f1},
{2, 3, f2},
};
int main()
{
unsigned char temp = 0;
InQue(0xAA);
InQue(0xAA);
InQue(0xAA);
InQue(0x02);
/*InQue(11);
InQue(0x0d);*/
InQue(0x0d);
InQue(0xAA);
InQue(0x03);
InQue(11);
InQue(11);
InQue(0x0d);
InQue(0x0a);
while(1)
{
for(temp = 0; temp <22; temp++)
{
TDE(tde_arr, 2);
}
}
return 0;
}