当接收到串口或者网口等通讯接口的数据时,为了避免大量的使用if 和esle或者Switch和case语句增加代码的阅读难度。此时就可以使用上类似于指针状态机的模型。下面直接给出一个例子,例子省略了数据从串口等通讯接口获取的过程,数据处理一般并没有状态可言,因此不用对特定的状态进行定义,直接用数据头处理,类同于使用状态机进行处理。
//使用头文件定义(定义的是解完包数据头)
#if 1
#define date1 0x01
#define date2 0x02
#define date3 0x03
#define date4 0x04
#define date5 0x05
#endif
//枚举定义(定义的是解完包数据头)
#if 0
typedef enum{
date1 = 1,
date2,
date3,
date4,
date5
}dateid;
#endif
typedef struct state_use{
uint8_t dateid;
int8_t (*deal)(uint8_t *buf, uint16_t len);
uint16_t (*ack)(uint8_t *rbuf, uint8_t rlen);
}state_use1;
int8_t deal_date_1(uint8_t *buf, uint16_t len)
{
//数据处理1
}
int8_t deal_date_2(uint8_t *buf, uint16_t len)
{
//数据处理2
}
int8_t deal_date_4(uint8_t *buf, uint16_t len)
{
//数据处理4
}
int8_t deal_date_5(uint8_t *buf, uint16_t len)
{
//数据处理5
}
uint16_t ack_date_1(uint8_t *rbuf, uint8_t rlen)
{
//数据回复
}
uint16_t ack_date_3(uint8_t *rbuf, uint8_t rlen)
{
//数据回复
}
uint16_t ack_date_5(uint8_t *rbuf, uint8_t rlen)
{
//数据回复
}
//结构体数组
state_use state_table[] = {
//数据头 数据处理函数(无填NULL) 数据回复函数(无填NULL)
{date1, deal_date_1, ack_date_1},
{date2, deal_date_2, NULL},
{date3, NULL, ack_date_3},
{date4, deal_date_4, NULL},
{date5, deal_date_5, ack_date_5},
};
//对接收的数据解包
uint8_t unpacking(uint8_t *rbuf)
{
uint8_t date_id;
{
此处对数据进行解包,得到下面需要用到的数据头,放在date_id;
}
uint8_t z;
uint8_t i = sizeof(state_table)/sizeof(state_use);
for(z=0;z<i;z++);
if(state_table[z] == date_id)
{
if(state_table[z].deal != NULL)
state_table[z].deal(第一个参数传取点头的数据地址,计算数据长度);
if(state_table[z].ack != NULL)
state_table[z].ack(第一个参数传取点头的数据地址,计算数据长度);
}
}