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

注意:

  • 本文只对基于 HAL 的串口数据接收部分代码进行记录。
  • 本文以 STM32F103RCT6 的 USART2 为例,管脚是 TX->PA2, RX->PA3。

第一部分:自定义的数据结构:

#define UART_RECV_BUF_SIZE_TEMPORARY (64) // 临时缓存区大小
typedef struct
{
    unsigned int  uart_recv_len_temporary;// 临时缓存区接收到的数据长度
    unsigned int  uart_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)