Skip to main content
GSaw
Associate III
August 22, 2022
Question

Input Capture not consistent (STM32F103C6)

  • August 22, 2022
  • 12 replies
  • 2801 views

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.

This topic has been closed for replies.

12 replies

waclawek.jan
Super User
August 22, 2022

> 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
GSawAuthor
Associate III
August 23, 2022

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
August 23, 2022

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.

GSaw
GSawAuthor
Associate III
August 23, 2022

Output of arduino frequency has been verified with oscilloscope.

What do you think could be wrong in above code?

ONadr.1
Senior III
August 23, 2022

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.

ONadr.1
Senior III
August 23, 2022

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

GSaw
GSawAuthor
Associate III
August 23, 2022

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
August 23, 2022

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.)

GSaw
GSawAuthor
Associate III
August 23, 2022

Can you explain it a little bit please? I'm unable to understand.

Thank you.