Skip to main content
Raider E
Associate III
December 15, 2016
Question

ADC cannot read multiple channels ..

  • December 15, 2016
  • 9 replies
  • 1810 views
Posted on December 16, 2016 at 00:08

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.

    9 replies

    Seb
    ST Employee
    December 16, 2016
    Posted on December 16, 2016 at 01:00

    How about using ADC Injected Channels? They have a Data Register per channel ==> no DMA needed ==> Simpler?

    Raider E
    Raider EAuthor
    Associate III
    December 16, 2016
    Posted on December 16, 2016 at 01:07

    Hi  Seb,

    thank you for your reply, i am still in my early stages learning and not sure how the injected channels mode work. any example code for the multi channels using an injected channel mode I can start with? many thanks

    Seb
    ST Employee
    December 16, 2016
    Posted on December 16, 2016 at 04:01

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6qr&d=%2Fa%2F0X0000000bwk%2FyASKeBOw_ZnyUKbhWthXE32VRcUnAfQI3KzzJqkZrUk&asPdf=false
    Raider E
    Raider EAuthor
    Associate III
    December 16, 2016
    Posted on December 16, 2016 at 01:04

    Ok now I diabled DMA and wrote the following :

    HAL_ADC_Start(&hadc1);

    HAL_ADC_PollForConversion(&hadc1,1000);

    value[0]= HAL_ADC_GetValue(&hadc1);

    value[1]= HAL_ADC_GetValue(&hadc1);

    HAL_ADC_Stop(&hadc1);

    sConfig.Channel = ADC_CHANNEL_2;

    sConfig.Rank = 2;

    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

    {

    Error_Handler();

    }

    sConfig.Channel = ADC_CHANNEL_0;

    sConfig.Rank = 1;

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

    {

    Error_Handler();

    }

    and it reads two channels. However, it reads OK for few seconds and then the the values swap for a second and then come back, so value[0] becomes value[1] and vice versa and only happes for a second then its fine. Further why it reads 

    ADC_CHANNEL_2 in value[0], I though the one with the lower rank number will be read first, is that correct?

    Raider E
    Raider EAuthor
    Associate III
    December 19, 2016
    Posted on December 19, 2016 at 01:29

    Hi again,

    I am trying to use DMA now as its more straightforward but still not working for me. Ain[0 below is only reading some weired voltage .17 instead of 1.3V and Ain[1] reads nothing stays 0.  can you please have a look and let me know what might have gone wrong:

    #include 'stm32f7xx_hal.h'

    #include 'global.h'

    #define NO_OF_CHANNELS 2

    #define NO_OF_ADCs 1

    //Note that Interrupts for all peripherals are located in the xxx_msp file and xxx_it

    void MX_ADC1_Init(void);

    void MX_DMA_Init(void);

    void readAins(void);

    void MX_DMA_Init(void)

    {

    /* DMA controller clock enable */

    __HAL_RCC_DMA2_CLK_ENABLE();

    /* DMA interrupt init */

    /* DMA2_Stream0_IRQn interrupt configuration */

    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

    }

    void MX_ADC1_Init(void)

    {

    ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

    */

    hadc1.Instance = ADC1;

    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;

    hadc1.Init.Resolution = ADC_RESOLUTION_12B;

    hadc1.Init.ScanConvMode = ENABLE;

    hadc1.Init.ContinuousConvMode = DISABLE;

    hadc1.Init.DiscontinuousConvMode = DISABLE;

    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

    hadc1.Init.NbrOfConversion = 2;

    hadc1.Init.DMAContinuousRequests = ENABLE;

    hadc1.Init.EOCSelection = DISABLE;

    HAL_ADC_Init(&hadc1);

    // if (HAL_ADC_Init(&hadc1) != HAL_OK)

    // {

    // Error_Handler();

    // }

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

    */

    sConfig.Channel = ADC_CHANNEL_2;

    sConfig.Rank = 2;

    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;

    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

    {

    Error_Handler();

    }

    sConfig.Channel = ADC_CHANNEL_0;

    sConfig.Rank = 1;

    HAL_ADC_ConfigChannel(&hadc1, &sConfig);

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

    {

    Error_Handler();

    }

    // All Channels has to be preconfgured here as above

    }

    void readAins(void){

    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&value2, 2);

    Ain[0]=value2[0];

    Ain[1]=value2[1];

    }

    msp file:

    void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)

    {

    GPIO_InitTypeDef GPIO_InitStruct;

    if(hadc->Instance==ADC1)

    {

    /* USER CODE BEGIN ADC1_MspInit 0 */

    /* USER CODE END ADC1_MspInit 0 */

    /* Peripheral clock enable */

    __HAL_RCC_ADC1_CLK_ENABLE();

    /**ADC1 GPIO Configuration

    PA0/WKUP ------> ADC1_IN0

    PA1 ------> ADC1_IN1

    */

    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;

    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USER CODE BEGIN ADC1_MspInit 1 */

    /* USER CODE END ADC1_MspInit 1 */

    /* Peripheral DMA init*/

    hdma_adc1.Instance = DMA2_Stream0;

    hdma_adc1.Init.Channel = DMA_CHANNEL_0;

    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;

    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;

    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;

    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

    hdma_adc1.Init.Mode = DMA_CIRCULAR;

    hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;

    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

    hdma_adc1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;

    hdma_adc1.Init.MemBurst = DMA_MBURST_SINGLE;

    hdma_adc1.Init.PeriphBurst = DMA_PBURST_SINGLE;

    HAL_DMA_Init(&hdma_adc1);

    // if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)

    // {

    // Error_Handler();

    // }

    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

    }

    }

    void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)

    {

    if(hadc->Instance==ADC1)

    {

    /* USER CODE BEGIN ADC1_MspDeInit 0 */

    /* USER CODE END ADC1_MspDeInit 0 */

    /* Peripheral clock disable */

    __HAL_RCC_ADC1_CLK_DISABLE();

    /**ADC1 GPIO Configuration

    PA0/WKUP ------> ADC1_IN0

    PA1 ------> ADC1_IN1

    */

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1);

    /* Peripheral DMA DeInit*/

    HAL_DMA_DeInit(hadc->DMA_Handle);

    // __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

    }

    /* USER CODE BEGIN ADC1_MspDeInit 1 */

    /* USER CODE END ADC1_MspDeInit 1 */

    }

    T J
    Senior III
    January 22, 2017
    Posted on January 22, 2017 at 08:10

    Hi, did you get it working ?