目录
本篇博文整理来源:物联网IoT技术,分享使用C语言映射表可以实现很不错的嵌入式软件开发思路。
主要包含两方面:映射表解析数据协议和映射表实现函数调用和跳转。
1、解析数据协议
解析UART、SPI等通信协议我们要设计很多解析函数。通常使用if...else if...else的结构拆解协议串,映射表的方式让你大开眼界。
首先定义数据结构,如下所示:
typedef struct
{
char CMD[CMDLen];
unsigned char (*cmd_operate)(char *data);
}Usart_Tab;
定义指令、函数映射表,如下所示:
static const Usart_Tab InstructionList[CMDMax]=
{
{"PWON",PowOn},
{"PWOFF",PowOff},
{"HDCP",HdcpOnOff},
{"/V",QueryKaVersion},
{"EDIDUpgrade",UpdataEDID},
{"Psave",Psave},
{"Precall",Precall},
{"Pclear",Pclear},
};
解析函数实现,如下所示:
unsigned char DataAnalysis(char *buf)
{
unsigned char i,Result;
char *NEXT=NULL;
for(i=0;i<CMDMax;i++)
{
NEXT=StrCmp(buf,(char*)InstructionList[i].CMD);
if(NEXT!=NULL)
{
Result=InstructionList[i].cmd_operate(NEXT);
}
}
return Result;
}
2、函数调用和跳转
写逻辑功能或者状态机时,通常我们直接调用函数名实现跳转,这种方式在阅读代码时,程序的可读性和关联性就没那么好理解了。可以使用映射表来定义函数的调用和跳转方式。
首先定义菜单枚举,如下所示:
typedef enum
{
stage1=0,
stage2,
stage3,
stage4,
stage5,
stage6,
stage7,
stage8,
stage9,
}SCENE;
定义数据结构,如下所示:
typedef struct {
void (*current_operate)(); //当前场景的处理函数
SCENE Index; //当前场景的标签
SCENE Up; //按下Up键跳转的场景
SCENE Down; //按下Down键跳转的场景
SCENE Right; //按下Left键跳转的场景
SCENE Left; //按下Right键跳转的场景
}STAGE_TAB;
定义函数映射表,如下所示:
STAGE_TAB stage_tab[]={
#. operate Index Up Down Left Right
{Stage1_Handler, stage1, stage4, stage7, stage3, stage2},
{Stage2_Handler, stage2, stage5, stage8, stage1, stage3},
{Stage3_Handler, stage3, stage6, stage9, stage2, stage1},
{Stage4_Handler, stage4, stage7, stage1, stage6, stage5},
{Stage5_Handler, stage5, stage8, stage2, stage4, stage6},
{Stage6_Handler, stage6, stage9, stage3, stage5, stage4},
{Stage7_Handler, stage7, stage1, stage4, stage9, stage8},
{Stage8_Handler, stage8, stage2, stage5, stage7, stage9},
{Stage9_Handler, stage9, stage3, stage6, stage8, stage7},
};
定义两个变量保存当前场景和上一个场景,如下所示:
char current_stage=stage1;
char prev_stage=current_stage;
按下Up按键,跳转到指定场景current_stage的值根据映射表改变,如下所示:
current_stage =stage_tab[current_stage].Up;
场景改变后,根据映射表执行相应的函数Handler,如下所示:
if(current_stage!=prev_stage)
{
stage_tab[current_stage].current_operate();
prev_stage=current_stage;
}