AnsweredAssumed Answered

STM32F746, ADC

Question asked by s.boris on Jul 25, 2016
Latest reply on Sep 1, 2016 by Dowell.Sherman
Hello, I have a few question about ADC. I want to drive ADC through DMA. The problem is that when I choose more than 6 samples I cannot enter in HAL_ADC_ConvCpltCallback. My second question is how to set the time to fill the array

static void hw_adc_init_channel(U8 adc, U8 channel)
{
    GPIO_InitTypeDef gpio_init;                 // Init gpio at analog mode
 
    //Enables the AHB1 peripheral clock
    __HAL_RCC_GPIOF_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
 
    gpio_init.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; // Set analog input for adc 3, channel 4,5,6,7,8
    gpio_init.Mode = GPIO_MODE_ANALOG;
    gpio_init.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOF, &gpio_init);
 
    gpio_init.Pin = GPIO_PIN_0; // Set analog input for adc 3, channel 0
    gpio_init.Mode = GPIO_MODE_ANALOG;
    gpio_init.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &gpio_init);
 
 
}
 
/*****************************************************************************/
/*****************************************************************************/
static void hw_adc_dma_init(ADC_HandleTypeDef* hadc3)
{
    static DMA_HandleTypeDef hdma;
 
    __HAL_RCC_DMA2_CLK_ENABLE();
 
    hdma.Instance = DMA2_Stream0;
    hdma.Init.Channel  = DMA_CHANNEL_2;
    hdma.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma.Init.MemInc = DMA_MINC_ENABLE;
    hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma.Init.Mode = DMA_CIRCULAR;
    hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
    hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
    hdma.Init.MemBurst = DMA_MBURST_SINGLE;
    hdma.Init.PeriphBurst = DMA_PBURST_SINGLE;
 
    HAL_DMA_Init(&hdma);
 
    __HAL_LINKDMA(hadc3, DMA_Handle, hdma); // Associate init DMA handle to ADC DMA
 
    // Set DMA priority
    // When 2 interrupts have same preemption priority, then he one who has higher sub priority will be execute first.
    // If both interrupts both have same preemption priority and sub priority, the one comes first will be execute first
    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
 
/*****************************************************************************/
/*****************************************************************************/
void hw_adc_3_init(ADC_INIT* _adc3)
{
    ADC_ChannelConfTypeDef adc_channel_conf;    // Config which channel will be active
 
    // Enable the High Speed APB (APB2) peripheral clock for ADC3
    __HAL_RCC_ADC3_CLK_ENABLE();
 
    // Init ADC3 registers
    hadc3.Instance = ADC3;
    hadc3.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;           // ADC prescaler, its common to all ADCs. PLCK div
    hadc3.Init.ContinuousConvMode = ENABLE;
    hadc3.Init.DMAContinuousRequests = ENABLE;                          // DMA continuous mode is enable
    hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;                         // Set data alignment
    hadc3.Init.DiscontinuousConvMode = DISABLE;                         // Discontinuous mode is enabled
    hadc3.Init.NbrOfDiscConversion   = 0;
    hadc3.Init.EOCSelection = DISABLE;
    hadc3.Init.ExternalTrigConv = ADC_CR2_EXTSEL;
    hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc3.Init.NbrOfConversion = adc_3->adc_channel_activation;         // Select how many channels will be scanned
    hadc3.Init.Resolution = ADC_RESOLUTION_8B;                          // Set resolution of the conversion of ADC. 12 bit -> minimum 15 ADC clock cycles
    hadc3.Init.ScanConvMode = DISABLE;                                  // ADC read only 1 channel, that with rank = 1 ..... (ADC can read with all 8 channel. Injected mode)
 
    HAL_ADC_Init(&hadc3);
 
    // Sequence of channel read
    adc_channel_conf.Channel = ADC_CHANNEL_0;
    adc_channel_conf.Rank = 1;                                          // Specifies the rank in the regular group sequencer
    adc_channel_conf.SamplingTime = adc_3->adc_sample_frequency;        // Sample time individually for each channel
    HAL_ADC_ConfigChannel(&hadc3, &adc_channel_conf);
 
 
    adc_3 = _adc3;
 
    hw_adc_init_channel(3, 1);
    hw_adc_dma_init(&hadc3);
 
}
 
/*****************************************************************************/
/*****************************************************************************/
void hw_adc_3_start()
{
    HAL_ADC_Start_DMA(&hadc3, (U32 *)&adc_convert_value[0], 20); // Length: The length of data to be transferred from ADC peripheral to memory.
}
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc3)
{
    BSP_LED_Toggle(LED1);
    adc_convert_value[0] = hadc3->Instance->DR;
}
 
/*****************************************************************************/
/*****************************************************************************/
void DMA2_Stream0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(hadc3.DMA_Handle);
}

Outcomes