Showing results for 
Search instead for 
Did you mean: 

Frequency measurement with COMP1 and TIM2 NUCLEO-144 H723ZG board

Associate III

I have NUCLEO-144 H723ZG board. 

I created a frequency meter app for the NUCLEO board, but the quality of the frequency measurement a sinusoidal voltage is very poor. I have a generated 720mV RMS, 126.7Hz signal between 0 and +2.5V (max) biased to +1.25V. On scope, the frequency meter connected to the output of the COMP1 shows 126.700x, the 4th digit is 1 or 0. The NUCLEO board measures almost 1Hz less than the frequency meter on scope (I checked it with a real frequency meter and the scope value is right).

My other problem is that the minimum value of the frequency = 125.451, the maximum value = 125.9264Hz, the average = 125.7246 and the standard deviation = 0.0775Hz. I could not measure the frequency as good as a simple scope.


I enabled COM1 comparator. I connected the input sine voltage to the positive input (COMP1_INP) and I connected the negative input (COMP1_INN) to the +1.25V reference voltage to which the input signal is biased. With setting the COMP1 speed to “COMP_POWERMODE_HIGHSPEED�? I got terrible output voltage. Both edges of the output are bounced (200-250 spikes) at least 1-3us. Then I set the COMP1 speed to “COMP_POWERMODE_MEDIUMSPEED�? and I got only a couple of spikes. Then I set the COMP1 speed to “COMP_POWERMODE_ULTRALOWPOWER�? and I got no spikes. The hysteresis was always set to “COMP_HYSTERESIS_HIGH�?. Why? Can somebody explain it?

I connected the comparator output with a wire to the Capture Channel 1 input of the 32-bit TIM2. The timer runs on 275MHz (3.636ns) as a simple up counter, with ARR = 0xFFFFFFFF, Prescaler = 0. It is started with HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);

When rising edge of comparator detected on the Capture CHN1 input of TIM2 then TIM2 captures the value its 32-bit counter and calls the HAL_TIM_IC_CaptureCallback(). I read the capture 1 register and store the value in last period count if this is the first interrupt. It this is not the first interrupt then I subtract the current count from the last count (I also update the last value register to the current one). This is the period time in counts. I set a flag in the callback function to signal that I measured a new period time count. In the main() loop when this is true then I simply divide the 275MHz TIM2 clock with the period count. This is my measured frequency. Because I don’t have LCD and send it via serial port to the terminal APP of my notebook. The application runs continuously.

Even though this is a simple period time measurement I cannot not answer the following two questions.

  1. Why do I have so poor quality of the measurement? (See attached log picture)
  2. Why does the calculated frequency 1Hz less than the input signal frequency? This around 1Hz inaccuracy is constant. I can use any frequency it measures 1 Hz less. XTAL frequency problem? Or this is the side effect 2MHz * 275 with the PLL1?

Can somebody help. (Sample app for NUCLEO-144 H723ZG board is available if needed)

Thanks for any help, any idea.



> But the 25MHz/3 = 8.333333MHz cannot be set only to #define HSE_VALUE (8333333UL) (in the stm32h7xx_hal_conf.h file) so all the HAL_RCC_GetXXXClock() functions return a bit faulty frequencies.

Then don't use Cube/HAL functions to determine the frequency. Write your own: you know the *exact* rational (25/3) value, so why would you need to *call* any function to learn it?

I understand that Cube/HAL functions use this function internally. That's the basic problem with Cube/HAL: it caters only for a miniscule range of "usual" cases (any "library" inevitably is limited in this way). Anything slightly out of usual, and it gets into way more than it helps.


Thanks Jan, I do not use any frequency related functions from HAL_RRC_***. This 8.333MHz is temporary solution. I ordered the 25MHz crystal and the two caps. We will use the 25MHz external crystal oscillator as HSE.

Thank you for your help.

Best regars,