cancel
Showing results for 
Search instead for 
Did you mean: 

Input Capture not consistent (STM32F103C6)

GSaw
Associate II

I'm using STM32F103C6T6 to capture input frequency configured on TIM2, Channel 1 (A0).

I'm generating 1KHz frequency from Arduino Uno (using tone(Pin, 1000) function) connected to STM32 Pin PA0.

Timer Configurations of STM32:

Prescaler set to : 10000-1

ARR set to : 7200-1

Code is as below

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim)
{
    if(gu8_State == IDLE)
    {
        gu32_T1 =  HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_1);
        gu8_State = DONE;
    }
    else if(gu8_State == DONE)
    {
        gu32_T2 = HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_1);
        gu32_Ticks = gu32_T2 - gu32_T1;
        gu32_Freq = (HAL_RCC_GetPCLK2Freq()/gu32_Ticks * 10000);
        if(gu32_Freq != 0)
        {
          sprintf(gu8_MSG, "Frequency = %lu Hz\n\r", gu32_Freq);
          HAL_UART_Transmit(&huart1, gu8_MSG, sizeof(gu8_MSG), 100);
        }
        gu8_State = IDLE;
    }
}

When Frequency in Arduino is set as : 1000, Input frequency is calculated as 1028.

When Frequency in Arduino is set as : 500, Input frequency is calculated as 514.

When Frequency in Arduino is set as : 100, Input frequency is calculated as 100.

When Frequency in Arduino is set as : 200, Input frequency is calculated as 200.

and likewise.

I'm unable to understand what is incorrect in above code and why is this happening for frequencies (500 and 1000) and not others.

Please help. Thank you.

12 REPLIES 12

> gu32_Freq = (HAL_RCC_GetPCLK2Freq()/gu32_Ticks * 10000);

Please copypaste code you've actually used.

Print gu32_Ticks too, it will help in understanding why are your results different from your expectation.

> ARR set to : 7200-1

Why?

JW

GSaw
Associate II

Since the required delay is 1 second,

using formula (PSC+1)*(ARR+1) = TIMclk * Updatefrequency

(PSC+1)*(ARR+1) = 72MHz * 1

when PSC = (10000-1)

ARR will be (7200 - 1).

Therefore ARR = (7200 - 1) is used.

Code is exactly same as above except new print statements are added.

Please refer to the screenshots below.

Thanks.

Image 1 : Arduino frequency : 900 , stm32 captured frequency 900 

0693W00000QOHJRQA5.png 

Image 2 : Arduino frequency : 1000 , stm32 captured frequency 1028

0693W00000QOHJWQA5.png 

Image 3 : Arduino frequency : 500 , stm32 captured frequency 514/480

0693W00000QOHJbQAP.png 

Image 4 : Arduino frequency : 5000 , stm32 captured frequency 3600/7200

0693W00000QOHJgQAP.png

ONadr.1
Senior III

I would recommend measuring the frequency output of the arduino with a frequency meter to rule out that the output from the arduino is not correct.

Output of arduino frequency has been verified with oscilloscope.

What do you think could be wrong in above code?

Im not sure (I dont know types and values), but there is a potential problem in

gu32_Freq = (HAL_RCC_GetPCLK2Freq()/gu32_Ticks * 10000);

There shoul be great diference betwen division first and multiple then, or multiple first and division then. Try to use brackets to be sure, that the order of operation is correct.

GSaw
Associate II

Okay will do that and let you know. Thank you!

Edit:

Tried (HAL_RCC_GetPCLK2Freq()/(gu32_Ticks * (10000)));

Still same result.

ONadr.1
Senior III

What types are those varables? What values they have for 1000Hz?

https://deepbluembedded.com/stm32-input-capture-frequency-measurement-example-timer-input-capture-mode/

I've referred to this link. (Removed overflow calculation and a few things changed)

ONadr.1
Senior III

It's clear now. You have too little discernment. For values of gu32_Ticks 7,8,9 the calculated output frequency is 1028, 900, 800. There is nothing in between. (You cant get value 1000, because all values are integral.)