ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

电赛D题简易电路特性测试仪:五项测量与故障判断方案

电赛D题简易电路特性测试仪:五项测量与故障判断方案

简介:2019年Ti杯电子设计竞赛D题资料包面向准备参加电子设计竞赛的高校学生与指导教师,围绕D题赛题材料、方案实现与复盘学习展开,适合具备电路分析、嵌入式编程和模拟/数字电路基础的读者查漏补缺。压缩包为zip格式,体积约54.39MB;上游文件总数一栏为0,文件类型明细暂无数据,具体构成以包内为准,预览信息提示其中可能包含主项目目录及与赛题相关的工程资料。已有325人学习,说明该赛题具有一定关注度。读者可据此了解D题涉及的知识范围,包括微控制器编程、传感器应用、运放与滤波器、ADC/DAC、通信协议及数据分析等,并借助项目材料梳理设计思路、对照实现方案和总结排错经验,提升从赛题理解到系统落地的综合能力。

1. 那道电赛D题,真正难的是造一把"尺子"

2019年电赛D题,也就是那道简易电路特性测试仪,被测对象只是一只再普通不过的放大电路,任务书却要求测出它的输入电阻、输出电阻、电压增益、幅频特性,找出上下限截止频率,最后还要在电路被人为改坏时判断出坏在哪。不少人第一反应是"信号发生器加示波器,十分钟的事",真上手才发现,用别人的仪器测很容易,自己搭一套仪器去测就很难——激励会改变被测电路的工作点,检波器有建立时间,探头线在几百千赫兹上开始失真。这套方案要干的事只有一件:用一片DDS、一片真有效值检波和一颗主控,把这五项测量加一次故障判决全自动做完,误差压进5%。适合正在准备电赛的同学、要做测量类课设的人,也适合想给模拟电路板配一台自检工装的从业者。

2. 测量原理拆解:四个参数怎么变成能采样的电压

这道题的所有指标,最后都要落成ADC能读的直流电压。四个参数对应四种变换:电阻变成压降,比值变成dB,频率变成判决量。原理本身不难,难的是每一层变换都会引入系统误差,必须在设计阶段就想好在哪里校准、在哪里补偿。

先给一张总表把关系理清楚,后面的小节都围着它展开。

测量项直接测的量换算关系主要误差源
输入电阻 RiRs 两端压降Ri = Rs·Vi/(Vs−Vi)Rs 精度、注入幅度过大导致削波
输出电阻 Ro空载/带载两次输出Ro = RL·(Vo1/Vo2−1)RL 精度、切换瞬间冲击
增益 Au输入输出幅值Au = 20·log10(Vo/Vi)两通道增益失配
截止频率 fL/fH扫频曲线−3dB 门限插值频点密度、建立时间不足
故障类型五维特征向量阈值 + 故障字典阈值过紧或过松

2.1 输入电阻:串一只已知电阻,把阻值换算成压降

方法本身是教科书里的串联分压:信号源输出 Vs,经已知电阻 Rs 接到被测电路输入端,测出输入端电压 Vi,则 Ri = Rs·Vi/(Vs−Vi)。这个式子成立的前提是 Rs 本身足够准、Vi 和 Vs 是同一时刻的有效值、并且被测电路在测量时的工作状态和正常工作时一致。

为什么不用万用表电阻档直接量?断电测量会引入表内直流源,放大电路的非线性元件工作点全变了,量出来的值和实际工作状态下的输入电阻根本不是一回事;很多电路的 Ri 本身就随工作点漂移,静态量一遍、动态又变一遍,只会越测越糊涂。

Rs 的取值有讲究。太大,注入到被测电路的信号衰减严重,输出端信噪比掉下来,高频段尤其明显;太小,Rs 上的压降相对量测误差变大,Vi 越接近 Vs,Vi/(Vs−Vi) 这个除法就越敏感。我的取值习惯是 Rs ≈ 被测电路标称 Ri,此时 Vi 大约等于 Vs 的一半,两路 ADC 量程都用得比较满,相对误差最小。

注入幅度同样要控。调到被测电路不失真最大输出幅度的 30%~50% 比较稳,太小会淹没在噪声里,太大直接把输出推到削波区,测出来的增益和 Ri 全是错的。信号源和被测电路之间串一只 1~10μF 的隔直电容,避免源内阻上的直流偏置改变被测电路的工作点。

/* 输入电阻:信号源串已知电阻 Rs,测 Rs 两端压降换算 * rs : 串联取样电阻,单位欧姆,用 1% 金属膜 * vs_rms : 信号源输出端有效值(Rs 靠源那一侧) * vi_rms : 被测电路输入端有效值 * 返回值 : 输入电阻;返回负值代表测量异常 */ float measure_rin(float rs, float vs_rms, float vi_rms) { /* 保护:压降不足说明输入开路、量程选错或信号源幅度太小 */ if (vs_rms <= vi_rms + 1e-4f) return -1.0f; if (vi_rms < vs_rms * 0.02f) return -1.0f; /* 压降过大,多半是 Ri 远小于 Rs */ return rs * vi_rms / (vs_rms - vi_rms); }

函数里两个保护分支是血泪经验:压降不足多半是输入开路或者信号根本没接上,压降过大则说明 Rs 选得比 Ri 大太多,两个情况下算出来的数都不能信,直接返回错误让别人去换量程,比返回一个看似合理的假值安全得多。

2.2 输出电阻:两次测量,把负载切换做成一次实验

输出电阻用空载和带载两次输出幅值反推:Ro = RL·(Vo1/Vo2 − 1)。Vo1 是空载输出,Vo2 是接上 RL 之后的输出。负载电阻 RL 取 Ro 的 1~2 倍,此时 Vo2/Vo1 大约落在 0.33~0.5,压降明显,两路读数的相对误差都被放大得可控;RL 取得太大,Vo2 和 Vo1 几乎一样,减去 1 之后全剩噪声;取得太小,输出级直接削波。

有个容易被忽略的细节:两次测量之间输入激励必须完全一致。所以输出电阻这一项不能用扫频做,必须固定在中频(通常 1kHz)单点,切换负载用继电器,切换完延时 20~50ms 等输出稳定再采。继电器接触电阻只有几十毫欧,相对几 kΩ 的 Ro 完全可以忽略,但如果图省事用模拟开关,几欧姆的导通电阻就直接算进误差里了。

/* 输出电阻:空载与带载各测一次 * rl : 负载电阻,单位欧姆 * vo_open : 空载输出有效值 * vo_load : 接负载后的输出有效值 */ float measure_rout(float rl, float vo_open, float vo_load) { if (vo_load < 1e-4f) return -1.0f; /* 输出被拉死,检查负载 */ if (vo_load > vo_open * 0.95f) return -1.0f; /* 压降太小,RL 选得过大 */ return rl * (vo_open / vo_load - 1.0f); }

2.3 增益与幅频特性:从单点到 61 点对数扫频

中频增益取 1kHz 单点,Au = 20·log10(Vo/Vi)。幅频特性则要扫频:从 10Hz 扫到 1MHz,覆盖音频段和一般小信号放大电路的整个通带。

扫频一律用对数间隔,不用线性间隔。原因很实在:截止频率在频轴上是跨数量级分布的,下限可能只有几十赫兹,上限能到几百千赫兹。线性扫频在高频段点挤成一团,低频段却稀稀拉拉,画出来的曲线在转角处全是折线,−3dB 点根本插不准。对数扫频每十倍频程固定点数,10Hz 到 1MHz 正好五个十倍频程,取每十倍频程 12 点、总点数 61 点,配合插值已经够用;追求曲线好看可以加到每十倍频程 20 点,代价是整轮扫频时间翻倍。

每个频点要停留多久,由检波器的时间常数决定。真有效值芯片外接滤波电容决定了它的建立时间,停留时间不能小于 3~5 倍时间常数,否则读到的永远是上一个频点的残留值,曲线会整体右移。低频段还要额外考虑信号周期本身:10Hz 的信号一个周期就是 100ms,起码等五个周期才谈得上稳定。

2.4 故障判断:把曲线形状变成五维特征向量

故障判断是这道题的发挥部分,也是最容易做成"玄学"的一块。我的做法是把测量结果组织成一个五维向量(Ri、Ro、Au、fL、fH),先和标称值比偏差,再拿偏差的方向去查故障字典。单管共射放大电路的典型故障和参数变化方向大致如下:

故障类型RiRoAufLfH
基极上偏置电阻开路明显上升略升大幅下降上升略降
基极上偏置电阻短路明显下降略降大幅下降略升下降
输入耦合电容开路不变不变大幅下降大幅上升不变
射极旁路电容失效上升不变下降不变下降
负载电阻开路不变上升空载增益偏高不变上升

判决逻辑分两层:第一层判"有没有坏",五个偏差量全部落在 ±10% 以内就当正常,避免误报;第二层判"坏在哪",取偏差最大的那一维做主判据,再用第二维做校验。两层之间加一个死区,偏差在 10%~20% 之间的不参与定位,只提示"疑似异常"。

这套字典不是万能的,两个元件同时坏、或者故障引起的参数偏移方向恰好抵消,都会失效。答辩时被问到"你的方案能不能定位所有故障",老老实实说清楚覆盖范围和失效条件,比硬撑着说"全能"要得分高。

3. 硬件架构:三条链路各管一件事

整块板子按信号流向切成三条链路:激励链路负责产生幅度恒定、频率可控的正弦;检波链路负责把交流幅值变成直流电压;控制与人机链路负责调度、计算和显示。三条链路之间只通过模拟信号和几根控制线连接,边界划清楚,调试时才能一段一段地隔离问题。

3.1 激励链路:DDS、低通滤波与幅度调理

DDS 芯片直接输出的正弦带有大量时钟镜像和高次谐波,必须过一级低通。截止频率取 1.2MHz 左右的五阶巴特沃斯,既能把 1MHz 以内的基波放过去,又能把镜像压到 −40dB 以下。这一级省掉,后面检波器读到的有效值里就混着镜像功率,高频段增益会莫名其妙虚高。

幅度调理用可编程增益放大器或者数字电位器加分压网络,作用是让扫频全程输出幅度保持恒定。这里有个硬性要求:扫频过程中绝对不能改增益。一旦在中途切换档位,幅频曲线上就会出现一个台阶,被误判成谐振或者截止点。

输出缓冲用运放做跟随,串 50Ω 输出电阻。这 50Ω 一定要在软件里算进信号源内阻——计算 Ri 时的 Rs 是"50Ω 加上实际取样电阻",漏掉这 50Ω,测小电阻时误差能到十几个百分点。

激励链路指标取值说明
频率范围10Hz ~ 1MHz对数扫频,61 点
输出幅度0.1 ~ 2Vrms 可调扫频期间锁定不变
幅度平坦度±0.5dB 以内需在出厂前逐台校准
输出阻抗50Ω计算 Ri 时必须计入
谐波失真< 1%靠低通滤波保证

3.2 检波链路:真有效值、峰值检波、软件计算怎么选

三种方案各有各的适用面,选错了后面全是补丁。

方案精度成本建立时间适用场景
真有效值芯片高,0.5% 级较高由外接电容决定,几十毫秒全频段通用,最省心
二极管峰值检波中,小信号非线性明显低快只测中频增益,且信号 > 500mV
ADC 直接采样 + 软件计算取决于采样率最低无低频段,采样率需 ≥ 20 倍信号频率

1MHz 的信号要直接采样,采样率至少 20MSPS,主控片内 ADC 那点速率根本不够,得外挂高速 ADC 或者用等效采样,复杂度和成本反而不如一片真有效值芯片。所以我的选择是输入输出两路各挂一片真有效值检波,输出接 RC 低通再做阻抗缓冲送进 ADC,软件侧只负责采平均值。这是用钱换时间的选择,做课设和电赛都划算。

检波器前端的输入阻抗要足够高,至少是被测电路输出阻抗的 10 倍,否则探头一挂上去就把被测电路加载了,测出来的增益比真实值低一截,而且这个误差随频率变化,校都校不回来。

3.3 主控、人机与电源:把模拟地和数字地分开

主控选带 FPU 的 Cortex-M4 级别芯片,原因不是算力焦虑,而是扫频过程中要做几十次 log10、pow、开方,没有硬件浮点的话一轮扫频要几百毫秒,配合每点的建立延时,整机响应会拖到十几秒,演示时很难看。

显示用 320×240 的 TFT,横轴对数频率、纵轴 dB,画 61 个点加连线足够清楚。人机交互用旋转编码器加两三个按键,比纯按键好操作,比触摸屏省事。

电源部分是最容易埋雷的地方:被测电路往往需要 ±12V,系统自己用 5V 和 3.3V,DDS 的时钟又是几十兆赫兹的高速数字信号。模拟地和数字地必须单点连接,连接点选在 ADC 的 AGND 引脚附近;DDS 的时钟走线要远离两路模拟输入,能包地就包地。这几条做到了,后面调试能省一半时间。

4. 软件实现:扫频状态机、数据处理与曲线绘制

软件的主线很短:设频点、等稳定、采两路、算增益、存点,循环 61 次,最后找截止频率、画图、判故障。真正花时间的是每个环节的边界条件处理。

4.1 扫频主循环与建立时间

/* 扫频单点测量:设频点 -> 等待建立 -> 双通道采样 -> 存点 */ #define F_START 10u /* 起始频率 Hz */ #define F_STOP 1000000u /* 终止频率 Hz,共 5 个十倍频程 */ #define SWEEP_POINTS 61 /* 每十倍频程 12 点 */ typedef struct { uint32_t freq; float vin_rms; float vout_rms; float gain_db; } sweep_point_t; sweep_point_t g_curve[SWEEP_POINTS]; /* 低频多等、高频少等:至少覆盖 5 个信号周期,下限 2ms */ static uint32_t settle_ms(uint32_t f) { uint32_t t = 5000u / (f ? f : 1u); return (t < 2u) ? 2u : t; } /* 第 i 点频率按对数等间隔分布:f = f_start * 10^(i*step) */ static uint32_t freq_of_index(uint16_t i) { double step = log10((double)F_STOP / F_START) / (SWEEP_POINTS - 1); return (uint32_t)(F_START * pow(10.0, i * step)); } uint8_t sweep_run(void) { for (uint16_t i = 0; i < SWEEP_POINTS; i++) { uint32_t f = freq_of_index(i); dds_set_freq(f); /* 只改频率,增益档位全程锁定 */ delay_ms(settle_ms(f)); float vin = adc_read_avg(CH_IN, 32, K_IN); float vout = adc_read_avg(CH_OUT, 32, K_OUT); if (vin < 1e-4f) return ERR_NO_SIGNAL; /* 断线或信号源未起振 */ g_curve[i].freq = f; g_curve[i].vin_rms = vin; g_curve[i].vout_rms = vout; g_curve[i].gain_db = 20.0f * log10f(vout / vin); } return OK; }

settle_ms用 5000/f 这个经验式,本质是保证每个频点至少等过五个信号周期,同时给了 2ms 的下限防止高频段把整轮扫频拖得太久。按 61 点算下来一轮大约 1.2 秒,加上找点和绘图,整机响应能控制在两秒以内,演示时观感是"按一下就出结果"。

freq_of_index用 pow 现算而不是查表,是为了改点数时不用重新生成表;如果主控没有 FPU,这里要换成预先算好的 61 个频率常量数组。

4.2 有效值读取与去极值处理

/* 读检波输出:连采 n 点,排序后掐头去尾取平均,再乘通道校准系数 * 检波输出是带纹波的直流,取平均即可; * 若跳过检波直接采交流,必须保证每周期 >= 20 点且采整数个周期 */ float adc_read_avg(uint8_t ch, uint16_t n, float k_cal) { uint16_t buf[32]; float sum = 0.0f; for (uint16_t i = 0; i < n; i++) buf[i] = adc_sample(ch); sort_u16(buf, n); for (uint16_t i = 2; i < n - 2; i++) sum += adc_to_volt(buf[i]); return sum / (n - 4) * k_cal; }

掐头去尾这两点是专门对付偶发尖峰的。继电器切换、DDS 写寄存器、屏幕刷新都会在模拟通道上耦合出一两个异常采样点,算术平均会被这两点拖偏,中值或者排序截断稳得多。k_cal是每个通道单独的幅度校准系数,出厂校一次,把检波器的增益误差和前级运放的失配全部吸收进去。

4.3 −3dB 点搜索与曲线绘制

截止频率不能直接取"第一个低于中频增益 3dB 的点",那样精度受限于频点密度。正确做法是先定出中频平台增益,再从平台往两侧扫,找到跨过门限的相邻两点,在对数频率轴上做线性插值。

/* 先求中频平台增益(取中段 60% 的中位数),再向两侧找 -3dB 交叉点 */ typedef struct { uint32_t f_low, f_high; float a_mid_db; } bw_result_t; static uint32_t log_interp(uint32_t f1, float g1, uint32_t f2, float g2, float thr) { float t = (thr - g1) / (g2 - g1); /* 0~1 之间的插值位置 */ return (uint32_t)(f1 * powf((float)f2 / f1, t)); } bw_result_t find_bandwidth(const sweep_point_t *c, uint16_t n) { bw_result_t r = {0}; float tmp[SWEEP_POINTS]; uint16_t s = n / 5, m = 0; for (uint16_t i = s; i < n - s; i++) tmp[m++] = c[i].gain_db; r.a_mid_db = median_f32(tmp, m); /* 中位数抗单点毛刺 */ float thr = r.a_mid_db - 3.0f; uint16_t mid = s + m / 2; for (uint16_t i = mid; i > 0; i--) if (c[i].gain_db >= thr && c[i-1].gain_db < thr) { r.f_low = log_interp(c[i-1].freq, c[i-1].gain_db, c[i].freq, c[i].gain_db, thr); break; } for (uint16_t i = mid; i < n - 1; i++) if (c[i].gain_db >= thr && c[i+1].gain_db < thr) { r.f_high = log_interp(c[i].freq, c[i].gain_db, c[i+1].freq, c[i+1].gain_db, thr); break; } return r; }

中频增益用中位数而不是平均值,是因为扫频曲线在谐振点附近常有一两个突跳,平均值会被带偏,中位数不会。插值函数在对数频率轴上做线性插值,和扫频的间隔方式一致,插出来的频率误差可以压到一个频点间隔的十分之一以内。

绘图部分只有一条坐标映射要记住:横轴先取 log10 再线性映射到像素,纵轴按 dB 线性映射,纵轴范围一般取 −40dB 到中频增益 +10dB,超出部分裁剪。坐标映射写错时曲线会整体偏移但形状还对,很容易被误判成硬件问题。

4.4 系统校准:把自己这把尺子的误差扣掉

开机自检时做三项校准。幅度校准:把信号源直连到两路检波输入,扫一遍频,记录系统本身的频响,测量时逐点扣除;这一步能把 DDS 输出平坦度、低通滤波器的滚降、检波器的频响误差全部消掉。电阻校准:用两个 1% 精密电阻分别当 Rs 和 RL 的参照,修正软件里的实际阻值。零点校准:输入端短路,记录两路 ADC 的直流偏置,测量时先减掉。

校准值存在 EEPROM 里,每台设备一份。不做这三项,基本要求那 5% 的误差指标很难稳定达到,尤其高频段。

5. 避坑清单:五个最容易翻车的点

5.1 输入电阻读数一直跳,甚至算出负数

现象是同一个电路连测五次,Ri 从 3kΩ 跳到 12kΩ,偶尔返回 −1。原因通常是注入幅度太大,被测电路输出已经削波,输入端等效阻抗随信号瞬时值变化,有效值自然不稳。解决办法是把注入幅度降到不失真最大输出的 30% 左右,并在测量前先做一次"扫幅度"——从 0.1V 往上加,找到输出开始非线性拐点,退回到拐点的六成。另一个可能是隔直电容太小,低频段容抗和 Ri 可比,测出来的值偏低,把电容加到 10μF 以上即可。

5.2 幅频曲线低频段全是毛刺,高频段反而平滑

这是建立时间不够的典型症状。低频信号周期长,检波器滤波电容还没来得及充到稳态值,程序已经采完走人了,读到的值忽高忽低。把settle_ms的计算基数从 5000/f 提到 10000/f,或者在低频段额外加固定 100ms 延时,曲线立刻就干净了。还有个隐蔽原因:屏幕刷新和 ADC 采样抢总线,把绘图放到扫频结束之后再做,不要在采集中间刷屏。

5.3 高频段增益虚高,1MHz 附近甚至超过中频增益

先查探头。检波器输入如果用的是普通杜邦线,几十厘米的线在 1MHz 上就是一根天线,拾取的干扰直接进检波器。换成屏蔽线、地线尽量短、探头地夹就近接被测电路地,虚高通常会掉下去 3~5dB。再查低通滤波器,如果 DDS 的镜像没滤干净,检波器读的是基波加镜像的总有效值,高频段自然虚高,用示波器看一眼 DDS 输出波形就能确认。

5.4 切负载测输出电阻时,读数跳变或者电路自激

继电器切换瞬间,负载从无穷大突变到几 kΩ,输出端的容性负载和运放的相位裕度一起作用下很容易起振。解决办法是切换后强制延时 50ms,并且采样时取 32 点里的中位数而不是平均值。如果仍然自激,在负载电阻上并一只几十皮法的小电容,或者在输出端串 22Ω 隔离电阻,把容性负载和运放隔开。

5.5 故障判断频繁误报,好的电路被判成坏的

九成原因是阈值定得太紧。器件本身有 5% 的容差,测量系统还有 2%~3% 的误差,两边一叠加,正常电路的参数偏差就能到 8%。把"正常"的判定区间放到 ±15%,"故障"的判定门限放到 25% 以上,中间留出死区只报"疑似"。另一个原因是标称值本身不准——标称值应该来自对一块已知良好电路的实际测量,而不是照抄理论计算,理论值和实际值差 20% 是常事。

6. 验收与答辩:用一张测试记录表证明方案站得住

这道题的评分点很集中:基本要求的四项测量精度、发挥部分的故障判断准确率、以及整机的人机交互流畅度。答辩现场最忌讳的是"我测了,挺准的"这种口头结论,评委要看的是数据。我一般会准备一张覆盖全部指标的测试记录表,现场抽测其中两三项,其余直接给表。

测试项测试条件指标要求实测判定
输入电阻Ri 标称 3.3kΩ误差 ≤ 5%3.28kΩ(−0.6%)合格
输出电阻Ro 标称 2.2kΩ误差 ≤ 5%2.31kΩ(+5.0%)合格
中频增益1kHz,输入 50mVrms误差 ≤ 5%40.2dB(+0.5%)合格
下限截止频率标称 120Hz误差 ≤ 10%126Hz(+5%)合格
上限截止频率标称 180kHz误差 ≤ 10%172kHz(−4.4%)合格
故障判断预设 5 种单一故障正确率 ≥ 80%5/5合格

表格之外,演示流程要提前排好,控制在三分钟以内:先上一块好电路,跑一次完整测量,让曲线在屏上画出来;再换一块预先做坏的电路,展示故障判断结果;最后手动短路一个电阻,看系统能不能当场识别。这个顺序是从"正常"到"异常",评委的接受度最高。

被追问时最常遇到三个问题,提前想好答案。问"为什么用真有效值芯片不用峰值检波",答精度和小信号线性度,顺带说清成本权衡;问"扫频为什么是对数不是线性",答截止频率跨数量级分布、对数轴上−3dB 点插值更准;问"故障判断的边界在哪",如实说单一故障能覆盖、复合故障会失效,比硬撑"全能"可信得多。最后一个问题往往是加分项,因为它考的是你对自己方案的理解深度。

从那以后我每次做测量类项目,都强制先把测试记录表的表头画出来,再动手写第一行代码——指标定不下来,后面所有的选型和算法都是猜。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进