当前位置: 代码迷 >> 综合 >> STM32—cubeIDE+DMA+USART 接收任意长度的数据
  详细解决方案

STM32—cubeIDE+DMA+USART 接收任意长度的数据

热度:29   发布时间:2024-02-19 20:34:51.0

关于usart串口收发信息网上能搜到很多相关资料,但大都是只能是有限的字符,有的能发不限字符,但大部分不能直接用,对新手来说不是很友好。按以下做,其实很简单就能实现

1、配置USART1,选择异步asynchronous,软件自动配置了PA9和PA10管脚

2、配置时钟树,我用默认的,然后生成代码。

3、修改UASRT串口程序

先声明下:

volatile uint8_t rx_len = 0;             //接收一帧数据的长度
volatile uint8_t recv_end_flag = 0;    //一帧数据接收完成标志
uint8_t rx_buffer[200]={0};   //接收数据缓存

修改static void MX_USART1_UART_Init(void)函数

直接拷贝吧,代码如下:  

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);          //使能IDLE中断
  HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);

3、修改串口中断函数。

void USART1_IRQHandler(void)    //串口中断
{
    uint32_t tmp_flag = 0;
    uint32_t temp;

    HAL_UART_IRQHandler(&huart1);
    if(USART1 == huart1.Instance)
    {
        tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位

        if((tmp_flag != RESET))//idle标志被置位
        {
            recv_end_flag = 1;  // 接受完成标志位置1
            __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位

            HAL_UART_DMAStop(&huart1); //
            temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数
            rx_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数

            HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收
        }
    }
 }

4、主函数中串口中断的处理函数,在main()函数的里增加如下代码:

 while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      if(recv_end_flag ==1)
              {
                  printf("rx_len=%d\r\n",rx_len);//打印接收长度
                  HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);//接收数据打印出来
                  for(uint8_t i=0;i<rx_len;i++)
                      {
                          rx_buffer[i]=0;//清接收缓存
                      }
                  rx_len=0;//清除计数
                  recv_end_flag=0;//清除接收结束标志位
              }
              HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收

  }
  /* USER CODE END 3 */

5、赶紧编译测试吧,发任意多个字符都可以返回