[蓝桥杯嵌入式]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接收
        }

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

相关推荐
qq_459234424 天前
【题库】| 商用密码应用安全性评估从业人员考核题库(四十)
职场和发展·密码学·学习方法·考核·商用密码·商用密码应用安全性评估·密评
敲敲了个代码4 天前
[特殊字符] 空数组的迷惑行为:为什么 every 为真,some 为假?
前端·javascript·react.js·面试·职场和发展
Lester_11014 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
LCG元4 天前
低功耗显示方案:STM32L0驱动OLED,动态波形绘制与优化
stm32·嵌入式硬件·信息可视化
z20348315204 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
古译汉书4 天前
【IoT死磕系列】Day 7:只传8字节怎么控机械臂?学习工业控制 CANopen 的“对象字典”(附企业级源码)
数据结构·stm32·物联网·http
Alaso_shuang4 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
2501_918126914 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发
诚思报告YH4 天前
视频面试软件市场洞察:2026 - 2032年复合年均增长率(CAGR)为10.3%
面试·职场和发展
重生之后端学习4 天前
74. 搜索二维矩阵
开发语言·数据结构·算法·职场和发展·深度优先