ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于ATmega644与eFuse的嵌入式电源路径保护设计实践

基于ATmega644与eFuse的嵌入式电源路径保护设计实践 去年给一套现场设备做控制系统改造的时候我被电源问题折磨了将近一周。设备装在远处电源线拉得长电机一启动母线电压就能从 24V 掉到 17V而一旦堵转电流直接蹿到 20A 以上。最难受的不是过流本身而是短路瞬间把同一母线上传感器和通信模块的供电一起拽崩明明故障灯亮了上位机却连不上只能靠人去现场断电重启。试过加大电容、换滤波磁珠效果都很一般。后来我把思路从“滤”改成“断”给每路非关键负载配上一颗 TPS259483AYWPR 这样的 eFuse再用一块 ATmega644 在旁边负责状态监测、故障判定和自动恢复才真正解决了问题。这套结构也成了我现在做嵌入式电源路径保护的首选方案。如果你也经常被后级短路、热插拔、瞬间过流搞得头大这篇文章值得从头看到尾。1. 为什么 ATmega644 和 eFuse 会搭在一起我的需求背景1.1 工业应用里电源路径到底有多容易出问题我碰到的案例不是个例。在工业控制柜里常见的拓扑是 24V 总线进来经过板载 DC-DC 得到 12V 或 5V 中间母线再分别供给传感器、通信模块、继电器、电机驱动器等负载。这种多负载共享直流母线的结构天生就存在几个风险热插拔工作人员带板带电插拔时接插件接触瞬间会对母线电容产生很大的冲击电流轻则拉低电压重则打火花烧触点。后级短路某一路负载内部发生短路时如果没有保护器件整个母线电压都会被拉垮其余所有模块跟着断电复位。堵转与瞬时过流电机堵转、加热器冷态电阻小、电容性负载开机充电这些都会在几十毫秒内抽取远超正常的电流。感性负载断开时的反向冲击继电器或电机在断电瞬间会产生较大的反向电动势在母线上形成尖峰。这些问题不是靠加大电容就能解决的。电容是储能但短路是低阻路径电容只会加剧放电。真正需要的是一个“快速断流开关”在几十微秒内把故障负载和母线隔离开同时把正常工作的模块留在线路上。1.2 熔断器、PTC、分立 MOS 方案为什么都不让我满意做电源路径保护常见的“传统方案”有四种我都试过。熔断器最便宜但熔断之后只能换没法远程复位而且熔断时间不确定无法应对瞬间的窄脉冲过流。PTC 自恢复保险丝虽然能复位但是动作速度慢电阻值随温度漂移精度很差而且长时间处于过温状态后寿命衰减严重。分立 PMOS 加比较器的方案我在早期用过它是用一个采样电阻把电流信号拉出来和基准比较后驱动一个 MOS 管关断。听起来很自由但实际调试很麻烦运放带宽不够环路相位裕量不足就会振荡电流检测电阻的功率损耗又大1A 电流过 50mΩ 电阻就白扔 50mW电流越大损失越吓人。而且我发现这种方案在输入电压跌到欠压点时比较器自身供电都会出问题可靠性很难保证。所以后来我把目光放到 eFuse 上。eFuse 内部集成了功率 FET、电流采样网络、限流环路和保护逻辑在一块很小的芯片里面完成了传统方案一大片分立器件才能做的事。响应速度快、限流精度高、体积小还能提供 UVLO、过压保护、过温保护和软启动这些正是工业现场最需要的。1.3 ATmega644 在这里的定位故障决策与自动恢复看到有人说eFuse 自己就能保护为什么还要加一颗 ATmega644因为 eFuse 只能“干活”不能“思考”。它可以在过流时切断输出但切断之后怎么办是立刻重新导通还是保持断开等待检查是重试三次就彻底锁死还是直接把上位机叫起来这需要一个外部逻辑来仲裁。ATmega644 就是做这个决策的。64KB Flash 足够装下完整的状态机和通信协议4KB SRAM 可以缓存故障记录2KB EEPROM 能保存历史运行数据。更重要的是它内核是 5V 供电可以直接和 eFuse 的逻辑引脚匹配不需要电平转换。相比 STM32在这个场景下它并不算高性能但正是因为性能低功耗低、逻辑简单、出问题容易排查反而更适合拿来当监护角色。2. TPS259483 这颗 eFuse 到底解决了什么2.1 芯片内部都帮你把保护做完了TPS259483AYWPR 是 TPS25948 系列里的一个具体型号后缀 AYWPR 主要是封装和卷装信息选型时不用太纠结后缀。这颗芯片的典型应用是把一个输入电压转成受保护的输出电源路径内部集成了四样关键东西一是功率 FET。这颗 FET 负责正常通流和关断导通电阻比较低12V 下跑 2A 电流时芯片发热可以接受不用额外加散热器。二是采样限流网络。芯片内部有电流检测结构外部只需要一颗电阻接到 ILIM 引脚就能设定限流值。限流点不是“大概值”而是有明确精度的这在工业上非常关键。普通分立采样电阻方案里采样电阻误差加上比较器失调整体误差可能超过 20%而 eFuse 内部校准过的模拟环路可以把误差控制在一个小得多、可直接参考手册的范围。三是保护和监控逻辑。它内置了输入欠压锁定、输入过压关断、过温关断还有输出短路保护。只要后级把电流拉到限流点以上芯片会在一个极短的时间内把输出拉低同时拉低 FLT 引脚通知外部控制器。四是软启动功能。通过 dV/Dt 引脚外接电容可以设定输出电压的爬升速率避免热插拔时瞬间电流冲击。这个功能是很多普通负载开关没有的。2.2 选型时我看重的几个关键参数这次选型我重点关注四个参数。第一是输入耐压范围。TPS25948 系列有不同耐压版本我选的这颗最高输入约 18V所以我把它放在 12V 中间母线上而不是直接保护 24V 总线。如果你要做 24V 系统需要选更高耐压版本或者在前面加一级 DC-DC 降到安全电压。第二是限流范围。我给这颗芯片设定的限流点是 2A因为负载正常工作电流是 500mA峰值短时能到 1.2A。2A 既覆盖了峰值又不会让短路电流大得过分。第三是导通电阻。导通电阻直接影响正常工作时芯片的发热尤其是在密闭的控制柜里。这颗芯片的内阻在同级别里是比较低的12V 输入、500mA 常载时只损失大约 6mW完全不是问题。第四是故障恢复行为。TPS25948 系列里有的型号支持自动重试有的支持闩锁关断。我特意选了闩锁关断版本因为我不想让一个 500mA 的临时过流引起反复重启振荡。真正要重试也应该由外部 MCU 按照策略来而不是让模拟芯片自己傻乎乎地重启。2.3 普通负载开关和 eFuse 的差异别买错了很多刚接触的人会把 eFuse 和“负载开关”混为一谈。负载开关比如常见的低压侧单通道开关确实也有电流限制但它的设计目标是开关逻辑不是精确保护。这里要分清应用场景对比项普通负载开关TPS259483 这类 eFuse典型耐压≤ 5V 或 ≤ 12V最高可达数十伏限流精度较粗通常 ±30%相对精确可按电阻设定软启动部分有功能简单可调爬升斜率状态反馈常只有 PWRON有 FLT/PG 供 MCU 使用保护种类常见过流过流、过压、欠压、过温、反向保护如果你只需要给一个 3.3V 数字模块做开关普通负载开关够用。但如果你要保护的是 12V 工业母线上的电机驱动器或通信模块面对的可能是不明原因的短路、热插拔和电压波动那一定要上 eFuse。3. 电源路径保护控制器ATmega644 的外围设计3.1 整体电源架构为什么 MCU 不能从 eFuse 后面取电这套系统里ATmega644 的供电不要从 eFuse 的输出端取。这是一个很重要的经验。因为 eFuse 关断的是“故障负载”而 MCU 是要在故障发生时继续工作的。如果 MCU 自己也依赖 eFuse 后面的电压那 eFuse 一旦锁断MCU 也跟着断电后面所有恢复逻辑全废了。我的做法是24V 输入先经过板载 DC-DC 降到 12V这路 12V 作为系统中间母线。然后 eFuse 放在 12V 母线和负载之间负载包括电机驱动器、通信模块和继电器。而 ATmega644 的供电是从 eFuse 输入端也就是 12V 母线分出来经过一颗 5V LDO 再单独供给 MCU。这样即使 eFuse 锁断MCU 也活着可以统计故障次数、写入日志甚至在空闲时 ping 一下上位机。3.2 引脚分配和最小电路我实际用到的引脚分配是这样的信号ATmega644 引脚方向说明ENPB5输出控制 eFuse 使能高有效FLTPD2 / INT0输入eFuse 故障信号下降沿中断IMONPC0ADC 输入电流监测电压VINPC1ADC 输入eFuse 输入端电压采样VOUTPC2ADC 输入eFuse 输出端电压采样UART TXPD1输出日志输出LEDPA0输出锁死状态指示电路上EN 引脚由 MCU 的 PB5 输出一个 5V 电压直接驱动。FLT 引脚在 eFuse 内部是漏极开路输出所以要在 MCU 侧接一颗 10k 上拉电阻到 5V。IMON 引脚输出的是一个与负载电流成比例的电压为了抗干扰我在布线时串了 1k 电阻并在 MCU 的 ADC 引脚旁加了一颗 100nF 滤波电容。很多人会问eFuse 的 FLT 引脚能不能直接接到 MCU 中断可以但要注意 FLT 在正常工作时是高电平故障时拉低。如果你的 eFuse 工作在低电平有效状态千万别忘记上拉电阻。我曾经在一次实验中忘记上拉结果 FLT 引脚浮空MCU 被随机噪声中断折腾到“精神分裂”。3.3 故障处理状态机从不解锁到智能重试控制程序的核心是一个状态机主要分四个状态正常运行、故障锁断、等待恢复、永久锁断。正常运行状态下MCU 周期性读取 IMON、VIN、VOUT做简单的平均值滤波。如果一切正常什么也不做就好。一旦 FLT 引脚出现下降沿MCU 立刻进入故障锁断状态。在这个状态里首先要做的事情是“冷静”不要立刻恢复。我会先把 EN 拉到低电平维持 250ms让 eFuse 彻底放电同时读取一次 VIN 和 VOUT 判断故障类型。例如如果 VIN 还在正常范围而 VOUT 被拉低那大概率是后级短路如果 VIN 本身也消失了那问题可能在更上游。接着进入等待恢复状态。我设置的默认策略是等待 10 秒然后重试一次。如果连续重试三次都失败就进入永久锁断状态点亮 LED并通过 UART 向上位机发送故障码。等到人工排除故障后可以通过上位机指令或者按下复位键清零。这套状态机说起来简单但实际处理时我踩了不少坑比如重试过快会形成一个 1Hz 左右的“喘振”把 MOSFET 当电热毯用。后来我加了最少等待时间保证每次重试前负载电容已经完全放电。3.4 限流点和软启动的计算示例以我这台设备为例负载正常电流 500mA短时峰值 1.2A输出电容是 220uF。限流点我设置为 2A理由是给峰值留足裕量同时又不至于让故障短路电流超过 3A 的感知阈值。软启动电容的计算也很直接。输出爬升斜率越快冲击电流越大我需要把冲击电流限制在 500mA 以内。充电电流和斜率的关系是 I ≈ C × (dV/dt)所以斜率 I / C 0.5A / 220uF ≈ 2.3V/ms。12V 输出就意味着软启动时间大约 5.2ms。按 TPS259483 手册里 dV/Dt 电容和爬升率的关系我选了 22nF 的电容实测输出爬升时间稳定在 5ms 左右热插拔时母线压降几乎可以忽略。4. 从原理图到 PCB布局布线的关键经验4.1 功率环路要小别把 eFuse 当成普通芯片布局很多人画 eFuse 电路时把输入电容放得很远觉得反正都是直流电容位置无所谓。这个想法在 eFuse 这里行不通。虽然 eFuse 不是高速收发器但它在限流动作时内部 FET 会在几微秒内切换状态如果输入电容和芯片之间形成大环路会在 FLT 动作瞬间产生很高的电压尖峰反而干扰 MCU 读取状态。我的布局原则是输入电容尽量靠 IN 和 GND 引脚输出电容尽量靠 OUT 和 GND 引脚形成两个紧凑的回路。输入电容我用了 100uF 的电解电容并联 100nF 陶瓷电容输出电容也用 220uF全部放在靠近功率引脚的同一面。如果空间不够至少也要保证电容的 GND 焊盘通过短而粗的走线直达芯片地焊盘不要绕着走。功率走线尽量加宽。12V 2A 虽然电流不大但考虑到故障时可能有 4 倍限流值的瞬时电流流过我建议做主回路走线至少 1mm 宽必要时直接在铺铜层上画。不要把电源线做成细长条那样会引入附加电感在短路时产生压尖峰。4.2 采样走线的开尔文接法IMON 和 VOUT 的采样走线不能用功率路径的同一根线。功率路径上的大电流会在铜箔电阻上产生压降如果采样线共享这一段走线ADC 读到的值和真实值会有偏差而且这个偏差会随负载变化很难校准。正确做法是开尔文接法。从芯片的 IMON 输出脚和输出电容正极分别引出独立的细走线走到 MCU 的 ADC 引脚。这两根细走线不要交叉也不要贴住功率走线中间保持 0.5mm 间距。为了抑制高频噪声我在 MCU 引脚侧加了 1k 电阻和 100nF 电容做低通滤波。这个滤波器的截止频率大约在 1.6kHz足够覆盖电源检测需求也不会掩盖真正的过流毛刺。4.3 散热焊盘和过孔阵列TPS259483 这类 eFuse 的封装底部通常有散热焊盘不要为了省事只从边上走线而不处理散热焊盘。我在 PCB 上给中心焊盘开了一个 4×4 的过孔阵列孔径 0.3mm覆盖到地平面。过孔阵列的作用是把热量从芯片底部导到完整地平面否则长期跑 2A 时芯片表面温度会上升十几度最终影响限流点精度。地平面我建议使用完整的一块不要为了美观切成两半。只要 MCU 数字地、模拟地和功率地都在同一个电位域并且功率地上的大电流不会流过 MCU 地磁位就不会出现地弹问题。实在要分也应该靠星型连接把所有地都汇聚到一个点不要形成大面积分割。4.4 软启动电容的位置和 EMI软启动电容是设置 dV/Dt 的元件它工作在毫秒级对噪声不算敏感但仍要放在芯片引脚旁边走线越短越好。如果走线过长寄生电容和电阻会改变实际的爬升率让你在调试时发现“明明按手册算的为什么实测慢这么多”。EMI 方面软启动是控制 dV/dt 最直接的手段。斜率越快噪声越强斜率越慢输出建立越慢。我实测过 2nF 电容时噪声尖峰会影响相邻的模拟传感器换成 22nF 后一切安静下来。如果你有 EMC 测试压力建议直接先选一个比较保守的斜率宁可启动慢一点也别给实验室的测试仪器加戏。5. 固件实现的关键细节5.1 初始化代码把端口和 ADC 配好下面这段是我实际在 AVR GCC 环境里用的初始化代码为了可读性我做了精简。#include avr/io.h #include avr/interrupt.h #include util/delay.h #define EN_PIN PB5 #define FLT_PIN PD2 #define IMON_CH 0 #define VIN_CH 1 #define VOUT_CH 2 #define MAX_RETRY 3 volatile uint8_t fault_flag 0; uint8_t retry_count 0; static inline void efuse_set_enable(uint8_t on) { if (on) PORTB | (1 EN_PIN); else PORTB ~(1 EN_PIN); } void system_init(void) { // EN 引脚设为输出初始关闭 DDRB | (1 EN_PIN); efuse_set_enable(0); // FLT 引脚上拉作为中断输入 DDRD ~(1 PD2); PORTD | (1 PD2); // INT0 下降沿触发 EICRA | (1 ISC01); EIMSK | (1 INT0); // ADCAVCC 作为基准单次转换模式 ADMUX (1 REFS0); ADCSRA (1 ADEN) | (1 ADPS2) | (1 ADPS1); // 64分频 // PA0 用于故障指示灯 DDRA | (1 PA0); sei(); } uint16_t adc_read(uint8_t ch) { ADMUX (ADMUX 0xF0) | (ch 0x0F); ADCSRA | (1 ADSC); while (ADCSRA (1 ADSC)); ADCSRA | (1 ADIF); return ADC; }这里有个细节ADC 通道选择要放在每次读取之前不能只在初始化里选一次。因为状态机可能需要在不同时间点读取 IMON、VIN、VOUT 不同的通道每次切换通道后至少要等几个 ADC 时钟周期让采样电容稳定下来。我实际代码里会在读取后丢弃第一次的值或者直接连读两次取第二次这样准确度更好。5.2 FLT 中断处理别在 ISR 里做重活FLT 引脚接入 INT0 中断下降沿触发。我在中断服务程序里只做一件事把 fault_flag 置 1然后退出。真正的故障处理放在主循环里做。原因很简单中断服务程序里如果执行 _delay_ms会阻塞整个 MCU 的调度尤其在系统里还有其他定时器任务时一个小故障就能放大成整体罢工。主循环的逻辑是这样的int main(void) { system_init(); // 先自检一遍再使能输出 efuse_set_enable(1); while (1) { if (fault_flag) { fault_flag 0; efuse_set_enable(0); _delay_ms(250); // 等输出电容放电 retry_count; if (retry_count MAX_RETRY) { PORTA | (1 PA0); // 亮灯永久锁断 } else { _delay_ms(10000); // 等 10 秒 efuse_set_enable(1); } } // 正常工作时周期采样并处理日志 uint16_t imon adc_read(IMON_CH); uint16_t vin adc_read(VIN_CH); uint16_t vout adc_read(VOUT_CH); _delay_ms(50); } }这里需要说明重试计数器的清零策略很重要。我的做法是如果一次重试后系统能够持续正常运行超过 2 分钟就把 retry_count 清零。这样不会因为两周前的一次偶发干扰导致今天真故障时只重试一次就锁死。5.3 电流监测的软件滤波和阈值判定IMON 脚出来的电压信号虽然有硬件 RC 滤波但到 ADC 后我还是做了软件处理。我用的是一种简单的滑动平均维护一个长度为 8 的环形缓冲每次采样取平均值。这个滤波器对 50Hz 的工频干扰有大约 13dB 的抑制对短时过流信号也不会抹成平地。如果你要做更严格的过流判定不要只看绝对值。比如通过 IMON 电压换算出的电流达到 1.8A持续 10ms 以上我才认定为“故障”而一个 2A、200us 的尖峰可以由 eFuse 自己处理不需要 MCU 介入。这时候你可以把中断触发条件设为 FLT 拉低而不是 IMON 超限因为 IMON 超限有延迟FLT 是硬件直接拉低反应快得多。5.4 日志输出用最原始的 UART 协议日志我用的是 UART波特率 9600输出一行 ASCII 字符串。尽量别用复杂协议比如 JSON 还得引一个解析库。我这边只是打印“FAULT LATCH, VIN12.1V, VOUT0.2V, IMON2.3A”上位机只需要按行读取和 grep 就够。虽然土但在现场排查时非常高效。如果需要对时可以加一条外部 RTC但我在这个项目里没加。MCU 每次开机时从串口接收一个时间戳存到 EEPROM之后按秒累加。故障日志也写到 EEPROM重启后还能看到历史记录。这个功能虽然简单但在排查“为什么昨天半夜设备死了今天早上才恢复”的时候价值非常大。6. 实测和调优我踩过的几个坑6.1 限流电阻的温漂让限流点悄悄偏移刚开始我图省事ILIM 电阻用了普通 0603 贴片电阻温漂 100ppm/°C。结果夏天现场温度升高后限流点从 2A 漂到了 1.7A正常工作的设备都开始不定期触发 FLT。后来我把 ILIM 电阻换成了 0.1% 精度、25ppm/°C 的精密电阻同时把它放在离发热元件远一点的位置。这颗电阻虽然贵几毛钱但它直接决定整个保护系统的精度这个钱不能省。6.2 上电瞬间误触发 FLT软启动电容背锅调试时遇到过最诡异的问题eFuse 每次上电都会锁断但示波器看输出电流根本没有到限流点。排查链路是这样的先用示波器同时抓 FLT 和 VOUT发现 FLT 在输出爬升到三分之一时就拉低了。再看 IMON 波形发现输出电容充电的浪涌电流虽然没有到 2A但已经接近限流点。然后去翻手册发现 eFuse 内部有一个积分型的限流响应短时间的浪涌也可能让内部的比较器翻转表现成误触发。解决办法不是提高限流点而是把软启动电容从 4.7nF 换成 22nF让输出爬升更平缓。电容涨价了但解决了问题还进一步降低了 EMI。如果你遇到类似问题先用示波器确认输出爬升率再决定调 dV/Dt 还是调限流点不要盲目加大限流值。6.3 ATmega644 的 ADC 基准受电源波动影响ATmega644 的 ADC 基准如果直接用 AVCC而 AVCC 又是从 12V 母线经过 5V LDO 得到的那么母线上出现大电流冲击时LDO 输出会有一个小台阶这个台阶会直接反映到 ADC 的读数上。你会发现明明 eFuse 没有动作IMON 电压却在电机启动瞬间跳变误报故障。我后来把 ADC 基准切换到了内部 1.1V 基准虽然量程变小了但稳定性明显提升。内部基准的绝对精度也可以接受因为我的用途主要是故障判定不是高精度测量。如果你需要更精准的电流数据可以在 AREF 脚外接一个 2.5V 基准源并在代码里做偏移校准。校准方法很简单先用精密万用表量出基准电压再对比 ADC 读到的值算出一个比例系数存进 EEPROM。6.4 闩锁模式、看门狗和人工复位协同我特意选了闩锁模式但 MCU 不能死在现场。假如 ATmega644 因为某种原因死机eFuse 处于闩锁关断状态系统就彻底没人管了。所以我给 MCU 开了硬件看门狗超时复位后先把 eFuse 保持关断等待 5 秒确认 MCU 正常再重新使能。这个设计虽然简单但可靠地避免了“MCU 死机 eFuse 锁断 设备永久停机”的僵局。现场修复时我建议把 LED 指示做明确绿灯常亮代表正常黄灯闪烁代表正在重试红灯常亮代表永久锁断。有了灯现场运维人员不用拿万用表量来量去。我还留了一个外部按钮一键清零故障计数这个按钮接在 PA1 上长按 3 秒才会触发避免误触。这套方案做完到现在已经跑了三个多月。中途出现过两次真实的短路故障一次是电机驱动器内部电容击穿另一次是接线端子被灰尘污染导致爬电打火。两次都是 eFuse 在几微秒内完成保护ATmega644 按策略先重试、失败后锁断并通过 UART 留给现场人员清晰的事件日志。现在我把这套结构也用在新的开发台上后续准备做一个小板子把一路 eFuse 扩展成四路独立保护让 ATmega644 统一做四路的状态仲裁再挂上一个 OLED 显示每路的电流和故障码。如果你也打算做类似的多路保护建议先把单路的调稳再考虑扩展否则多路故障同时发生时状态机复杂度会指数上升。
返回列表