[Jihai M3 core APM32E103VET6S MINI development board] 02. USART online interaction function
[Copy link]
The APM32E103VET6S MINI development board has a DB9 RS-232 interface. The J3 jumper is used to select whether to connect to the MCU's USART1 or USART2 port pins, as shown in the following figure:
This article mainly implements the serial communication interaction function between the PC and the MCU through the query sending and interrupt receiving functions of USART, and parses the data/commands sent by the PC to execute the corresponding function. Here, we need to introduce an open source Letter Shell, which has very powerful functions. For details, please refer to the following link: https://github.com/NevermindZZT/letter-shell. This article mainly shares the specific steps of transplantation and implementation of the function part:
- First, you need to define a global SHELL structure variable:
/* Private variables ---------------------------------------------------------*/
SHELL_TypeDef shell;
- Initialize the serial port configuration parameters and assign values to the member parameters in the shell structure variable:
/*******************************************************************************
* [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);
}
- Construct shell structure variable member function:
/*******************************************************************************
* @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
}
- Implement the serial port interrupt receiving function and pass the received data to the shell for parsing:
/*******************************************************************************
* @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));
}
}
- Finally, modify the corresponding shell configuration according to the needs. For details, please refer to the relevant macro definitions in the shell_cfg.h file.
After the shell is transplanted, the shellPortInit function is called in the main function for initialization, and the correctly compiled program is downloaded to the MCU for operation. The PC port uses the SecureCRT software for docking and debugging. After the MCU starts running, it prints log information and waits for the PC to enter command characters. After inputting help on the PC and pressing the Enter key, the MCU parses and executes the received command. The operation is as follows:
Software engineering source code:
Project.zip
(287.33 KB, downloads: 4)
|