[蓝桥杯嵌入式]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:发送数据的长度;

使用:

直接调用即可发送:

  while (1)
  {
        HAL_UART_Transmit_DMA(&huart1,"Hello2\r\n",strlen("Hello2\r\n"));
        HAL_Delay(1000);
  }

现象:

DMA接收:

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

#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中

头部声明结构体变量
 

USART_STRUCT usart1Struct;

再进入stm32g4xx_it.c中

继承上面的变量

extern USART_STRUCT usart1Struct;

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

/**
  * @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循环中改为下面代码:

if(usart1Struct.recv_end_flag == 1)  //接收完成标志
        {
            HAL_UART_Transmit_DMA(&huart1,   (uint8_t*)usart1Struct.rx_buffer,usart1Struct.rx_len);//将接收的数据发回去

            memset(usart1Struct.rx_buffer,0,usart1Struct.rx_len);//清空缓存区
            usart1Struct.rx_len = 0;//清除计数
            usart1Struct.recv_end_flag = 0;//清除接收结束标志位
                        
            HAL_UART_Receive_DMA(&huart1,(uint8_t*)usart1Struct.rx_buffer,BUFFER_SIZE);//重新打开DMA接收
        }

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值