• STM32基于HAL库的USART+DMA使用


    开发板:正点原子阿波罗

    创建工程

    使能USART
    在这里插入图片描述

    开启DMA

    在这里插入图片描述

    配置中断

    在这里插入图片描述

    以上配置好之后,点击生成工程

    一、接收、发送指定长度数据

    指定接收、发送的数据长度为1

    定义一个接收缓冲区

    char tx_buffer[10];
    
    • 1

    编写中断回调函数

    当触发接收中断时,将接收到的数据通过DMA发送出去

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    	if (huart->Instance == USART1) {
    		//函数要使用DMA方式的
    		HAL_UART_Transmit_DMA(&huart1,tx_buffer,1);  
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    当触发发送中断时,使用DMA接收一下

    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
    	if (huart->Instance == USART1) {
    		函数要使用DMA方式的
    		HAL_UART_Receive_DMA(&huart1,tx_buffer,1);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使能接收中断

    在main.c中

    在这里插入图片描述
    编译、下载进去就能看到效果

    二、接收、发送不定长度数据

    接收不定长度时,需要判断USART什么时候为空闲状态,当触发空闲中断时,证明此时已经接收全部数据,需要

    用到的函数有

    HAL_UART_DMAStop(UART_HandleTypeDef *huart)//停止DMA传输
    __HAL_DMA_GET_COUNTER(__HANDLE__)//得到DMA传输了多少数据
    __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__)//清除空闲标志
    HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)//使用DMA的方式发送
    HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)//使用DMA的方式接收
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使能空闲中断

    MX_USART1_UART_Init() 函数中添加

      /* USER CODE BEGIN USART1_Init 2 */
      //使能空闲中断
      __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
      /* USER CODE END USART1_Init 2 */
    
    • 1
    • 2
    • 3
    • 4

    定义一个接收缓冲区

    /* USER CODE BEGIN 0 */
    #define RXSIZE  1024   /
    uint8_t rx_buffer[RXSIZE] = {0};
    uint16_t RxNum = 0;
    /* USER CODE END 0 */
    
    • 1
    • 2
    • 3
    • 4
    • 5

    编写USART1中断

    /**
      * @brief This function handles USART1 global interrupt.
      */
    void USART1_IRQHandler(void)
    {
    	/* USER CODE BEGIN USART1_IRQn 0 */
    	
    	//判断空闲标志
    	if (__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) == SET) {
    		//清除空闲中断标志
    		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
    		//停止DMA
    		HAL_UART_DMAStop(&huart1);
    		//接收了多长的数据
    		RxNum = RXSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    		//将接收到的数据再发送出去
    		HAL_UART_Transmit_DMA(&huart1,rx_buffer,RxNum);
    	}
    	/* USER CODE END USART1_IRQn 0 */
    	HAL_UART_IRQHandler(&huart1);
    	/* USER CODE BEGIN USART1_IRQn 1 */
    	/* USER CODE END USART1_IRQn 1 */
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    编写中断回调函数

    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
      if (huart->Instance == USART1) {
        RxNum = 0;
        //清空一个缓冲区
        memset(rx_buffer,0,RXSIZE);
        //使能接收
        HAL_UART_Receive_DMA(&huart1,rx_buffer,RXSIZE);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使能接收中断

    在main.c中

    若是不添加这句则无法进入中断
    在这里插入图片描述
    编译、下载进去就能看到效果

  • 相关阅读:
    2.Seq2Seq注意力机制
    【Transformers】第 5 章 :文本生成
    数据结构和算法(二)--算法分析
    YB2410是一种高效的同步步进能够输送2A负载的降压DC/DC转换器
    Matlab之并行程序设计实战教程
    SQL Server、MySQL主从搭建,EF Core读写分离代码实现
    git学习笔记
    【2023集创赛】Arm杯二等奖作品:基于Arm Cortex-M3的体感节奏音乐游戏机
    【Docker】学习纪录+操作纪录
    Win10 cmd如何试用tar命令压缩和解压文件夹
  • 原文地址:https://blog.csdn.net/m0_47329175/article/details/125450332