STM32 利用空闲中断接收数据

STM32 利用串口空闲中断接收不定长数据

  1. 利用cubeMX打开DMA串口接收中断
  2. 利用CubeMX打开串口中断
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
  1. 打开空闲中断

    //打开空闲中断使能
      __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
    
  2. 使能DMA 接收数据

    //启动 DMA 接收数据
    HAL_UART_Receive_DMA(&huart2, uart2_data, 128);
    
  3. 在中断函数内部调用自定义中断函数

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
HB_IRQHandler(&huart2);
  /* USER CODE END USART2_IRQn 1 */
}
  1. 空闲中断触发以后需要清除空闲中断标志(使用如下函数),
  2. 在空闲中断函数内部计算已经传输的字节数量
uint8_t uart2_data[128];
uint8_t uart2_flag = 0;
void HB_IRQHandler(UART_HandleTypeDef *huart)
{
    if (huart == &huart2)
    {
        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))

        {
            HAL_UART_DMAStop(huart);
            //__HAL_UART_CLEAR_FLAG(huart,UART_FLAG_IDLE); //使用这个函数不生效,不知道为啥
            __HAL_UART_CLEAR_IDLEFLAG(huart);
            uart2_flag = 1;
            //计算获取到的数据个数
            //huart->RxXferSize     希望传输的数据个数
            //huart->hdmarx->Instance->CNDTR DMA还需要传输的字节数
            huart->RxXferCount = huart->RxXferSize - huart->hdmarx->Instance->CNDTR;
        }
    }
}



串口口中断函数调用自定义中断函数

/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
	
  /* USER CODE BEGIN USART2_IRQn 1 */
	//调用自定义函数
	 HB_IRQHandler(&huart2);
  /* USER CODE END USART2_IRQn 1 */
}

cubeMX设置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

main 函数初始化代码


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    MX_USART2_UART_Init();
    /* USER CODE BEGIN 2 */
    printf("hello hebao\r\n");

    Button_Create("Button1",
                  &Button1,
                  Read_KEY1_Level,
                  0);
    Button_Attach(&Button1, EV_CLICK, Btn1_Dowm_CallBack);           //单击
    Button_Attach(&Button1, EV_DOUBLE_CLICK, Btn1_Double_CallBack);  //双击
    Button_Attach(&Button1, EV_LONG_CLICK, Btn1_Continuos_CallBack); //连按

    //HAL_UART_Receive_IT(&huart2, uart2_data, 32);
    //打开空闲中断使能
    __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);

    //启动 DMA 接收数据
    HAL_UART_Receive_DMA(&huart2, uart2_data, 128);
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        Button_Process(); //需要周期调用按键处理函数
        HAL_Delay(50);
        if (uart2_flag)
        {

            for (uint8_t i = 0; i < huart2.RxXferCount; i++)
            {
                printf("%02x ", uart2_data[i]);
            }
            printf("\r\n");
            uart2_flag = 0;
            //数据处理完成以后再次打开接收数据
            HAL_UART_Receive_DMA(&huart2, uart2_data, 128);

            //__HAL_UART_CLEAR_OREFLAG(&huart2);
            // HAL_UART_Receive_IT(&huart2, uart2_data, 32);
        }
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}


测试结果

在这里插入图片描述

Guess you like

Origin blog.csdn.net/u010261063/article/details/119542763