尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MR25H40CDF与PIC18LF45K50实战:SPI MRAM驱动、掉电保护与Flash迁移指南

MR25H40CDF与PIC18LF45K50实战:SPI MRAM驱动、掉电保护与Flash迁移指南 嵌入式项目里存储方案的选择往往决定了整个系统的可靠性和维护成本。我做过不少工业数据采集和参数存储的项目早期用EEPROM后来换SPI Flash再后来接触到MRAM这类新型非易失存储器每一次切换背后都是踩坑踩出来的经验。这次要聊的组合是MR25H40CDF加PIC18LF45K50一颗是4Mbit的SPI MRAM一颗是PIC18系列里外设比较均衡的低功耗8位单片机。这个搭配在工业现场的数据记录、参数保存、掉电保护场景里非常实用尤其适合那些对写入寿命和写入速度都有要求的场合。整篇内容我会从器件选型逻辑、硬件连接、SPI驱动编写、读写时序、数据完整性保障几个维度展开把我在实际项目中积累的操作细节和避坑经验都放进来不管你是刚接触SPI存储的新手还是想从Flash迁移到MRAM的老手应该都能找到可以直接用的东西。1. 为什么这个组合值得认真对待1.1 MR25H40CDF到底解决了什么痛点先说MR25H40CDF这颗芯片。它是Everspin出的SPI接口MRAM容量4Mbit也就是512KB组织方式是512K×8位。MRAM的全称是磁阻随机存取存储器核心原理是用磁性隧道结存储数据而不是像Flash那样靠浮栅电荷。这个区别带来的实际好处非常直接写入不需要擦除、写入速度是纳秒级、写入寿命几乎无限。我在一个工业称重项目里用过SPI Flash存标定参数每次标定要写一次产线一天标定几百台Flash的10万次擦写寿命虽然够用但写入前必须擦除整个扇区一旦写到一半掉电整个扇区的数据就全丢了。MRAM没有这个问题它是按字节直接覆盖写不需要擦除掉电也不会丢已经写进去的数据。MR25H40CDF的具体参数值得列一下供电电压2.7V到3.6VSPI接口最高40MHz时钟支持SPI模式0和模式3工作温度范围覆盖工业级-40到85摄氏度还有扩展级到105摄氏度的版本。封装是8引脚SOIC引脚定义和标准SPI Flash兼容这意味着如果你原来板子上焊的是W25Q40或者类似的小容量Flash理论上可以直接替换当然驱动要改。它的写入电流典型值大约十几毫安待机电流只有几微安对于电池供电或者低功耗采集节点来说很友好。有一点需要特别注意MR25H40CDF的存储阵列是真正的随机存取没有扇区、没有页的概念你可以直接对任意地址写任意字节。这和Flash的先擦后写逻辑完全不同。很多从Flash转过来的工程师第一反应是找擦除指令结果发现根本没有。这个特性简化了驱动但也意味着你不能用原来Flash那套读-改-擦-写的流程得重新设计数据写入策略。1.2 PIC18LF45K50在这个方案里的角色PIC18LF45K50是Microchip的PIC18F系列8位单片机LF版本意味着它支持低电压供电工作电压范围2.0V到3.6V和MR25H40CDF的2.7V到3.6V有重叠区间所以整个系统可以统一用3.3V供电。它内置32KB Flash程序存储器、2048字节SRAM、256字节EEPROM还有丰富的外设SPI、I2C、UART、多个定时器、10位ADC、比较器、PWM模块等。封装有40引脚PDIP和44引脚TQFP两种做工业控制板的话TQFP更省空间。选这颗片子配MR25H40CDF主要看中几点。第一它的MSSP模块支持SPI主模式最高时钟可以到系统时钟的四分之一如果系统跑16MHzSPI可以到4MHz虽然跑不满MRAM的40MHz上限但对于大多数数据记录场景已经足够。第二它的低功耗特性好休眠电流在纳安级别配合MRAM的微安级待机整个数据记录节点可以用电池撑很久。第三PIC18的生态成熟编译器、调试器、代码示例都齐全开发周期短。第四它有两个SPI相关的引脚映射选项布局灵活。这里要提醒一个容易忽略的点PIC18LF45K50的SPI模块在配置为从模式时SS引脚必须由外部控制但在主模式下你可以用任意GPIO做片选不一定非要用硬件SS引脚。这一点在PCB布局时很关键因为MRAM的片选需要单独控制用普通GPIO反而更灵活。我在一个项目里因为把片选接到了硬件SS上结果发现SPI模块在某些配置下会自动控制这个引脚导致片选时序不对后来改成普通GPIO才解决。1.3 这个组合适合哪些场景从应用场景来看这个组合特别适合几类需求。一是工业现场的数据记录仪需要频繁写入采集数据比如每秒写一次Flash的寿命和擦除延迟都吃不消MRAM可以轻松应对。二是需要掉电瞬间保存关键状态的应用比如电机控制器在断电前要把当前位置和参数写进去MRAM的纳秒级写入和无需擦除特性让这个操作非常可靠。三是需要频繁更新配置参数的设备比如智能仪表用户可能经常调整量程、报警阈值这些参数存在MRAM里写入次数完全不用操心。反过来如果你的应用只是偶尔写一次数据比如一年写几次日志那用MRAM有点浪费SPI Flash或者EEPROM更经济。MR25H40CDF的价格比同容量Flash高不少选型时要算清楚成本账。另外如果你的数据量很大512KB不够用那得考虑更大容量的MRAM或者换其他方案。这个组合的定位是中小容量、高可靠性、高频写入的场景。2. 硬件连接与PCB布局的实操细节2.1 引脚连接与电平匹配MR25H40CDF是8引脚SOIC封装引脚定义如下1脚是片选CS2脚是SPI时钟SCK3脚是数据输入SI4脚是地VSS5脚是数据输出SO6脚是写保护WP7脚是保持HOLD8脚是电源VCC。PIC18LF45K50这边我用的是RC3作为SCKRC4作为SISDORC5作为SOSDIRC2作为片选。注意PIC的命名习惯SDO是数据输出接MRAM的SISDI是数据输入接MRAM的SO别接反了。电平匹配方面两边都是3.3V供电直接连接即可不需要电平转换。但要注意PIC18LF45K50的I/O口在3.3V供电时输出高电平大约在2.8V到3.0V之间MRAM的输入高电平门限是0.7×VCC也就是2.31V左右所以逻辑高电平是够的。如果系统供电是3.0V那PIC的输出高电平可能只有2.5V左右仍然高于2.1V的门限问题不大。但如果供电降到2.7V就要仔细核对数据手册了因为PIC的输出高电平会随供电下降可能接近MRAM的输入门限。WP和HOLD这两个引脚不能悬空。WP是写保护低电平有效如果你不需要硬件写保护直接接到VCC。HOLD是保持引脚低电平有效用于暂停SPI通信不用的话也接到VCC。我见过有人把这两个脚悬空结果MRAM工作不稳定偶尔写不进去查了半天才发现是引脚浮空导致。稳妥做法是各接一个10k上拉到VCC或者直接短接到VCC。2.2 PCB布局中的SPI走线要点SPI走线在低速下比如1MHz以下要求不高但如果你想把时钟跑到10MHz以上布局就得讲究了。SCK是时钟线最容易产生干扰走线要尽量短避免和模拟信号线平行走。SI和SO是数据线尽量等长虽然SPI不是差分信号但等长有助于减少时序偏差。CS片选线在每次通信时都会翻转如果走线太长边沿会变缓可能导致MRAM误判。我在一个四层板上做过测试SCK走线从5厘米缩短到2厘米通信误码率从万分之一降到几乎为零。所以如果条件允许MRAM尽量靠近单片机放置走线控制在3厘米以内。如果板子空间受限必须走长线可以在SCK上串一个22欧姆到33欧姆的电阻减缓边沿抑制反射。这个电阻值不能太大否则上升沿太慢高速通信会出问题。电源去耦也很关键。MRAM的VCC引脚旁边要放一个0.1微法的陶瓷电容越近越好最好在2毫米以内。再并一个1微法或者10微法的钽电容或陶瓷电容提供瞬态电流。MRAM在写入瞬间电流会跳变如果去耦不够电源上会有毛刺可能导致写入失败或者单片机复位。我吃过这个亏后来在每个存储芯片旁边都加了大小电容组合问题再没出现过。2.3 上电时序与复位处理MR25H40CDF的上电时序要求不严VCC上升到2.7V以上后芯片内部有个上电复位电路大约需要100微秒到1毫秒的稳定时间。在这段时间内不要发起SPI通信否则可能读到无效数据。我的做法是在单片机初始化时先延时10毫秒再做MRAM的首次访问。这个延时不影响系统启动速度但能保证存储芯片完全就绪。PIC18LF45K50这边上电复位后要配置振荡器、I/O口、MSSP模块。配置顺序建议是先设I/O方向把CS拉高不选中然后配置SPI的时钟极性、相位、速率最后使能SPI模块。如果顺序反了比如先使能SPI再拉高CS可能在配置过程中产生一个短暂的片选有效脉冲导致MRAM误动作。虽然概率不高但工业产品要杜绝这种隐患。还有一个细节如果系统中有复位按钮或者看门狗复位复位后MRAM的状态不会改变数据仍然保留。但单片机的SPI模块会回到默认状态所以每次复位后都要重新初始化SPI。我在代码里把SPI初始化封装成一个函数上电和复位后都调用确保状态一致。3. SPI驱动编写与MRAM读写操作3.1 PIC18LF45K50的MSSP模块配置PIC18LF45K50的SPI配置涉及几个寄存器SSPCON1、SSPCON2、SSPSTAT、SSPADD。主模式下SSPADD用来设置时钟分频。假设系统时钟Fosc是16MHzSPI时钟是Fosc除以4再除以SSPADD1的两倍关系具体公式要看数据手册。简单说如果SSPADD设为0SPI时钟是Fosc/4也就是4MHz设为1是Fosc/82MHz。我一般先用低速比如1MHz调通再逐步提高。配置代码大概长这样// SPI主模式初始化时钟约1MHz SSPSTAT 0x40; // 数据在时钟中间采样具体看模式 SSPCON1 0x30; // SSPEN1, CKP1, 主模式时钟Fosc/16 SSPADD 3; // 分频值配合SSPCON1得到目标时钟 TRISC2 0; // CS引脚输出 TRISC3 0; // SCK输出 TRISC5 1; // SDI输入 TRISC4 0; // SDO输出 RC2 1; // CS默认拉高这里要注意SPI模式。MR25H40CDF支持模式0CPOL0CPHA0和模式3CPOL1CPHA1。模式0是时钟空闲低电平数据在上升沿采样模式3是时钟空闲高电平数据在下降沿采样。两种模式都能用我习惯用模式0因为大多数SPI Flash和传感器都用模式0代码通用性好。配置时CKP位决定空闲电平SSPSTAT的SMP位决定采样时刻要配合好。3.2 单字节读写函数与片选控制SPI通信的基本单元是字节收发。PIC18的MSSP模块有一个SSPBUF寄存器写入数据启动发送同时接收数据也进这个寄存器。所以读写是同时进行的。一个典型的字节交换函数unsigned char SPI_ExchangeByte(unsigned char data) { SSPBUF data; // 写入要发送的数据 while(!SSPIF); // 等待传输完成 SSPIF 0; // 清除中断标志 return SSPBUF; // 返回接收到的数据 }片选控制要严格。每次操作MRAM前先把CS拉低然后发送指令和地址再读写数据最后把CS拉高。CS拉高后MRAM内部会把这次操作提交如果是写操作数据在这时候真正写入存储阵列。所以CS的上升沿很关键不能太快也不能太慢。太快可能导致MRAM还没完成内部写入太慢影响效率。实测下来CS拉高后至少保持100纳秒再开始下一次操作比较稳妥。MRAM的指令集很简单读指令是0x03写指令是0x02还有读状态寄存器0x05、写状态寄存器0x01等。读操作时序是CS拉低发送0x03发送24位地址因为512KB需要19位地址但MRAM用24位地址格式然后连续读取数据每读一个字节地址自动加一。写操作类似发送0x02发送24位地址然后连续写入数据。注意写操作没有页边界限制可以一直写到存储末尾。3.3 连续读写与地址自动递增MR25H40CDF支持连续读写地址在每次字节传输后自动递增到达最高地址后回卷到0。这个特性在批量读写时很有用。比如你要保存一个512字节的数据块只需要发一次读指令和起始地址然后连续读512个字节即可不用每次都发地址。写操作也一样一次发指令和起始地址然后连续写。但这里有个坑如果你在连续写的过程中CS被意外拉高写入会中断已经写入的数据保留但后续数据丢失。所以连续写的时候要确保CS稳定。我在代码里用了一个循环每次写之前检查CS状态虽然理论上不会变但多一层保护没坏处。另外连续写的时候要注意不要超过存储容量虽然地址会回卷但回卷后覆盖开头的数据可能不是你想要的。读操作相对简单没有写入延迟问题。MRAM的读访问时间是纳秒级SPI时钟多快读就多快。我实测在4MHz SPI时钟下读512字节大约1毫秒出头完全满足实时性要求。写操作稍微复杂一点因为MRAM内部写入虽然快但SPI传输本身需要时间。写512字节在4MHz下也是1毫秒左右加上CS开销总共不到2毫秒。3.4 状态寄存器与写保护机制MR25H40CDF内部有一个状态寄存器可以读取和写入。状态寄存器的位定义包括写保护使能、块保护位等。默认情况下写保护是关闭的你可以直接写数据。如果你需要保护某些区域不被误写可以通过状态寄存器设置块保护。比如把前64KB设为只读后面的区域可写。这个功能在存储固件参数和用户数据混合的场景很有用。读状态寄存器的代码unsigned char MRAM_ReadStatus(void) { unsigned char status; RC2 0; // CS拉低 SPI_ExchangeByte(0x05); // 读状态寄存器指令 status SPI_ExchangeByte(0xFF); // 读回状态 RC2 1; // CS拉高 return status; }写状态寄存器要小心因为状态寄存器本身也受写保护逻辑影响。如果已经设置了块保护再想改回来需要先解除保护而解除保护可能需要特定的时序。我建议在初始化时就把状态寄存器配置好运行中尽量不改。如果确实需要动态修改一定要在数据手册里确认时序要求特别是写使能指令0x06和写状态指令之间的间隔。还有一个细节MRAM的写保护引脚WP是硬件保护低电平有效。如果你把WP接地那所有写操作都被禁止包括写状态寄存器。所以WP引脚要么接VCC要么用GPIO控制不要直接接地。我在一个项目里为了保险把WP接地结果调试时发现怎么写都写不进去查了半天才想起来这个引脚。4. 数据完整性与掉电保护策略4.1 为什么MRAM不需要磨损均衡从Flash转过来的工程师经常会问MRAM需要磨损均衡吗答案是基本不需要。Flash的擦写寿命有限比如10万次如果频繁写同一个地址那个块很快就会坏掉所以需要磨损均衡算法把写入分散到不同块。MRAM的写入寿命是无限的至少数据手册标称是10的14次方次以上实际上可以认为是无限。所以你可以放心地反复写同一个地址不用担心寿命问题。但这不意味着可以乱写。虽然存储单元不会坏但频繁写同一个地址在系统层面可能有其他影响比如功耗、电磁干扰等。不过在大多数应用里这些影响可以忽略。我在一个每秒写一次数据的项目里连续运行了三个月写入次数超过800万次MRAM没有任何异常。所以对于MRAM磨损均衡不是必须的代码可以简化很多。不过有一个场景需要注意如果你用MRAM存储文件系统或者数据库那磨损均衡可能还是需要的不是因为存储单元会坏而是因为文件系统本身的元数据更新可能集中在某些区域。但这是文件系统层面的问题不是MRAM的问题。对于裸机直接读写MRAM的应用完全不用考虑磨损均衡。4.2 掉电瞬间的数据保存方案工业现场最怕的就是掉电丢数据。MRAM的写入速度极快但前提是数据已经通过SPI传到了MRAM内部。如果掉电发生在SPI传输过程中那部分数据可能没写进去。所以掉电保护的关键是在电源电压下降到单片机工作下限之前把关键数据写完。PIC18LF45K50有一个可编程的低电压检测模块可以设置检测电压阈值。当电源电压降到阈值时产生中断在中断里快速把关键数据写入MRAM。这个中断的响应时间加上SPI传输时间必须小于电源从阈值降到单片机最低工作电压的时间。假设电源上有100微法电容负载电流10毫安电压从3.3V降到2.0V的时间大约是13毫秒。在这13毫秒内你要完成中断响应、数据准备、SPI传输。SPI传100字节在4MHz下大约200微秒加上中断开销总共不到1毫秒时间非常充裕。具体实现时LVD中断里不要做复杂运算直接把预先准备好的数据缓冲区通过SPI写入MRAM。数据缓冲区在正常运行时就要维护好掉电时直接写。我一般会在RAM里维护一个影子数据结构每次数据变化时更新影子掉电中断里把影子整体写入MRAM。这样中断里只做SPI传输速度最快。还有一个技巧MRAM的写入是即时生效的不需要等待。所以掉电中断里写完就可以不管了不需要像Flash那样等待擦除完成。这大大简化了掉电保护逻辑。我在一个电机控制器项目里用这个方案掉电时保存转子位置和运行参数恢复后系统能无缝继续客户反馈很好。4.3 数据校验与冗余存储虽然MRAM本身很可靠但SPI通信可能受干扰数据在传输过程中可能出错。所以关键数据最好加校验。最简单的方案是加CRC校验。每个数据块后面跟一个CRC16或者CRC32读取时校验不通过就重读或者报错。CRC的计算可以在写入前做读取后验证。冗余存储是另一个思路。把同一份数据存两份地址隔开读取时对比两份数据一致才采用不一致就用备份恢复。这个方案占用双倍空间但对于512KB的MRAM来说存两份256KB的数据通常够用。我在一个安全相关的项目里用了三份冗余加上CRC可靠性非常高。不过冗余存储有个问题如果两份数据都错了怎么办概率很低但理论上存在。更稳妥的方案是加一个版本号或者时间戳每次写入时版本号加一读取时选版本号最新的那份。这样即使某次写入出错只要另一份是好的就能恢复。版本号本身也要校验防止回卷。4.4 初始化时的数据恢复流程系统上电后第一件事是检查MRAM里的数据是否有效。我的做法是在MRAM的固定地址放一个魔数和版本号比如地址0x000000放0x5A5A地址0x000001放数据结构版本。上电后先读这两个字节如果魔数不对说明MRAM是空的或者数据损坏那就用默认值初始化。如果魔数对但版本号不匹配说明数据结构变了需要做数据迁移或者重新初始化。数据恢复流程要设计得健壮。我一般分几步第一步读魔数和版本判断数据是否有效第二步读CRC校验数据完整性第三步如果校验失败尝试读备份区第四步如果备份也失败加载默认值并记录错误标志。这个流程在代码里是一个状态机每一步都有超时和重试机制防止死循环。还有一点初始化时不要急着写MRAM。有些工程师上电后不管三七二十一先把默认值写进去结果把之前保存的有效数据覆盖了。正确做法是先读确认无效后再写。我在一个项目里因为初始化逻辑写反了导致每次上电都覆盖用户参数客户投诉了好几次后来改成先读后写才解决。5. 性能实测与常见问题排查5.1 不同SPI时钟下的读写速度对比我拿PIC18LF45K50跑16MHz系统时钟SPI分频从Fosc/4到Fosc/64实测了MR25H40CDF的读写速度。测试方法是连续写1024字节然后连续读1024字节用定时器计时。结果如下SPI时钟写1024字节耗时读1024字节耗时误码情况4MHz约2.1ms约2.0ms无2MHz约4.2ms约4.1ms无1MHz约8.3ms约8.2ms无500kHz约16.5ms约16.4ms无从数据看读写速度基本对称因为MRAM的读和写都是通过SPI传输瓶颈在SPI时钟。4MHz下写1KB大约2毫秒对于每秒写一次的应用绰绰有余。如果你需要更快可以提高系统时钟到48MHzSPI可以到12MHz但PIC18LF45K50的最高系统时钟是64MHz通过PLL实际跑48MHz没问题。不过高速下PCB布局要更讲究否则误码率会上升。误码测试我做了连续100万次读写没有出现误码。但这个测试是在实验室环境下工业现场有电磁干扰可能需要加屏蔽或者降低时钟。我在一个变频器旁边做过测试4MHz下偶尔有误码降到2MHz就稳定了。所以现场调试时如果发现数据偶尔出错先降SPI时钟试试。5.2 写入失败与数据错乱的排查路径写入失败是常见问题排查要按顺序来。第一步查硬件CS、SCK、SI、SO四根线有没有接错WP和HOLD有没有上拉电源电压是否在2.7V以上。我遇到过CS接错到另一个GPIO的情况结果怎么都写不进去用示波器看波形才发现CS根本没动。第二步查SPI配置模式对不对时钟极性相位是否匹配分频值是否合理。第三步查指令时序写操作前有没有发写使能指令如果需要CS拉低到第一个时钟沿之间有没有足够延时。数据错乱通常是时序问题。比如读出来的数据整体偏移一个字节那可能是CS拉低后第一个时钟沿来得太快MRAM还没准备好。解决方法是CS拉低后加一个小延时比如1微秒。或者检查SPI模式模式0和模式3的采样时刻不同用错了会读到错位的数据。还有一种情况是地址发错了比如24位地址只发了16位那读出来的数据肯定不对。我在一个项目里遇到过写进去的数据读出来是乱的查了两天最后发现是SPI时钟太快MRAM的建立时间不够。数据手册上写最高40MHz但那是在理想条件下的实际PCB走线有电容电感边沿变缓有效时钟频率要打折。降到10MHz以下就正常了。所以数据手册的参数是上限实际用的时候要留余量。5.3 电源噪声导致的偶发故障电源噪声是嵌入式系统里最隐蔽的问题。MRAM在写入时电流会突然增大如果电源去耦不够VCC上会有电压跌落可能导致写入失败或者单片机复位。我遇到过一个案例系统运行几小时后偶尔复位查了很久没找到原因后来用示波器抓电源波形发现每次MRAM写入时VCC上有200毫伏的毛刺正好触发了单片机的欠压复位。解决办法是在MRAM的VCC引脚旁边加一个10微法的陶瓷电容再并一个0.1微法的。如果空间允许再加一个磁珠或者小电感把MRAM的电源和单片机的电源稍微隔离。这样MRAM写入时的电流冲击不会影响单片机。另外电源走线要粗地线要完整最好用星型接地把数字地和模拟地分开。还有一个细节如果系统里有电机或者继电器这些感性负载在开关时会产生很大的反电动势通过电源线传导到MRAM。这种情况下除了加去耦还要在感性负载两端加续流二极管在电源入口加TVS管。我在一个工业控制板上加了这些保护后偶发故障率从每月几次降到零。5.4 长时间运行的数据保持验证MRAM的数据保持能力理论上很强但实际产品要验证。我做过一个加速老化测试把写满数据的MRAM放在85摄氏度环境下每隔一段时间读出来校验。测试了1000小时数据没有丢失。按照数据手册的标称MRAM的数据保持时间超过20年工业级温度下也超过10年。这个指标比Flash好很多Flash在高温下数据保持时间会大幅缩短。不过测试归测试实际产品里还是要做定期校验。我的做法是在系统空闲时每隔一段时间比如一天读一次关键数据校验CRC如果发现错误就从备份恢复。这个机制在MRAM上其实很少触发但加上去不费什么事能提高系统的可靠性。另外如果产品有远程升级功能升级前最好把关键数据备份到MRAM的另一个区域升级后再恢复防止升级过程中掉电导致数据丢失。6. 从Flash迁移到MRAM的代码改造要点6.1 擦除逻辑的移除与写入流程简化如果你原来用SPI Flash代码里肯定有扇区擦除、页写入这些函数。迁移到MRAM后擦除函数可以整个删掉写入函数也要改。Flash的写入流程是读整个扇区到RAM修改要改的字节擦除扇区再把整个扇区写回去。MRAM的流程是直接写目标地址想写几个字节就写几个字节。代码量减少很多而且没有擦除延迟写入响应快。但要注意Flash的页写入通常有页边界限制比如256字节一页跨页要分两次写。MRAM没有页概念可以跨任意边界连续写。所以原来处理页边界的代码可以删掉。不过如果你的数据结构是按页对齐的迁移后可以保持对齐也可以不对齐看方便。我一般保持对齐因为代码改动小而且对齐后地址计算简单。还有一个区别Flash写入前通常要发写使能指令MRAM也有写使能但很多情况下可以省略因为MRAM默认就是可写的。不过为了兼容性和安全性我建议还是保留写使能指令特别是在有写保护需求的时候。写使能指令是0x06发一次对后续一次写操作有效写完自动清除。6.2 地址映射与数据结构调整Flash的地址空间通常按扇区组织比如4KB一个扇区扇区内可以按字节读但写要整扇区擦。MRAM是线性地址空间512KB连续没有扇区边界。所以原来按扇区分配的数据结构可以改成按实际大小分配节省空间。比如原来一个参数占4KB扇区现在可以只占几十字节。但数据结构调整要小心。如果原来依赖扇区边界做数据隔离比如参数区和日志区各占一个扇区迁移后要重新规划地址。我的做法是画一个地址映射表把每个数据块的起始地址、长度、用途列清楚然后按这个表改代码。地址映射表最好放在头文件里用宏定义方便修改。还有一个问题Flash的擦除次数有限所以原来可能用了磨损均衡算法把写入分散到不同扇区。迁移到MRAM后磨损均衡可以去掉但如果你原来用磨损均衡实现了某种日志功能比如循环记录那这个逻辑要保留只是底层写入函数换成MRAM的。循环记录在MRAM上更简单因为不用擦除直接覆盖写就行。6.3 写保护与安全机制的重新设计Flash通常有块保护功能通过状态寄存器设置。MRAM也有类似功能但实现方式不同。Flash的块保护通常是保护整个扇区MRAM可以按更细的粒度保护具体看数据手册。迁移时如果原来依赖Flash的块保护来防止误写那在MRAM上要重新配置。我的建议是如果安全要求高除了用MRAM的硬件保护还在软件层加校验比如写之前检查地址范围写之后读回验证。写保护引脚WP的用法也要注意。Flash的WP引脚通常是低电平有效MRAM也是。但有些Flash的WP只在特定指令下生效MRAM的WP是实时的拉低就写不进去。所以如果原来用GPIO控制WP做动态保护迁移后逻辑要调整。我一般把WP直接接VCC不用硬件保护全靠软件控制这样更灵活。安全机制方面如果原来有加密或者签名迁移后这些逻辑不变只是存储介质变了。但要注意MRAM的读取速度比Flash快如果加密算法依赖读取延迟做某种保护那在MRAM上可能失效。不过这种情况很少见大多数加密算法不依赖存储介质的速度。6.4 实际迁移案例中的性能对比我做过一个实际迁移案例原来用W25Q40 Flash存工业仪表的标定参数和运行日志每天标定几次日志每小时写一次。Flash方案下每次标定要擦除一个4KB扇区耗时约50毫秒期间单片机要等待影响了实时响应。迁移到MR25H40CDF后标定参数直接写耗时不到1毫秒实时性大幅提升。日志写入也从原来的读-改-擦-写变成直接追加代码简化了一半。性能对比数据Flash方案下写100字节参数平均耗时45毫秒含擦除MRAM方案下耗时0.3毫秒。读操作两者差不多都是SPI传输时间。功耗方面Flash擦除时电流较大约15毫安持续时间长MRAM写入电流约10毫安持续时间短所以平均功耗MRAM更低。可靠性方面Flash方案在掉电时如果正在擦除整个扇区数据丢失MRAM方案掉电时最多丢失当前正在写的字节之前的数据都保留。迁移后唯一增加的成本是芯片价格MR25H40CDF比W25Q40贵几倍。但从系统可靠性和开发维护成本看这个投入值得。特别是工业产品现场故障的维修成本远高于芯片差价。所以如果应用场景匹配我强烈建议考虑MRAM方案。7. 几个容易被忽略的工程细节7.1 上拉电阻的取值与影响SPI总线上拉电阻的取值有讲究。CS、SCK、SI、SO四根线通常CS需要上拉保证单片机复位时MRAM不被选中。上拉电阻一般用10k太小了增加功耗太大了上升沿变缓。如果SPI时钟高比如10MHz10k上拉可能不够因为线电容和上拉电阻形成RC延迟导致边沿变缓。这时候可以降到4.7k或者2.2k。SCK和SI、SO一般不需要上拉因为它们是推挽输出单片机主动驱动。但如果总线上有多个从设备或者走线很长可以加上拉提高抗干扰能力。我一般只在CS上加10k上拉其他线不加。如果现场干扰大再考虑加。还有一个细节MRAM的HOLD引脚如果不用一定要上拉到VCC。我见过有人把HOLD悬空结果MRAM偶尔进入保持状态通信中断。HOLD是低电平有效悬空时电平不确定可能被干扰拉低。所以稳妥做法是10k上拉到VCC。7.2 多设备共享SPI总线的片选管理如果一个SPI总线上挂多个设备比如MRAM加一个SPI温度传感器那CS管理就很重要。任何时候只能有一个设备的CS有效其他都要拉高。我在代码里用一个CS管理函数切换设备时先拉高当前CS再拉低目标CS中间加一个小延时确保总线稳定。多设备共享时SCK、SI、SO三根线是共用的所以每个设备的SPI模式必须一致。如果MRAM用模式0传感器用模式3那就不能共享总线得用两个SPI模块或者软件模拟。PIC18LF45K50只有一个MSSP模块所以如果设备模式不同只能用GPIO模拟SPI或者分时切换模式。分时切换模式比较麻烦因为每次切换都要重新配置寄存器而且切换期间总线状态可能不稳定。所以选型时尽量选SPI模式一致的设备。还有一个问题如果某个设备在通信过程中突然掉电它的SPI引脚可能变成低电平把总线拉死。这种情况下其他设备也无法通信。解决办法是在每个设备的SI和SO上串一个小电阻比如100欧姆这样即使某个设备引脚短路也不会完全拉死总线。或者用SPI缓冲器芯片但成本高。我在一个项目里遇到过传感器掉电拉死总线的问题后来加了串阻解决。7.3 温度范围与工业级选型确认MR25H40CDF有工业级和扩展级两种温度范围。工业级是-40到85摄氏度扩展级是-40到105摄氏度。如果你的产品用在户外或者高温环境比如太阳能逆变器、汽车电子那要选扩展级。扩展级的价格稍高但可靠性有保障。我见过一个案例客户用了工业级芯片在85摄氏度以上环境结果数据偶尔出错换了扩展级就好了。PIC18LF45K50也有温度等级工业级是-40到85摄氏度。如果环境温度超过85度要考虑其他型号或者加散热。另外温度对SPI时序有影响高温下信号传播速度变化可能导致时序余量减少。所以在高温环境下SPI时钟要降额使用比如原来跑4MHz高温下降到2MHz。选型时还要看供货和生命周期。MRAM芯片的供货周期可能比Flash长价格波动也大。所以如果产品生命周期长要提前备货或者找替代型号。Everspin的MRAM有几个容量和接口的变体比如并口、SPI、QSPI选型时要确认封装和引脚兼容性。7.4 调试工具与波形观测方法调试SPI通信示波器是必备的。用四通道示波器同时抓CS、SCK、SI、SO能直观看到时序。触发方式设为CS下降沿这样每次通信都能抓到。看波形时重点看几个地方CS拉低到第一个SCK沿的延时是否足够SCK的占空比是否接近50%SI和SO的数据在SCK沿上是否稳定。如果发现数据在SCK沿上还在跳变说明建立时间不够要降时钟或者改布局。逻辑分析仪比示波器更好用因为它能直接解码SPI协议把二进制数据翻译成字节显示。我用的是Saleae的逻辑分析仪配合软件能直接看到读写的地址和数据调试效率很高。如果没有逻辑分析仪也可以用单片机的UART把读写的数据打印出来但这样看不到时序只能看数据对不对。还有一个技巧在代码里加一个回环测试函数把SI和SO短接发送什么就接收什么。如果回环测试通过说明单片机的SPI模块配置正确问题在MRAM或者走线上。如果回环测试都不通过那肯定是单片机配置问题。这个测试能快速定位问题范围节省调试时间。8. 写在最后的几点个人体会这个组合我用在好几个项目里了从数据记录仪到电机控制器整体表现很稳。MRAM的无需擦除、无限写入特性一旦用习惯了再回去用Flash会觉得处处受限。PIC18LF45K50虽然是个8位机但外设够用开发工具成熟配MRAM做中小规模的数据存储绰绰有余。选型时不要只看参数要算总账。MRAM芯片贵但省了擦除逻辑、磨损均衡、掉电保护的大部分复杂度开发和维护成本降下来了。工业产品现场故障一次维修成本可能就超过芯片差价。所以如果应用场景匹配这个投入是值得的。最后分享一个小技巧MRAM的CS引脚在PCB上尽量靠近单片机走线短且直。如果板子空间实在紧张可以把MRAM放在单片机背面通过过孔连接这样走线最短。我试过这种布局4MHz SPI下通信非常稳定误码率为零。另外MRAM的电源引脚旁边一定要放去耦电容0.1微法和10微法并联这是保证可靠性的底线不能省。
返回列表