回顾一下上一篇
简单的实现GD32F150R8 与Labview 之间的通讯,代码如下
switch (cGetChar)
{.......................
}
cGetChar 大小决定任务的复杂性与扩展性。这里意味着最多有且仅有128种的扩展,并且也不利于数据通信。并且在可读性上很差在日后维护性上带来很大的不足。
采用command line 进行扩展。其实很简单,只不过是性字符串的比较
利于命令"set led %d\r\n",却对led显示的模式进行设置
但串口接收到\r\n时,对command 进行分析,并且与GD32F150R8中注册的command进行寻找配对
当找到时,调用其对应的函数,进行解析。而main函数就变得很简单
关键代码如下:
int main(void)
{
//int i;
char cGetChar;
EVB_LEDConfig();
EVB_Uart2Config();
PRINTF("\r\nLabview & GD32F150\r\n");
while(1)
{
run_cmd();
}
}
char *
get_line (char *line)
{
int pos;
int ch;
pos = 0;
ch = (int)uif_in_char();
while ( (ch != 0x0D /* CR */) &&
(ch != 0x0A /* LF/NL */) &&
(pos < UIF_MAX_LINE))
{
switch (ch)
{
case 0x08: /* Backspace */
case 0x7F: /* Delete */
if (pos > 0)
{
pos -= 1;
uif_out_char(0x08); /* backspace */
uif_out_char(' ');
uif_out_char(0x08); /* backspace */
}
break;
default:
if ((pos+1) < UIF_MAX_LINE)
{
if ((ch > 0x1f) && (ch < 0x80))
{
line[pos++] = (char)ch;
uif_out_char((char)ch);
}
}
break;
}
ch = (int)uif_in_char();
}
line[pos] = '\0';
uif_out_char(0x0D); /* CR \r 回车*/
uif_out_char(0x0A); /* LF \n 换行*/
return line;
}
void
run_cmd (void)
{
/*
* Global array of pointers to emulate C argc,argv interface
*/
int argc;
char *argv[UIF_MAX_ARGS + 1]; /* one extra for null terminator */
get_line(cmdline1);
argc = make_argv(cmdline1,argv);
//if (!(argc = make_argv(cmdline1,argv)))
if( argc==0 )
{
/* no command entered, just a blank line */
strcpy(cmdline1,cmdline2);
argc = make_argv(cmdline1,argv);
}
cmdline2[0] = '\0';
if (argc)
{
int i;
for (i = 0; i < UIF_NUM_CMD; i++)
{
if (strcasecmp(UIF_CMDTAB.cmd,argv[0]) == 0)
{
if (((argc-1) >= UIF_CMDTAB.min_args) &&
((argc-1) <= UIF_CMDTAB.max_args))
{
if (UIF_CMDTAB.flags & UIF_CMD_FLAG_REPEAT)
{
strcpy(cmdline2,argv[0]);
}
UIF_CMDTAB.func(argc,argv);
return;
}
else
{
uif_printf(SYNTAX,argv[0]);
return;
}
}
}
uif_printf(INVCMD,argv[0]);
uif_printf(HELPMSG);
}
}
以后的扩展都在UIF_SETCMD UIF_SETCMDTAB[]={
{"led",0,1,uif_cmd_led,"set led"}
};
进行不断的扩展,就能实现很复杂的响应
void
uif_cmd_led (int argc, char **argv)
{
int success = false;
uint32 data =0;
(void)argc;
(void)argv;
data = get_value(argv[2],&success,10);
switch (data)
{
case 0:
EVB_LEDControl(LED1, LED_OFF);
EVB_LEDControl(LED2, LED_OFF);
break;
case 1:
EVB_LEDControl(LED1, LED_ON);
EVB_LEDControl(LED2, LED_OFF);
break;
case 2:
EVB_LEDControl(LED1, LED_OFF);
EVB_LEDControl(LED2, LED_ON);
break;
case 3:
EVB_LEDControl(LED1, LED_ON);
EVB_LEDControl(LED2, LED_ON);
break;
default:
break;
}
}
UIF_SETCMD UIF_SETCMDTAB[]={
{"led",0,1,uif_cmd_led,"set led"}
};
const int UIF_NUM_SETCMD = UIF_SETCMDTAB_SIZE;
|