STM32 笔记 01 篇(基于 HAL 的串口数据接收)

注意:

  • 本文只对基于 HAL 的串口数据接收部分代码进行记录。
  • 本文以 STM32F103RCT6 的 USART2 为例,管脚是 TX->PA2, RX->PA3。
第一部分:自定义的数据结构:
#define UART_RECV_BUF_SIZE_TEMPORARY (64) // 临时缓存区大小 typedef struct { unsigned intuart_recv_len_temporary; // 临时缓存区接收到的数据长度 unsigned intuart_recv_len_formal; // 正式缓存区接收到的数据长度 unsigned char uart_recv_buf_temporary[UART_RECV_BUF_SIZE_TEMPORARY]; // 临时缓存区 unsigned char uart_recv_buf_formal[UART_RECV_BUF_SIZE_TEMPORARY * 2]; // 正式缓存区 }ts_uart_recv;


第二部分:自定义的全局函数:
/** * This function enable uart interrupt and reset uart receive buff. * @param uart_handle * @param uart_recv */ void init_uart_interrupt(UART_HandleTypeDef* uart_handle, ts_uart_recv* uart_recv) { memset(uart_recv, 0, sizeof(ts_uart_recv)); // Reset serial receiving memory.__HAL_UART_ENABLE_IT(uart_handle, UART_IT_RXNE); // Enable UART_IT_RXNE. __HAL_UART_ENABLE_IT(uart_handle, UART_IT_IDLE); // Enable UART_IT_IDLE. __HAL_UART_CLEAR_IDLEFLAG(uart_handle); // Reset UART_FLAG_IDLE. }

/** * This function will be called in the interrupt function. * @param uart_handle * @param uart_recv */ void uart_interrupt_recv_callback(UART_HandleTypeDef* uart_handle, ts_uart_recv* uart_recv) { if(__HAL_UART_GET_FLAG(uart_handle, UART_FLAG_RXNE) != RESET) { unsigned char ch =uart_handle->Instance->DR; // Read a byte.if(uart_recv->uart_recv_len_temporary < sizeof(uart_recv->uart_recv_buf_temporary)) { uart_recv->uart_recv_buf_temporary[(uart_recv->uart_recv_len_temporary)++] = ch; // Store data in temporary cache. }__HAL_UART_CLEAR_FLAG(uart_handle,UART_FLAG_RXNE); // Reset UART_FLAG_RXNE. } if(__HAL_UART_GET_FLAG(uart_handle, UART_FLAG_IDLE) != RESET) { if (uart_recv->uart_recv_len_formal < sizeof(uart_recv->uart_recv_buf_formal)) { memcpy(&uart_recv->uart_recv_buf_formal[uart_recv->uart_recv_len_formal], uart_recv->uart_recv_buf_temporary, uart_recv->uart_recv_len_temporary); // Save data from temporary cache to the end of formal cache. uart_recv->uart_recv_len_formal += uart_recv->uart_recv_len_temporary; // Calculate data length in formal cache. }memset(uart_recv->uart_recv_buf_temporary, 0, uart_recv->uart_recv_len_temporary); // Reset temporary cache space. uart_recv->uart_recv_len_temporary = 0; // Reset data length of temporary cache space./* Reset UART_FLAG_IDLE */ unsigned long temp; temp = uart_handle->Instance->SR; // Must temp = uart_handle->Instance->DR; // Must __HAL_UART_CLEAR_IDLEFLAG(uart_handle); } }


第三部分:硬件初始化以及静态变量定义
static UART_HandleTypeDef huart2; // uart2 handle. static ts_uart_recv uart_recv_2; // uart2 receive cache. /** * This function is to configure UART2 hardware. */ void init_uart_2(void) { /* Enable clock*/ __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /* Configure GPIO */ GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Configure NVIC */ HAL_NVIC_SetPriority(USART2_IRQn, 1, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); /* Configure UART */ huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); /* Enable uart interrupt */ init_uart_interrupt(&huart2, &uart_recv_2); }

第四部分:中断服务函数配置
/** * This function is uart2 interrupt server function. */ void USART2_IRQHandler(void) { uart_interrupt_recv_callback(&huart2, &uart_recv_2); HAL_UART_IRQHandler(&huart2); }


【STM32 笔记 01 篇(基于 HAL 的串口数据接收)】

    推荐阅读