STM32 HAL DMA中断配置

这篇具有很好参考价值的文章主要介绍了STM32 HAL DMA中断配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

使用HAL库方式DMA中断时,在网上找了好多资料都没有怎么介绍。所以就自己研究了一下,并做个记录。我的芯片型号是STM32G030。下面我以I2C传数据为例介绍下HAL库是如何使用DMA中断的。

MXCUBE配置

我使用的是I2C2,简单配置下参数,加上DMA通道。
hall库i2c的dma配置,stm32,单片机
hall库i2c的dma配置,stm32,单片机
DMA貌似默认开启了中断,蓝色的勾勾是我自己勾上的,没有用到I2C的中断不勾也可以。
hall库i2c的dma配置,stm32,单片机

DMA初始化

打开工程后主函数里有个MX_DMA_Init();它的内部就是开启DMA的RCC和NVIC,这里就不放图了。

I2C初始化

打开这个文件的第一眼,看到最上端的全局变量hdma_i2c2_rx和hdma_i2c2_tx,实际上DMA的初始化我更感觉是放在这里的。

I2C_HandleTypeDef hi2c2;
DMA_HandleTypeDef hdma_i2c2_rx;
DMA_HandleTypeDef hdma_i2c2_tx;

I2C的初始化我直接略过,和只用I2C通讯配置没区别。拉到最下边的函数HAL_I2C_MspInit

	/* I2C2 DMA Init */
    /* I2C2_RX Init */
    hdma_i2c2_rx.Instance = DMA1_Channel1;
    hdma_i2c2_rx.Init.Request = DMA_REQUEST_I2C2_RX;
    hdma_i2c2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_i2c2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_i2c2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_i2c2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_i2c2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_i2c2_rx.Init.Mode = DMA_NORMAL;
    hdma_i2c2_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_i2c2_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c2_rx);
        /* I2C2_TX Init */
    hdma_i2c2_tx.Instance = DMA1_Channel2;
    hdma_i2c2_tx.Init.Request = DMA_REQUEST_I2C2_TX;
    hdma_i2c2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_i2c2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_i2c2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_i2c2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_i2c2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_i2c2_tx.Init.Mode = DMA_NORMAL;
    hdma_i2c2_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_i2c2_tx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c2_tx);

这里实际上跟I2C+DMA通信也没什么区别。

I2C+DMA+中断通信过程

在我看了他的驱动函数后,我发现只要是后缀带有DMA的函数,都自动有DMA中断的处理过程。有这几个函数:

  • HAL_I2C_Mem_Write_DMA
  • HAL_I2C_Master_Receive_DMA
  • HAL_I2C_Master_Seq_Receive_DMA
  • HAL_I2C_Master_Seq_Transmit_DMA
  • HAL_I2C_Master_Transmit_DMA
  • HAL_I2C_Mem_Read_DMA
  • HAL_I2C_Mem_Write_DMA
  • HAL_I2C_Slave_Receive_DMA

我随便点开一个HAL_I2C_Mem_Write_DMA,这几个都是差不多,只是用途不一样,带Mem的方便与EEPROM类似的通讯,他需要发从机的设备地址和内存地址,就可以用这个。
在该函数内我只列出我觉得重要的代码,

  1. hi2c->XferISR用于绑定中断处理函数

    hi2c->XferISR     = I2C_Master_ISR_DMA;
    
  2. 这里dma绑定了相关的传输处理函数,传输完成和传输错误,然后开启DMA的中断使能,当传输完成后就会进入I2C_DMAMasterTransmitCplt。

    if (hi2c->hdmatx != NULL)
    {
      /* Set the I2C DMA transfer complete callback */
      hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
    
      /* Set the DMA error callback */
      hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
    
      /* Set the unused DMA callbacks to NULL */
      hi2c->hdmatx->XferHalfCpltCallback = NULL;
      hi2c->hdmatx->XferAbortCallback = NULL;
    
      /* Enable the DMA channel */
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
    }
    
  3. 该函数最后开启DMA搬运。

    /* Enable DMA Request */
      hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
    

最后是通讯过程的DMA中断了,当触发了DMA的中断类型就会进入该函数,就只有三种传输完成一半、传输完成以及传输错误。

void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_i2c2_rx);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

进入到HAL_DMA_IRQHandler,假设触发了传输完成,就会执行相应关闭DMA中断、清空DMA中断标志位最后调用传输完成的回调函数。

	...
	if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
      {
        /* Disable the transfer complete and error interrupt */
        __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);

        /* Change the DMA state */
        hdma->State = HAL_DMA_STATE_READY;
      }
      /* Clear the transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU)));

      /* Process Unlocked */
      __HAL_UNLOCK(hdma);

      if (hdma->XferCpltCallback != NULL)
      {
        /* Transfer complete callback */
        hdma->XferCpltCallback(hdma);
      }
    }
    ...

这个hdma->XferCpltCallback()函数指针在我们在开始时就赋值了

 /* Set the I2C DMA transfer complete callback */
  hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;

进入到该函数发现关闭了I2C的DMA请求

/* Disable DMA Request */
  hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;

但是函数内我并没有找到用户可以自定义的回调函数,可供我们自己使用。我自己在里边加入了些代码,实测发现是可以进去的。

总结

最后总结HAL库方式的DMA中断默认就是开启状态,只是没有给用户开启自定义回调函数使用,也不知道是没必要还是我没找到。文章来源地址https://www.toymoban.com/news/detail-856654.html

到了这里,关于STM32 HAL DMA中断配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 HAL FreeRTOS 硬件I2C 使用

    因为某个项目想要颜色识别,去识别球的颜色,但是又不想多来个摄像头,所以想尝试一下颜色传感器的方案。但是经过尝试,HAL库生成的 FreeRTOS 硬件 I2C 读写一直在报错。 刚好手头上有九轴陀螺仪的例程代码。最后用FreeRTOS 硬件 I2C 读取数据。 这里提到了阻塞式 HAL 函数(

    2024年02月20日
    浏览(43)
  • STM32 HAL库函数学习 I2C篇

    本篇内容讲述STM32的硬件IIC功能。硬件IIC的使用在F1系列上可能会有问题。本次使用的测试平台是H7,用于AT24C02芯片的读写正常,暂不清楚在其他芯片上使用是否正常。 1、HAL_StatusTypeDef HAL_I2C_Init (I2C_HandleTypeDef * hi2c) I2C初始化函数,使用CubeMx生成。需要选中I2C硬件指定的IO口。

    2023年04月08日
    浏览(33)
  • STM32 i2c从机模式中断处理参考

    void I2C1_IRQHandler(void) {   /* USER CODE BEGIN I2C1_IRQn 0 */     extern void i2c1_irq(I2C_HandleTypeDef *hi2c);     i2c1_irq(hi2c1);     return ;   /* USER CODE END I2C1_IRQn 0 */   if (hi2c1.Instance-ISR (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {     HAL_I2C_ER_IRQHandler(hi2c1);   } else {     HAL_I2C_EV_IRQHandler(hi2c1);   }  

    2024年01月22日
    浏览(36)
  • STM32F4_HAL库_串口阻塞/中断/DMA三种方式发送数据的配置

    串口阻塞发送的意思就是,发送一段数据,在没有发送完所有数据之前,一直停留在此发送函数(可设定阻塞时间),这个过程中会阻塞别的程序运行; HAL库的配置分为两个层次,一个是HAL库内部调用的、与MCU硬件相关的初始化xxx_MspInit,一个是我们外部调用的初始化xxx_In

    2023年04月25日
    浏览(43)
  • STM32之I2C总线知识和HAL库函数

    一、 I2C总线知识 I2C总线物理拓扑结构 I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接

    2024年02月21日
    浏览(38)
  • STM32基于CubeMX与HAL库的I2C应用

    1.1 物理层         I2C协议和摩托罗拉公司的SPI协议一样,是一种通讯协议。串行外围设备接口,是一种高速全双工的通信总线,是由 Phiilps 公司开发的。由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内

    2024年02月21日
    浏览(61)
  • 【STM32CubeMX+HAL库】I2C详解+读写EEPROM

    在之前的标准库中,STM32的硬件IIC非常复杂,更重要的是它并不稳定,所以都不推荐使用。但是在我们的HAL库中,对硬件IIC做了全新的优化,使得之前软件IIC几百行代码,在HAL库中,只需要寥寥几行就可以完成 那么这篇文章将带你去感受下它的优异之处。 通过本篇博客您将

    2024年02月03日
    浏览(45)
  • STM32设置为I2C从机模式(HAL库版本)

    我之前出过一篇关于STM32设置为I2C从机的博客,现在应粉丝要求,出一篇HAL库版本的I2C从机编程。 基于官方库版本的可以看下我之前发的文章:STM32设置为I2C从机模式 测试芯片:STM32F103RCT6 测试方法:用一个USB转I2C的工具接到STM32的I2C引脚上,通过上位机工具进行读写操作。如

    2024年02月12日
    浏览(55)
  • STM32 HAL库硬I2C的TOF050C模块

    最近在倒腾毕业设计,需要用到TOF050C,但是现有的案例都是软IIC,并且还是基于STM32F103的,笔者用的STM32F767,没有GPIO-CRH寄存器。问题来了,如果我每次都要去看寄存器手册属实费时间,这不干脆直接用硬IIC? 于是乎,打开了TOF050C手册,硬啃! 这手册好在它有工作流程图,

    2024年02月14日
    浏览(50)
  • Clion开发STM32之HAL库I2C封装(基础库)

    引用参考: Clion开发STM32之HAL库GPIO宏定义封装(最新版)

    2024年02月13日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包