STMicroelectronics / STM32CubeG4

STM32Cube MCU Full Package for the STM32G4 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
Other
182 stars 98 forks source link

TIM_InputCapture HAL Example uwDiffCapture always the same value when changing APB2 prescaler #14

Closed VictorTagayun closed 3 years ago

VictorTagayun commented 3 years ago

Hello Newbie here. I was testing HAL example "TIM_InputCapture" using TIM1. To get the value of input freq, it uses this formula:

uwFrequency = HAL_RCC_GetPCLK2Freq() / uwDiffCapture;

As I was changing the APB2 Prescaler in CubeMX, the value uwDiffCapture still remains the same. That means, uwFrequency will change because HAL_RCC_GetPCLK2Freq() changes. I also add this to check the new APB2 freq as I change it in CubeMX:

PCLK2Freq = HAL_RCC_GetPCLK2Freq();

Should it be using APB1 freq instead for TIM1?

ASELSTM commented 3 years ago

Hi @VictorTagayun,

First we would like to thank you for your contribution.

The uwDiffCapture value is the difference between two consecutive TIM captures and it's an important parameter to measure the injected signal frequency. In fact, uwDiffCapture value changes according to the frequency of the injected signal and the value of the APB2 prescaler.

Unfortunately, we couldn't reproduce the issue described above. In order to have more information about the problem may i ask you some questions :

  1. Which value of uwDiffCapture are you getting when keeping the initial APB2 prescaler value (RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;) ?

  2. What is the frequency of the injected signal ?

  3. Did you make sure that you are injecting the signal in the pin PA9 which corresponds to channel 2 of TIM1 ?

Please let us know your feedback so that we can help you.

Best regards,

VictorTagayun commented 3 years ago

Hi,

When you change to

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

or any divider,

the value of HAL_RCC_GetPCLK2Freq() will become different

but the value of

uwDiffCapture

will remain the same because the output of APB2 will be multiplied back again.

image

ASELSTM commented 3 years ago

Hi @VictorTagayun,

Indeed, for a prescaler equal to RCC_HCLK_DIV2 the value of uwDiffCapture is similar to the one obtained for a prescaler equal to RCC_HCLK_DIV1, given that the output of the APB2 is multiplied by 2 for prescalers other than RCC_HCLK_DIV1. However, uwDiffCapture value changes for the rest of APB2 prescaler values.

Actually, uwDiffCapture value is the difference between two consecutive TIM captures and it corresponds to the number of timer clock ticks. This difference is then translated into a physical value according to TIMx_CLK based on this relation :

                                       uwFrequency = TIMx_CLK / uwDiffCapture

In fact, APB2 prescaler allows to define the value of the timer clock frequency. In this example, since the APB2 prescaler is equal to 1 so TIMx_CLK corresponds to HAL_RCC_GetPCLK2Freq().

Thus, the APB2 prescaler has an impact on the TIM clock frequency, that has in turn an impact on uwDiffCapture value which then vary according to the APB2 prescaler.

Hope I have answered your question.

With regards,

VictorTagayun commented 3 years ago

Below is the original firmware with an added variable uwHAL_RCC_PCLK2Freq on line 303

image

with an input waveform of around 30k and

image

with APB2 Prescaler of 1.

image

==============

Then I change the Prescaler 2 and keep the same waveform

image

Now I have a different frequency.

image

I change to a different prescaler of 4.

image

image

ASELSTM commented 3 years ago

Hi @VictorTagayun,

Actually, the complete expression to compute the input frequency uwFrequency is as detailed in the 2.3 Timer input capture mode section of the AN4013 :

Period = Capture(1) /(TIMx_CLK (PSC+1)(ICxPSC)*polarity_index(2))

This expression has been simplified and made adapted to our example to become as below :

                                                uwFrequency = TIMx_CLK / uwDiffCapture

In the other hand, according to the reference manual the TIMx_clk can be as follows :

7.2.13 Timer clock

The timer clock frequencies are automatically defined by hardware. There are two cases:

  1. If the APB prescaler equals 1, the timer clock frequencies are set to the same frequency as that of the APB domain.
  2. Otherwise, they are set to twice (×2) the frequency of the APB domain.

Thus, when APBx prescaler is equal to 1 TIMx_CLK = PCLKx Frequency otherwise *TIMx_CLK = 2 PCLKx Frequency**.

In this example the APB2 prescaler is equal to 1, then TIMx_CLK = PCLK2 Frequency which leads to the expression used in the example :

                                        uwFrequency = HAL_RCC_GetPCLK2Freq() / uwDiffCapture

However, if APB2 prescaler is different from 1 then *TIMx_CLK = 2 PCLK2 Frequency**, so in this case the expression should be updated as following in order to have right frequencies :

                                       uwFrequency = 2 x HAL_RCC_GetPCLK2Freq() / uwDiffCapture

Hence, the expression used in this example has been simplified and adapted to our use case and to the configuration of this one. Therefore for a different clock configuration the expression must also be updated in order to get the right values.

With regards,

VictorTagayun commented 3 years ago

Thank you for the information. Is it possible to update this feature in the next release so that it will be done automatically and calculated automatically in the initialization? For a newbie like me, it would be hard to catch. Or make another function to determine APB2 timer clocks separated from APB2 peripheral clocks.

ASELSTM commented 3 years ago

Hi @VictorTagayun,

This example allows explain how to use the TIM peripheral to measure an external signal frequency. Therefore, the whole configuration and the used input frequency calculation expression are adapted to this particular use case.

Unfortunately, we can't separate the definition of the APB2 timer clocks from the APB2 peripheral clocks since it is closely related. Indeed, the APB2 timer clocks is automatically defined by hardware. It can then be set to the same frequency as that of the APB2 peripheral clocks. Otherwise, it is set to twice (×2) the frequency of the APB2 peripheral clocks.

Please allow me then to close this thread. Thank you for your comprehension and thank you again for your contribution.

With regards