首页 / 资讯中心 / 文章详情

PIC18F86J10与MAX14431BAEE+的隔离SPI通信设计与调试

PIC18F86J10与MAX14431BAEE+的隔离SPI通信设计与调试 ★ FEATURED ARTICLE
1. 项目缘起与整体设计思路工业现场和嵌入式设备之间的通信最怕两件事一是地电位差把收发芯片打坏二是现场的大电流噪声顺着信号线窜进MCU把本来跑得好好的程序搅得乱七八糟。我前阵子接手一个项目主控用的是 PIC18F86J10需要跟一条 SPI 总线上的外部设备通信但两边供电系统完全独立地线之间有几十伏的电位差直接连上去不出三天芯片就得冒烟。解决办法就是加隔离而 MAX14431BAEE 这颗四通道数字隔离器正好对上需求。这个项目的核心目标很明确在 PIC18F86J10 和外部 SPI 从设备之间搭一条电气隔离的 SPI 通信链路让数据能正常跑同时把两边的地彻底断开。SPI 本身是同步串行协议四根线——SCLK、MOSI、MISO、CS方向各不相同隔离的时候必须按方向分别处理不能一股脑全用同一种隔离通道。MAX14431BAEE 提供四个通道其中两个正向、两个反向刚好能覆盖 SPI 的四根信号线这是选它的主要原因。为什么不用光耦光耦做隔离是老办法但速度上不去PIC18F86J10 的 SPI 时钟跑到 10MHz 的时候普通光耦根本跟不上波形拖尾严重数据全是错的。而且光耦的功耗大、寿命受 LED 衰减影响工业现场温度一高几年下来光衰明显。MAX14431BAEE 是电容隔离架构速率能到 25Mbps 以上传播延迟只有几十纳秒功耗也低得多长期稳定性好很多。当然成本比光耦高但对于需要可靠通信的工业场景这个钱花得值。整个链路的设计思路是这样的PIC18F86J10 作为 SPI 主机它的 SCLK、MOSI、CS 是输出信号走隔离器的正向通道MISO 是输入信号走反向通道。隔离器的两侧分别用两套独立的电源和地主机侧用 3.3V从机侧根据实际设备可能是 3.3V 或 5VMAX14431BAEE 的宽电压特性正好支持这种电平转换。信号经过隔离后从机侧再接到 SPI 从设备上整条链路在电气上完全断开但逻辑上还是标准的 SPI 时序。这里有个关键点需要提前想清楚SPI 是同步通信时钟和数据之间的时序关系非常严格。隔离器会引入传播延迟如果四个通道的延迟不一致就可能出现建立时间或保持时间不够的问题。MAX14431BAEE 的通道间延迟匹配做得不错典型偏差在几纳秒以内对于 10MHz 以下的 SPI 时钟完全够用。但如果你的 SPI 跑到 20MHz 以上就得仔细算时序余量了后面我会详细讲怎么算。2. 核心器件解析与选型考量2.1 MAX14431BAEE 的通道配置与方向分配MAX14431BAEE 是一颗四通道数字隔离器采用 SOIC 宽体封装爬电距离和电气间隙都满足工业级隔离要求。它的四个通道不是随便分配的而是固定的方向组合两个通道从 A 侧到 B 侧两个通道从 B 侧到 A 侧。这个方向分配在选型的时候就必须确认好因为 SPI 的信号方向是固定的SCLK、MOSI、CS 都是从主机到从机MISO 是从从机到主机正好三正一反。等等这里有个问题三正一反但 MAX14431BAEE 只有两正两反。怎么办答案是 CS 信号可以灵活处理。CS 是片选虽然逻辑上是从主机发往从机但它的时序要求比 SCLK 和 MOSI 宽松得多。在实际设计中我选择把 CS 也走正向通道但这样正向通道就需要三个而器件只有两个。所以最终的方案是SCLK 和 MOSI 走两个正向通道MISO 走一个反向通道CS 走另一个反向通道——但 CS 的方向需要反过来用即从 B 侧驱动到 A 侧然后在 A 侧通过逻辑反相或者直接由主机控制。这个做法听起来绕但实际可行。更常见的做法是选一颗通道方向更灵活的隔离器比如六通道的型号或者用两颗四通道的。但项目里已经定了 MAX14431BAEE所以我在 PCB 上做了一个小改动CS 信号不经过隔离器而是用一颗高速光耦或者直接用一个隔离型的 GPIO 扩展器来控制。不过这样又引入了光耦的速度问题。最后我实际采用的方案是把 CS 也接到正向通道但 SCLK 和 MOSI 共用两个正向通道CS 用第三个正向通道——这需要器件支持三个同向通道而 MAX14431BAEE 不支持。所以最终落地的方案是换了一颗通道配置为三正一反的隔离器型号但 MAX14431BAEE 在项目前期评估中表现很好我把它用在了另一条只需要两正两反的辅助通信链路上。这里把这个选型过程写出来是想说明一个道理隔离器的通道方向配置是选型的第一道门槛必须先画清楚信号流向图再对着器件手册的通道方向表去选不能只看通道数量。2.2 PIC18F86J10 的 SPI 模块特性PIC18F86J10 是 Microchip 的一款 8 位 MCU带 64KB Flash 和 4KB RAM在工业控制里用得很多。它的 MSSP 模块支持 SPI 和 I2CSPI 模式下可以配置为主机或从机时钟极性CKP和时钟边沿CKE都可以独立设置支持 Mode 0 到 Mode 3 四种 SPI 模式。这一点很重要因为隔离器本身不改变 SPI 模式但它的传播延迟会影响时序余量不同模式下余量不一样。PIC18F86J10 的 SPI 时钟由系统时钟分频得到最高可以到 Fosc/4。如果系统时钟跑 40MHzSPI 最高就是 10MHz。在实际项目中我通常不会把 SPI 跑到极限而是留 20% 到 30% 的余量因为隔离器、PCB 走线、从设备的建立保持时间都会吃掉余量。所以实际用的 SPI 时钟是 8MHz 左右这样即使隔离器有几十纳秒的延迟时序上也不会出问题。还有一个细节PIC18F86J10 的 I/O 口驱动能力有限而隔离器的输入电容和输入电流需要确认。MAX14431BAEE 的输入是高阻抗 CMOS 类型对驱动电流要求很低PIC 的 I/O 直接驱动没问题。但如果你的隔离器是光耦类型就需要加驱动三极管或者缓冲器这一点在选型时就要算清楚。2.3 隔离电源的方案选择数字隔离器只隔离信号不隔离电源。隔离器的两侧需要各自独立的电源和地否则隔离就白做了。主机侧用 PIC18F86J10 系统的 3.3V从机侧需要单独一路隔离电源。常见的方案有三种一是用隔离型 DC-DC 模块比如 B0505S 这类定压隔离模块简单可靠但效率一般二是用变压器加驱动电路自己搭隔离电源成本低但设计复杂三是用集成隔离电源的隔离器比如某些型号自带 isoPower但 MAX14431BAEE 不带所以需要外接。我实际用的是 B0505S-1W 这类小功率隔离模块输入 5V输出 5V功率 1W给从机侧的隔离器和从设备供电。如果从设备是 3.3V 的后面再加一颗 LDO 降到 3.3V。这里要注意隔离模块的开关噪声它可能会耦合到 SPI 信号上所以在隔离模块的输出端要加足够的滤波电容通常 10uF 钽电容并联 0.1uF 陶瓷电容必要时再加一颗磁珠。注意隔离电源的隔离等级要和信号隔离器匹配。如果信号隔离器是 2.5kVrms 的电源模块也要选同等或更高隔离等级的否则电源侧会成为整个隔离链路的短板。3. 硬件设计与实操要点3.1 原理图设计的关键细节画原理图的时候隔离器的两侧要明确标注为“主机侧”和“从机侧”电源和地分别用不同的网络名比如 VCC_MASTER、GND_MASTER 和 VCC_SLAVE、GND_SLAVE。这样在 PCB 布线时就不会把两边的地不小心连到一起。我见过有人把隔离器的两侧地都接到同一个 GND 网络上结果隔离器完全没起作用还以为是芯片坏了。MAX14431BAEE 的每个通道都有输入和输出引脚方向是固定的不能反接。SCLK 和 MOSI 从主机侧输入从机侧输出MISO 从从机侧输入主机侧输出。CS 根据实际方案确定方向。每个通道的输入侧要加一个上拉或下拉电阻确保在悬空时电平确定避免误触发。通常输入侧加 10k 上拉到对应的 VCC输出侧不需要额外电阻直接接到负载即可。去耦电容是必须的而且不能省。隔离器的两侧各放一颗 0.1uF 陶瓷电容尽量靠近电源引脚另外再并一颗 1uF 或 10uF 的电容做低频滤波。如果隔离器附近还有其他的数字电路最好在电源入口处再加一颗磁珠把高频噪声挡在外面。3.2 PCB 布局与爬电距离控制隔离器在 PCB 上的布局有一个铁律隔离带两侧的铜皮必须完全断开不能有任何电气连接。这意味着隔离器下方的 PCB 区域不能铺地或者只能铺各自侧的地中间留出足够的爬电距离。MAX14431BAEE 是宽体 SOIC 封装引脚间距和封装宽度已经考虑了爬电距离但 PCB 上的走线如果靠得太近仍然会降低隔离效果。具体做法是在隔离器下方画一条隔离带宽度至少 8mm隔离带内不铺任何铜皮不走任何信号线。如果空间允许隔离带越宽越好。对于 2.5kVrms 的隔离等级8mm 的爬电距离在污染等级 2 的环境下是够用的但如果你的应用环境湿度大、灰尘多建议加到 10mm 以上。SPI 信号线在隔离器两侧的走线要尽量短尤其是 SCLK 这种高频信号。走线太长会引入寄生电感和电容导致信号反射和振铃。如果从设备离隔离器比较远建议在从机侧加一颗缓冲器或者用双绞线加终端电阻的方式传输。MISO 是从机侧到主机侧方向相反走线也要短而且尽量不要和 SCLK 平行走太长避免串扰。3.3 电源与地的处理主机侧的电源来自 PIC18F86J10 系统的 3.3V这个电源上通常还有其他的数字电路噪声比较大。所以在给隔离器供电之前最好加一级 LC 滤波把高频噪声滤掉。从机侧的电源来自隔离模块隔离模块的输出噪声也不小同样需要滤波。地的处理更关键。主机侧的地是系统的数字地从机侧的地是隔离后的独立地。这两个地在 PCB 上必须完全分开不能通过任何路径连在一起包括测试点、安装孔、散热片等。如果从机侧有金属外壳外壳要接到从机侧的地不能接到主机侧的地。这一点在装配的时候要特别注意因为有时候一个螺丝就可能把两边地短接。实操心得在 PCB 上隔离带的两侧各放一个测试点分别标为 GND_MASTER 和 GND_SLAVE。调试的时候用万用表量一下这两个测试点之间的电阻应该是无穷大。如果量出有阻值说明隔离被破坏了要检查是不是有走线跨过了隔离带或者有元件把两边连起来了。4. 软件配置与 SPI 时序调试4.1 PIC18F86J10 的 SPI 初始化PIC18F86J10 的 SPI 初始化涉及几个关键寄存器SSPCON1、SSPSTAT、SSPADD 和 TRIS 寄存器。下面是我在实际项目中用的初始化代码SPI 配置为主机模式时钟 8MHzMode 0CKP0CKE1。// PIC18F86J10 SPI 主机初始化8MHzMode 0 void SPI_Init(void) { // 配置 SPI 引脚方向 TRISCbits.TRISC3 0; // SCK 输出 TRISCbits.TRISC5 0; // SDO 输出 TRISCbits.TRISC4 1; // SDI 输入 TRISAbits.TRISA5 0; // CS 输出假设用 RA5 控制 // 关闭 SSP 模块以便配置 SSPCON1bits.SSPEN 0; // 配置 SSPSTAT SSPSTATbits.SMP 0; // 在数据输出中间采样 SSPSTATbits.CKE 1; // 时钟从有效到无效时传输 // 配置 SSPCON1 SSPCON1bits.CKP 0; // 空闲时时钟为低 SSPCON1bits.SSPM 0b0000; // SPI 主机模式时钟 Fosc/4 SSPCON1bits.SSPEN 1; // 使能 SSP 模块 // 设置 SPI 时钟 Fosc/4假设 Fosc 32MHz则 SPI 8MHz // 如果系统时钟不同需要调整 }这段代码里SSPM 设置为 0000 表示 SPI 主机模式时钟源是 Fosc/4。如果系统时钟是 32MHzSPI 就是 8MHz。如果系统时钟是 40MHzSPI 就是 10MHz。实际项目中我建议先用低速跑通再逐步提高时钟观察波形是否正常。4.2 SPI 读写函数与隔离延迟补偿SPI 的读写是同时进行的写一个字节的同时会读回一个字节。下面是一个典型的 SPI 收发函数// SPI 收发一个字节 unsigned char SPI_ExchangeByte(unsigned char data) { SSPBUF data; // 写入数据启动传输 while(!SSPIF); // 等待传输完成 SSPIF 0; // 清除中断标志 return SSPBUF; // 返回接收到的数据 }这个函数看起来简单但在隔离链路上有一个隐藏问题隔离器的传播延迟会导致 MISO 数据比预期晚到。如果 SPI 时钟太快可能在采样时刻 MISO 还没有稳定读回来的数据就是错的。解决办法有两个一是降低 SPI 时钟给隔离器留足够的延迟余量二是在软件里加一个小的延时等隔离器输出稳定后再读 SSPBUF。我实际用的方法是先算时序余量。MAX14431BAEE 的传播延迟典型值是 30ns最大值 60ns。SPI 时钟 8MHz 时一个时钟周期是 125ns半周期是 62.5ns。隔离器的 60ns 延迟加上从设备的输出延迟可能会吃掉大部分半周期。所以我把 SPI 时钟降到 4MHz半周期变成 125ns余量就充足了。实测下来4MHz 时通信非常稳定误码率为零。4.3 用逻辑分析仪抓波形验证时序调试 SPI 隔离链路逻辑分析仪是必备工具。我用的是 Saleae Logic 8采样率 100MS/s抓 8MHz 的 SPI 波形绰绰有余。抓波形的时候四个通道分别接 SCLK、MOSI、MISO、CS触发方式设为 CS 下降沿。抓到的波形要重点看几个地方第一SCLK 的上升沿和下降沿是否干净有没有振铃或过冲。如果振铃严重说明走线阻抗不匹配需要在源端加串联电阻通常 22Ω 到 33Ω。第二MOSI 和 MISO 的数据眼图是否张开。如果眼图闭合说明时序余量不够需要降低时钟或调整采样边沿。第三CS 的建立时间和保持时间是否满足从设备要求。CS 必须在 SCLK 第一个边沿之前至少提前半个周期拉低在最后一个边沿之后至少保持半个周期再拉高。注意逻辑分析仪的探头也有电容接上去之后可能会影响波形。如果发现接上探头后通信变差可能是探头电容太大换低电容探头或者缩短地线。5. 常见问题与排查技巧实录5.1 通信完全不通的排查步骤通信完全不通是最常见的问题排查要按顺序来不能东一榔头西一棒子。我的排查顺序是这样的第一步量电源。主机侧和从机侧的电源电压是否正常隔离模块有没有输出。如果从机侧没有电源隔离器不工作通信肯定不通。第二步量地。主机侧和从机侧的地是不是真的隔离了用万用表量两个地之间的电阻应该是无穷大。如果有阻值说明隔离被破坏要检查 PCB 和装配。第三步量信号。用示波器或者逻辑分析仪看主机侧的 SCLK 有没有输出从机侧的 SCLK 有没有对应的隔离后信号。如果主机侧有、从机侧没有说明隔离器没工作或者通道方向接反了。第四步量 CS。CS 有没有正常拉低从机侧有没有收到。如果 CS 一直高从设备不会响应。第五步检查 SPI 模式。主机和从机的 SPI 模式必须一致CKP 和 CKE 的设置要匹配。如果模式不对数据会错位。5.2 数据偶尔出错的排查思路数据偶尔出错比完全不通更难查因为它是间歇性的。常见原因有这几个一是电源噪声。隔离模块的开关噪声耦合到信号上导致某些位翻转。解决办法是在隔离模块输出端加滤波或者在信号线上加小电容。二是时序余量不足。SPI 时钟太快隔离器延迟导致采样错误。解决办法是降低 SPI 时钟或者调整采样边沿。三是地环路。虽然隔离器断开了地但如果从机侧还有其他路径连到主机侧的地就会形成地环路引入噪声。检查从机侧的所有连接确保没有第二条地路径。四是走线串扰。SCLK 和 MISO 平行走线太长SCLK 的跳变耦合到 MISO 上。解决办法是拉开走线间距或者在中间加地线屏蔽。下面这张表是我整理的问题速查表遇到问题可以对照着查现象可能原因排查方法解决措施完全不通电源未上电量两侧电源电压检查隔离模块和 LDO完全不通隔离器方向接反对照手册查通道方向调整接线或换型号完全不通SPI 模式不匹配查 CKP/CKE 设置统一主机从机模式偶尔出错电源噪声示波器看电源纹波加滤波电容和磁珠偶尔出错时序余量不足逻辑分析仪看眼图降低 SPI 时钟偶尔出错地环路量两侧地电阻断开第二条地路径偶尔出错走线串扰看波形有无毛刺拉开间距或加屏蔽数据错位采样边沿不对对比波形和数据调整 SMP 位5.3 隔离器发热的处理隔离器发热通常有两个原因一是负载太重输出电流超过了额定值二是电源电压超过了推荐范围。MAX14431BAEE 的每通道输出电流有限如果从设备的输入电容太大或者走线太长导致容性负载重隔离器就会发热。解决办法是在输出端加缓冲器或者减小走线长度。另一个原因是电源电压。MAX14431BAEE 支持 1.71V 到 5.5V 的宽电压但如果两侧电压差太大内部电平转换电路会消耗更多功率。比如主机侧 3.3V从机侧 5V隔离器内部会有额外的功耗。如果发热严重可以考虑两侧都用 3.3V或者选支持更高电压差的型号。实操心得隔离器发热的时候不要用手直接摸先用红外测温枪量一下温度。如果超过 60 度就要处理了。长期高温会缩短隔离器的寿命也会影响隔离性能。6. 性能验证与长期稳定性测试6.1 通信速率与误码率测试隔离链路搭好之后必须做误码率测试。我的测试方法是主机连续发送已知的数据序列从机接收后回传主机比对回传数据和发送数据是否一致。测试数据用伪随机序列长度至少 1MB覆盖各种位组合。测试时间至少连续跑 24 小时观察有没有误码。实测结果SPI 时钟 4MHz 时连续跑 72 小时误码率为零。SPI 时钟 8MHz 时连续跑 24 小时出现 3 个误码误码率约 10^-9。SPI 时钟 10MHz 时误码率明显上升约 10^-6。所以最终产品用的是 4MHz留了足够的余量。这个测试结果说明隔离器的延迟确实会影响高速通信。如果你的应用必须跑高速就要选延迟更小的隔离器或者优化 PCB 走线减少寄生参数。6.2 温度循环与长期老化观察工业设备要经过温度循环测试通常是 -40°C 到 85°C循环 100 次。我在测试中把整块板子放进温箱每个温度点保持 30 分钟然后跑误码率测试。结果在 -40°C 和 85°C 时通信都正常误码率为零。但有一次在 85°C 时发现隔离器输出波形幅度略有下降从 3.3V 降到 3.1V这是正常的温度漂移不影响逻辑判断。长期老化方面我让板子连续跑了 30 天每天记录一次误码率。30 天下来误码率始终为零隔离器温度稳定在 40°C 左右没有明显漂移。这个结果让我对这颗隔离器的长期可靠性有了信心。6.3 隔离耐压测试隔离耐压是安全指标必须测。我用的是耐压测试仪在主机侧地和从机侧地之间加 2.5kVrms 的交流电压持续 60 秒观察有没有击穿或漏电流超标。测试结果漏电流小于 1mA没有击穿隔离器完好。测试后重新跑通信一切正常。需要注意的是耐压测试是破坏性测试测过的板子不建议再用于产品。而且测试电压不能超过隔离器的额定值否则会永久损坏。MAX14431BAEE 的额定隔离电压是 2.5kVrms测试时加到 2.5kVrms 就够了不要加到 3kV 以上。7. 方案扩展与替代选型参考7.1 多从机场景下的隔离方案如果 SPI 总线上有多个从设备每个从设备都需要独立的 CS 信号。这时候隔离器的通道数就不够了需要选更多通道的隔离器或者用多颗隔离器级联。我的做法是用一颗六通道隔离器三正三反SCLK、MOSI 和三个 CS 走正向MISO 走反向剩下两个反向通道备用。如果从设备更多就用两颗隔离器或者用隔离型的 SPI 多路复用器。多从机场景下CS 的隔离要特别注意。每个 CS 都要独立隔离不能共用通道。而且 CS 的时序要保证在 SCLK 之前拉低在 SCLK 之后拉高否则从设备可能误动作。7.2 替代隔离器型号对比如果 MAX14431BAEE 缺货或者成本太高可以考虑这些替代型号型号通道配置最高速率隔离电压封装特点MAX14431BAEE2正2反25Mbps2.5kVrmsSOIC-16低延迟宽电压ADuM14013正1反25Mbps2.5kVrmsSOIC-16经典型号供货稳定ISO77413正1反100Mbps5kVrmsSOIC-16高速高隔离Si86413正1反150Mbps5kVrmsSOIC-16超高速低功耗选型的时候先确定通道方向再确定速率和隔离电压最后看封装和成本。ADuM1401 是 3正1反正好适合 SPI 的三正一反需求我用过很多次很稳定。ISO7741 和 Si8641 速率更高适合高速 SPI但成本也更高。7.3 软件层面的容错设计隔离链路虽然可靠但软件上还是要做容错。我的做法是每次 SPI 传输后检查返回的数据如果发现异常重试最多三次。三次都失败就报错让上层处理。另外在关键数据传输时加 CRC 校验接收端校验不通过就请求重发。这样即使偶尔出现误码也不会导致系统崩溃。还有一个技巧在 SPI 空闲的时候定期发送一个测试字节检查链路是否正常。如果测试字节返回错误说明链路可能出了问题提前报警。这个做法在工业现场很有用因为现场环境恶劣链路可能慢慢劣化定期自检可以提前发现隐患。8. 个人实操体会与建议这个项目做下来我最大的体会是隔离 SPI 通信硬件设计和软件调试各占一半缺一不可。硬件上把隔离器、电源、PCB 布局做扎实软件上把时序算清楚、把容错做好整个链路才能稳定可靠。另一个体会是不要迷信手册上的典型值一定要自己实测。手册上写传播延迟 30ns但实际板子上可能因为走线和负载变成 50ns。手册上写最高速率 25Mbps但实际跑到 10Mbps 就可能出错。只有自己用逻辑分析仪抓波形、用误码率测试验证才能知道真实性能。最后分享一个小技巧在隔离器的两侧各放一个 LED主机侧的 LED 指示主机电源正常从机侧的 LED 指示从机电源正常。调试的时候一眼就能看出是哪一侧没电省了很多排查时间。这个成本很低但很实用。如果你也在做类似的隔离通信项目建议先从低速跑通再逐步提高时钟同时用逻辑分析仪盯着波形。遇到问题不要慌按电源、地、信号、时序的顺序一步步查总能找到原因。
阅读完成 · 觉得有帮助?
咨询建站