2017-04-01 422 views
0

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

  1. 我使用轮询方法初始化传感器,它工作正常。
  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); 
} 

`

  • 我设置传感器存储器的正确地址可从使用读轮询方法。
  • 现在我想用DMA读取32个字节。我必须使用I2C_TransferHandling()函数发送传感器地址吗?应该发送什么其他参数呢?有什么我错过了DMA初始化的是,执行后:
  • I2C_DMACmd(I2C1, I2C_DMAReq_Rx, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE);

    没有公交车(我检查它使用逻辑分析仪)上发生的。

    回答

    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初始化函数后。