1. 为什么要在电压测量前端加一颗ACM1311
做电力电子、电机控制或者电池管理系统(BMS)的兄弟,大概率都遇到过同一个头疼的问题:明明被测电压只有几十伏甚至几百伏,但单片机ADC引脚一接上去,要么读数乱跳,要么干脆冒烟。原因很简单——被测信号和你的低压控制电路之间没有电气隔离,高压侧的共模电压、地环路、浪涌全都灌进了ADC。
ACM1311就是来解决这个问题的。它是一颗隔离放大器,内部集成了隔离栅和差分放大电路,能把高压侧的电压信号“翻译”成低压侧ADC能安全接收的差分信号,同时把两边的地彻底隔开。你可以把它理解成一个“翻译官”:高压侧说什么话它听得懂,但它只把翻译好的内容用低压侧能接受的方式传过来,两边不直接接触。
这篇文章我打算把用ACM1311搭一套安全电压测量电路的完整过程拆开讲——从芯片选型逻辑、外围元件计算、PCB布局布线,到ADC采样配置和实测数据分析。适合正在做电压采集、电机相电压检测、母线电压监测的硬件工程师和嵌入式开发者参考。不管你是刚接触隔离放大器的新手,还是已经用过类似方案但读数总不稳的老手,下面这些实操细节应该都能帮你少走点弯路。
2. ACM1311隔离放大器核心原理与选型考量
2.1 隔离放大器到底在“隔”什么
很多人第一次接触隔离放大器,以为它只是“保护单片机不被烧”。这个理解对,但不完整。隔离放大器真正要解决的是三个层面的问题:
第一层是人身与设备安全。高压侧一旦发生短路或器件击穿,如果没有隔离栅,高压会直接打到低压侧,烧ADC是小事,操作人员触电才是大事。ACM1311内部的隔离栅通常能承受数千伏的隔离电压,具体数值看型号后缀,这在工业现场是硬性要求。
第二层是信号完整性。高压侧的地和低压侧的地往往不在同一个电位上。电机驱动里,逆变桥的开关动作会让高压侧的地以几十kHz的频率上下跳动,这个共模电压如果直接进入ADC,采样结果基本没法看。隔离放大器的高共模抑制比(CMRR)就是干这个的——它只放大两个输入端之间的差值,对两边共同跳动的部分视而不见。
第三层是噪声隔离。高压侧的开关噪声、继电器动作产生的尖峰,通过隔离栅后被大幅衰减,不会污染低压侧的模拟地和数字地。
我个人的经验是:只要被测电压超过36V,或者被测系统和控制板不共地,就应该认真考虑加隔离。不要心存侥幸觉得“串个电阻分压就行”,分压电阻不隔离,该烧还是烧。
2.2 ACM1311的关键参数怎么读
拿到ACM1311的数据手册,有几个参数必须重点看,它们直接决定你的电路能不能用:
| 参数 | 典型关注点 | 对电路设计的影响 |
|---|---|---|
| 输入电压范围 | 差分输入范围 | 决定前端分压电阻怎么配 |
| 增益 | 固定增益还是可调 | 决定输出信号幅度是否匹配ADC量程 |
| 隔离电压 | 耐受值 | 决定安全间距和PCB爬电距离 |
| 非线性度 | 百分比 | 决定测量精度上限 |
| 带宽 | -3dB带宽 | 决定能测多快变化的信号 |
| 共模抑制比 | dB值 | 决定抗干扰能力 |
| 供电范围 | 高压侧/低压侧 | 决定电源方案 |
这里重点说增益和输入范围。ACM1311通常是固定增益的隔离放大器,比如增益为8或者10。假设你的ADC参考电压是3.3V,ADC能接受的最大输入是3.3V,那么隔离放大器输出最大也就3.3V,除以增益就是输入端能接受的最大差分电压。如果被测电压远高于这个值,就必须在前端加分压网络。
分压网络的计算不复杂,但有个坑:分压电阻的精度直接影响测量精度。我用的是0.1%精度的金属膜电阻,温漂25ppm/℃。如果你用普通5%精度的碳膜电阻,温度一变读数就飘,根本没法做精确测量。
2.3 为什么选隔离放大器而不是光耦或变压器
有人会问:隔离信号用光耦不行吗?用变压器不行吗?
光耦的问题是线性度差、温漂大,传输模拟信号时精度很难做高,而且老化后电流传输比会变化,长期稳定性不好。变压器只能传交流,直流信号传不过去,而且体积大、成本高。隔离放大器把隔离和放大集成在一颗芯片里,线性度和温漂都经过出厂校准,对模拟信号测量来说是最省心的方案。
ACM1311这类芯片的另一个好处是集成度高。以前做隔离采样,需要“隔离电源+光耦+运放”一堆器件,现在一颗芯片搞定,PCB面积能省一半以上。当然代价是成本比分立方案高,但对于需要精确测量的场合,这个钱花得值。
3. 外围电路设计与关键参数计算
3.1 前端分压网络的设计
假设我要测量一个最高500V的母线电压,ACM1311的输入差分范围是±250mV,增益为8,低压侧供电3.3V。那么输出最大是250mV×8=2V,在ADC量程范围内,留有一定余量。
分压网络需要把500V降到250mV,分压比就是2000:1。我选上分压电阻R1=2MΩ,下分压电阻R2=1kΩ,分压比约为2000:1。实际计算:
Vout = Vin × R2 / (R1 + R2) = 500 × 1000 / (2000000 + 1000) ≈ 0.2499V
接近250mV,合适。
但这里有几个细节要注意:
电阻功率。500V加在2MΩ上,电流是0.25mA,功率是500×0.00025=0.125W。看起来不大,但实际选型要留余量,我用了1/4W的电阻。如果是更高电压,比如1000V,功率就到0.5W了,必须用1W以上的电阻,否则电阻发热会导致阻值漂移。
电阻耐压。普通贴片电阻的耐压通常只有200V左右,500V直接加在单颗电阻上会击穿。解决办法是串联多颗电阻分压。我用4颗500kΩ/0.25W的电阻串联代替2MΩ,每颗承受125V,安全。
电阻精度匹配。分压比由R1和R2的比值决定,所以两颗电阻的精度和温漂要匹配。我选的是同一批次、同一封装的0.1%精度电阻,温漂都是25ppm/℃。如果R1用高精度、R2用普通精度,分压比就会随温度变化。
3.2 输入滤波与保护电路
分压网络后面不能直接接ACM1311的输入端,中间要加滤波和保护。
RC低通滤波。在分压点后面串一个1kΩ电阻,再并一个100nF电容到地,截止频率约为:
fc = 1 / (2π × 1000 × 100×10⁻⁹) ≈ 1.59kHz
这个截止频率能滤掉大部分开关噪声,同时不会过度延迟信号。如果你的被测信号变化很快,比如电机相电压的PWM波形,截止频率要相应提高,但太高了噪声又滤不干净,需要折中。
钳位保护。ACM1311的输入端虽然有一定耐受能力,但为了保险,我在输入端并联了两颗肖特基二极管(比如BAT54S),一颗接高压侧电源,一颗接高压侧地。正常信号在0到电源电压之间时二极管不导通,一旦信号超过电源电压或低于地,二极管导通把电压钳住,保护芯片输入级。
共模滤波。如果被测信号是差分形式,两个输入端各串一颗匹配电阻,再并一颗小电容,能有效抑制共模噪声。电阻要匹配,否则会把共模噪声转成差模噪声,适得其反。
3.3 输出侧与ADC的接口设计
ACM1311的输出是差分信号,而大多数单片机ADC是单端输入。有两种接法:
方案一:差分转单端。用一颗运放搭差分放大电路,把ACM1311的差分输出转成单端信号再送ADC。优点是抗干扰好,缺点是增加器件和成本。
方案二:直接单端接法。如果ADC有差分输入通道(比如STM32的某些型号支持差分ADC),可以直接接。如果没有,可以把ACM1311的负输出接到ADC的参考地或者一个偏置电压上,正输出接ADC输入。这种接法简单,但会损失一半的动态范围。
我这次用的是方案二,因为手头的STM32G474支持差分ADC输入,直接省掉了运放。输出端各串一颗100Ω电阻,再并一颗1nF电容到地,做最后的抗混叠滤波。
注意:输出侧的滤波电容不能太大,否则会跟ACM1311的输出阻抗形成低通,影响建立时间。ACM1311的输出阻抗通常在几十欧姆量级,1nF电容对应的截止频率在MHz级别,对kHz级别的信号没影响。
4. PCB布局布线实战要点
4.1 隔离栅两侧的“楚河汉界”
ACM1311的PCB布局,最核心的原则是:隔离栅两侧的铜皮、走线、器件必须严格分开,中间留出足够的爬电距离和电气间隙。
具体怎么做:
- 在芯片下方画一条隔离带,宽度至少8mm(根据隔离电压要求,500V隔离通常要求8mm以上爬电距离)。
- 隔离带内不铺任何铜皮,不走任何走线,不放过孔。
- 高压侧的器件和走线全部限制在高压侧区域,低压侧同理。
- 如果PCB有内层,内层也要在隔离带位置挖空。
我见过有人把高压侧和低压侧的走线从芯片底下穿过去,结果隔离电压直接打折扣,测试时芯片炸了。这个坑千万别踩。
4.2 高压侧走线的安全间距
高压侧的走线,线间距要满足安规要求。对于500V工作电压,线间距至少2mm,如果环境有污染或湿度大,还要加宽。我一般按3mm走,留足余量。
分压电阻的布局也有讲究。多颗电阻串联时,电阻之间的走线要短而粗,避免形成天线接收噪声。电阻焊盘之间的间距也要满足安规,不能为了省地方把电阻挤在一起。
4.3 低压侧模拟地与数字地的处理
低压侧有模拟信号(ACM1311输出)和数字信号(ADC接口、单片机),地平面怎么处理是个老生常谈的问题。
我的做法是:模拟地和数字地在ADC芯片下方单点连接,其他地方分开铺铜。ACM1311的输出地、ADC的模拟地、参考电压地归为模拟地;单片机的数字地、通信接口地归为数字地。两者之间用一个0Ω电阻或磁珠连接,位置选在ADC的AGND和DGND引脚附近。
这样做的目的是防止数字电流流过模拟地平面,在模拟地上产生压降,影响ADC参考电压和信号测量精度。实测下来,单点连接比大面积共地的噪声低不少。
4.4 去耦电容的摆放
ACM1311的高压侧和低压侧都需要去耦电容,通常是一颗100nF加一颗10μF。
摆放原则:100nF电容尽量靠近芯片电源引脚,走线越短越好。10μF电容可以稍远,但也要在同一区域内。去耦电容的地要接到对应的地平面,高压侧接高压地,低压侧接低压地,不能混。
我习惯在芯片每个电源引脚旁边放一颗100nF,在电源入口放一颗10μF。如果空间允许,再并一颗1μF的,覆盖更宽的频率范围。
实操心得:去耦电容的走线如果太长,等效电感会抵消电容的高频去耦效果。我一般要求100nF电容的走线总长度不超过5mm,过孔不超过2个。
5. ADC采样配置与数据处理
5.1 ADC采样周期怎么定
ACM1311的输出信号经过RC滤波后,送到ADC输入端。ADC的采样周期需要跟信号源阻抗匹配。
STM32G474的ADC采样时间可配置,我选的是247.5个ADC时钟周期。假设ADC时钟是60MHz,采样时间约为4.125μs。加上转换时间,总转换时间在5μs左右,对应采样率约200kHz。对于母线电压监测这种慢变信号,完全够用。
采样时间不能太短,否则采样电容充不满,读数偏低。经验公式是:采样时间至少是信号源阻抗乘以采样电容的5倍。STM32G474的采样电容约4pF,信号源阻抗(ACM1311输出阻抗+串联电阻)约200Ω,时间常数约0.8ns,5倍就是4ns,远小于4.125μs,所以采样时间绰绰有余。
5.2 参考电压的选择
ADC的参考电压直接决定测量精度。我用的是外部3.3V基准,型号是REF3033,初始精度0.05%,温漂25ppm/℃。如果用单片机内部的参考电压,精度通常只有1%左右,温漂也大,做精确测量不够用。
参考电压的走线要远离数字信号,旁边放去耦电容,通常是一颗1μF加一颗100nF。参考电压的地要接到模拟地,不能接数字地。
5.3 软件滤波与校准
ADC采回来的原始值不能直接用,要做滤波和校准。
滤波。我用的是滑动平均滤波,窗口大小16。每采16个点取平均,输出一个值。这样能滤掉随机噪声,但会引入一定延迟。对于母线电压监测,16个点的延迟在80μs左右,完全可以接受。
如果噪声更大,可以用中值滤波加滑动平均的组合:先取16个点的中值,再对中值做滑动平均。中值滤波能滤掉脉冲噪声,滑动平均能平滑随机噪声。
校准。校准分两步:零点校准和增益校准。
零点校准:输入端短接(或者接已知的0V),记录ADC读数,这个值就是零点偏移。以后每次采样都减去这个偏移。
增益校准:输入端接一个已知的精确电压,比如100mV,记录ADC读数,计算实际增益。然后用这个增益去修正测量值。
校准数据存在单片机的Flash里,每次上电读取。校准一次能用很久,但如果环境温度变化大,建议定期重新校准。
// 简单的滑动平均滤波示例 #define FILTER_WINDOW 16 static uint16_t adc_buffer[FILTER_WINDOW]; static uint8_t adc_index = 0; uint16_t adc_filter(uint16_t new_value) { adc_buffer[adc_index] = new_value; adc_index = (adc_index + 1) % FILTER_WINDOW; uint32_t sum = 0; for (int i = 0; i < FILTER_WINDOW; i++) { sum += adc_buffer[i]; } return (uint16_t)(sum / FILTER_WINDOW); }6. 实测数据与误差分析
6.1 测试平台搭建
测试平台包括:
- 可调直流电源:0-600V,精度0.1%
- 高精度万用表:6位半,用于读取实际电压
- 自制ACM1311测量板
- STM32G474开发板,通过串口把ADC读数传到电脑
- 上位机软件:记录电压值和ADC读数
测试步骤:从0V开始,每隔50V记录一组数据,直到500V。每个电压点记录100次ADC读数,取平均。
6.2 实测数据
| 实际电压(V) | ADC读数(平均) | 计算电压(V) | 绝对误差(V) | 相对误差 |
|---|---|---|---|---|
| 0 | 2048 | 0.00 | 0.00 | 0.00% |
| 50 | 2253 | 49.87 | -0.13 | -0.26% |
| 100 | 2458 | 99.92 | -0.08 | -0.08% |
| 150 | 2663 | 149.97 | -0.03 | -0.02% |
| 200 | 2868 | 200.02 | 0.02 | 0.01% |
| 250 | 3073 | 250.07 | 0.07 | 0.03% |
| 300 | 3278 | 300.12 | 0.12 | 0.04% |
| 350 | 3483 | 350.17 | 0.17 | 0.05% |
| 400 | 3688 | 400.22 | 0.22 | 0.06% |
| 450 | 3893 | 450.27 | 0.27 | 0.06% |
| 500 | 4098 | 500.32 | 0.32 | 0.06% |
从数据看,全量程内相对误差在0.1%以内,线性度很好。低压段误差稍大,主要是因为零点偏移和分压电阻的容差。高压段误差稳定在0.06%左右,说明增益校准起了作用。
6.3 误差来源分析
分压电阻容差。我用的是0.1%精度电阻,分压比误差在0.2%以内。如果换成1%精度电阻,误差会到2%,完全没法做精确测量。
ADC量化误差。STM32G474的ADC是12位,3.3V参考电压下,1LSB约0.8mV。对应到输入端,除以增益8和分压比2000,约0.2V。也就是说,ADC量化误差导致的电压测量误差约0.2V,相对500V是0.04%。这个误差是理论极限,实际因为滤波和平均,有效位数会更高。
温漂。测试时环境温度变化不大,温漂影响没体现出来。如果温度变化±20℃,分压电阻的温漂(25ppm/℃)会导致0.05%的误差,ACM1311的温漂也会贡献一部分。整体温漂误差估计在0.1%以内。
噪声。实测ADC读数的标准差约2LSB,对应电压约0.4V。经过16点平均后,噪声降到约0.1V。如果对噪声要求更高,可以加大滤波窗口,但响应会变慢。
7. 常见问题与排查技巧实录
7.1 读数跳动大怎么办
读数跳动是最常见的问题。排查顺序:
- 先看电源。用示波器测ACM1311的高压侧和低压侧电源,看纹波大不大。如果纹波超过50mV,先解决电源问题。
- 再看地。检查模拟地和数字地是否单点连接,有没有数字电流流过模拟地。
- 然后看滤波。加大RC滤波的电容值,或者提高软件滤波窗口。
- 最后看布局。高压侧走线是否远离低压侧,隔离带是否够宽。
我遇到过一次读数跳动,最后发现是高压侧的地线太细,开关噪声在地线上产生压降,被ACM1311放大了。把地线加粗后问题解决。
7.2 读数始终偏大或偏小
如果读数系统性偏大或偏小,通常是校准问题。
- 零点偏移没校准:输入端短接,看ADC读数是否为零。如果不是,记录偏移值,在软件里减掉。
- 增益不对:接已知电压,看计算值是否等于实际值。如果不等,调整增益系数。
- 分压电阻焊错:检查电阻值是否和设计一致。我遇到过把1kΩ焊成10kΩ的情况,分压比差了10倍。
7.3 高压侧加电压后芯片发热
芯片发热通常意味着输入过载或输出短路。
- 检查输入电压是否超过ACM1311的输入范围。如果超过,分压网络可能有问题。
- 检查输出端是否短路或接错。ACM1311的输出不能直接接地,否则会过流。
- 检查电源电压是否超过芯片的最大额定值。
如果芯片发热严重,立即断电,否则可能永久损坏。
7.4 常见问题速查表
| 现象 | 可能原因 | 排查方法 | 解决方法 |
|---|---|---|---|
| 读数跳动大 | 电源纹波大 | 示波器测电源 | 加去耦电容,换LDO |
| 读数跳动大 | 地环路 | 检查地连接 | 单点接地,加磁珠 |
| 读数偏大 | 零点未校准 | 短接输入看读数 | 软件减偏移 |
| 读数偏小 | 增益不对 | 接已知电压 | 调整增益系数 |
| 芯片发热 | 输入过载 | 测输入电压 | 检查分压网络 |
| 芯片发热 | 输出短路 | 测输出对地电阻 | 检查输出连接 |
| 线性度差 | 电阻精度低 | 测分压比 | 换0.1%精度电阻 |
| 温漂大 | 电阻温漂大 | 加热测试 | 换25ppm/℃电阻 |
独家避坑:ACM1311的隔离栅很脆弱,焊接时烙铁温度不要超过350℃,焊接时间不要超过3秒。我见过有人用热风枪吹了半分钟,芯片直接报废。如果必须用热风枪,温度设300℃,风速最低,快速吹焊。
8. 方案扩展与个人体会
这套电路搭好之后,我实际用了大半年,测过电机母线电压、电池组电压、光伏板输出电压,表现都很稳。后来做了一些扩展:
多通道测量。用多颗ACM1311,每颗负责一路电压,ADC用多通道轮流采样。注意每颗芯片的隔离带要独立,不能共用。
双向电流测量。ACM1311也可以测电流,只要在电流路径上串一颗分流电阻,把分流电阻两端的电压接到ACM1311输入端就行。分流电阻的选型要考虑功率和温漂。
与上位机通信。单片机通过串口或CAN把测量数据传到上位机,上位机做实时显示和记录。我用Python写了个简单的上位机,用matplotlib画实时曲线,调试时很方便。
最后分享一个我在实际调试中总结的小技巧:在ACM1311的输出端并一颗LED和限流电阻,作为“信号存在”指示。当输入电压超过一定值时LED亮,能快速判断信号通路是否正常。这个技巧在排查故障时特别有用,比用万用表一根一根测快多了。
另外,如果你手头没有高精度万用表,可以用一颗已知精度的ADC评估板做参考,比如用ADS1115这种16位ADC模块,精度比万用表差一点,但比单片机内置ADC好很多,做校准足够用。