使用DMA的STM32F0发现I2C传输

使用DMA的STM32F0发现I2C传输,stm32,i2c,dma,stm32f0,Stm32,I2c,Dma,Stm32f0,我试图使用DMA从I2C传感器(BNO055)获取数据,但无法启动DMA传输。我找到了很多F1、F3和F4 STM微控制器的例子,但对F0没有任何帮助。 我所做的是: 我使用轮询方法初始化传感器,它工作正常 我使用以下代码初始化DMA: ` ` 我使用轮询方法设置要读取的传感器内存的正确地址 现在我想使用DMA读取32个字节。是否必须使用I2C\u TransferHandling()函数发送传感器地址?那么应该发送哪些其他参数?在DMA初始化中,执行以下操作后,我遗漏了什么: I2C\u DM

我试图使用DMA从I2C传感器(BNO055)获取数据,但无法启动DMA传输。我找到了很多F1、F3和F4 STM微控制器的例子,但对F0没有任何帮助。 我所做的是:

  • 我使用轮询方法初始化传感器,它工作正常
  • 我使用以下代码初始化DMA:
  • `

    `

  • 我使用轮询方法设置要读取的传感器内存的正确地址
  • 现在我想使用DMA读取32个字节。是否必须使用
    I2C\u TransferHandling()
    函数发送传感器地址?那么应该发送哪些其他参数?在DMA初始化中,执行以下操作后,我遗漏了什么:
  • I2C\u DMACmd(I2C1,I2C\u DMAReq\u Rx,启用);
    DMA_Cmd(DMA1_信道3,启用);
    


    总线上没有发生任何事情(我使用逻辑分析器进行检查)。

    您可以使用STMCubeMx生成代码。在STMCubeF0中还有一些STM32F0的DMA示例代码。我为STM32F0发现板生成了一个I2C代码

    I2C初始化函数可以如下所示

        static void MX_I2C1_Init(void)
        {
    
          hi2c1.Instance = I2C1;
          hi2c1.Init.Timing = 0x2000090E;
          hi2c1.Init.OwnAddress1 = 0;
          hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
          hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
          hi2c1.Init.OwnAddress2 = 0;
          hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
          hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
          hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
          if (HAL_I2C_Init(&hi2c1) != HAL_OK)
          {
            Error_Handler();
          }
    
            /**Configure Analogue filter 
            */
          if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
          {
            Error_Handler();
          }
    
        }
    
    void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct;
      if(hi2c->Instance==I2C1)
      {
      /* USER CODE BEGIN I2C1_MspInit 0 */
    
      /* USER CODE END I2C1_MspInit 0 */
    
        /**I2C1 GPIO Configuration    
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* Peripheral clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
    
        /* Peripheral DMA init*/
    
        hdma_i2c1_rx.Instance = DMA1_Channel3;
        hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);
    
        hdma_i2c1_tx.Instance = DMA1_Channel2;
        hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
        hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);
    
      /* USER CODE BEGIN I2C1_MspInit 1 */
    
      /* USER CODE END I2C1_MspInit 1 */
      }
    
    }
    
    和DMA_Init函数如下

        static void MX_I2C1_Init(void)
        {
    
          hi2c1.Instance = I2C1;
          hi2c1.Init.Timing = 0x2000090E;
          hi2c1.Init.OwnAddress1 = 0;
          hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
          hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
          hi2c1.Init.OwnAddress2 = 0;
          hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
          hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
          hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
          if (HAL_I2C_Init(&hi2c1) != HAL_OK)
          {
            Error_Handler();
          }
    
            /**Configure Analogue filter 
            */
          if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
          {
            Error_Handler();
          }
    
        }
    
    void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct;
      if(hi2c->Instance==I2C1)
      {
      /* USER CODE BEGIN I2C1_MspInit 0 */
    
      /* USER CODE END I2C1_MspInit 0 */
    
        /**I2C1 GPIO Configuration    
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* Peripheral clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
    
        /* Peripheral DMA init*/
    
        hdma_i2c1_rx.Instance = DMA1_Channel3;
        hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);
    
        hdma_i2c1_tx.Instance = DMA1_Channel2;
        hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
        hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);
    
      /* USER CODE BEGIN I2C1_MspInit 1 */
    
      /* USER CODE END I2C1_MspInit 1 */
      }
    
    }
    

    初始化函数之后,您应该调用
    HAL\u DMA\u Start\u IT

    您可以使用STMCubeMx生成代码。在STMCubeF0中还有一些STM32F0的DMA示例代码。我为STM32F0发现板生成了一个I2C代码

    I2C初始化函数可以如下所示

        static void MX_I2C1_Init(void)
        {
    
          hi2c1.Instance = I2C1;
          hi2c1.Init.Timing = 0x2000090E;
          hi2c1.Init.OwnAddress1 = 0;
          hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
          hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
          hi2c1.Init.OwnAddress2 = 0;
          hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
          hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
          hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
          if (HAL_I2C_Init(&hi2c1) != HAL_OK)
          {
            Error_Handler();
          }
    
            /**Configure Analogue filter 
            */
          if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
          {
            Error_Handler();
          }
    
        }
    
    void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct;
      if(hi2c->Instance==I2C1)
      {
      /* USER CODE BEGIN I2C1_MspInit 0 */
    
      /* USER CODE END I2C1_MspInit 0 */
    
        /**I2C1 GPIO Configuration    
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* Peripheral clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
    
        /* Peripheral DMA init*/
    
        hdma_i2c1_rx.Instance = DMA1_Channel3;
        hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);
    
        hdma_i2c1_tx.Instance = DMA1_Channel2;
        hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
        hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);
    
      /* USER CODE BEGIN I2C1_MspInit 1 */
    
      /* USER CODE END I2C1_MspInit 1 */
      }
    
    }
    
    和DMA_Init函数如下

        static void MX_I2C1_Init(void)
        {
    
          hi2c1.Instance = I2C1;
          hi2c1.Init.Timing = 0x2000090E;
          hi2c1.Init.OwnAddress1 = 0;
          hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
          hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
          hi2c1.Init.OwnAddress2 = 0;
          hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
          hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
          hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
          if (HAL_I2C_Init(&hi2c1) != HAL_OK)
          {
            Error_Handler();
          }
    
            /**Configure Analogue filter 
            */
          if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
          {
            Error_Handler();
          }
    
        }
    
    void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct;
      if(hi2c->Instance==I2C1)
      {
      /* USER CODE BEGIN I2C1_MspInit 0 */
    
      /* USER CODE END I2C1_MspInit 0 */
    
        /**I2C1 GPIO Configuration    
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* Peripheral clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
    
        /* Peripheral DMA init*/
    
        hdma_i2c1_rx.Instance = DMA1_Channel3;
        hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);
    
        hdma_i2c1_tx.Instance = DMA1_Channel2;
        hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
        hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
        hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
        hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
        hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);
    
      /* USER CODE BEGIN I2C1_MspInit 1 */
    
      /* USER CODE END I2C1_MspInit 1 */
      }
    
    }
    
    在初始化函数之后,您应该调用
    HAL\u DMA\u Start\u IT