964|5

112

帖子

0

资源

一粒金砂(中级)

【HC32F460开发板测评】03.基于UART功能实现SHELL的移植与控制 [复制链接]

本帖最后由 xld0932 于 2021-4-8 23:32 编辑

本篇主要实现的是掌握USART通讯,能够实现数据的收发操作,串口的接收使用中断机制;基于USART功能添加SHELL程序,通过操作LED灯来实现一个简单的SHELL控制调用。

 

1.USART通讯

开发板上提供了USB转UART部分的硬件电路,我们只需要一根Micro USB线将开发板与电脑进行连接,WIN10系统电脑会自动识别并安装USB转串口有驱动程序,再结合MCU的USART3接口,可以实现MCU与电脑端的串口数据通讯;

image-20210408230932-1.png

USART初始化配置程序:将USART配置成115200(波特率),N(校验位),8(数据位),1(停止位),使能串口的接收和发送功能,使能接收中断功能并配置接收中断;配置GPIO引脚复用成USART功能引脚,如下程序所示:

/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void UsartRxIrqCallback(void)
{
    printf("%c", USART_RecData(M4_USART3));
    USART_FuncCmd(M4_USART3, UsartTxAndTxEmptyInt, Enable);
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void UsartErrIrqCallback(void)
{
    if(USART_GetStatus(M4_USART3, UsartFrameErr)   != Reset)
    {
        USART_ClearStatus(M4_USART3, UsartFrameErr);
    }

    if(USART_GetStatus(M4_USART3, UsartParityErr)  != Reset)
    {
        USART_ClearStatus(M4_USART3, UsartParityErr);
    }

    if(USART_GetStatus(M4_USART3, UsartOverrunErr) != Reset)
    {
        USART_ClearStatus(M4_USART3, UsartOverrunErr);
    }
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void USART3_Configure(void)
{
    stc_irq_regi_conf_t stcIrqRegiCfg;

    const stc_usart_uart_init_t stcInitCfg =
    {
        UsartIntClkCkNoOutput,
        UsartClkDiv_1,
        UsartDataBits8,
        UsartDataLsbFirst,
        UsartOneStopBit,
        UsartParityNone,
        UsartSamleBit8,
        UsartStartBitFallEdge,
        UsartRtsEnable,
    };

    /* Enable peripheral clock */
    PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART3, Enable);

    /* Initialize USART IO */
    PORT_SetFunc(PortE, Pin04, Func_Usart3_Rx, Disable);
    PORT_SetFunc(PortE, Pin05, Func_Usart3_Tx, Disable);

    /* Initialize UART */
    if(USART_UART_Init(M4_USART3, &stcInitCfg) != Ok)
    {
        while(1);
    }

    /* Set baudrate */
    if(USART_SetBaudrate(M4_USART3, 115200) != Ok)
    {
        while(1);
    }

    /* Set USART RX IRQ */
    stcIrqRegiCfg.enIRQn      = Int000_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartRxIrqCallback;
    stcIrqRegiCfg.enIntSrc    = INT_USART3_RI;
    enIrqRegistration(&stcIrqRegiCfg);

    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART RX error IRQ */
    stcIrqRegiCfg.enIRQn      = Int001_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartErrIrqCallback;
    stcIrqRegiCfg.enIntSrc    = INT_USART3_EI;
    enIrqRegistration(&stcIrqRegiCfg);

    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /*Enable RX && RX interupt && TX function*/
    USART_FuncCmd(M4_USART3, UsartRx,    Enable);
    USART_FuncCmd(M4_USART3, UsartRxInt, Enable);
    USART_FuncCmd(M4_USART3, UsartTx,    Enable);
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
int fputc(int ch, FILE *f)
{
    USART_SendData(M4_USART3, (uint8_t)ch);
    while(Reset == USART_GetStatus(M4_USART3, UsartTxEmpty));

    return ch;
}

 

通过上面的程序,我们可以看到在接收中断函数中,接收到的数据又通过printf函数再次打印出来,printf函数是通过USART发送功能重载fputc这个函数来实现的, 运行结果如下图所示:

image-20210408231242-2.png

我们在控制LED闪烁的时候使用了Ddl_Delay1ms这个函数,这个是在ddl.config.h文件中通过配置DDL_UTILITY_ENABLE宏为DDL_ON才可以使用的;在使能DDL_UTILITY_ENABLE这个宏之后,在hc32f46x_utility.h 文件中默认定义了UART_DEBUG_PRINTF这个宏,所以导致在我们重载fputc这个函数的时候会报错,所以我样在hc32f46x_utility.h文件中把这个宏注释掉就可以了。

 

2.移植SHELL

下载SHELL开源源代码:https://github.com/NevermindZZT/letter-shell,最新的版本是3.0的,程序中使用的是2.x的版本;在官网上有详细的功能、移植、配置,以及相应的应用说明,大家可以去深入了解,我们这边还是结合HC32F460来实现应用移植;在工程中添加letter shell 2.x的源文件,添加自定义的shell_port.c和shell_port.h这两个文件,将之前的串口初始化程序移动到这个.c文件中来实现;移植过程如下:

  • 定义一个shell结构体对象;
  • 实现这个结构体中write的实现,即通过串口打印输出一个字节数据;
  • 调用shellInit函数进行初始化;
  • 在串口接收中断回调函数中调用shellHandler函数,将串口接收到的数据传递到这个函数中进行解析处理;

这样我们最单的SHELL框架就移植完成了;尝试编译运行一下,如下图所示:

image.png

具体的代码实现可以参考最后的附件工程源代码部分。

 

3.SHELL控制

结合上篇的LED闪烁的实验,我们通过调用SHELL自定义的命令来控制LED闪烁的起停动作,具体实现如下程序:

/* Private variables ---------------------------------------------------------*/
uint8_t LED_ToggleEnable = 1;


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void LED_Toggle(void)
{
    if(LED_ToggleEnable)
    {
        LED0_TOGGLE();  Ddl_Delay1ms(100);
        LED1_TOGGLE();  Ddl_Delay1ms(100);
        LED2_TOGGLE();  Ddl_Delay1ms(100);
        LED3_TOGGLE();  Ddl_Delay1ms(100);
    }
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void LED_StartToggle(void)
{
    LED_ToggleEnable = 1;
}
SHELL_EXPORT_CMD(start, LED_StartToggle, led start toggle);


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void LED_StopToggle(void)
{
    LED_ToggleEnable = 0;
}
SHELL_EXPORT_CMD(stop, LED_StopToggle, led stop  toggle);


 

4.运行结果


 

 

5.工程源代码

Project_USART_SHELL.zip (820.79 KB, 下载次数: 10)

赞赏

1

查看全部赞赏

个人签名We are a team and we work as a team !

回复

1998

帖子

3

资源

版主

厉害了!还没尝试过shell的移植,有机会试一下!!!感谢分享!


回复

4748

帖子

1

资源

五彩晶圆(中级)

谢谢分享,freertos搞的全家桶也有个freertos-cli的组件。

个人签名

默认摸鱼


回复

1

帖子

0

资源

一粒金砂(初级)

厉害了,感谢分享


回复

2

帖子

0

资源

一粒金砂(初级)

求加好友,我正在使用华大mcu,目前有一些困惑。

回复

2

帖子

0

资源

一粒金砂(初级)

我自己也使用usart1实现了类似shell命令行的功能

回复
您需要登录后才可以回帖 登录 | 注册

最新文章 更多>>
    关闭
    站长推荐上一条 1/9 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表