Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


Stm32F446XX , TIM2 Frequency measurement using input capture giving inconsistent captures

Hello all,
I am using Nucleo F446ze board. And trying to measure frequency from one of the GPPIO pin(PA1) . I am using waveform generator to send input signal to PA1 pin . I am using TIM2 timer which is set to input captur mode on channel 2.
I am getting very inconsistent input capture. Here are the details on my setu up
I have generate code using STM32CubeMax ,
System Clock is set to 16Mhz
The TIM2 configuraion is as below

static void MX_TIM2_Init(void){
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;
//for TIM2 - APB1 bus speed is 42MHz — no pll in thie settings ..so consider sys clock speed it 42MHz
htim2.Instance = TIM2;
htim2.Init.Prescaler =0;
htim2.Init.Period = 10000-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
{
Error_Handler();
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}

sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 15;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}

}
My GPIO config is as
static void MX_GPIO_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();

GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

Captur call back is as below

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM2) //check if the interrupt comes from TIM3
{
input_capture = __HAL_TIM_GetCompare(&htim2,TIM_CHANNEL_2);// read capture value
__HAL_TIM_SetCounter(&htim2, 0);//reset counter after input capture

}
}

So when I run main program I get very inconsistent input captur value. I see the graph in STM Studio
So for eg. If my sys clock = 16Mhz, Tim2 PRESCALAR = 0 AND PERIOD = 10000
And if I send 1Mhz signal from waveform generator to PA1 pin . I should be getting input capture at counter 16Mhz/1Mhz = 16 correct ?. But I am getting very randome values like 4 5, 100,60,30..etc etc.

Could you please help check if anything wrong with my code? Or if I am missing any settings.

Thanks a lot in advanced.

Hi

1MHz is far to fast.

That would mean 1us for the interrupt handler (the callback is only a small part of it) plus overhead at only 16 MHz clock tsss tsss.

Try 50 kHz.

Dieter

Thanks a lot Dieter. It does work for 50Khz and lower frequency.

I want to read/measuer frequency upto 5Mhz. I tried to set up 180Mhz sys clock and APB1 90Mhz. i can read the inpucature concistenly upto 18Khz ..after that i is again inconsistent.
Could you please guide how could i measuer frequency upto 5Mhz and what should be the sys clock ? I think i cant go beyond 180Mhz with Nucleo F446Ze.

I have attached my clock configuration image

Thanks,
Ash


Hi

Use external clock for a timer and let it count pulses.
Read AN4776 to get the idea.

Dieter

thaks for the respond. I set it up TIM2 to external clock and ETR mode 1 and trigger cource is on rising edge.

I read the counter value in the main loop . So this is the count at rising pulse I beleive. What should be the better option to read this pulses to calculate frequency?

Should I use another timer or DMA? I am not sure how to get those pulses count to measuer frequency. I am searching on web but havent found any example that usese two timer to measure freq.

Could you please point me to any example if you know one?

Thanks,
A