1. 为什么交流分析是SPICE仿真里最容易被低估的一环
很多人第一次接触SPICE,都是从直流工作点或者瞬态分析入门的。搭个分压电路,跑个.op,看一眼节点电压,觉得仿真不过如此。再进阶一点,跑个.tran,看个方波响应,示波器波形一出来,感觉已经掌握了电路仿真的精髓。但真正到了设计滤波器、放大器、反馈环路、振荡器的时候,你会发现,光看时域波形根本不够用——你需要知道这个电路在不同频率下的表现,需要知道相位裕度够不够,需要知道在哪个频点会自激。这时候,交流分析(AC Analysis)就登场了。
SPICE中的交流分析,本质上是一种小信号线性化频域分析。它做的事情,是把电路在某个直流工作点附近线性化,然后在这个线性化模型上,用不同频率的正弦小信号去激励,观察电路的幅频响应和相频响应。注意这里有两个关键词:小信号和线性化。这意味着交流分析不会告诉你大信号下的失真情况,也不会告诉你电路会不会因为摆率限制而出现非线性行为。它给你的,是一个在特定工作点附近的线性化频域画像。
这个画像有什么用?举几个实际场景。你在设计一个运放电路,想知道它的闭环带宽和相位裕度,交流分析可以直接给你开环增益曲线和相位曲线,你从图上就能读出穿越频率和相位裕度。你在设计一个LC滤波器,想知道它的-3dB截止频率和阻带衰减斜率,交流分析扫一遍频率就一目了然。你在设计一个反馈系统,想知道它会不会振荡,交流分析给出的环路增益波特图就是最直接的判据。甚至你在用74HC14这种施密特触发器做振荡器的时候,虽然它本身是非线性器件,但通过合理设置交流分析的激励方式,也能大致判断振荡频率的量级。
但问题在于,很多教程讲交流分析,只告诉你“加个AC源,写个.ac dec 10 1 1Meg,然后看波特图”。至于为什么是dec而不是oct或lin,为什么是10个点而不是100个点,AC源的幅值设多少合适,交流分析的结果为什么和瞬态仿真对不上,这些问题很少有人讲透。我见过太多人跑完交流分析,看着曲线一脸茫然,不知道从哪读起,也不知道结果可不可信。这篇文章就围绕这些实际问题展开,把SPICE交流分析的里里外外讲清楚。
2. 交流分析的核心机制与仿真器内部逻辑
2.1 小信号线性化到底做了什么
要理解交流分析,先得理解SPICE仿真器在跑.ac之前做了什么。当你写下.ac dec 100 1 10k这条指令时,仿真器并不是直接跳到频域去算的。它的第一步,是先跑一次直流工作点分析。这次直流分析的结果,是所有非线性器件(二极管、三极管、MOS管)在各自工作点附近的等效线性化参数。比如一个BJT,在直流工作点确定后,仿真器会计算出它的小信号跨导gm、输入电阻rπ、输出电阻ro,然后用这些线性元件替换掉原来的非线性模型。一个MOS管也是类似,算出gm、gds、cgs、cgd等小信号参数。
这个过程叫工作点线性化。线性化之后,整个电路就变成了一个纯线性网络,包含电阻、电容、电感、受控源和独立源。对于线性网络,频域分析就变得非常直接:把每个电容替换成1/(jωC),每个电感替换成jωL,然后对整个网络列节点方程,求解复数矩阵。仿真器会在你指定的频率范围内,逐个频点求解这个复数矩阵,得到每个节点的复数电压(幅值和相位)。
这里有一个非常关键的推论:交流分析的结果完全依赖于直流工作点。如果直流工作点不对,比如晶体管偏置在截止区,那么算出来的gm就接近零,交流分析的结果就会完全失真。我见过有人跑交流分析,发现增益是负的几十dB,查了半天电路拓扑,最后发现是偏置电阻焊错了位置,晶体管根本没导通。所以跑交流分析之前,先跑一次.op,确认所有器件的直流工作点合理,这是最基本的操作纪律。
2.2 频率扫描方式的选择逻辑
.ac指令的语法是.ac <扫描类型> <点数> <起始频率> <终止频率>。扫描类型有三种:dec(十倍频程)、oct(倍频程)、lin(线性)。这三种方式的选择不是随意的,它直接决定了你看到的曲线分辨率和仿真速度。
dec表示每个十倍频程内取多少个频点。比如.ac dec 10 1 1Meg,意思是从1Hz到1MHz,每个十倍频程取10个点。1Hz到1MHz一共6个十倍频程,所以总点数是60个。oct表示每个倍频程取多少个点,lin表示在整个频率范围内线性取点。对于大多数频域分析,dec是最常用的,因为波特图的横轴本身就是对数坐标,dec取点在对数坐标下是均匀分布的,曲线看起来最自然。
点数怎么选?10个点通常够看趋势,但如果你要精确找-3dB点或者相位裕度,10个点可能不够。我一般用100个点起步,对于窄带滤波器或者高Q值的谐振电路,甚至会用1000个点。点数越多,仿真越慢,但现代仿真器跑一个几千点的交流分析通常也就几秒钟的事,没必要在这上面省。有一个经验法则:如果你在波特图上看到曲线有明显的折角或者毛刺,那多半是点数不够,加密频点再跑一次。
起始频率和终止频率的设置也有讲究。起始频率不要设0,因为1/(jωC)在ω=0时是无穷大,仿真器会报错。一般从1Hz或者0.1Hz开始。终止频率要覆盖你关心的所有频段,比如音频电路关心到100kHz就够了,射频电路可能要扫到GHz。但也不要盲目扫太宽,频率范围越宽,同样的点数下每个频段的分辨率就越低。
2.3 AC源的设置细节与常见误区
交流分析需要一个交流激励源。在SPICE中,独立电压源或电流源可以同时包含直流分量和交流分量。比如V1 in 0 DC 5 AC 1,表示这个源在直流分析时输出5V,在交流分析时输出幅值为1V的正弦小信号。这里的AC 1就是交流幅值。
这里有一个非常容易踩的坑:AC幅值设多少合适?很多人随手设成1V,觉得方便读数。但交流分析是小信号分析,AC幅值本身不影响结果——因为整个系统是线性的,输入幅值1V和1mV,输出的幅值会等比例缩放,但幅频响应的形状和相位完全一样。所以设1V只是为了读数方便,比如增益为0dB时输出就是1V。但要注意,有些仿真器在计算某些非线性器件的等效参数时,会用到AC幅值来判断扰动大小,虽然理论上不影响,但设一个合理的值(比如1V或1mV)是稳妥的做法。
另一个坑是AC源的相位。默认情况下AC源的相位是0度,但你可以通过AC 1 90这样的语法设置初始相位。在多源电路中,源之间的相位关系会影响输出。比如你在做差分电路分析时,两个输入源的相位差180度,这时候就必须显式设置相位。我见过有人做差分放大器交流分析,两个源都设成0度,结果输出一直是零,查了半天以为是电路问题,其实是激励设置错了。
还有一个更隐蔽的坑:AC源不能和瞬态源混用。有些仿真器允许你在同一个源上同时定义AC和SIN,但交流分析只会用AC后面的值,瞬态分析只会用SIN后面的值。如果你只写了SIN没写AC,交流分析时这个源就是零,输出自然也是零。这个错误在新手里非常常见,因为很多人是从瞬态分析转过来的,习惯性地只写了SIN。
3. 从零搭建一个完整的交流分析实例
3.1 被测电路的选择与搭建
光讲理论没意思,我们直接搭一个实际电路来跑。选一个二阶RC低通滤波器作为被测对象,因为它足够简单,但又能展示交流分析的核心价值。电路拓扑是这样的:输入节点in,经过一个电阻R1到节点mid,再从mid经过一个电阻R2到输出节点out,mid到地接一个电容C1,out到地接一个电容C2。这是一个经典的二阶低通滤波器,截止频率由R和C的值决定。
取R1=R2=1kΩ,C1=C2=100nF。截止频率的理论值大约是1/(2π√(R1R2C1C2)),代入数值算一下:√(1k×1k×100n×100n) = √(1e-8) = 1e-4,所以2π×1e-4 ≈ 6.28e-4,截止频率约1591Hz。这个值后面可以用来验证仿真结果。
在SPICE网表中,这个电路可以这样写:
* Second-order RC Low-Pass Filter V1 in 0 DC 0 AC 1 R1 in mid 1k R2 mid out 1k C1 mid 0 100n C2 out 0 100n .ac dec 100 10 100k .plot ac vdb(out) vp(out) .end注意V1的定义:DC 0 AC 1,直流分量为0,交流幅值为1。因为这是一个无源RC网络,没有直流偏置问题,所以直流分量设0没问题。.ac dec 100 10 100k表示从10Hz到100kHz,每个十倍频程100个点。.plot指令用来输出幅频和相频曲线,vdb(out)是输出节点的电压分贝值,vp(out)是相位。
3.2 仿真结果解读与理论验证
跑完仿真,你会得到两条曲线。幅频曲线在低频段是0dB,因为电容开路,电阻分压比为1。随着频率升高,电容开始起作用,增益逐渐下降。在截止频率附近,增益下降到-3dB,然后以-40dB/十倍频程的斜率下降。相频曲线从0度开始,在截止频率附近下降到-90度,最终趋向-180度。
这里有一个细节值得注意:二阶RC滤波器的两个电容不是独立的,它们之间存在相互作用。如果你用一阶RC的公式去套,会发现在截止频率附近的理论值和仿真值有偏差。精确的传递函数是H(s) = 1/(1 + s(R1C1 + R1C2 + R2C2) + s²R1R2C1C2)。代入数值算一下,R1C1 + R1C2 + R2C2 = 1k×100n + 1k×100n + 1k×100n = 3e-4,R1R2C1C2 = 1e-8。所以传递函数是1/(1 + 3e-4s + 1e-8s²)。这是一个二阶系统,阻尼系数ζ = 3e-4/(2√1e-8) = 3e-4/(2e-4) = 1.5,大于1,说明系统是过阻尼的,没有峰值。仿真结果应该和这个传递函数完全吻合。
如果你把C2去掉,只留C1,那就变成了一阶RC滤波器,截止频率是1/(2πR1C1) = 1/(2π×1k×100n) ≈ 1591Hz,斜率为-20dB/十倍频程。你可以自己改一下网表跑一遍,对比两种电路的波特图,感受一下阶数对滤波特性的影响。
3.3 用74HC14做振荡器的交流分析尝试
前面提到74HC14的SPICE模型,这是一个很有意思的话题。74HC14是施密特触发反相器,本身是非线性器件,严格来说不适合直接做交流分析。但如果你把它的SPICE模型打开看,会发现模型内部通常包含一个反相器核心加上一些寄生电容和电阻。在直流工作点附近,如果偏置在翻转阈值附近,仿真器会把它线性化成一个反相放大器,这时候跑交流分析,可以看到它的小信号增益和带宽。
具体怎么做?把74HC14的输入端通过一个电阻分压偏置到翻转阈值附近(比如VCC/2),然后加一个AC源,跑交流分析,看输出端的幅频响应。你会发现它在低频段有很高的增益(因为反相器在阈值附近增益最大),随着频率升高,增益下降,相位从180度开始变化。这个仿真可以帮你估算振荡器的起振条件和大致频率范围。
但要注意,这种分析只能给出定性参考,不能精确预测振荡频率。因为施密特触发器的翻转阈值有迟滞,实际振荡频率还取决于RC充放电时间,这些是非线性效应,交流分析覆盖不了。我一般用交流分析来快速判断“这个电路有没有可能振荡”,然后用瞬态分析来精确测量振荡频率和波形。两者结合,效率最高。
4. 交流分析中的典型问题与排查手册
4.1 曲线异常时的排查思路
跑交流分析最让人头疼的就是曲线不对。明明电路拓扑没问题,参数也检查过了,但波特图就是和预期对不上。这时候不要慌,按下面的顺序排查。
第一步,确认直流工作点。把.ac指令临时改成.op,跑一次直流分析,看所有节点的电压和所有器件的电流是否合理。如果某个晶体管处于截止区或者饱和区,交流分析的结果必然不对。这一步能排除掉大部分问题。
第二步,确认AC源设置。检查激励源是否有AC参数,幅值是否非零,相位是否正确。如果电路中有多个源,检查它们的相位关系是否符合预期。一个快速验证方法:把AC源直接接到一个已知电阻上,跑交流分析,看电流是否等于V/R。如果不对,说明源设置有问题。
第三步,确认频率范围。如果起始频率设得太高,可能错过了低频段的平坦区;如果终止频率设得太低,可能看不到高频段的滚降。把频率范围放宽再跑一次,看看曲线是否完整。
第四步,确认点数。如果曲线看起来有很多毛刺或者折角,增加点数再跑。有时候曲线看起来“不对”,其实只是分辨率不够。
第五步,检查单位。SPICE中1k是1000,1meg是1e6,1m是1e-3。很多人把1meg写成1m,结果频率范围差了六个数量级。这个错误极其常见,而且极其隐蔽,因为仿真器不会报错,只是结果完全不对。
4.2 交流分析与瞬态分析结果对不上的原因
这是一个经典问题:交流分析显示-3dB带宽是1kHz,但瞬态分析加一个方波,发现上升时间对应的带宽只有500Hz。为什么对不上?
原因通常有三个。第一,交流分析是小信号线性化,瞬态分析是大信号非线性。如果电路中有压摆率限制或者饱和效应,瞬态响应会比小信号预测的慢。第二,交流分析假设输入是正弦小信号,瞬态分析的方波包含丰富的高次谐波,这些谐波可能超出线性范围。第三,交流分析的带宽定义是幅值下降-3dB,而瞬态分析的上升时间定义是10%到90%,两者之间的换算关系是BW ≈ 0.35/tr,但这个公式只适用于一阶系统,高阶系统会有偏差。
我一般用交流分析来指导设计,用瞬态分析来验证设计。如果两者偏差在20%以内,通常可以接受;如果偏差很大,就要检查是不是有非线性效应被忽略了。
4.3 常见问题速查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 输出全为零 | AC源未设置或幅值为零 | 检查源的AC参数 |
| 增益曲线平坦无滚降 | 频率范围太窄或电容值太小 | 放宽频率范围,检查电容值 |
| 相位曲线跳变 | 点数太少或存在多个极点 | 增加点数,检查电路阶数 |
| 仿真报错“singular matrix” | 存在悬空节点或电容直连 | 检查节点连接,加大电阻到地 |
| 结果与理论偏差大 | 直流工作点不对 | 先跑.op确认工作点 |
| 高频段增益异常上升 | 模型中有寄生反馈路径 | 检查器件模型和寄生参数 |
提示:每次修改电路后,先跑
.op确认工作点,再跑.ac。这个习惯能帮你省下大量排查时间。
4.4 几个我踩过的坑
第一个坑:用电容直接耦合交流源。有人为了隔直,在AC源和电路之间串了一个大电容。这在瞬态分析里没问题,但在交流分析里,这个电容的容抗会随频率变化,低频段容抗很大,导致实际加到电路上的信号幅值远小于1V。结果就是低频段增益看起来很低,误以为电路有问题。正确做法是直接用AC源,或者用足够大的电容(比如1F)让容抗在关心频段内可忽略。
第二个坑:忽略了仿真器的默认温度。SPICE默认温度是27°C,但有些器件的模型参数对温度敏感。如果你在高温下测试过电路,仿真时忘了设温度,结果会对不上。.temp 85可以设置仿真温度。
第三个坑:用.plot而不是.print。.plot是图形输出,.print是文本输出。有些老版本仿真器对.plot的支持不好,曲线显示不全。如果.plot出来的图不对,试试.print ac vdb(out) vp(out),看文本数据是否正常。文本数据正常而图形不对,那就是后处理的问题,不是仿真本身的问题。
5. 进阶技巧:让交流分析更贴近实际
5.1 用.step指令批量扫描参数
如果你想知道某个元件值变化对频响的影响,比如反馈电容从1pF变到10pF,带宽怎么变,不需要手动改网表跑多次。用.step指令可以自动扫描。语法是.step param Cx 1p 10p 1p,配合.param Cx=1p使用。仿真器会自动跑10次,每次Cx取不同的值,然后把所有曲线画在同一张图上。这个功能在优化电路参数时非常高效。
我一般用.step来扫描反馈电阻、补偿电容、负载电容这些关键参数,一次跑出十几条曲线,一眼就能看出趋势。比手动改参数跑仿真快十倍不止。
5.2 用.meas指令自动提取关键指标
看曲线读数是件很累的事,尤其是要找-3dB点或者相位裕度的时候。.meas指令可以自动测量。比如.meas ac bw when vdb(out)=-3,仿真器会自动找到增益下降到-3dB时的频率,并输出这个值。.meas ac phase_margin find vp(out) when vdb(out)=0可以找到增益穿越0dB时的相位值。
这些测量指令可以写在网表里,每次仿真自动输出结果,不需要人工读数。对于需要反复迭代的设计,这个功能能省下大量时间。我习惯在网表末尾加几条.meas,跑完仿真直接看输出日志,关键指标一目了然。
5.3 交流分析在反馈环路设计中的特殊用法
反馈环路的稳定性分析是交流分析最有价值的应用场景之一。但直接跑闭环交流分析是看不出稳定性的,你需要跑环路增益。方法是在反馈环路中插入一个交流源,通常放在反馈节点和误差放大器之间。这个源要设置成AC 1,DC 0,这样它不影响直流工作点,只在交流分析时注入扰动。
然后分别测量注入点两侧的电压,环路增益就是Vreturn/Vinject。在波特图上,如果环路增益在相位达到-180度之前就下降到0dB以下,系统就是稳定的。相位裕度就是增益穿越0dB时的相位与-180度的差值。一般要求相位裕度大于45度,最好在60度左右。
这个方法的难点在于找到合适的注入点。注入点必须保证直流反馈路径不被破坏,同时交流信号能顺利注入。我一般选择在反馈电阻和误差放大器输入之间注入,因为这个点的直流阻抗匹配容易处理,交流注入也方便。
5.4 高频段的模型选择与寄生参数影响
低频段跑交流分析,理想模型通常够用。但到了高频段,器件的寄生参数就开始起作用了。比如一个MOS管,在低频段你只需要关心gm和gds,但到了高频段,cgs、cgd、cdb这些寄生电容会显著影响频响。如果你的仿真结果和实测在高频段对不上,多半是模型不够精确。
解决方法是使用更精确的器件模型,或者在电路中外挂寄生电容。比如你知道PCB上有一条走线大约有2pF的寄生电容,就在对应节点到地加一个2pF的电容。这样仿真结果会更接近实际。但要注意,寄生参数不是越多越好,加太多会让仿真变慢,而且有些寄生参数你根本不知道准确值。我一般只加那些对结果影响最大的寄生参数,比如高频节点的对地电容和串联电感。
注意:高频仿真时,仿真器的默认设置可能不够精确。检查一下是否有
RELTOL、ABSTOL、VNTOL这些收敛参数的设置,必要时调小它们以提高精度。但调太小会导致仿真变慢甚至不收敛,需要权衡。
6. 从仿真到实测的衔接经验
仿真跑得再好,最终还是要落到实际电路上。我这些年最大的体会是:交流分析的结果和实测的偏差,主要来自三个方面。第一是器件模型的精度,尤其是电感和电容的寄生参数,以及半导体器件的高频模型。第二是PCB布局带来的寄生效应,比如走线电感、焊盘电容、地平面阻抗。第三是测量设备的带宽和探头负载效应。
我的做法是:仿真时留足够的裕量。比如仿真显示相位裕度60度,实际电路可能只有45度,所以设计目标定在70度以上。仿真显示带宽1MHz,实际可能只有800kHz,所以设计目标定在1.2MHz以上。留裕量不是保守,而是对模型不确定性的尊重。
另外,实测时要注意测量方法。用示波器看波特图,需要扫频信号源和幅相接收机,或者用网络分析仪。如果用手动逐点测量,效率极低而且容易出错。我一般先用仿真确定大致范围,然后只在关键频点做实测验证,比如截止频率、谐振频率、相位穿越频率。这样既能验证仿真,又不用花太多时间。
最后分享一个小技巧:如果你手头没有昂贵的频响分析设备,可以用一个信号发生器和示波器做简易的频响测量。信号发生器输出正弦波,示波器同时看输入和输出,手动改变频率,记录幅值和相位差。虽然慢,但对于低频电路(几百kHz以下)完全够用。我早期做音频滤波器的时候就是这么干的,一个频点一个频点地测,虽然笨,但数据很扎实。
这个内容后续还可以这样扩展:把交流分析和蒙特卡洛分析结合起来,看看元件容差对频响的影响;或者把交流分析和温度扫描结合起来,看看温漂对带宽的影响。这些进阶玩法在实际工程中非常有用,尤其是做高可靠性设计的时候。