PIC18LF45K50 SPI隔离方案:MAX14431BAEE+数字隔离器实战
1. 项目缘起与整体设计思路工业现场和嵌入式设备之间的通信最怕两件事一是地电位差把通信芯片打坏二是现场的各种电磁干扰把数据搅乱。我前阵子接手一个项目主控板是 PIC18LF45K50负责采集几路传感器数据然后要把数据送到另一块板子上的控制器。两块板子分别由不同的电源供电地线之间有几十毫伏到几百毫伏的电位差直接连 SPI 通信跑不了多久就出现数据错乱严重的时候芯片直接发热罢工。这个项目的核心就是解决这个“不同地电位之间如何可靠传 SPI 数据”的问题。方案选的是 MAX14431BAEE 这颗四通道数字隔离器把 PIC18LF45K50 的 SPI 信号隔离之后再送到对端。选它而不是光耦原因很直接光耦做 SPI 隔离速度上不去而且光耦的传输延迟和脉宽失真在高速时钟下会让时序彻底崩掉。MAX14431BAEE 是电容隔离架构支持最高 25Mbps 的速率传播延迟在纳秒级通道间匹配也好做 SPI 隔离非常合适。先把这个项目的整体框架说清楚。PIC18LF45K50 作为 SPI 主机输出 SCK、MOSI、CS 三根信号MISO 是从机回给主机的数据。这四根线全部经过 MAX14431BAEE 隔离隔离器的两侧分别由各自的电源域供电中间靠电容隔离栅传递信号。隔离之后两侧的地彻底分开地电位差不再影响通信现场干扰也被挡在隔离栅之外。为什么选 PIC18LF45K50 而不是别的单片机这颗芯片在低功耗和成本之间平衡得不错自带 MSSP 模块硬件 SPI 用起来省心而且工作电压范围宽2.0V 到 5.5V 都能跑适合电池供电或者低压工业场景。它的 SPI 最高时钟可以到 10MHz系统时钟 64MHz 时配合 MAX14431BAEE 的 25Mbps 能力余量充足。这里要强调一个设计原则隔离 SPI不是简单地把四根线各接一个隔离通道就完事。SPI 是同步通信SCK 是时钟基准MOSI 和 MISO 的数据必须在 SCK 的边沿被正确采样。如果隔离器各通道之间的传播延迟差异太大数据眼图就会偏移采样就可能出错。MAX14431BAEE 的通道间传播延迟偏差典型值只有几纳秒这是它能胜任 SPI 隔离的关键。还有一个容易被忽略的点CS 片选信号的隔离。很多人觉得 CS 是低速信号随便隔离一下就行。实际上 CS 的边沿决定了从机什么时候开始监听 SCK如果 CS 的延迟和 SCK 的延迟不匹配从机可能在第一个时钟边沿还没准备好的时候就收到了时钟导致第一个 bit 丢失。所以 CS 也必须走同一颗隔离器保证延迟特性一致。整体设计上我把 MAX14431BAEE 放在两块板子之间的连接处隔离器的 A 侧接 PIC18LF45K50 的电源域B 侧接对端的电源域。A 侧电源用 3.3VB 侧也是 3.3V但两组电源完全独立地也完全分开。隔离器的两侧各放一个 0.1uF 的去耦电容紧贴电源引脚这一点后面会详细说。2. 核心器件解析与选型考量2.1 MAX14431BAEE 的关键特性MAX14431BAEE 是四通道数字隔离器采用电容隔离技术。它的几个关键参数直接决定了能不能用在 SPI 隔离场景里。第一个是数据速率。这颗芯片最高支持 25Mbps对应到 SPI 时钟就是 25MHz 的 SCK 频率。PIC18LF45K50 的 SPI 最高 10MHz所以速率上完全够用而且有余量。余量很重要因为实际布线、隔离器本身的抖动都会吃掉一部分时序裕量如果器件速率刚好卡在临界值批量生产时就会出问题。第二个是传播延迟。MAX14431BAEE 的传播延迟典型值是 11ns最大值 16ns。这个数值在数字隔离器里属于中等偏上水平。对于 10MHz 的 SPI一个时钟周期是 100ns半周期 50ns。16ns 的延迟相对于 50ns 的半周期占比 32%看起来不小但关键在于四个通道的延迟是否一致。如果 SCK、MOSI、MISO、CS 四个通道的延迟都是 16ns那它们之间的相对关系没变采样点就不会偏。MAX14431BAEE 的通道间延迟匹配典型值是 2ns最大 5ns这个指标才是 SPI 隔离的核心。第三个是隔离耐压。MAX14431BAEE 的隔离耐压是 2.5kVrms持续 60 秒工作电压 445Vrms。对于工业现场常见的几百伏地电位差这个耐压足够了。如果场景更恶劣比如电力设备附近可能需要选耐压更高的型号但一般工业嵌入式场景2.5kVrms 是安全线。第四个是通道方向配置。MAX14431BAEE 是四通道但通道方向是固定的还是可配置的这个要查手册。我用的这颗是四个通道同向的配置也就是说四个通道都是从 A 侧到 B 侧或者都是 B 侧到 A 侧。SPI 需要三根线从主机到从机SCK、MOSI、CS一根线从从机到主机MISO方向是 31。如果隔离器是四通道同向那就需要两颗或者选通道方向可配置的型号。我实际用的是 MAX14431BAEE 的变体通道方向是 3 正 1 反正好匹配 SPI 的 31 需求。选型的时候一定要看清楚通道方向配置这是最容易踩的坑。2.2 PIC18LF45K50 的 SPI 模块配置PIC18LF45K50 的 MSSP 模块可以配置成 SPI 主机模式。关键寄存器有 SSPCON1、SSPSTAT、SSPBUF、SSPADD。SPI 主机模式下SSPADD 不用时钟由 SSPCON1 的 SSPM 位选择。SPI 模式有四种由 CKP 和 CKE 两个位决定。CKP 决定时钟空闲电平CKE 决定数据在哪个边沿采样。对于大多数 SPI 从机模式 0CKP0CKE1或者模式 3CKP1CKE1比较常见。我用的从机是模式 0SCK 空闲低电平数据在上升沿采样下降沿变化。时钟频率由 SSPCON1 的 SSPM 位和系统时钟共同决定。PIC18LF45K50 在 64MHz 系统时钟下SPI 时钟可以配置为 Fosc/4、Fosc/16、Fosc/64 等。Fosc/4 就是 16MHz但芯片手册说 SPI 最高 10MHz所以实际要用 Fosc/16得到 4MHz。4MHz 的 SCK周期 250ns半周期 125nsMAX14431BAEE 的 16ns 延迟占比 12.8%裕量很充足。这里有个细节PIC18LF45K50 的 SPI 时钟分频是 2 的幂次不能任意分频。如果你需要 5MHz 的 SCK可能配不出来只能选最接近的 4MHz 或 8MHz。选型的时候要算清楚别等到调试的时候才发现频率不对。2.3 为什么不用光耦光耦做 SPI 隔离最大的问题是速度。普通光耦的传输延迟在微秒级好一点的高速光耦也要几百纳秒而且脉宽失真大。SPI 的 SCK 是连续时钟每个周期都要翻转光耦的上升沿和下降沿延迟不一致几个周期下来时钟占空比就偏得不成样子从机根本没法正确采样。另外光耦的通道间匹配更差。同一颗光耦里的两个通道延迟可能差几十纳秒不同批次之间差异更大。SPI 的四根线如果各走各的光耦延迟对不齐数据肯定错。还有功耗和寿命问题。光耦的发光二极管需要持续电流驱动功耗比数字隔离器高一个数量级。而且 LED 会老化几年之后传输特性就变了。数字隔离器是电容耦合没有老化问题寿命长得多。成本上高速光耦其实不比数字隔离器便宜尤其是四通道的场景四颗高速光耦加起来可能比一颗四通道数字隔离器还贵。所以综合来看SPI 隔离选数字隔离器是更合理的选择。3. 硬件设计与实操要点3.1 电源与去耦设计MAX14431BAEE 需要两侧独立供电VDD1 和 VDD2 分别接各自的电源域。供电电压范围是 1.71V 到 5.5V所以 3.3V 和 5V 系统都能用。我这边两侧都是 3.3V但电源完全独立地也分开。去耦电容是必须的而且位置很关键。每侧的 VDD 引脚旁边要放一个 0.1uF 的陶瓷电容距离引脚不超过 2mm。这个电容的作用是提供瞬态电流因为数字隔离器在信号翻转的时候需要瞬间电流如果电源走线太长电感效应会让电压跌落导致隔离器内部逻辑出错。我实测过去耦电容离引脚 5mm 和 2mm信号眼图有明显差异。5mm 的时候SCK 上升沿有振铃眼图张开度小2mm 的时候波形干净很多。所以布线的时候去耦电容一定要紧贴引脚先过电容再过引脚不要先过引脚再分支到电容。另外两侧的电源要加一个 10uF 的钽电容或者陶瓷电容做 bulk 去耦放在电源入口处。0.1uF 管高频10uF 管低频两个配合才能覆盖整个频段。注意两侧的地绝对不能连在一起否则隔离就失效了。PCB 上要明确划分隔离带隔离带下面不能走任何信号线包括电源线。隔离带的宽度至少 8mm保证爬电距离。3.2 PCB 布局与布线SPI 信号线的布线有几个原则。第一SCK、MOSI、MISO、CS 四根线尽量等长。等长是为了保证延迟一致虽然隔离器本身有通道匹配但 PCB 走线的不等长会叠加到总延迟上。10MHz 的 SCK信号在 FR4 上的传播速度大约是 15cm/ns如果两根线差 3cm延迟就差 0.2ns相对于 16ns 的隔离器延迟这个差异可以忽略。但如果差 30cm延迟差 2ns就接近隔离器的通道匹配极限了。所以等长控制在 1cm 以内比较稳妥。第二SCK 和 MOSI 尽量远离或者中间加地线隔离。SCK 是时钟翻转频繁容易耦合到 MOSI 上。如果耦合严重MOSI 的数据眼图会变差。我一般会在 SCK 和 MOSI 之间走一根地线或者至少保持 3 倍线宽的间距。第三隔离器两侧的走线要分开A 侧的线不要跨到 B 侧的区域。隔离带是物理分界线A 侧的信号线全部在 A 侧区域B 侧的线全部在 B 侧区域不要交叉。第四MISO 是从机到主机的信号方向和其他三根相反。布线的时候要注意MISO 的驱动端在 B 侧接收端在 A 侧所以 MISO 的走线要从 B 侧的从机拉到隔离器的 B 侧输入再从隔离器的 A 侧输出拉到 PIC18LF45K50 的 MISO 引脚。3.3 隔离器的通道分配MAX14431BAEE 的四个通道我这样分配通道方向信号说明CH1A→BSCK主机时钟到从机CH2A→BMOSI主机数据到从机CH3A→BCS主机片选到从机CH4B→AMISO从机数据到主机这个分配的前提是隔离器的通道方向是 3 正 1 反。如果用的是四通道同向的型号就需要两颗隔离器或者用一颗六通道的。选型的时候一定要确认通道方向这是硬件设计的第一步。通道分配还有一个考虑把 SCK 和 MISO 放在不相邻的通道上。SCK 是输出MISO 是输入如果它们相邻SCK 的翻转可能会耦合到 MISO 的输入上。虽然隔离器内部有隔离但引脚之间的耦合还是存在的。我一般把 SCK 放在 CH1MISO 放在 CH4中间隔两个通道耦合最小。4. 软件配置与通信实现4.1 PIC18LF45K50 SPI 初始化PIC18LF45K50 的 SPI 初始化核心是配置 SSPCON1 和 SSPSTAT。下面是我实际用的初始化代码基于 XC8 编译器。void SPI_Init(void) { // 配置 SCK、SDO 为输出SDI 为输入 TRISCbits.TRISC3 0; // SCK TRISCbits.TRISC5 0; // SDO (MOSI) TRISCbits.TRISC4 1; // SDI (MISO) // CS 用普通 IO 控制 TRISBbits.TRISB0 0; // CS LATBbits.LATB0 1; // CS 默认高 // SSPSTAT: CKE1, SMP0 // CKE1: 数据在主动时钟的下降沿变化上升沿采样 // SMP0: 在数据输出时间的中间采样 SSPSTAT 0x40; // SSPCON1: SSPEN1, CKP0, SSPM0000 (Fosc/4) // 实际用 Fosc/16SSPM0010 SSPCON1 0x20; // 清空 SSPBUF SSPBUF 0; }这段代码里SSPSTAT 的 CKE 位设为 1对应 SPI 模式 0。SSPCON1 的 SSPM 设为 0010对应 Fosc/16。如果系统时钟是 64MHzSPI 时钟就是 4MHz。这里有个坑PIC18LF45K50 的 SPI 时钟分频是 Fosc/4、Fosc/16、Fosc/64没有 Fosc/8。如果你想要 8MHz 的 SCK在 64MHz 系统时钟下是配不出来的只能选 4MHz 或 16MHz。16MHz 超过了芯片手册的 10MHz 上限所以只能用 4MHz。选型的时候要算清楚这个。4.2 SPI 字节收发函数SPI 是全双工发一个字节的同时会收到一个字节。下面是收发函数。uint8_t SPI_ExchangeByte(uint8_t txData) { SSPBUF txData; // 写入发送数据 while(!PIR1bits.SSPIF); // 等待传输完成 PIR1bits.SSPIF 0; // 清除中断标志 return SSPBUF; // 返回接收数据 }这个函数是阻塞式的发一个字节等一个字节。对于低速 SPI 够用但如果要高速传输可以用中断或者 DMA。PIC18LF45K50 没有 DMA所以只能用中断或者阻塞。我这边数据量不大阻塞式够用。CS 的控制要单独做因为 CS 是普通 IO。void SPI_CS_Low(void) { LATBbits.LATB0 0; } void SPI_CS_High(void) { LATBbits.LATB0 1; }CS 拉低之后要等一小段时间再发 SCK让从机有时间准备。这个时间取决于从机的响应速度一般几十纳秒到几百纳秒。我这边从机是 SPI FlashCS 拉低后等 100ns 就够了。4.3 隔离对 SPI 时序的影响隔离器引入的延迟对 SPI 时序的影响主要体现在两个方面。第一SCK 的延迟。主机发出的 SCK 经过隔离器之后到达从机的时间晚了 16ns。从机在 SCK 的边沿采样 MOSI而 MOSI 也经过隔离器也晚了 16ns。如果 SCK 和 MOSI 的延迟完全一样那从机看到的 SCK 和 MOSI 的相对关系没变采样正确。这就是为什么通道间匹配比绝对延迟更重要。第二MISO 的延迟。从机发出的 MISO 经过隔离器之后到达主机的时间晚了 16ns。主机在 SCK 的边沿采样 MISO但主机这边的 SCK 是没有延迟的主机直接产生 SCK。所以主机采样 MISO 的时候MISO 可能还没到。这个问题怎么解决关键在于 SPI 模式的选择。SPI 模式 0 是在 SCK 上升沿采样数据在下降沿变化。主机在上升沿采样 MISO而 MISO 是在上一个下降沿变化的中间隔了半个周期。4MHz 的 SCK半周期是 125nsMISO 的 16ns 延迟相对于 125ns 的裕量占比 12.8%完全够用。如果 SCK 频率提高到 10MHz半周期 50ns16ns 延迟占比 32%裕量就紧张了。这时候要考虑用 SPI 模式 1 或模式 3在 SCK 的下降沿采样给 MISO 多留半个周期的时间。但模式 1 和模式 3 的采样边沿不同要跟从机匹配。我实测下来4MHz 的 SCK 配模式 0MISO 采样很稳眼图张开度很大。10MHz 的时候眼图明显变小但还能工作。如果超过 10MHz就建议换更快的隔离器或者降低 SCK 频率。5. 常见问题与排查技巧5.1 通信完全不通第一次上电如果 SPI 完全没反应先查这几个地方。第一隔离器的电源。用万用表量 VDD1 和 VDD2确认都是 3.3V。如果某一侧没电隔离器不工作信号传不过去。我遇到过 VDD2 的电源芯片没使能导致 B 侧没电查了半天才发现是使能引脚悬空了。第二CS 信号。用示波器看隔离器 B 侧的 CS确认 CS 拉低的时候B 侧也能看到低电平。如果 B 侧 CS 一直是高说明隔离器的 CS 通道坏了或者方向搞反了。第三SCK 信号。同样用示波器看 B 侧的 SCK确认有时钟输出。如果没有查 A 侧的 SCK 有没有隔离器有没有供电。第四MISO 信号。主机发数据的时候看 MISO 有没有回数据。如果 MISO 一直是高或者一直是低说明从机没响应或者 MISO 通道方向搞反了。5.2 数据偶尔出错通信能通但偶尔出错这种问题最难查。常见原因有几个。第一个是地电位差太大。虽然隔离器把地分开了但如果地电位差超过了隔离器的共模抑制范围信号还是会出错。MAX14431BAEE 的共模抑制能力是 25kV/us一般工业场景够用。但如果现场有大功率设备频繁启停地电位差可能瞬间跳变很大这时候要考虑加共模扼流圈或者 TVS 管。第二个是电源噪声。隔离器的两侧电源如果有噪声会影响内部逻辑。用示波器看 VDD 引脚的纹波如果超过 100mV就要加去耦电容或者换 LDO。我遇到过 B 侧的电源和电机共用电机一转SPI 就出错。后来给 B 侧单独加了一个 LDO问题解决。第三个是 SCK 频率太高。前面算过10MHz 的时候裕量只有 68%如果从机的响应速度慢或者 PCB 走线不好就会偶尔采样错。降低 SCK 频率到 4MHz问题就消失了。所以调试的时候先用低速跑通再逐步提高频率。第四个是 CS 的时序。CS 拉低之后如果立刻发 SCK从机可能还没准备好。在 CS 拉低和第一个 SCK 之间加一个延时比如 1us给从机准备时间。这个延时在软件里加很简单。5.3 隔离器发热隔离器发热一般是功耗超标。MAX14431BAEE 的功耗和信号频率有关频率越高功耗越大。如果 SCK 一直跑在 10MHz而且四个通道都在翻转功耗会比较大。查功耗的方法量 VDD1 和 VDD2 的电流乘以电压就是功耗。MAX14431BAEE 在 10MHz 下的典型功耗是几十毫瓦如果超过 100mW就要查是不是有通道短路或者负载太重。另外隔离器的输出驱动能力有限如果负载电容太大输出级会一直处于大电流状态导致发热。SPI 的走线电容一般几十 pF问题不大。但如果走线很长或者接了很长的排线电容可能上百 pF这时候要在隔离器输出端加缓冲器。5.4 常见问题速查表现象可能原因排查方法解决措施完全不通隔离器没供电量 VDD1/VDD2 电压检查电源芯片使能完全不通CS 方向反了示波器看 B 侧 CS确认通道方向配置完全不通MISO 方向反了示波器看 MISO确认通道方向配置偶尔出错地电位差太大量两侧地之间的电压加共模扼流圈或 TVS偶尔出错电源噪声示波器看 VDD 纹波加去耦电容或 LDO偶尔出错SCK 频率太高降低频率测试降到 4MHz 或更低偶尔出错CS 时序不对看 CS 和 SCK 的时序CS 拉低后加延时隔离器发热功耗超标量 VDD 电流降低频率或加缓冲器隔离器发热负载电容太大量输出端电容加缓冲器或缩短走线6. 实操心得与经验总结这个项目做下来有几个心得值得分享。第一个是选型的时候一定要看通道方向。我一开始选了一颗四通道同向的隔离器画完 PCB 才发现 SPI 需要 31 的方向只能飞线改板浪费了一周时间。后来换成 3 正 1 反的型号一次成功。所以选型第一步确认通道方向。第二个是去耦电容的位置比容值更重要。0.1uF 的电容放在引脚旁边和放在 5mm 外效果差很多。我现在的习惯是去耦电容的焊盘直接放在引脚旁边走线先过电容再过引脚这样瞬态电流的回路最小。第三个是调试的时候先用低速跑通。我一开始就把 SCK 设到 10MHz结果数据偶尔出错查了两天才发现是频率太高。后来降到 4MHz一次跑通然后再逐步提高频率找到稳定工作的上限。这个上限就是你的设计裕量批量生产的时候要留 20% 的余量。第四个是示波器是必备工具。SPI 隔离的问题光靠万用表查不出来必须用示波器看波形。我一般会同时看 A 侧和 B 侧的 SCK、MOSI、CS对比延迟和波形质量。如果 B 侧的波形明显变差说明隔离器或者布线有问题。第五个是隔离带的设计要严格。PCB 上隔离带下面不能走任何线包括电源线。我见过有人把电源线从隔离带下面穿过去结果隔离效果大打折扣。隔离带的宽度至少 8mm如果工作电压高还要更宽。最后再分享一个小技巧如果 SPI 从机离隔离器比较远可以在隔离器的输出端加一个 22 欧姆的串联电阻抑制反射。这个电阻对信号幅度有一点衰减但能明显改善眼图。我实测过加了这个电阻之后10MHz 下的眼图张开度提升了 20% 左右。这个方案后续还可以扩展。比如如果 SPI 从机不止一个可以用隔离器的 CS 通道做片选译码或者用多颗隔离器分别隔离不同的从机。如果通信距离更远可以在隔离器后面加差分驱动器把 SPI 转成差分信号传输抗干扰能力更强。如果现场干扰特别严重还可以在隔离器前面加 TVS 管和共模扼流圈做多级防护。