[极海M3内核 APM32E103VET6S MINI开发板]02.USART在线交互功能
[复制链接]
APM32E103VET6S MINI开发板带有一个DB9的RS-232接口,通过J3跳帽来选择连接的是MCU的USART1还是USART2端口引脚,如下图所示:
本文主要实现的是通过USART的查询发送和中断接收功能来实现PC端与MCU端的串口通讯交互功能,通过对PC端发送过来的数据/命令进行解析,执行相应的功能函数;这边就需要引入到一个开源的Letter Shell,其功能非常强大,具体的可以参考如下链接:https://github.com/NevermindZZT/letter-shell,本文主要还是具体的移植和实现功能部分的步骤分享:
/* Private variables ---------------------------------------------------------*/
SHELL_TypeDef shell;
- 初始化串口配置参数,并对shell结构体变量中成员参数进行赋值:
/*******************************************************************************
* [url=home.php?mod=space&uid=159083]@brief[/url] * @param
* @retval
* [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void shellPortInit(void)
{
GPIO_Config_T GPIO_ConfigStruct;
USART_Config_T USART_ConfigStruct;
#if 1
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);
USART_ConfigStructInit(&USART_ConfigStruct);
USART_ConfigStruct.baudRate = 115200;
USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
USART_ConfigStruct.parity = USART_PARITY_NONE;
USART_ConfigStruct.mode = USART_MODE_TX_RX;
USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
USART_Config(USART1, &USART_ConfigStruct);
USART_EnableInterrupt(USART1, USART_INT_RXBNE);
NVIC_EnableIRQRequest(USART1_IRQn, 0, 1);
USART_Enable(USART1);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_9;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_10;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
#else
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART2);
USART_ConfigStructInit(&USART_ConfigStruct);
USART_ConfigStruct.baudRate = 115200;
USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
USART_ConfigStruct.parity = USART_PARITY_NONE;
USART_ConfigStruct.mode = USART_MODE_TX_RX;
USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
USART_Config(USART2, &USART_ConfigStruct);
USART_EnableInterrupt(USART2, USART_INT_RXBNE);
NVIC_EnableIRQRequest(USART2_IRQn, 0, 0);
USART_Enable(USART2);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_2;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_3;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
#endif
shell.write = shellPortWrite;
shellInit(&shell);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void shellPortWrite(const char ch)
{
#if 1
USART_TxData(USART1, (uint8_t)ch);
while(USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
#else
USART_TxData(USART2, USART_RxData(USART2));
while(USART_ReadStatusFlag(USART2, USART_FLAG_TXBE) == RESET);
#endif
}
- 实现串口中断接收函数,将接收到的数据传递到shell中进行解析:
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void USART1_IRQHandler(void)
{
if(USART_ReadIntFlag(USART1, USART_INT_RXBNE) == SET)
{
shellHandler(&shell, USART_RxData(USART1));
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void USART2_IRQHandler(void)
{
if(USART_ReadIntFlag(USART2, USART_INT_RXBNE) == SET)
{
shellHandler(&shell, USART_RxData(USART2));
}
}
- 最后就是根据需要,修改相应的shell配置,具体的可以参考shell_cfg.h这个文件中的相关宏定义
完成shell的移植后,在main函数中调用shellPortInit函数进行初始化,将编译无误的程序下载到MCU运行;PC端口使用SecureCRT软件进行对接调试,MCU启动运行后打印日志信息,然后等待PC输入指令字符,在PC端输入help并敲入回车键后,MCU对接收到的命令进行解析执行,运行如下所示:
|