1

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

  1. 我使用 poll 方法初始化传感器,它工作正常。
  2. 我使用以下代码初始化 DMA:

`

void I2C1_DMA_Init(uint8_t *BNO055_DMA_buffer)
{
    RCC->AHBENR |= (RCC_AHBPeriph_DMA1);#
    DMA_InitTypeDef DMA_str;
    DMA_StructInit(&DMA_str);
    DMA_str.DMA_PeripheralBaseAddr = (uint32_t)I2C1->RXDR;
    DMA_str.DMA_MemoryBaseAddr = (uint32_t)BNO055_DMA_buffer;
    DMA_str.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_str.DMA_BufferSize = 32;
    DMA_str.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_str.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_str.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_str.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_str.DMA_Mode = DMA_Mode_Normal;
    DMA_str.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_str.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_str);
}

`

  1. 我使用 poll 方法设置了要读取的传感器内存的正确地址。
  2. 现在我想使用 DMA 读取 32 个字节。我必须使用I2C_TransferHandling()函数发送传感器地址吗?那么应该发送哪些其他参数呢?我在执行后的 DMA 初始化中错过了什么:

I2C_DMACmd(I2C1, I2C_DMAReq_Rx, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE);

总线上什么也没有发生(我使用逻辑分析仪检查它)。

4

1 回答 1

0

您可以使用 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();
      }

    }

DMA_Init 函数如下

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_DMA_Start_IT.

于 2017-04-01T23:16:32.910 回答