2017-04-01 2 views
0

J'essaie d'obtenir des données d'un capteur I2C (BNO055) en utilisant DMA, mais je ne peux pas démarrer la transmission DMA. J'ai trouvé beaucoup d'exemples pour les microcontrôleurs F1, F3 et F4 STM, mais rien d'utile pour F0. Ce que je fais est:STM32F0 découverte I2C transfert en utilisant DMA

  1. J'initialize capteur en utilisant la méthode de sondage et il fonctionne très bien.
  2. I initialiser DMA en utilisant le code suivant:

`

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. I Régler l'adresse correcte de la mémoire de capteur devant être lu à partir de l'utilisation méthode d'interrogation
  2. Maintenant, je voudrais lire 32 octets en utilisant DMA. Dois-je envoyer une adresse de capteur en utilisant la fonction I2C_TransferHandling()? Quels autres paramètres devraient être envoyés alors? Qu'est-ce que j'ai manqué à l'initialisation du DMA après l'exécution:

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

Rien ne se passe sur le bus (je vérifie à l'aide d'un analyseur logique).

Répondre

0

Vous pouvez générer du code à l'aide de STMCubeMx. Il existe également des exemples de codes DMA pour STM32F0 dans STMCubeF0. J'ai généré un code I2C pour la carte de découverte STM32F0.

Votre fonction init I2C peut être aussi suivre

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(); 
     } 

    } 

et la fonction DMA_Init que suivre

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 */ 
    } 

} 

Après des fonctions d'initialisation, vous devez appeler HAL_DMA_Start_IT.