基于 FPGA 的数字频率计设计
数字频率计是测量信号频率的重要工具。普通万用表精度有限,示波器操作复杂,而基于 FPGA 的方案可提供快速、精准且可定制的测量能力。
为什么非要用 FPGA 做频率计?
传统 MCU 依靠中断或定时器轮询处理高频信号时,响应延迟和任务调度抖动会影响测量精度。FPGA 采用硬件并行运行模式,所有逻辑同时工作,无软件延迟。其全流水线化的测频引擎可在纳秒级完成计数、数据打包及模式切换,适用于通信系统时钟监控、雷达回波分析等对高频、低抖动有要求的应用。
核心架构
一个完整的数字频率计系统包含以下模块:
- 前端调理电路:将正弦/小信号变换成标准方波;
- PLL 锁相环:外接 10MHz 温补晶振,提供精准时间基准;
- 主控状态机:控制测量流程;
- 高速计数器:统计单位时间内脉冲数(测频法);
- 周期测量模块:精确捕捉单个周期长度(测周法);
- 自动量程切换逻辑:动态选择最优算法;
- 结果缓存与打包:FIFO + 数据格式化;
- 通信接口:UART / Ethernet 输出至上位机或 LCD。
第一步:输入信号调理
现实信号可能微弱、带噪声或含负电压,直接输入 FPGA IO 口易误触发或损坏芯片。需通过前端调理电路完成保护、放大整形及电平匹配。
典型设计要点:
- 输入端加 TVS 二极管和限流电阻(如 1kΩ);
- 使用交流耦合电容隔断直流偏置,配合电阻网络提供偏置电压;
- 核心采用高速比较器(如 ADCMP600),搭配迟滞反馈提升抗干扰能力;
- 输出端串联小电阻用于阻抗匹配。
注意:不要依赖 FPGA 内部施密特触发输入做主要整形,其滞后电压不精确。
对于超过 100 MHz 的射频信号,建议外接预分频器芯片,先将频率降至 50 MHz 以内再送入 FPGA。
第二步:高精度时间基准
频率本质是单位时间内的事件次数,参考时钟必须极其稳定。选用 10 MHz 温补晶振(TCXO),日老化率优于±0.5 ppm。通过 FPGA 内部 PLL 将其倍频至 100 MHz 或更高作为主时钟。
| 功能 | 作用 |
|---|---|
| 倍频 | 将 10 MHz → 100 MHz,提升时间分辨率 |
| 相位校正 | 消除时钟路径延迟,确保全局同步 |
| 抖动抑制 | 输出时钟 RMS 抖动可控制在 50 ps 以内 |
| 多路输出 | 同时生成多个同源时钟 |
设计建议:使用 Xilinx IP Catalog 或 Intel Quartus MegaWizard 配置 PLL,在约束文件中明确声明输入时钟频率和抖动参数,开启 Global Clock Buffer 选项。
第三步:测频与测周双模策略
单一方法无法覆盖全频段,需结合两种方法。
方法一:直接测频法(适合中高频)
打开已知宽度的闸门(如 1 秒),统计上升沿数量。 $$ f = \frac{N}{T} $$ 若 $ T = 1,\text{s} $,则 $ N $ 的值即为频率(Hz)。低频时分辨率不足。
方法二:测周法(专治低频)
精确测量一个周期长度,取倒数。 $$ f = \frac{1}{t_{\text{period}}} $$ 利用 100 MHz 时钟(10 ns 分辨率)测量周期,低频段优势巨大。
自动切换策略
// 先进行一次粗测 wire [39:0] coarse_count; wire use_period_measurement;
// 若粗测频率低于 1kHz,则启用测周法 assign use_period_measurement = (coarse_count < 40'd100);
关键代码实现
1. 安全的上升沿检测(防亚稳态)
module edge_detector_safe (
input clk,
input reset_n,
input signal_in,
output rising_edge
);
reg sig_d1, sig_d2;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
sig_d1 <= 1'b0;
sig_d2 <= 1'b0;
end else begin
sig_d1 <= signal_in;
sig_d2 <= sig_d1;
end
end
assign rising_edge = sig_d1 & ~sig_d2;
endmodule
2. 可配置闸门时间的计数器
module freq_counter (
input clk,
input reset_n,
input gate_en,
input sig_edge,
output reg [39:0] count_val
);
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
count_val <= 40'd0;
else if (gate_en && sig_edge)
count_val <= count_val + 1'b1;
else if (!gate_en)
count_val <= 40'd0;
end
endmodule
3. 测周法实现
module period_meter (
input clk_100m,
input reset_n,
input start_pulse,
output reg [31:0] period_count,
output done
);
reg capture_en;
always @(posedge clk_100m or negedge reset_n) begin
if (!reset_n) begin
capture_en <= 1'b0;
period_count <= 32'd0;
end else begin
if (start_pulse) begin
capture_en <= 1'b1;
period_count <= 32'd0;
end else if (capture_en) begin
period_count <= period_count + 1'b1;
end
end
end
assign done = (period_count != 0) && start_pulse;
endmodule
系统整合与优化
- 资源优化:共享高速时钟,复用计数器,按需开启模块。
- 功耗与 EMC:关闭未使用的 I/O Bank,高速信号走内层屏蔽,电源入口加滤波,数字地与模拟地单点连接。
实战调试经验
- 低频跳数:检查参考时钟稳定性,加强 LDO 滤波。
- 高频不准:检查前端比较器供电及迟滞电压。
- 串口乱码:使用异步 FIFO 桥接不同时钟域。
- 自校准:定期注入标准信号修正系统偏差。
应用场景
- 高校电子类课程实验箱;
- 无线监测终端(跟踪振荡器频率漂移);
- 自动化产线测试仪;
- 天文授时辅助设备。
未来可扩展 DDS 激励、FFT 预处理及 AI 异常识别等功能。

