自定义单片机命令行源码

       调试单片机程序往往要用串口,光有输出也不够爽,我自己一直留着一份命令行代码,只要单片机资源足够就放上去。直接贴源码如下:


#define PARAM_MAX       (10)  /* 最多支持10个参数 */
#define CLI_MAX_LEN     (32)  /* 缓存大小,根据资源和最长命令行长度决定 */

/* 用户输入命令行 */
unsigned char g_input_buf[CLI_MAX_LEN];
unsigned char g_input_idx = 0;

/**********************************************************
函数描述 : 16进制字符转数值
输入参数 : c -- 字符,不作参数检查
输出参数 : 
返 回 值 : 数值,
作   者  : gavinpeng
时   间  : 2016.11.25
************************************************************/
unsigned char char_to_val(unsigned char c)
{
    if ( (c >= '0') && (c <= '9') )
        return c - '0';
    else if ( (c >= 'A') && (c <= 'Z') )
        return c - 'A' + 10;
    else if ( (c >= 'a') && (c <= 'z') )
        return c - 'a' + 10;
    else 
        return 0;
}

/**********************************************************
函数描述 : 字符串转数值
输入参数 : str -- 字符串
输出参数 : 
返 回 值 : 数值,
作   者  : gavinpeng
时   间  : 2016.11.25
************************************************************/
int str_to_int(unsigned char *str)
{
    int flag;
    int value = 0;
    unsigned char *p = str;

    if ( NULL == str )
        return 0;

    /* 16进制 */
    if ( (str[0] == '0') && ((str[1] == 'x') || (str[1] == 'X')) )
    {
        value = 0;
        p = &str[2];
        while ( *p )
        {
            value = value * 16 + char_to_val(*p);
            p++;
        }
        return value;
    }

    /* 10进制 */
    if ( str[0] == '-' )
        flag = -1;
    else
        flag = 1;

    value = 0;
    p = str;
    while ( *p ) 
        value = value * 10 + char_to_val(*p++);

    value = value * flag;

    return value;
}

/**********************************************************
函数描述 : 命令行测试
输入参数 : 
输出参数 : 
返 回 值 : 
作   者  : gavinpeng
时   间  : 2016.11.25
************************************************************/
void cmd_proc_test(int argc, char *argv[])
{
    int val;

    /* test val */
    if ( argc == 2 )
    {
	    val = str_to_int(argv[1]);
		printf("val = %d\r\n", val);
        return;
    }
}

/**********************************************************
函数描述 : 命令行菜单
输入参数 : 
输出参数 : 
返 回 值 : 
作   者  : gavinpeng
时   间  : 2016.11.25
************************************************************/
void cmd_usage(void)
{
    printf("\r\ncmd usage:\r\n");
	printf("? -- this menu\r\n");
	printf("ver -- show version\r\n");
	printf("test val -- how to use int\r\n");
}

/**********************************************************
函数描述 : 处理用户输入的命令
输入参数 : 
输出参数 : 
返 回 值 : 
作   者  : gavinpeng
时   间  : 2016.11.25
************************************************************/
void cmd_proc(void)
{
    int argc;
    char *argv[PARAM_MAX];
    char *p;

    /* 格式化字符串,把空格分开的词放入多个字符串 */
    p = (char*)g_input_buf;
    while ( *p && (' ' == *p) ) p++;

    if ( *p == '\0' )
        return;

    argc = 0;
    argv[argc++] = p;

    while ( *p )
    {
        if ( ' ' == *p ) 
        {
            *p++ = '\0';

            while ( *p && (' ' == *p) ) p++;

            if ( *p == '\0' )
                break;
            else
                argv[argc++] = p;

            if ( argc >= PARAM_MAX )
                return;
        }

        p++;
    }

    /* 处理消息 */
    if ( strcmp("?", argv[0]) == 0 )
	    cmd_usage();
	else if ( strcmp("ver", argv[0]) == 0 )
        printf("master ver: 1.0\r\n%s %s\r\n", __DATE__, __TIME__);
    else if ( strcmp("test", argv[0]) == 0 )
        cmd_proc_test(argc, argv);
    else
    {
        printf("unknown cmd: %s\r\n\r\n", argv[0]);
		cmd_usage();
    }

    return;
}

/**********************************************************
函数描述 : 分析输入的字符
输入参数 : buf -- 输入的字符首指针
           len -- 输入字符的长度
输出参数 : 
返 回 值 : 
作   者  : gavinpeng
时   间  : 2016.11.25
************************************************************/
void cmd_parse(char *buf, unsigned int len)
{
    int i = 0;
    char c;

    while ( i < len )
    {
		c = buf[i++];

		if ( c <= 0 )
			continue;

        switch ( c )
        {
            case '\r':
            case '\n': /* 0x0A, 回车的处理 */
                //g_input_buf[g_input_idx++] = '\r';
                printf("\r\n");
				g_input_buf[g_input_idx] = '\0';
				cmd_proc();
                g_input_idx = 0;
                break;

            case '\b': /* 0x08, 退格键 */
                if ( g_input_idx > 0 )
                {
                    g_input_idx--;
                    printf("\b \b");
                }
                g_input_buf[g_input_idx] = 0;
                break;

            default:
                /* 添加可见字符,其它忽略 */
                g_input_buf[g_input_idx++] = c;
				printf("%c", c);
                break;
        }
    }
}

/* 这里是串口中断函数 */
void uart1_ISR(void) interrupt
{
    // 从串口寄存器读出数据,放进全局buffer中
    if ( g_uart_rx_len < CLI_MAX_LEN )
        g_uart_db_rx_buf[g_uart_db_rx_len++] = uart_buf; 
}

void main(void)
{
    // 串口初始化
	
	// 主循环
	while ( 1 )
	{
	    if ( g_uart_db_rx_len ) 
        {
            cmd_parse(g_uart_db_rx_buf, g_uart_db_rx_len);
            g_uart_db_rx_len = 0;
        }
	}
}

有更好的,欢迎指出。

惯例要介绍一下自家的产品:

https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.594c1debREF8Mj&id=579411892273

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值