FPGA+STM32频率计实现(2015国赛F题)

Posted by 橙叶 on Fri, Apr 9, 2021

频率计,简单且常用的设备。下面我们来探讨如何足够准确地测出频率。

假设我们已经将输入信号处理成方波信号。

容易想到的测定频率的两种方式:计频和测周。计频,即在固定时间内测量方波一侧边沿的数量,适用于高频率信号的测量。测周,即测量相邻两个上升沿(或下降沿,本文以上升沿为例)之间的时间间隔,取倒数即得到频率,适用于低频率信号的测量。

在计频法中,如果想要系统误差小于千分之一,计频法的“固定时间”应当至少是待测信号周期的1000倍,因此计频法不适于低频率信号的测量,因为需要非常长的测量时间(比如1Hz的信号要1000s才能完成一次测试),计频法还有一个更深层的问题:对待测信号的计量有±1的误差,这很好理解,我们想要有一个“固定时间”,必然要有一个计时器来确定一个“时间闸门”,在这个“闸门”开启时,计数器工作,统计待测信号的上升沿。对于待测信号来说,计时器开启的时间是随机的,因此在“时间闸门”里待测信号到来的边沿可能多一个或少一个,这意味着在1s内测量1kHz以上的信号时,我们只能精确到1Hz,对于小数点后的数字毫无办法,虽然精度达到了千分之一,但已经无法更加精确(除非再加长测量时间)。

测周法从理论上讲没有待测信号±1的误差,但是在测周法里,我们先遇到一个上升沿,这时候看一下时间,再遇到一个上升沿,再看一下时间,然后两个时间相减得到差值。如果我们的测量设备拥有无限高频率(而且精确)的时钟,无论待测信号以什么频率输入,都可以准确地检测到它的边沿并在一瞬前完成想要的动作,那么测周法将无往而不利。但是假设使用的FPGA开发板的晶振只有50M;STM32F407的频率只有168M,而且它的计时器一点也不准。事实上STM32F407定时器的脉冲捕获功能在300kHz以上就罢工了,如果使用计时器外部时钟功能,低频下计数会非常不准(漏掉边沿)。但是测周法的理论依然有用,后面会说到。

单片机实在难堪大任,我们需要设计专门的硬件电路。

回过头来做一个思考,如果要测定一个待测信号的频率,我们需要什么?

  • 一个足够准确的参考时钟

仅此而已。在上述两种方法里,驱动计时器的时钟就是这个参考时钟。但是之所以二者都失败了,无非是1.计数器、计时器设计缺陷,计时/计数不准确2.方法本身缺陷。

“等精度测频”

等精度测频解决了测量结果±1误差的问题。等精度测频在计频法的基础上,让“时间闸门”的开启不再是随机的,而是与待测信号的上升沿同步。这样在固定的“时间闸门”内,统计到的待测信号的上升沿的数目是固定的(只要“时间闸门”的变化小于待测信号的一个周期)。

想要有一个长度相对稳定的“时间闸门”,就需要一个定时器,想要这个定时器运转,就需要能驱动它的时钟。虽然统计到的待测信号的上升沿的数目已经稳定了,但是我们不知道统计这些上升沿花了多长时间(因为”时间闸门”的长度是不稳定的),我们需要一个准确的参考信号作为时间尺度上的参考。

在具体的设计中,产生时间闸门的定时器实际上与参考信号使用的是同一个时钟源,因此,上述设计可以简化成一个开启和停止均与待测信号边沿同步的定时器。具体到逻辑上的实现,当待测信号的上升沿到来时,启动定时器,在定时器完成一个固定时间的计时后(但仍在计时),待测信号下一个上升沿到来时结束计时。最终得到待测信号的计数值和定时器的最终停止时的计时值。

避免测量结果不准确和上下跳动的关键在于定时器开启的时间内,计数到的待测信号的上升沿是固定的。



comments powered by Disqus