2019-07-11 11:23 AM
Hi, I'm trying to generate a 500KHz counter on TIM1 on the STM32F7 to trigger an ADC conversion and I'm currently having issues as it seems to top out at 360KHz. I'm toggling a GPIO pin with a scope to the input and simply changing the Period on the timer to see what's happening.
Here's my current code:
With a period of 539, I get 200Khz as expected:
With a period of 239, I get around 300kHz
With a peroid of 215, I get around 330 kHz instead of the expected 500Khz.
With a period of 108, I get a frequency of around 369Khz:
I'm using CubeMX to generate my project files and I initialise my timer like this:
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 108;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_OC1REF;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
}
I start the timer in interrupt mode:
if(HAL_TIM_Base_Start_IT(&htim1) != HAL_OK)
{
Error_Handler();
}
I then toggle a GPIO Pin When Period has elapsed:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1)
{
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);
}
}
I've tried changing the speed of the GPIO pin:
/*Configure GPIO pin : PG6 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
but this doesn't seem to make any difference. Can someone please help shed some light on this?
2019-07-11 11:58 AM
The TIM provide direct methods to toggling signals and triggering ADC, suggest you use those rather than determine the saturation point of the core with interrupt entry/exit and multi-layered overhead added by HAL.
2019-07-11 01:50 PM
Thanks for the reply, Clive. That's currently what I'm doing. I'm using ADC_EXTERNALTRIGCONV_T1_TRGO on Timer 1 to trigger a conversion on the ADC but I would like to reliably determine what this frequency is to know my sampling rate. I guess, I could just compute the FFT and do a back calculation to determine the sampling frequency. What is the best way to check the ADC is starting a conversion on the correct timings without using interrupts? Would toggling a GPIO on the
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
work as well?