[蓝桥杯嵌入式]hal库 stm32 (DMA串口1收发,采用空闲中断方法)

前言:

本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用

所用工具:

1、芯片: STM32G431RBT6

2、STM32CubeMx软件

3、IDE: MDK-Keil软件

4、STM32G4xxHAL库

知识概括:

通过本篇博客您将学到:

DMA工作原理

STM32CubeMX创建DMA例程

HAL库定时器DMA函数库

首先:串口配置

先找到引脚PA9,PA10,打开串口1接收。

然后在打开串口1。

如果顺序弄错,串口1的引脚就会是PC4,PC5;

然后左边找到串口1,选择异步通信,波特率看实际情况,我改为9600

点进DMA

点击ADD添加两个DMA,分别是RX和TX的。其它参数保持默认

进入中断控制,打开中断其它的配置时钟配置,工程配置,调试配置就不赘述了。

生成代码,打开工程

串口DMA发送

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);

参数描述

HAL_StatusTypeDef返回值:函数是否执行成功,成功:HAL_OK,失败:HAL_ERROR

huart指定串口地址;

pData:发送数据缓存的地址;

Size:发送数据的长度;

使用:

直接调用即可发送:

cpp 复制代码
  while (1)
  {
        HAL_UART_Transmit_DMA(&huart1,"Hello2\r\n",strlen("Hello2\r\n"));
        HAL_Delay(1000);
  }

现象:

DMA接收:

首先,在main.h中定义好结构体

cpp 复制代码
#define BUFFER_SIZE 256

typedef struct USART_STRUCT
{
    unsigned char  rx_len;  //接收一帧数据的长度
    unsigned char  recv_end_flag; //一帧数据接收完成标志
    char rx_buffer[BUFFER_SIZE];//接收缓存数组
}USART_STRUCT;

然后在main.c中

头部声明结构体变量

cpp 复制代码
USART_STRUCT usart1Struct;

再进入stm32g4xx_it.c中

继承上面的变量

cpp 复制代码
extern USART_STRUCT usart1Struct;

再找到USART1_IRQHandler()函数,将里面改为下面的代码

cpp 复制代码
/**
  * @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    uint32_t temp;
    if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))//idle标志被置位
    { 
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
        HAL_UART_DMAStop(&huart1); //
        temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
        //这句和上面那句等效
        usart1Struct.rx_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
        usart1Struct.recv_end_flag = 1;    // 接受完成标志位置1    
     }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  /* USER CODE END USART1_IRQn 1 */
}

这个函数会进行空闲中断的处理

回到主函数

在while循环中改为下面代码:

cpp 复制代码
if(usart1Struct.recv_end_flag == 1)  //接收完成标志
        {
            HAL_UART_Transmit_DMA(&huart1,(uint8_t*)usart1Struct.rx_buffer,usart1Struct.rx_len);//将接收的数据发回去
            usart1Struct.rx_len = 0;//清除计数
            usart1Struct.recv_end_flag = 0;//清除接收结束标志位
            memset(usart1Struct.rx_buffer,0,usart1Struct.rx_len);
            
            HAL_UART_Receive_DMA(&huart1,(uint8_t*)usart1Struct.rx_buffer,BUFFER_SIZE);//重新打开DMA接收
        }

改完,编译运行
有什么问题可以在评论区问我

相关推荐
.NET修仙日记1 小时前
2026 .NET 面试八股文:高频题 + 答案 + 原理(面试加分技巧)
面试·职场和发展·.net·.net core·微软技术
dqsh062 小时前
关于STM32G474芯片有规律的自动重启的问题
stm32·单片机·嵌入式硬件·系统重启·原因解析
_深海凉_2 小时前
LeetCode热题100-分割回文串
算法·leetcode·职场和发展
yong99902 小时前
基于 STM32 的 4×4 矩阵键盘源码
stm32·矩阵·计算机外设
国产芯片设计2 小时前
【LCD驱动实战】单颗YL1621脚位不足?双芯片联动驱动方案详解
stm32·单片机·mcu·51单片机·硬件工程
笨笨小乌龟115 小时前
单片机的半主机模式与 MicroLib 机制(Keil UseMicroLIB)
stm32·单片机·嵌入式硬件
流年如夢5 小时前
单链表Ⅲ(LeetCode)
数据结构·算法·leetcode·职场和发展
Tutankaaa7 小时前
知识竞赛计分如何确保绝对准确?双机热备方案详解与实施要点
笔记·学习·职场和发展
旧梦吟9 小时前
5.9 电工考试-易错题
stm32·嵌入式硬件
foundbug9999 小时前
STM32 + SHT20 温湿度测试 TFT 显示方案
stm32·单片机·嵌入式硬件