简介:2016年TI杯大学生电子设计竞赛E题“脉冲信号参数测量仪”官方赛题PDF,面向电子信息类参赛学生、指导教师及电赛备赛团队。文件完整收录题目任务、各项测量指标、评分标准与设计报告规范,详列频率10Hz~2MHz、占空比10%~90%、幅度0.1~10V及上升时间50~999ns的误差限要求,并涵盖标准矩形脉冲信号发生器(1MHz、100ns脉宽、5V幅度)的设计条件,附有脉冲参数定义与测试说明,便于对照备赛。资源为单个PDF文档,体积仅369KB,内容精炼,适合直接阅读、打印或存入移动设备。已有372人浏览学习,适合用于赛事规则研读、方案论证、电路与软件设计参考,能帮助参赛者精准把握题目评分要点,减少审题偏差。
1. 题目在问什么:从竞赛题到一台能测脉宽的仪器的距离
很多人拿到“脉冲信号参数测量仪”这个题目时,第一反应是把它当成一个单片机计数题:脉冲来了就计数,脉宽宽就数得多,最后把数字显示出来。真的做起来会发现,一台能稳定测出频率、脉宽、占空比和上升时间的仪器,精度瓶颈根本不在计数逻辑,而在模拟前端和参考时钟。数字部分只要架构选对,很快就能写完;模拟部分一旦处理不当,频率测准了但脉宽偏了,上升时间测出来甚至比真实值大一个数量级。
这道题适合两类人:一类是准备电子设计竞赛的学生,想在备赛期把仪器类题目吃透;另一类是做自动化测试设备、脉冲型传感器接口的嵌入式工程师。它考察的不是会不会点亮数码管,而是能否把一个模拟信号无失真地送进数字世界,并在噪声、温漂和有限时钟分辨率中间找到平衡。这篇文章按我平时做测量仪的完整路径来讲:先拆需求,再定架构,然后分别解决频率、脉宽和上升时间的测量,最后列出最常踩的坑和验证方法。
2. 脉冲参数测量仪的设计拆解:先把要测的量和硬件架构定下来
2.1 被测参数与测量链:从信号输入到数字显示的完整路径
设计一台脉冲参数测量仪,第一步不是选 FPGA,而是把“要测哪些参数、每个参数最可能有哪条测量路径”列成一张表。常见题设要求测量一组参数,实际竞赛题会根据指标微调,但大框架是这几项。
| 参数 | 定义 | 常用测量路径 |
|---|---|---|
| 幅度(高电平/低电平) | 高电平与低电平之间的电压差 | 峰值检波后 ADC,或阈值扫描法 |
| 频率/周期 | 相邻上升沿的时间间隔 | 等精度计数 |
| 脉冲宽度 | 高电平保持时间 | 粗计数 + TDC 细计时 |
| 占空比 | 脉宽除以周期 | 由脉宽和周期计算,或分两路计数 |
| 上升时间 | 从 10% 幅度到 90% 幅度的时间 | TDC + 高速比较器 |
| 下降时间 | 从 90% 幅度到 10% 幅度的时间 | 同上 |
有了参数表,测量链就清楚了。常见做法是:输入保护电路先挡住过压,高阻缓冲级把信号无损交给下一级;然后根据幅度范围做增益调整或衰减,使整形比较器的输入处于最佳摆幅;比较器把模拟脉冲变成数字方波,之后才进入 FPGA 或单片机的计数引脚。换句话说,测量链的模拟段决定信号保真度,数字段决定时间分辨率。很多人把注意力全放在计数器代码上,忘了比较器才是整个测量链的起点。
幅度测量值得单独说。很多窄脉冲信号不能用普通峰值检波,因为二极管的导通时间不够,检波电容根本充不到真实峰值。我一般会用“阈值扫描法”:用 DAC 给比较器设一个阈值,从低到高扫,同时观测比较器输出的脉宽。阈值低于信号低电平时,比较器始终输出高电平,脉宽无穷大;阈值高于信号高电平时,比较器始终输出低电平,脉宽为零。当阈值刚好等于信号高电平的一半时,比较器输出的高电平时间等于原信号在 50% 电平处的脉宽。因此,可以在软件里做二分搜索,找到“输出脉宽刚好缩到原脉宽一半”的那个阈值,这个阈值就是信号高电平的一半。这个方法不需要高速 ADC,非常适合竞赛环境下的窄脉冲幅度测量。
再补充一个容易被忽略的定义问题:脉冲宽度、上升时间和下降时间的基准点不是随意取的。脉宽一般以 50% 幅度点为基准,上升时间以 10% 到 90% 幅度为基准。如果比较器阈值只固定在某个电压,不随输入幅度变化,那么一个 1V 和一个 5V 的同样宽度脉冲,测出来的脉宽会有明显差异。所以,完成幅度测量后,要把 DAC 阈值设置到幅度的一半,再去测脉宽和占空比。这也是为什么测量链里必须先解决幅度,再谈时间参数。
2.2 前端调理:高速比较器、回差和输入阻抗的选择
前端调理电路的核心器件是高速比较器。普通运放工作在线性区,输出沿不够陡,不适合直接驱动数字计数器;高速比较器工作在开环状态,输出是射极耦合逻辑或低压差分信号,边沿稳定性好得多。我一般会选择传输延迟在几纳秒以内的比较器,并且关注两个指标:输入共模范围和最小可识别脉冲宽度。如果信号幅度只有几十毫伏,比较器输入失调电压稍大一点,阈值设定就会偏差,所以失调电压越低越好。
比较器回差(迟滞)是这条测量链里最容易翻车的地方。为了抑制噪声,比较器通常需要引入一点点正反馈,让上升沿触发点和下降沿触发点之间有一个滞后带。这个滞后带如果太大,上升沿触发点比设定阈值高,下降沿触发点比设定阈值低,结果就是输出的高电平时间比真实脉宽短。我一般把回差控制在信号幅度的 1% 到 3%。例如 5V 信号可以允许 50mV 回差,但是 0.5V 信号只能用 5mV 回差,否则脉宽会明显缩水。更稳妥的做法是让回差可调:用模拟开关切换不同阻值的反馈电阻,在测量小幅度信号时把回差关小,在大幅度信号时开大。最后在校准阶段用已知脉宽的标准方波把回差造成的偏移标定出来,再在软件里补偿。
输入阻抗的问题则直接决定上升时间能不能测准。如果输入端只放一个普通电阻分压器,输入电容加上 PCB 走线寄生电容,很容易达到 10pF 以上。被测信号源输出阻抗比较高时,这个电容和源电阻组成低通滤波器,边沿被拉慢,上升时间测出来自然偏大。我一般会在输入端先放一个高输入阻抗缓冲器,输入电阻做到 1MΩ 以上,输入电容控制在 2pF 到 5pF 之内。缓冲器后面再接衰减网络或比较器。需要注意的是,缓冲器的压摆率必须足够高,比如测量上升时间小于 10ns 的脉冲,缓冲器压摆率至少要上千伏每微秒,否则上升时间被缓冲器自己吃掉一大截。
比较器后面的数字信号也需要注意电平匹配。FPGA 或单片机的 IO 口如果是 3.3V 逻辑,比较器输出如果是 5V 或负逻辑,必须加电平转换和限幅电路。常见的做法是使用高速比较器输出端串一个小电阻,再经过 ESD 保护二极管或施密特缓冲器进 FPGA。这样做的目的是避免输出反射和过压损坏。很多人在面包板调试阶段直接飞线到 FPGA 引脚,边沿振铃严重,计数器疯狂跳数,就是这个环节没处理干净。
2.3 测量核心选型:FPGA 配合单片机,而不是纯单片机
纯单片机能不能做这个题目?如果只测频率和脉宽,用内部定时器输入捕获确实可以做,但上限非常明显。普通单片机的定时器时钟通常来自 PLL 倍频后的总线时钟,能做到几十到一两百兆赫兹,输入捕获分辨率就是这一个时钟周期。测一个 100ns 的脉宽,误差可能达到 5ns 到 10ns,相对误差已经很大;测上升时间这种更短的时间间隔,直接不可用。更重要的是,单片机的中断响应和引脚电平反转速度会让边沿时间抖动,这种抖动是随机的,软件无法补偿。
所以我更倾向于用 FPGA 做所有和时间相关的测量,单片机只做人机交互和结果换算。FPGA 内部可以做等精度频率计、TDC 延迟链、多路比较器状态同时采样,这些工作在单片机里要么做不了,要么做出来时序不可靠。常见的分工是:FPGA 负责对整形后的脉冲信号计数、捕获边沿在延迟链中的位置,然后把原始计数值通过 SPI 或并行总线送给单片机;单片机负责 DAC 阈值控制、幅度搜索、频率换算、脉宽换算、显示和按键。这样两边都不用跑实时性要求极高的代码,整体系统稳定性好很多。
选型时也不需要一味追求昂贵的大规模 FPGA。脉冲参数测量仪占用的逻辑资源并不大,等精度计数器加 TDC 总共可能只需要几千个逻辑单元。关键是 FPGA 要有足够的内置进位链资源,因为 TDC 要用到进位链做延迟线。同时要考虑开发板的时钟质量,板载晶振最好是可以更换或外接高质量参考时钟的。如果开发板上的时钟源只是一颗普通陶瓷谐振器,那频率测量的基础就不牢,后面再怎么校准都白费。
3. 用等精度测频法把频率测到六位有效数字
3.1 等精度测频原理:为什么固定闸门计数不靠谱
直接测频的做法是:打开一个固定时间闸门,比如 1 秒,数这个闸门内有多少个被测信号上升沿,然后用计数值除以 1 秒得到频率。这种方法有一个致命问题:闸门边沿和被测信号边沿不同步,计数值天然存在 ±1 的误差。测 1MHz 信号,1 秒闸门误差百万分之一,看起来还行;但如果被测信号降到 1Hz,1 秒闸门内可能只数到 1 个或 2 个边沿,误差达到接近 100%。所以固定闸门计数只能测高频,低频完全没法看。
等精度测频法的核心是让闸门边沿和被测信号边沿对齐。具体做法是:先产生一个“预置闸门”信号,它并不直接控制计数,而是经过被测信号的上升沿同步后,生成一个真正的测量闸门。这个测量闸门的开通和关闭都发生在被测信号的上升沿上,因此闸门内包含的被测信号周期数一定是整数,对被测信号计数就没有 ±1 误差。同时,用另一个计数器记录闸门内参考时钟的周期数。假设被测信号计数为 Nx,参考时钟计数为 Nref,参考频率为 fref,则被测频率 fx = Nx / Nref × fref。
这个式子的误差只来源于参考时钟计数 Nref 的 ±1。如果预置闸门持续 10ms,参考时钟为 100MHz,那么 Nref 大约是 1000000,误差约为百万分之一。把预置闸门加到 1 秒,误差就能降到亿分之一量级。换句话说,等精度测频是用“测量时间”换“低频精度”,频率越低,想要达到相同精度,需要的闸门就越长。这也是为什么最后一节我要强调多档闸门切换。
3.2 用 FPGA 实现等精度测频:一个可综合的参考模块
下面给一个简化的 Verilog 参考实现。它把“预置闸门产生”“被测信号同步”“参考时钟同步”分成三段写,便于理解。实际工程中,跨时钟域的同步链还要根据 FPGA 布局和时序约束进一步调整,但思路是通用的。
module ep_counter #( parameter W = 32 )( input wire clk_ref, // 参考时钟,例如 100MHz input wire sig_in, // 整形后的待测脉冲 input wire start, // 启动一次测量,高电平有效 input wire [W-1:0] pre_limit, // 预置闸门对应的参考时钟周期数 output wire done, // 测量完成标志 output reg [W-1:0] sig_cnt, // 被测信号计数 output reg [W-1:0] ref_cnt // 参考时钟计数 ); reg [W-1:0] pre_cnt; reg gate_raw; reg gate_sig; reg gate_meta; reg gate_ref; reg done_reg; // 预置闸门:在参考时钟域按 pre_limit 计数 always @(posedge clk_ref or negedge rst_n) begin if (!rst_n) begin pre_cnt <= {W{1'b0}}; gate_raw <= 1'b0; end else if (start) begin if (pre_cnt < pre_limit) begin gate_raw <= 1'b1; pre_cnt <= pre_cnt + 1'b1; end else begin gate_raw <= 1'b0; pre_cnt <= pre_cnt; end end else begin pre_cnt <= {W{1'b0}}; gate_raw <= 1'b0; end end // 预置闸门在被测信号上升沿同步 always @(posedge sig_in or negedge rst_n) begin if (!rst_n) gate_sig <= 1'b0; else gate_sig <= gate_raw; end // 同步回参考时钟域,消除亚稳态 always @(posedge clk_ref or negedge rst_n) begin if (!rst_n) begin gate_meta <= 1'b0; gate_ref <= 1'b0; end else begin gate_meta <= gate_sig; gate_ref <= gate_meta; end end // 被测信号计数:gate_sig 有效时在 sig_in 沿计数 always @(posedge sig_in or negedge rst_n) begin if (!rst_n) sig_cnt <= {W{1'b0}}; else if (gate_sig) sig_cnt <= sig_cnt + 1'b1; else sig_cnt <= {W{1'b0}}; end // 参考时钟计数:gate_ref 有效时在 clk_ref 沿计数 always @(posedge clk_ref or negedge rst_n) begin if (!rst_n) ref_cnt <= {W{1'b0}}; else if (gate_ref) ref_cnt <= ref_cnt + 1'b1; else ref_cnt <= {W{1'b0}}; end // 测量完成:预置闸门关断后再等同步链走完 always @(posedge clk_ref or negedge rst_n) begin if (!rst_n) done_reg <= 1'b0; else done_reg <= ~gate_raw & ~gate_ref; end assign done = done_reg; endmodule这个模块的代码逻辑是:启动信号start拉高后,预置计数器pre_cnt开始累加。只要pre_cnt小于pre_limit,gate_raw就是高电平;等于pre_limit后,gate_raw拉低。gate_raw进入被测信号域后变成gate_sig,它和被测信号是沿对齐的,所以sig_cnt的计数没有 ±1 误差。gate_sig再打两拍回到参考时钟域,变成gate_ref,ref_cnt记录的就是实际测量闸门的宽度。
参数说明:pre_limit是预置闸门的长度,单位是参考时钟周期。参考时钟如果为 100MHz,预置闸门 10ms 时,pre_limit设为 1000000。实际测量闸门会比预置闸门长一点,因为gate_raw拉低后,要等下一个被测信号上升沿才真正关闭,所以ref_cnt会比pre_limit稍大。这个偏差不影响计算公式,反而保证了对被测信号的计数完整性。
MCU 侧拿到sig_cnt和ref_cnt后,用下面这段代码换算频率:
uint32_t sig_cnt = read_from_fpga(REG_SIG_CNT); uint32_t ref_cnt = read_from_fpga(REG_REF_CNT); double f_ref = 100.0; // 参考时钟频率,单位 MHz double freq = (double)sig_cnt / (double)ref_cnt * f_ref; printf("freq = %.6f MHz\n", freq);这段代码只是把 FPGA 计数值代入公式。要注意sig_cnt和ref_cnt都是无符号整数,做除法前必须转成double,否则整数相除直接截断成 0。我见过不少人在这里翻车,频率怎么调都是 0,就是因为忘了强转类型。
3.3 参数调整:门闸时间、预分频和死区
等精度测频模块的三个关键参数是参考时钟频率、预置闸门时长和测量死区。参考时钟频率越高,同样闸门下ref_cnt越大,误差越小。但是参考时钟不能无限提高,FPGA 内部的全局时钟树和 TDC 延迟链需要满足时序约束,一般 100MHz 到 200MHz 是一个比较舒服的范围。
预置闸门时长需要根据被测频率动态切换。我的习惯是至少用三档:频率低于 1kHz 时用 1 秒闸门;1kHz 到 1MHz 用 10ms 闸门;高于 1MHz 用 1ms 闸门。为什么低频必须用长闸门?因为如果闸门内只包含几个信号周期,sig_cnt很小,相对精度就受制于这个整数计数值。等精度测频理论上对低频有效,但代价是测量时间长。用户按一下测量键,等半秒钟出结果,可以接受;如果每次测量都要等 10 秒,体验就很差。所以要在自动量程里增加超时机制,低频信号自动切到长闸门。
还有一个容易被忽略的参数是“死区”。一次测量结束后,计数器清零需要时间;如果紧接着启动下一次测量,gate_sig的同步链还没有完全复位,可能会把上一次的残留闸门带进来。我一般会在测量完成后等待 10 个参考时钟周期再允许下一次start,或者用 FPGA 状态机严格保证“空闲到测量到锁存到复位”的顺序。手动写逻辑时,不要图省事直接连续拉start。
4. 脉宽与上升时间的亚纳秒级测量:用 TDC 把时间间隔量化
4.1 直接用计数器测脉宽的精度天花板
测脉宽最朴素的方法是:用参考时钟作为计时基准,记录被测信号上升沿和下降沿之间经过了多少个参考时钟周期。假设参考时钟是 100MHz,一个周期 10ns,那么脉宽测量的分辨率就是 10ns。测一个 500ns 的脉宽,理论误差最多 10ns,相对误差 2%;测一个 100ns 的脉宽,误差可以到 10%,这已经很难满足题目要求了。
有人会说,用 FPGA 内部的 PLL 把时钟倍频到 200MHz,分辨率变成 5ns,不就行了吗?问题在于,时钟倍频不能无限提升,而且测量精度受限于系统时钟,而不是测量逻辑。真正想要把脉宽测到纳秒以下分辨率,必须引入时间数字转换器,也就是 TDC。TDC 做的事情是把一个时间间隔细分成很多小份,每一份可以小到几十皮秒,这样测脉宽和上升时间就不受参考时钟周期的直接限制。
4.2 延迟链 TDC 的原理:把周期切成一个个门延迟
TDC 最经典的做法是延迟链。被测信号边沿进入一串串联的延迟单元,每个延迟单元会有几十皮秒到几百皮秒的传播延迟。边沿每经过一个延迟单元,就相当于时间往前走了一个固定的小间隔。然后在某个参考时钟沿到来时,对延迟链上所有节点的输出做采样,形成一个 1 和 0 交替的热独码。从 1 变成 0 的位置,就是信号边沿相对于参考时钟沿的相位。
举个例子,如果延迟单元的平均延迟是 50ps,延迟链有 200 级,那么这条链可以覆盖 10ns 的时间范围,恰好是 100MHz 参考时钟的一个周期。采样结果中,前 80 级是 1,后面 120 级是 0,说明信号边沿大致落在第 80 级延迟单元附近,也就是距离参考时钟上升沿约 80×50ps=4ns 的位置。这个 4ns 就是细计数值。
FPGA 里做延迟链,通常直接用进位链结构,而不是普通逻辑门阵列。因为普通逻辑单元的传播延迟很大,而且布线延迟不可控;进位链在 FPGA 中是规则排列的,级间延迟更均匀,更容易满足时序约束。不同 FPGA 的进位链延迟差别很大,常见的范围是 10ps 到 50ps 一级,具体数值需要实测校准。这也就是为什么 TDC 部分不能跨器件直接抄代码:换一颗 FPGA 芯片,延迟单元的数量、布局和温度特性都可能变。
4.3 粗计数加细计数恢复脉宽和上升时间
单独靠延迟链做 TDC 只能测一个参考时钟周期以内的相位,而脉宽可能长达几百微秒甚至更久。所以实际工程必须把“粗计数”和“细计数”结合起来:粗计数器用参考时钟数信号高电平包含多少个完整时钟周期,细计数器用 TDC 测上升沿和下降沿各自在一个时钟周期内的相位。
假设上升沿相位为 p_start,下降沿相位为 p_end,参考时钟周期为 T,粗计数值为 N。如果 p_end 大于 p_start,说明上升沿和下降沿在同一个参考时钟周期内,脉宽等于 p_end 减 p_start;如果 p_end 小于 p_start,说明下降沿已经跨到了下一个时钟周期,脉宽等于 N×T 加 p_end 减 p_start。换算代码可以这样写:
typedef struct { uint32_t coarse; // 完整参考时钟周期数 uint16_t start_code; // 上升沿在 TDC 延迟链中的位置 uint16_t end_code; // 下降沿在 TDC 延迟链中的位置 } tdc_measure_t; float tdc_pulse_width_ns(tdc_measure_t *m, float clk_period_ns, float bin_ns) { float p_start = m->start_code * bin_ns; float p_end = m->end_code * bin_ns; if (p_end < p_start) { p_end += clk_period_ns; if (m->coarse > 0) m->coarse--; } return m->coarse * clk_period_ns + (p_end - p_start); }参数说明:clk_period_ns是参考时钟周期,比如 100MHz 对应 10.0ns;bin_ns是延迟链每一个 bin 的平均宽度,这个值必须由校准得到。如果延迟链的每一级延迟差别很大,就不能只用一个平均bin_ns,而应该把每一级的具体延迟存成查找表,逐级累加。上面的代码是简化版本,适合做原理验证。
上升时间测量就不能只靠一路 TDC 了。我一般会设置两个比较器阈值:一路阈值设在信号幅度的 10%,另一路设在 90%。两路比较器分别输出一个上升沿,用同一个 TDC 时间戳分别记录这两个上升沿对应的相位,再做差。这种做法要求被测信号是重复脉冲,因为两路阈值是同时工作的,不涉及阈值切换的延迟误差。如果只有一个比较器,那就只能在软件里切换阈值,测两次,然后把两个 TDC 时间差减去阈值切换带来的系统偏差。后者对校准要求更高,不推荐。
4.4 延迟链校准:码密度测试
TDC 的延迟链在实际芯片上不是等间隔的。受制造工艺影响,有的延迟单元可能只有 10ps,有的可能到 60ps,热独码的位置和真实时间之间不是简单线性关系。所以每块板子都需要做一次校准。
最常用的校准方法是码密度测试。给 TDC 输入大量边沿相位均匀分布的事件,统计每个延迟节点被采样到的次数。由于事件相位的概率密度在整个参考时钟周期内是均匀的,某个 bin 被命中的次数正好正比于它的宽度。遍历一遍后,就能得到每个 bin 的相对宽度。实际操作中,我会用信号发生器输出一个与参考时钟不成整数倍关系的自由脉冲,比如参考时钟 10MHz 时输出 3.333MHz,让边沿相位随机散布,累计统计 100 万次以上,得到的 bin 分布表就有足够的统计意义。校准表存到单片机 flash 里,每次开机可以复用,温度变化大时再重新测一次。
5. 测量误差排查:脉冲测量仪常见的五个坑
5.1 现象:脉冲宽度越测越窄,回差与阈值偏移在作怪
现象:给 ADC 输入一个标准 100ns 方波,示波器上显示 100ns,测量仪显示 93ns,而且把信号幅度从 5V 降到 1V 后,误差变得更大。原因:比较器回差太大。上升沿触发点比设定阈值高,下降沿触发点比设定阈值低,高电平有效时间被压缩。信号幅度越小,回差占的比例越大,脉宽缩短越明显。解决:把比较器回差钳到信号幅度的 1% 到 3%,并在软件里测量一个已知脉宽的标准方波,计算出回差造成的固定偏移量,在显示结果前补偿。注意,回差补偿不是简单的常量减法,它和信号边沿斜率有关,边沿越缓,误差越大,所以最彻底的办法还是硬件上减小回差。
5.2 现象:频率低端读数跳动,预置闸门取值过短
现象:输入 1Hz 标准信号,测量结果在 0.8Hz 到 1.2Hz 之间反复跳,把预置闸门改成 1 秒后,读数稳定下来,但是前面几次测量值仍然不稳。原因:预置闸门太短。等精度测频虽然消除了对被测信号的 ±1 误差,但是sig_cnt本身是个整数,如果预置闸门只有 10ms,那么 1Hz 信号在闸门内只能数到 0 或 1 个边沿,结果自然没有意义。解决:根据频率档位自动选择预置闸门长度,低频时至少保证闸门内有几百个信号周期。我用 1Hz 信号实测时,预置闸门通常设到 2 秒,让sig_cnt达到 2,配合参考计数,频率分辨率才够。
5.3 现象:上升时间越测越大,输入电容和比较器带宽拖后腿
现象:信号发生器标称输出上升时间 10ns,示波器实测 11ns,测量仪却显示 28ns。原因:测量仪的输入缓冲器输入电容太大,信号源输出阻抗和这个电容形成低通滤波器,把边沿拉慢了;或者比较器的带宽不够,输出边沿本身又增加了几纳秒。解决:输入端改用低输入电容的缓冲器,把 PCB 上输入节点铺铜面积减小,去掉不必要的过孔和插座;比较器换成传输延迟短、上升输出斜率高的型号。调试时可以在输入节点并联不同容值的电容,看测量值变化,以此估算前端引入的延迟,再在软件里扣除。这个方法需要信号源是已知的,不然分不清是信号源的问题还是前端的问题。
5.4 现象:同一信号在不同温度下测量结果漂移,参考时钟温漂没有处理
现象:上午校准好的测量仪,下午开机测同一个标准信号,频率读数高了几十 ppm,脉宽读数也跟着变。原因:大多数开发板用的是普通晶振,频率温度特性在 10ppm 到 100ppm 之间。参考时钟漂移会直接进入等精度测频的结果,因为频率公式里的 fref 用的是标称值,而实际值变了。TDC 的延迟链也会随温度变化,但变化幅度通常比晶振温漂小一个量级。解决:把系统时钟源换成温补晶振 TCXO,要求高就用恒温晶振 OCXO。如果只能用普通晶振,至少做一次开机校准:测量内部一个已知频率的方波,算出修正系数,再用于后续所有测量。这个修正系数可以每小时更新一次,但不能完全替代硬件的温漂。
5.5 现象:脉宽读数在临界值来回跳,边沿噪声触发抖动
现象:测量一个 50% 占空比的方波,脉宽读数大多数时候稳定,但偶尔会多一个 bin 或少一个 bin,肉眼看不出来,统计直方图能看到双峰。原因:信号边沿本身有随机抖动,比较器阈值点附近的噪声让触发时刻前后晃动;或者 TDC 的输入没有做边沿同步,亚稳态导致编码结果偶尔跳变。解决:对于重复脉冲信号,多取几次测量做统计,把直方图的峰值作为结果,不要用单次测量值。对于单次触发信号,则必须从模拟前端下手,降低比较器输入噪声,给比较器供电加滤波,在 TDC 输入端增加专用同步触发器。还有一个小技巧:TDC 对上升沿和下降沿分别做多次采样,然后分别平均,再相减得到脉宽,这样可以抵消一部分随机抖动。
6. 上板自测与交叉验证:判断脉冲测量仪真的能用的三招
第一招是用 FPGA 自己产生标准脉冲来测自己的测量通道。这个做法最常见,也最快。在 FPGA 里写一个简单的分频计数器,用系统时钟分频产生 1kHz、占空比 50% 的方波,通过一个 IO 引脚输出,再用一段短线接到测量仪的输入端。理论上 1kHz 方波的脉宽是 500us,测量仪显示结果在这个值附近就说明基本链路是通的。这个方法的好处是不依赖外部仪器,适合上电后第一时间定位问题。坏处是它不能验证模拟前端,因为信号从 FPGA IO 出来已经是数字方波,没有经过比较器回差带来的缩窄过程,所以只能验证数字测频和脉宽计算逻辑。
第二招是用信号发生器加数字示波器做交叉验证。信号发生器负责提供脉冲信号,数字示波器测出来一组参考值,测量仪测出来一组读数,两者对比。我一般会测三个点:100Hz、10kHz、1MHz 方波,分别记录频率、脉宽、上升时间。频率对比能看出参考时钟是否准;脉宽对比能看出比较器阈值和回差是否调好;上升时间对比能看出前端带宽是否足够。注意,信号发生器的脉宽和上升时间不一定比测量仪更准,它只是一个参考,必须先确认示波器本身测量档位设置合适,再用示波器测出来当作标准值。如果信号发生器输出边沿本身就慢,那对比时要选择上升时间明显小于理论值的情况。
第三招是做最坏情况边沿测试。用信号发生器把输出上升时间从最小调到最大,比如从 2ns 调到 100ns,观察测量仪的上升时间读数能否跟随。如果读数在一定范围内随信号发生器设定变化,但总有一个固定偏移,说明偏移主要来自输入缓冲和比较器延迟;如果读数在小上升时间时不变化,说明前端带宽不够,信号边沿还没形成就被削平了。这个测试能帮你把系统误差和随机误差分开,也是判断仪器极限能力的最终手段。
我自己第一次做这台仪器时,把精力全花在 FPGA 计数逻辑上,模拟前端只用一个普通比较器加固定电阻回差,结果测频率非常漂亮,测脉宽却一直差 5%。折腾两天后才意识到问题出在回差让比较器输出高电平时间变短了。从那以后我做任何测试测量类设备,都先调模拟前端,再动数字逻辑。测量仪器最忌讳把它当成纯数字系统来设计,信号还没进数字世界就已经失真,后面再花哨的算法也救不回来。希望帮到你。
本文还有配套的精品资源,点击获取