【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与电脑端的串口数据通讯;
USART初始化配置程序:将USART配置成115200(波特率),N(校验位),8(数据位),1(停止位),使能串口的接收和发送功能,使能接收中断功能并配置接收中断;配置GPIO引脚复用成USART功能引脚,如下程序所示:
-
- void UsartRxIrqCallback(void)
- {
- printf("%c", USART_RecData(M4_USART3));
- USART_FuncCmd(M4_USART3, UsartTxAndTxEmptyInt, Enable);
- }
-
-
-
- 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);
- }
- }
-
-
-
- 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,
- };
-
-
- PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART3, Enable);
-
-
- PORT_SetFunc(PortE, Pin04, Func_Usart3_Rx, Disable);
- PORT_SetFunc(PortE, Pin05, Func_Usart3_Tx, Disable);
-
-
- if(USART_UART_Init(M4_USART3, &stcInitCfg) != Ok)
- {
- while(1);
- }
-
-
- if(USART_SetBaudrate(M4_USART3, 115200) != Ok)
- {
- while(1);
- }
-
-
- 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);
-
-
- 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);
-
-
- USART_FuncCmd(M4_USART3, UsartRx, Enable);
- USART_FuncCmd(M4_USART3, UsartRxInt, Enable);
- USART_FuncCmd(M4_USART3, UsartTx, Enable);
- }
-
-
-
- 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这个函数来实现的, 运行结果如下图所示:
我们在控制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开源源代码: ,最新的版本是3.0的,程序中使用的是2.x的版本;在官网上有详细的功能、移植、配置,以及相应的应用说明,大家可以去深入了解,我们这边还是结合HC32F460来实现应用移植;在工程中添加letter shell 2.x的源文件,添加自定义的shell_port.c和shell_port.h这两个文件,将之前的串口初始化程序移动到这个.c文件中来实现;移植过程如下:
- 定义一个shell结构体对象;
- 实现这个结构体中write的实现,即通过串口打印输出一个字节数据;
- 调用shellInit函数进行初始化;
- 在串口接收中断回调函数中调用shellHandler函数,将串口接收到的数据传递到这个函数中进行解析处理;
这样我们最单的SHELL框架就移植完成了;尝试编译运行一下,如下图所示:
具体的代码实现可以参考最后的附件工程源代码部分。
3.SHELL控制
结合上篇的LED闪烁的实验,我们通过调用SHELL自定义的命令来控制LED闪烁的起停动作,具体实现如下程序:
-
- uint8_t LED_ToggleEnable = 1;
-
-
-
- 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);
- }
- }
-
-
-
- void LED_StartToggle(void)
- {
- LED_ToggleEnable = 1;
- }
- SHELL_EXPORT_CMD(start, LED_StartToggle, led start toggle);
-
-
-
- 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, 下载次数: 40)
|