This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer as frequency measurement: issue

Hello everyone,

I am using the STM32F407ZET6, amongst other things, for a frequency measurement.

The incoming sine signal is converted to a (positive only) square wave signal via hardware, and is then fed to a GPIO port, configured as external interrupt on rising edge.
To measure its cycle duration, I am starting a microsecond-increment timer on the first rising edge and disable its counter after, let’s say, 5 rising edges. On every timer interrupt a variable is incremented to keep count of the passed microseconds. Eventually I am using the mean value over those 5 cycles to determine the signal frequency
(I can’t use the input capture function of the timers because the square-signal lies on an unfitting port.)

Now this works very well. I get exact results that fit their purpose by all means.
But only up to the point where I add several delays (to control a LCD display) before the frequency measurement. For some reason this seems to interfere with the correct timer execution. The more or larger delay functions have been placed, the greater the error during the frequency measurement.

I’ve done the delays with the same timer I use for the frequency measurement (timer 3) and also by simple usage of NOP loops. Both create said error. I feel like, for some reason, it messes with the system ticks.

Any inputs on this topic would be greatly appreciated.

Kind regards,
Alain

Parents
  • Thank you very much for your help, everyone. The issue is solved.

    Per, it was indeed a pending external interrupt which was set during the LCD Setup time. I wasn't aware of the fact that the microcontroller sets interrupt flags as soon as the port is accordingly configured, and not only after the interrupt service routine itself was activated.
    However i do not seem to be able to reset the interrupt flag outside the service routine, so i simply ignore the first call of the ISR. It's not pretty but it works.

    In this application a free running usec timer is out of question due to time sensitive operations following the frequency measurement. To keep system performance high and the time measurement increments small, i am forced to toggle a usec interrupt timer. But i will keep this in the back of my head for later use. Thanks a lot for the input!

    Pier, i am aware that a 1 usec timer is very demanding for the uC, you are right in your pleads to avoid the likes. Unfortunately i am forced to use such small time increments to get an exact frequency value since all following calculations and measurements are based around the signal frequency. But to your reassurance: i only activate the timer on a few occasions when there is nothing much else to do for the processor. Also the measurement interrupts have a higher priority than the timer interrupt, which should secure its the proper execution.

    I used the SysTick counter before, subtracting an end and a start value and thus calculating the passed time. But i later on changed it to the toggling usec timer because i felt it is cleaner coding.

    I will definitely look into DWT_CYCCNT and HW Counter. Thank you very much for your advice.

    Best regards,
    Alain

Reply
  • Thank you very much for your help, everyone. The issue is solved.

    Per, it was indeed a pending external interrupt which was set during the LCD Setup time. I wasn't aware of the fact that the microcontroller sets interrupt flags as soon as the port is accordingly configured, and not only after the interrupt service routine itself was activated.
    However i do not seem to be able to reset the interrupt flag outside the service routine, so i simply ignore the first call of the ISR. It's not pretty but it works.

    In this application a free running usec timer is out of question due to time sensitive operations following the frequency measurement. To keep system performance high and the time measurement increments small, i am forced to toggle a usec interrupt timer. But i will keep this in the back of my head for later use. Thanks a lot for the input!

    Pier, i am aware that a 1 usec timer is very demanding for the uC, you are right in your pleads to avoid the likes. Unfortunately i am forced to use such small time increments to get an exact frequency value since all following calculations and measurements are based around the signal frequency. But to your reassurance: i only activate the timer on a few occasions when there is nothing much else to do for the processor. Also the measurement interrupts have a higher priority than the timer interrupt, which should secure its the proper execution.

    I used the SysTick counter before, subtracting an end and a start value and thus calculating the passed time. But i later on changed it to the toggling usec timer because i felt it is cleaner coding.

    I will definitely look into DWT_CYCCNT and HW Counter. Thank you very much for your advice.

    Best regards,
    Alain

Children
No data