写命令已经发出,Flash为何还是旧数据?
SPI线上出现02h和数据,只能证明字节被发送;Flash是否接受并完成编程,还要看WEL、WIP、擦除状态和页边界
逻辑分析仪已经抓到Page Program命令、24位地址和一串数据,CS也按预期拉低再拉高。重新读取同一地址,内容却仍是旧值,或者只有前半段正确。
SPI控制器只负责把比特移出引脚,它不知道外部Flash当前是否写保护、是否忙、目标位能不能直接翻转,也不会自动把跨页数据拆开。
工程判断是:通信成功与编程成功是两层状态。每次写入都要完成器件状态机闭环,不能用“命令发出”代替“数据落盘”。
先确认硬件引脚没有把写操作锁住
W25Q16类串行Flash除了CS、CLK、DIO和DO,还可能包含WP与HOLD等控制引脚。它们必须处在器件手册要求的稳定状态,不能悬空或在写周期中被意外拉动。
图1 MCU与W25Q16连接要同时处理CS、时钟、数据与保护引脚
CS的边界同样重要。一条页编程命令通常要求命令、地址和数据位于同一个有效CS帧内,过早拉高会结束指令,帧之间随意插入CS翻转也可能让器件重新解析。
上电后先读JEDEC ID和状态寄存器,可以验证总线模式、字节序和器件响应。能读ID仍不等于写路径合格,但能先排除最基础的接线与采样沿问题。
WREN之后,要读回WEL写使能命令通常把状态寄存器中的WEL位置位,它是页编程和擦除的授权。复位、掉电、某些写周期完成或错误流程后,WEL可能被清除。
图2 命令表把写使能、状态读取、页编程与擦除串成完整流程
稳妥流程不是发送06h后直接假设成功,而是立即读状态寄存器,确认WEL确实为1,再发送02h、地址和数据。若WEL未置位,应检查写保护、状态寄存器保护位和CS时序。
页编程启动后,WIP或BUSY位会保持有效。主控必须轮询到忙结束,才能发起下一次会修改存储阵列的操作;用固定短延时,在温度和供电变化后最容易失效。
串行NOR Flash编程通常只能把存储位从1变成0。若目标地址已有0,而新数据希望它回到1,单纯页编程无法完成,必须先擦除所在扇区。
图3 页编程要求WEL有效、目标已擦除,并遵守256字节页边界
擦除粒度通常大于一次写入的数据量。更新少数字节时,应先读出整个受影响区域,在RAM中合并新数据,擦除后再按页写回,并考虑掉电保护。
W25X16示例中的页编程一次最多256字节,且不能把一个数据块不加处理地跨过页边界。超出当前页的部分可能按器件规则回卷覆盖或产生非预期结果,驱动应按页剩余长度切分。
用状态与回读把每一步关上调试日志至少记录命令、地址、长度、发送前状态、启动后WIP变化、完成状态和回读校验。只有这样,失败才能被定位为授权、忙等待、擦除、跨页还是传输本身。
逻辑分析仪解码要核对SPI模式、采样沿和CS帧。读ID正确但大批量写失败时,重点看跨页切分和等待忙;完全不写时,优先看WEL、保护位和WP引脚。
图4 SPI模式与采样沿必须先正确,状态机诊断才有可信基础
写入结束后不要只比较首字节。对整个区块做回读,记录首个错误地址和期望/实际位差。若错误总发生在页边界或只能0变1失败,机制会非常清楚。
产品还应考虑写入中掉电。关键数据可使用双备份、版本号和校验,再在启动时选择完整版本,避免一次未完成擦除把配置区变成不可恢复的半状态。
状态寄存器中的块保护位、状态寄存器保护和写保护引脚可能共同限制写入范围。某些地址能写、某些地址始终保持旧值时,应先读出全部保护配置,并确认驱动没有在初始化中误写这些位。更换容量或厂商后,保护位定义可能不同,不能只复制旧驱动常量。
忙轮询也要设置超时。正常编程和擦除时间有上限,若供电跌落、器件异常或总线失去响应,死循环等待WIP会拖死整个系统。超时后应保存错误码、状态寄存器和操作地址,并进入可恢复路径,而不是立刻重复擦写同一扇区。
页写函数可以先计算当前地址到页尾还剩多少字节,取本次长度为“剩余数据”和“页内余量”的较小值。每完成一页都等待WIP清零并校验,再继续下一页。这样跨页行为由主控明确控制,不依赖器件回卷细节。
对频繁更新的小参数,直接反复擦同一扇区会消耗寿命。可采用日志式追加、磨损均衡或在RAM中合并后降低擦除次数,并记录掉电恢复信息。可靠驱动不仅要把这一次数据写进去,还要让长期重复写入和异常复位后仍能找回完整版本。
Flash写入不是一条02h命令,而是一条状态机:写使能、确认WEL、页编程、等待WIP清零、回读校验,必要时还要先擦除并按页切分。
下次看到总线有数据却写不进去,先把状态寄存器也抓进日志。命令是否发出只是起点,器件是否接受并完成才是结论。
声明:
本文由凡亿教育整理,转载请注明来源!
投稿/招聘/广告/课程合作/资源置换 请加微信:13237418207
暂无评论