This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

7 Channel ADC with DMA

Hi;

I want to read 7 channel ADC value with DMA.
Firstly Init ADC Settings;

void ADC_INIT(void)
{
          //ADC_ChannelConfTypeDef sConfig;


  hadc.Instance                   = ADC1;
  hadc.Init.ClockPrescaler        = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution            = ADC_RESOLUTION_8B; // 12 bit yap alican !!!!!
  hadc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD; /* Sequencer will convert the number of channels configured below, successively from the lowest to the highest channel number */
  hadc.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait      = DISABLE;
  hadc.Init.LowPowerAutoPowerOff  = DISABLE;
  hadc.Init.ContinuousConvMode    = DISABLE; /* Continuous mode disabled to have only 1 rank converted at each conversion trig, and because discontinuous mode is enabled */

  hadc.Init.DiscontinuousConvMode = ENABLE;                                                                                     /* Sequencer of regular group will convert the sequence in several sub-divided sequences */

  hadc.Init.ExternalTrigConv      = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */

  hadc.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trig of conversion by software start (no external event) */


  hadc.Init.DMAContinuousRequests = ENABLE;                                                                                             /* ADC-DMA continuous requests to match with DMA configured in circular mode */

  hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc.Init.SamplingTimeCommon    = ADC_SAMPLETIME_239CYCLES_5;


  HAL_ADC_Init(&hadc);

     sConfig.Rank         = 0;
     sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5 ;
     sConfig.Channel = REF_1_5_Volt_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L1_voltage_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L2_voltage_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L3_voltage_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L1_curent_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L2_curent_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig);

     sConfig.Channel = L3_curent_Pin;
     HAL_ADC_ConfigChannel(&hadc, &sConfig)

}

void ADC_DMA_INIT(void)
{
  /* DMA controller clock enable */
  __DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}


void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{

  if(hadc->Instance==ADC1)
  {

  GPIO_InitTypeDef          GPIO_InitStruct;
  RCC_OscInitTypeDef        RCC_OscInitStructure;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/

  /* Enable clock of GPIO associated to the peripheral channels */
    __HAL_RCC_GPIOA_CLK_ENABLE();

  /* Enable clock of ADCx peripheral */
         __HAL_RCC_ADC1_CLK_ENABLE();

  /* Note: In case of usage of asynchronous clock derived from ADC dedicated  */
  /*       HSI RC oscillator 14MHz, with ADC setting                          */
  /*       "AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1",            */
  /*       the clock source has to be enabled at RCC top level using function */
  /*       "HAL_RCC_OscConfig()" (see comments in stm32l1_hal_adc.c header)   */

  /* Enable asynchronous clock source of ADCx */
  /* (place oscillator HSI14 under control of the ADC) */

  HAL_RCC_GetOscConfig(&RCC_OscInitStructure);
  RCC_OscInitStructure.OscillatorType            = RCC_OSCILLATORTYPE_HSI14;
  RCC_OscInitStructure.HSI14CalibrationValue     = RCC_HSI14CALIBRATION_DEFAULT;
  RCC_OscInitStructure.HSI14State                = RCC_HSI14_ADC_CONTROL;
  HAL_RCC_OscConfig(&RCC_OscInitStructure);

  /* Enable clock of DMA associated to the peripheral */
        __HAL_RCC_DMA1_CLK_ENABLE();

 /*##- 2- Configure peripheral GPIO #########################*/

    GPIO_InitStruct.Pin  = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*##-3- Configure the DMA ##################################################*/

  /* Configure DMA parameters */
  hdma_adc.Instance = DMA1_Channel1;

  hdma_adc.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  hdma_adc.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_adc.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;   /* Transfer from ADC by half-word to match with ADC configuration: ADC resolution 10 or 12 bits */

  hdma_adc.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;   /* Transfer to memory by half-word to match with buffer variable type: half-word */

  hdma_adc.Init.Mode                = DMA_CIRCULAR; /* DMA in circular mode to match with ADC configuration: DMA continuous requests */

  hdma_adc.Init.Priority            = DMA_PRIORITY_HIGH;

  /* Deinitialize  & Initialize the DMA for new transfer */

  HAL_DMA_DeInit(&hdma_adc);
  HAL_DMA_Init(&hdma_adc);

  /* Associate the initialized DMA handle to the ADC handle */
  __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc);

  }

}



then i set Timer every 1 ms overflow and call interrupt

in main function :
ADC init

/* ADC Start with DMA */
HAL_ADC_Start_DMA(&hadc,(uint32_t *)ADC_Converted_Values,7);

then i call HAL_ADC_Start(&hadc); function every 1 ms thanks to TIMER 3

This is my code but I dont see ADC value if i use 7 channel so if i use Converted_Values Buffer size is 7 i dont measure ADC value and system is lock. but i set 4 channel i measure value.

what can i measure 7 channel with DMA

Thanks all of things
Alican

Parents
  • You doing wrong in declaring the dma buffer variable. You need to send the start address of the dma buffer.
    HAL_ADC_Start_DMA(&hadc,(uint32_t *)ADC_Converted_Values,7);

    You shoud do like this: HAL_ADC_Start_DMA(&hadc,(uint32_t *)&ADC_Converted_Values,7);

    Well, the adc values are limited to 8bit and the dma buffer is declared uint32_t. This could not work properly.

    In regular curcumstance, i use an array that was extend by two more element - the first and last element of the array
    is filled by a predefined value like "0xAA" and "0xBB". If the elements where overwritten by dma, something went wrong
    an could be detected by a simple compare statement.

    example:
    // Regular mode

    #define NumOfAdcChan 7 // num of scanned ADC channels
    #define DMABUFSIZE NumOfAdcChan + 2 // total elements of DMABuf-Array
    volatile uint16_t AdcDmaBuf[DMABUFSIZE] = {0xAA, 0, 0, 0, 0, 0, 0xBB};
    ...

    HAL_ADC_Start_DMA(&hadc,(uint32_t *)&AdcDmaBuf[1], NumOfAdcChan );

    I had started to use HAL since a couple of weeks and used stdlib previously. The structures and the handling of the HAL
    are different compare by the StdLib, but this are more extended and covers more mcu variants. It's just a different api,
    not less not more.

    Hope this helps anyone.

Reply
  • You doing wrong in declaring the dma buffer variable. You need to send the start address of the dma buffer.
    HAL_ADC_Start_DMA(&hadc,(uint32_t *)ADC_Converted_Values,7);

    You shoud do like this: HAL_ADC_Start_DMA(&hadc,(uint32_t *)&ADC_Converted_Values,7);

    Well, the adc values are limited to 8bit and the dma buffer is declared uint32_t. This could not work properly.

    In regular curcumstance, i use an array that was extend by two more element - the first and last element of the array
    is filled by a predefined value like "0xAA" and "0xBB". If the elements where overwritten by dma, something went wrong
    an could be detected by a simple compare statement.

    example:
    // Regular mode

    #define NumOfAdcChan 7 // num of scanned ADC channels
    #define DMABUFSIZE NumOfAdcChan + 2 // total elements of DMABuf-Array
    volatile uint16_t AdcDmaBuf[DMABUFSIZE] = {0xAA, 0, 0, 0, 0, 0, 0xBB};
    ...

    HAL_ADC_Start_DMA(&hadc,(uint32_t *)&AdcDmaBuf[1], NumOfAdcChan );

    I had started to use HAL since a couple of weeks and used stdlib previously. The structures and the handling of the HAL
    are different compare by the StdLib, but this are more extended and covers more mcu variants. It's just a different api,
    not less not more.

    Hope this helps anyone.

Children