Question
STM32F746, ADC
Posted on July 25, 2016 at 12:05
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);
}
#adc #stm32f746