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

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

相关推荐
chenziang114 分钟前
leetcode hot100 对称二叉树
算法·leetcode·职场和发展
wenchm3 小时前
细说STM32F407单片机IIC总线基础知识
stm32·单片机·嵌入式硬件
柒月的猫3 小时前
方格分割(蓝桥杯2017年试题D)
职场和发展·蓝桥杯
嵌入式lover3 小时前
STM32项目之环境空气质量检测系统软件设计
stm32·单片机·嵌入式硬件
kenwblack4 小时前
STM32 SPI读取SD卡
stm32·单片机
柒月的猫5 小时前
翻转(蓝桥杯2023大学C组试题E)
职场和发展·蓝桥杯
Solitudefire6 小时前
蓝桥杯刷题——day9
算法·蓝桥杯
1101 11017 小时前
STM32-笔记10-手写延时函数(SysTick)
笔记·stm32·单片机
极客小张7 小时前
基于STM32的智慧农业控制系统设计:python可视化、UART、I2C、TCP/HTTP技术
python·stm32·单片机·物联网·tcp/ip·毕业设计·课程设计
wenchm8 小时前
细说STM32F407单片机通过IIC读写EEPROM 24C02
stm32·单片机·嵌入式硬件