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

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

相关推荐
非概念32 分钟前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
无敌最俊朗@2 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习
EterNity_TiMe_2 小时前
【论文复现】STM32设计的物联网智能鱼缸
stm32·单片机·嵌入式硬件·物联网·学习·性能优化
7yewh6 小时前
嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻
驱动开发·stm32·嵌入式硬件·mcu·物联网·硬件架构·pcb工艺
编码小袁9 小时前
蓝桥杯:编程爱好者的试炼场
职场和发展·蓝桥杯
电子工程师UP学堂15 小时前
STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。
stm32
7yewh15 小时前
嵌入式硬件电子电路设计(五)MOS管详解(NMOS、PMOS、三极管跟mos管的区别)
stm32·嵌入式硬件·mcu·物联网·硬件架构·硬件工程·pcb工艺
白-胖-子16 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-奇数序列排序
c++·算法·蓝桥杯·等考·13级
可乐鸡翅好好吃16 小时前
关于stm32中IO映射的一些问题
stm32·单片机·嵌入式硬件
小刘同学-很乖17 小时前
MQTT从入门到精通之 MQTT 客户端编程
spring boot·stm32·物联网·iot