My observed sampling rate is much lower than expected and I cannot understand why.
I have the discovery STM32L053C6 Discovery board and I want to use ADCs sampling. I started from the example STM32L053C8-Discovery/Examples/ADC/ADC_RegularConversion_Interrupt/ from STM32CubeL0. In main, I have the following ADC initialisation:
AdcHandle.Instance = ADC1;
AdcHandle.Init.OversamplingMode = DISABLE;
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
AdcHandle.Init.LowPowerAutoPowerOff = DISABLE;
AdcHandle.Init.LowPowerFrequencyMode = DISABLE;
AdcHandle.Init.LowPowerAutoWait = DISABLE;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
AdcHandle.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.ContinuousConvMode = ENABLE;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
AdcHandle.Init.DMAContinuousRequests = DISABLE;
/* Initialize ADC peripheral according to the passed parameters */
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
/* ### - 2 - Start calibration ############################################ */
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler();
}
/* ### - 3 - Channel configuration ######################################## */
/* Select Channel 0 to be converted */
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* ### - 4 - Start conversion in Interrupt mode ########################### */
if (HAL_ADC_Start_IT(&AdcHandle) != HAL_OK)
{
Error_Handler();
}
And the call back as
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
/* Get the converted value of regular channel */
uwADCxConvertedValue = HAL_ADC_GetValue(AdcHandle);
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4);
}
I have the system clocks defined as
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
}
And the MSP init as
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO clock ****************************************/
__HAL_RCC_GPIOA_CLK_ENABLE();
/* ADC1 Periph clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
/*##- 2- Configure peripheral GPIO #########################################*/
/* ADC3 Channel8 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*##-3- Configure the NVIC #################################################*/
/* NVIC configuration for ADC EOC interrupt */
HAL_NVIC_SetPriority(ADC1_COMP_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_COMP_IRQn);
}
What that configuration, I would expect the conversion time to be at about 1.3µs. However, the PB4 toggles every 11µs. Which means that I get a sampling rate slightly above 80kS/s.
The manual mentions sampling rates above 1MS/s. I am sure that I am missing something, but cannot see what that would be. Or should I use DMA modes to get to higher sampling rates?
HAL_ADC_IRQHandler()
and maybe add aHAL_GPIO_WritePin(... GPIO_PIN_SET)
at the start andHAL_GPIO_WritePin(... GPIO_PIN_RESET)
at the end to see how much time it's taking. \$\endgroup\$