PWM信号隔离与重建:LAT1346脉宽跟随方案详解

发布时间:2026/8/30 23:50:35
PWM信号隔离与重建:LAT1346脉宽跟随方案详解 做嵌入式这些年PWM信号几乎天天见。不管是调个LED亮度、控个电机转速还是驱动舵机背后都是占空比和频率在说话。但有一类需求容易被忽视当PWM信号要跨板传输、电平转换、做电气隔离时直接飞线往往不够用——信号变形、电平不匹配、地电位不一致问题一大堆。这时候就需要一个能精确“复制”PWM的脉宽跟随方案也就是今天要聊的LAT1346。这篇文章我会把这个方案的来龙去脉讲透为什么需要脉宽跟随、LAT1346内部是怎么测脉宽和重建PWM的、硬件怎么接、参数怎么配、和STM32这类MCU怎么对接最后再把我实际调试中踩过的坑和排查方法整理出来。适合正在做电机控制、LED调光、PWM信号隔离或者多板互联的朋友参考不管是刚入门还是干了几年的应该都能找到对你有用的点。1. 方案概述与整体设计思路1.1 为什么不能直接一根线把PWM传过去很多朋友第一次接触脉宽跟随方案时都会问PWM不就是高低电平切换吗我直接用杜邦线从板A连到板B不就行了短距离、同电平、共地的情况下确实可以但实际工程里很少这么舒服。先说电平不匹配。主控普遍是3.3V IO而功率板的逻辑电平可能是5V甚至某些驱动器需要12V电平的PWM。3.3V直接接5V输入逻辑高电平刚刚够阈值勉强能用但余量很小反过来5V接3.3V的IO直接超压时间长了芯片容易挂。再说长线传输PWM从主控板拉出去三米五米线缆的分布电容会把方波的边沿磨圆占空比随之失真——高速时本来到驱动端还有70%占空比实测可能只剩60%电机转速和预期对不上。最头疼的是地电位差两块板各自有功率地和控制地地线之间有压差甚至噪声PWM高电平和低电平参考地都不一样信号到了对端根本不成样子。这些问题不是靠“把线焊粗”能解决的。工程上常规做法有三种一是用电平转换芯片解决电平问题但解决不了隔离和长线问题二是用光耦隔离能隔离能换电平但光耦的传输延迟大而且高电平传输延迟和低电平传输延迟不对称导致输出占空比和输入不一致三就是本篇的主角——脉宽跟随方案先把输入PWM的参数精确测量出来再重新生成一路高质量的PWM。1.2 LAT1346方案的核心架构LAT1346脉宽跟随方案本质上是一个“测量-重建”结构我画个简单的信息流你们就明白了输入PWM信号 → 输入调理滤波、钳位、电平适配 → 脉宽检测测量Ton和Tperiod → 逻辑处理算占空比、判断合法性 → 输出重建生成新的PWM → 输出PWM信号这套结构最关键的地方在于输出信号是“重新生成”的不是把输入信号放大或整形后透传。输出波形完全由本地时钟和逻辑电路决定所以输出边沿陡峭、幅值标准、抖动小。输入信号上的毛刺、振铃、电平波动通通不会带到输出端去。作为对比我把几种常见PWM传输方案放在一个表里方便直观感受差异方案典型延迟占空比误差隔离能力负载驱动能力适用场景直接导线连接纳秒级不受控高频明显无取决于IO同板/短距离电平转换芯片几纳秒小无一般电平匹配光耦隔离几百ns~几us较大高速更明显有弱低速隔离开关LAT1346脉宽跟随最大一个信号周期极小取决于时基无可外扩强高精度PWM重建、长线、多路同步用这个方案等于是把“传输PWM”变成了“传输PWM的参数”。参数传对了输出就一定对。代价是输出会比输入晚最多一个周期这在绝大多数控制场景里是可以接受的。2. 核心原理与关键技术细节2.1 输入级先处理干净再谈测量输入信号进来第一件事不是测而是处理。LAT1346的输入级有一段可控滤波目的就是滤掉高频毛刺和振铃。工业现场经常有电机电刷打火、继电器吸合这类干扰源PWM线上会叠加尖峰如果不滤波测量出的脉宽会被这些毛刺干扰得乱七八糟。但滤波不能乱加时间常数选大了反而坏事。RC滤波的时间常数τ R × C如果τ和PWM高电平宽度接近边沿就被“磨平”了测量出来的脉宽会偏大。举个例子1kΩ电阻配10nF电容τ 10μs拿来滤1kHz的PWM问题不大但要是输入是100kHz一个周期才10μs信号整个被滤成三角波根本没法测。我们实测下来100kHz以内的PWM用1kΩ1nF左右的滤波参数比较安全超过这个频率滤波就要仔细核算。输入电平兼容也是输入级的一个重要设计点。LAT1346的输入引脚可以直接吃3.3V和5V逻辑输入耐压做到5.5V左右所以常规MCU的PWM直接接就行。但如果你从24V系统里分压出来一个PWM或者传感器输出的是12V电平那就必须先分压再进硬接会烧输入级。很多网友翻车就翻在这只想着测脉宽忘了先确认输入电平在不在规格内。2.2 脉宽测量双沿捕获与自适应时基LAT1346的脉宽检测部分原理和单片机里的输入捕获是一回事。核心思路是记录边沿时刻上升沿进来记录t1下降沿进来记录t2下一个上升沿进来记录t3。于是高电平时间Ton t2 - t1信号周期Tperiod t3 - t1占空比Duty Ton / Tperiod × 100%这个流程本身不复杂复杂的是怎么测准。时基分辨率直接决定了占空比测量的精度。如果内部时基是0.5μs测一个20kHz周期50μs的PWM量化误差大约1%换算到占空比可能就是0.5%的偏差。很多要求不高的场景能忍但要是做LED恒流调光或者精密电机控制0.5%的占空比偏差就有感知了。LAT1346解决这个问题用的是自适应时基低频信号用较粗的时基当检测到输入频率变高时自动切换到更细的时基。这就像用尺子量东西量布匹用米尺量零件用游标卡尺。自适应切换不是在每个周期都来回试探而是有一个滞回区间避免频率在切换点附近震荡时导致时基反复横跳。除了分辨率防抖也是测量准确性的关键。工业现场的PWM信号往往带毛刺如果毛刺被当成有效边沿Ton和Tperiod就全错了。LAT1346的做法是连续多次测量一致才认定边沿有效连续次数可以在参数里配。这里要注意防抖次数越多越稳但响应越慢。我一般默认配4次对于大多数应用来说既不会误触发响应延迟也在可接受范围。2.3 输出级重建PWM的更新策略测量到Ton和Tperiod之后剩下的问题就是如何重建输出。LAT1346在下一个周期的起始点统一更新输出比较值这样做的好处是输出波形非常干净不会出现“更新到一半输出电平突然跳到新占空比中间态”的毛刺。有个细节值得展开占空比突变时的处理。比如输入占空比从90%突然变到10%如果输出还在高电平阶段直接更新比较寄存器输出的高电平就在中途被截断形成一个人为的窄脉冲。LAT1346的做法是在周期起点更新所以不会产生这种半截脉冲。这个特性对于驱动电机尤其重要因为窄脉冲对功率管的冲击很大。输出级另一个设计重点是驱动能力。LAT1346的输出不是弱弱的逻辑IO而是经过一级推挽驱动可以直接驱动LED灯串、MOSFET栅极串联一个限流电阻等常见负载。如果需要驱动继电器、大电流负载输出端再接一级驱动或者光耦即可。2.4 故障保护PWM信号说没就没PWM信号在实际运行中最怕什么不是不准而是“失联”。线松了、对端板子掉电了、程序跑飞了PWM信号随时可能消失。如果负载是电机PWM突然丢失电机可能以失控状态持续运转这是安全隐患。LAT1346的故障保护逻辑做在测量环节里如果超过设定时间没有检测到有效边沿就判定输入丢失然后按预设策略动作。输出可以配置为三种行为保持当前输出状态输出安全电平高电平或低电平可配关断输出高阻态配合外部下拉电阻同时FAULT引脚会拉低作为故障标志给主控读取。很多实际项目里我就是把FAULT信号接到MCU的外部中断上一旦PWM输入异常主控能在几毫秒内进入安全流程。频率超范围处理也是故障保护的一部分。如果输入频率超出设定范围比如配置的是1kHz~100kHz实际来了一个500kHz的信号测量结果已经不可信输出直接进入安全状态。占空比超限同理比如输入占空比长期卡在99.9%这多半不是正常控制信号而是异常状态。3. 配置与实操接入指南3.1 硬件接线与引脚说明以典型的LAT1346模块为例引脚不算多VCC3.3V~5.5V电源输入GND电源地PWM_INPWM信号输入PWM_OUTPWM信号输出FAULT故障标志输出低电平有效EN使能控制拉低可以强制关闭输出接线时有几个容易忽略的点。输入地和模块地必须共地否则输入信号根本没有参考电平测量无从谈起。FAULT是开漏输出外部要接一个上拉电阻到MCU的VCC不然拉低的时候读不到有效的低电平。EN引脚不能悬空不用的场合直接短接到VCC。我们遇到过好多次“模块不工作”最后查出来就是EN悬空了。PWM_OUT驱动容性负载时建议加一个22Ω左右的串联电阻防止输出边沿太陡引起振铃。如果是驱动MOSFET栅极串联电阻还能顺便限制栅极充电电流一举两得。3.2 参数配置按应用场景设置LAT1346的配置项不算多但每一项都和实际应用强相关配置输入滤波根据输入PWM频率选择滤波带宽。不确定频率范围时先按最低频率来保证信号能通过如果高频下测量不准再逐档收缩滤波。配置防抖次数建议4次起步。环境干净的场景可以设小一点提升响应速度工业现场则设大一点保证稳定。配置故障响应这一项直接关系到系统安全建议认真想清楚“PWM丢了我的负载怎么动才是安全的”。电机类负载通常选择输出安全电平或关断LED调光则可以选择保持。配置输出极性支持正常和反相两种极性。反相模式在驱动某些负逻辑的电路时很好用但注意反相后的占空比是 1-Duty别在公式换算上搞混。配置输入丢失判定时间默认按信号周期的若干倍来计算。信号频率越低判定时间应该配得越长避免信号很慢时被误判为丢失。3.3 与STM32对接示例LAT1346作为独立的脉宽跟随模块可以完全脱离MCU独立工作。但实际项目里我们往往还是需要MCU参与上层控制比如动态调整目标占空比、读取故障状态等。我用STM32F103的HAL库写了个简单的对接框架供大家参考。思路是用TIM2做输入捕获来测PWM用TIM3做输出比较来重建PWM。这样MCU侧就相当于把LAT1346的逻辑功能在STM32里复现了一遍。实际工程中如果你需要更多通道可以用这个思路配合LAT1346做“先算后发”的桥接。// TIM2 输入捕获初始化简化 void MX_TIM2_Init(void) { TIM_IC_InitTypeDef sConfigIC {0}; htim2.Instance TIM2; htim2.Init.Prescaler 72 - 1; // 72MHz/72 1MHz时基1us htim2.Init.CounterMode TIM_COUNTERMODE_UP; htim2.Init.Period 0xFFFF; HAL_TIM_IC_Init(htim2); // 通道1捕获上升沿 sConfigIC.ICPolarity TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler TIM_ICPSC_DIV1; sConfigIC.ICFilter 0x0F; // 输入滤波抗毛刺 HAL_TIM_IC_ConfigChannel(htim2, sConfigIC, TIM_CHANNEL_1); // 通道2捕获下降沿需开启通道1的间接映射 sConfigIC.ICPolarity TIM_INPUTCHANNELPOLARITY_FALLING; sConfigIC.ICSelection TIM_ICSELECTION_INDIRECTTI; HAL_TIM_IC_ConfigChannel(htim2, sConfigIC, TIM_CHANNEL_2); HAL_TIM_IC_Start_IT(htim2, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(htim2, TIM_CHANNEL_2); } // TIM3 PWM输出初始化简化 void MX_TIM3_Init(void) { TIM_OC_InitTypeDef sConfigOC {0}; htim3.Instance TIM3; htim3.Init.Prescaler 72 - 1; // 1MHz时基 htim3.Init.CounterMode TIM_COUNTERMODE_UP; htim3.Init.Period 1000 - 1; // 默认1kHz运行时动态调整 HAL_TIM_PWM_Init(htim3); sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 500; // 默认50%占空比 sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(htim3, sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim3, TIM_CHANNEL_1); } // 捕获中断回调根据捕获值重算占空比和周期 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { static uint32_t rising_time 0; static uint16_t ton 0, tperiod 0; if (htim-Channel HAL_TIM_ACTIVE_CHANNEL_1) { // 上升沿保存时间并计算周期 tperiod HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) - rising_time; rising_time HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // 周期算出后更新PWM输出周期 __HAL_TIM_SET_AUTORELOAD(htim3, tperiod); } else if (htim-Channel HAL_TIM_ACTIVE_CHANNEL_2) { // 下降沿计算高电平时间 ton HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) - rising_time; __HAL_TIM_SET_COMPARE(htim3, TIM_CHANNEL_1, ton); } }注意这段代码是简洁示意实际项目里建议把捕获值先拷贝到局部变量避免在中断里做复杂的运算另外输入捕获和输出要共用同一个时基基准这样计算出来才是同步的。很多人在这一步犯迷糊输入用的是TIM2的计数器输出用的是TIM3的计数器两者虽然都用74分频但计数器是独立运行的更新周期时可能有微小不同步。工程上更稳妥的做法是用TIM2的更新事件去触发TIM3的预装载或者干脆把输入输出放在同一个定时器的不同通道上。4. 典型应用场景实战4.1 电机调速H桥PWM的脉宽一致性电机控制里H桥驱动很常见需要两路互补的PWM并且要严格同步。如果主控板通过长线把PWM送到电机驱动板电机电流的跳变会通过地线干扰PWM信号占空比一旦漂移电机的扭矩波动和噪音都会变大。我做过一个直流有刷电机项目主控和驱动板相距约两米一开始就是直接飞线。空载测试还行一带上负载示波器看驱动板上的PWM占空比抖得厉害。后来在驱动板近端加了LAT1346把主控送过来的PWM先做一次脉宽跟随再生相当于把“长途跋涉后的脏信号”换成了“本地重新生成的干净信号”占空比误差从原来的5%左右降到0.3%以内电机噪音明显下降。这里要提醒LAT1346做的是脉宽跟随不是死区补偿。H桥互补PWM需要的死区时间LAT1346不会帮你生成。如果你的驱动芯片没有自带死区逻辑还是要在主控侧或者外置电路里把死区补上。4.2 LED调光与PWM风扇控制LED调光对占空比精度很敏感尤其是在低亮度区间。占空比1%和2%的区别肉眼完全看得出来。如果PWM信号经过长线传输后占空比偏了0.5%在低亮度区就是明显的亮度跳变。用LAT1346做一次重建把输入占空比精确锁定再输出给LED驱动调光曲线就顺滑多了。PWM风扇是另一个高频应用。四线风扇的PWM控制线标准频率一般是25kHz逻辑高电平通常要求接近5V。很多主控是3.3V输出直接接风扇大部分能工作但信号完整性没有保证。特别是在风扇线缆比较长或者线径细的情况下PWM高电平会被拉低到2V多风扇转速会不规则波动。把LAT1346放在风扇端输入接主控的PWM输出接风扇的PWM引脚25kHz的占空比信号被精准重建风扇转速就稳了。4.3 多路PWM同步扩展有时候一个主控要同时控制多个设备但逻辑上所有设备应该收到同一个PWM。比如一组灯带要同步呼吸或者多个风扇要同步调速。主控的IO资源有限不可能每个设备分一个定时器通道去输出。用LAT1346可以做“1拖N”的同步扩展主控输出一路PWM然后分发给多个LAT1346模块每个模块各自重建一路PWM给对应的设备。因为每路输出都是基于本地时钟重建的所以不存在级联衰减的问题只要模块之间的输入信号是同一个输出的占空比和频率就是一致的各模块之间的微小时基偏差会导致输出相位略有差异但对大多数应用无影响。这种方案比直接用缓冲器扇出信号更稳因为缓冲器解决不了长线传输的干扰问题而每个LAT1346等于在设备端重新生成了信号。5. 常见问题与排查技巧实录5.1 输出占空比和输入对不上这可能是出现频率最高的问题。现象是示波器上看输入50%占空比输出却是49.2%。排查思路先确认时基分辨率。如果配置的时基是1μs测一个50μs周期的PWM量化误差就已经有2%。把时基调细比如改为0.1μs误差会大幅下降。再看防抖设置。防抖次数过高在信号本身有轻微抖动时边沿被“延迟确认”导致Ton和Tperiod的测量点错位。防抖次数从4调回2很多时候偏差就消失了。最后检查输出更新时刻。如果输出是在检测到边沿的瞬间就更新而不是在周期起点更新那么每次更新都会引入一个额外的相位差累积起来占空比就偏了。确认输出更新配置为“周期起点统一更新”。5.2 输入有PWM输出一直没信号这种故障先不要怀疑模块坏了按顺序排查量一下VCC和GND电压是不是在规格范围内用示波器看PWM_IN引脚确认信号电平是否达到模块的输入阈值。有时候万用表量着有电压但信号边沿已经被拉得很缓模块内部滤波无法判定有效边沿查EN引脚是不是悬空或拉低了查FAULT引脚电平。如果FAULT是低电平说明进入了故障保护输入频率超范围或输入丢失判定时间设置不合理我遇到过一次很奇怪的现象输入信号明明是好的模块就是没输出。查了半天发现是PWM_IN和PWM_OUT接反了。这种低级错误在紧张的调试现场很容易犯建议大家上电之前先按引脚定义核对一遍线序。5.3 输出波形有毛刺或抖动输出波形不干净通常是负载端问题。模块输出直接接一个大的MOSFET栅极栅极电容很大如果输出边沿太陡就会在栅极电阻上产生振铃。解决方法是输出串一个22Ω~100Ω的电阻或者根据栅极电荷调整。如果输出端接的是感性负载比如继电器线圈一定要在负载两端并续流二极管否则关断瞬间的反向电动势可能把输出级打坏。也有一种情况是输入信号本身带高频干扰模块内部的滤波器没完全拦住导致测量跳变。这时提高输入滤波强度或者增加外围RC滤波都能改善输出抖动。5.4 上电瞬间输出状态异常上电时模块还没收到输入PWM输出会处于什么状态这个问题很多人在设计阶段不考虑等上电炸了才发现。LAT1346默认上电输出为关断状态但这不够——你还需要考虑你的负载在上电瞬间如何表现。如果负载是MOSFET驱动上电时模块输出高阻MOSFET栅极如果没有下拉可能会被干扰误开通。我的习惯做法是PWM_OUT对地加一个10kΩ下拉电阻保证失能状态下输出确定是低电平。同时把EN引脚的时序和主控的初始化顺序配合好主控先把所有IO配置安全再拉高EN使能模块。上电瞬间的“确定性”比什么都重要。5.5 常见问题速查现象可能原因排查/解决办法输出占空比偏小时基分辨率不够调细时基启用自适应时基输出占空比偏大输入滤波时间常数过大降低RC参数或调低滤波档位输出完全无信号PWM_IN虚焊或接线反核对线序用示波器量输入引脚波形输出无信号且FAULT为低输入频率超范围查输入频率与配置范围是否匹配输出偶尔跳一下防抖次数不足增大防抖次数或启用输入滤波输出边沿抖动负载振铃输出串电阻检查感性负载续流上电瞬间误输出输出未确定PWM_OUT对地加下拉电阻6. 拓展思路从脉宽跟随到闭环控制LAT1346方案本身解决的是“PWM信号忠实复制”的问题但这个思路再往前走一步就是闭环控制的雏形。脉宽跟随把测量和重建两个环节打通了如果在此基础上加一个比较器或ADC把输出端的电流/电压采样回来和输入目标做比较就可以构成一个简单的恒流或恒压控制环。比如做恒流控温你给一个PWM占空比作为目标LAT1346跟随输出驱动加热器温度传感器采回来当前的温度MCU根据误差调整目标占空比。这套架构里LAT1346负责把PWM忠实执行到位控制算法在MCU里跑各司其职边界清晰排查问题也方便。PWM相关的扩展方向其实很多PWM模拟DAC、PCA9685多路PWM扩展、STM32高级定时器做互补PWM输出、HRTIM高分辨率PWM等等。每个方向单独拿出来都能写一篇长文但万变不离其宗——PWM的本质就是时间参数的精确控制先把测量做准再把输出做稳剩下的都是应用层的活了。我自己做这几个项目下来最大的体会是脉宽跟随方案的价值往往不在“跟随”本身而在它把信号传输链路中的不确定性给消除了。信号从A点到B点中间有多少干扰、多少压降、多少地电位差这些你控制不了但你可以选择在B点重新生成一个和A点参数一致的信号。这个思路比单纯纠结怎么把线布得更好要省心得多。