PIC32 SPI驱动MR25H40CDF MRAM:工业非易失存储实战指南
做嵌入式的人都知道工业设备里最怕的不是“算不动”而是“丢了数据”。参数调好的设备重启一次变成出厂值运行日志写到一半突然掉电结果整片索引错乱这种问题在售后工单里能占到四成。这几年我在工业现场用得最顺手的一套组合是 Everspin 的 MR25H40CDF 串行 MRAM搭 Microchip 的 PIC32MX675F512L通过 SPI 接口完成读写。这套方案能直接把“非易失、掉电保存、频繁写入、随机读写”这几个痛点一次解决不用像伺候 NAND Flash 那样考虑坏块、擦除、磨损均衡也不用像 EEPROM 那样担心写穿。这篇文章不讲那些华而不实的架构只讲落地。包含硬件连接时的坑、PIC32 SPI 模块怎么配、MR25H40CDF 的读写驱动怎么写、掉电保护怎么做以及我踩过的几个典型问题。适合正在做工业控制、仪器仪表、机器人控制器的人参考也适合准备嵌入式面试时被问到“SPI 外设存储芯片怎么驱动”拿来当实战案例。1. 方案设计与选型思路1.1 为什么用 MRAM 而不是 Flash 或 EEPROM很多人一听到“非易失存储”第一反应就是 SPI Flash 或者 I2C EEPROM因为它们便宜、熟悉、例程多。但工业现场的环境和消费电子完全是两回事我用 MRAM 的原因很直接第一写入不需要擦除。普通 SPI NOR Flash 往已有数据的地址里写 0 没问题写 1 必须先擦除一擦就是整个扇区。工业设备里的参数通常是小块数据频繁改比如焊接参数、PID 调节值、运行状态每次都做“读-改-擦-写”的完整流程既慢又别扭。MR25H40CDF 是 MRAM 磁阻存储写入可以直接覆盖不需要前置擦除某种程度上你可以把它理解成“掉电不丢数据的 SRAM”。这在代码逻辑上省掉了一大堆麻烦。第二写寿命几乎没有上限。Flash 和 EEPROM 的写寿命都在十万到百万次这个量级做日志记录的时候一条一条追加几天就能把一片 EEPROM 写挂。MRAM 的写耐久远远超过这个量级做高频计数、实时日志这类应用时完全不用做磨损均衡代码简单太多。第三读写速度快。MR25H40CDF 的 SPI 时钟可以跑到几十兆赫兹读写时序和普通 SPI Flash 一样但省去了“等待擦除完成”的漫长过程。在 PIC32MX675F512L 这种 80MHz 主频的芯片上通过 SPI 搬运数据几乎没有瓶颈。当然MRAM 也不是没有缺点。单位容量价格比 Flash 高所以适合存关键数据而不是大块多媒体内容。另外虽然 MRAM 本身磁场抗干扰能力不错但引脚和 PCB 走线上的高频噪声仍然可能影响通信硬件上要稍微讲究一点。下面这张表是我经常用来跟人解释选型的对比项EEPROMNOR FlashNAND FlashMRAM写入前是否要擦除不需要整块擦除需要扇区擦除需要块擦除不需要写寿命约 100 万次约 10 万次约 10 万次远超 Flash单字节随机写方便要先读改写不方便方便写速度慢中等快但要有坏块管理快驱动复杂度低中高低典型应用小参数存储固件、掉电数据大容量文件系统高可靠日志、缓存、参数工业现场真正需要的其实不是“大容量”而是“可靠 简单”。MR25H40CDF 的容量是 4Mbit也就是 512KB和 PIC32MX675F512L 内置的 512KB Flash 容量恰好相当存个几十上百条参数、几千条运行日志完全够用。1.2 PIC32MX675F512L 在这个组合里扮演什么角色PIC32MX675F512L 是 Microchip PIC32MX 系列里的型号核心是 MIPS M4K主频 80MHz带 512KB 可编程 Flash 和 128KB 内存。这套配置做中低端工业控制器很舒服跑 Modbus、CAN、PID、电机控制都没问题同时有多个 SPI、UART、I2C、ADC 和比较器。我选择它还有一个原因这一类 MCU 的 SPI 外设功能完整有 DMA 支持有接收发送中断硬件上的帧同步逻辑也比较干净。在不需要操作系统的情况下你完全可以靠中断 状态机把它调得服服帖帖这对工业场景很重要。不过如果你看深入一点就会发现PIC32 的 SPI 模块和常见的 STM32 SPI 寄存器风格差别不小。它没有那种“一条指令直接收发一个字节”的直观感而是靠缓冲寄存器 SPIxBUF 同时完成收发。第一次用的时候容易晕后面我会把初始化代码和读写函数直接放出来照着配就行。MR25H40CDF 作为从设备挂在 PIC32 的 SPI 主模式下四根线分别是 SCK、SDOMOSI、SDIMISO、CS。片选信号由 PIC32 任意一个 GPIO 控制不一定要用硬件 CS。这样设计的好处是你在代码里可以非常灵活地控制片选的拉高拉低时机避免某些 SPI 外设在传输结束后片选释放异常的问题。2. 硬件连接与关键引脚细节2.1 四线 SPI 接法和去耦布局先讲电路。MR25H40CDF 采用 8 引脚 DFN 封装引脚功能不算复杂通常只需要关心电源 VCC、地 VSS、串行时钟 SCK、串行输入 SI、串行输出 SO、片选 CS、写保护 WP、暂停 HOLD。和 PIC32MX675F512L 连接时SCK 接 PIC32 的 SPI 时钟输出引脚SI 接 PIC32 的 SDO1 或 SDO2根据你选用的 SPI 模块决定SO 接 PIC32 的 SDI 引脚CS 接一个普通 GPIO。注意 CS 是低电平有效PIC32 GPIO 默认输出高初始化时先把 CS 拉高否则上电瞬间 MRAM 可能进入未知的接收状态。WP 和 HOLD 这两个引脚必须处理不能空着。WP 低电平会让状态寄存器里的写保护生效硬件上建议直接用一个 10kΩ 电阻上拉到 VCC把写保护功能默认关闭HOLD 低电平会让 SPI 通信暂停同样建议上拉到 VCC避免悬空受干扰。很多自己画板的人偷懒不接这两个引脚结果设备运行一阵子之后偶发性写失败排查半天最后发现是 HOLD 引脚受 EMC 干扰被拉低了一下通信直接卡死。电源部分MR25H40CDF 工作在 3.3VPIC32MX675F512L 的 IO 也是 3.3V所以不需要电平转换。比较重要的是 VCC 引脚旁边放一个 0.1μF 陶瓷电容再在稍远一点的位置放一个 1μF 或者 10μF 的钽电容。工业现场电机、继电器、变频器带来的电源毛刺非常恶心我见过不止一次因为去耦电容离芯片太远导致读回来的数据偶发错误。地线处理也要单独说一下。SPI 通信频率不算低SCK 和 SI 走线尽量短最好在底层放一个完整的地平面不要让 SPI 信号线和电源线长距离平行。2.2 写保护与状态寄存器里的“隐形开关”MR25H40CDF 和普通 SPI Flash 一样有一个状态寄存器里面最重要的位是写使能锁存 WEL、块保护 BP1/BP0、还有写保护启用 WPEN。上电后状态寄存器的默认状态一般是可以直接写入的但很多工程师在调试前期用其他 SPI Flash 例程往里写过状态寄存器可能把块保护位打开了之后所有 WRITE 指令都静默失败这个特别坑。所以我的习惯是每次系统初始化的时候先读一遍状态寄存器确认 BP 位没有置位。如果检测到被保护了就执行写入状态寄存器指令把块保护清掉。当然如果你的产品需要防止运行过程中误写完全可以让硬件 WP 引脚低有效同时通过状态寄存器开启保护这样软件写不了只能通过拉低引脚 解锁指令才能写。不过绝大多数项目用不上这么严格我建议默认关闭保护把业务层的数据校验做好就行。状态寄存器操作还有一个细节执行 WREN 写使能指令之后如果紧接着执行的是 WRSR 指令状态寄存器可以更新如果执行的是其他不相关的指令WEL 会自动清零。我后面提供的代码里每个写流程都会在整条命令开始前单独发一次 WREN然后再发写命令这是最简单也最不会出错的习惯。3. PIC32 SPI 初始化与读写驱动实现3.1 先配好 PIC32 的 SPI 主模式PIC32MX675F512L 的 SPI 外设用寄存器操作时主要看 SPIxCON、SPIxSTAT、SPIxBUF、SPIxBRG 四个寄存器。SPIxCON 配置模式、时钟极性和相位SPIxBRG 决定波特率SPIxSTAT 包含使能位和各种标志SPIxBUF 是收发数据缓冲。MR25H40CDF 支持 SPI Mode 0 和 Mode 3在我自己项目里统一用 Mode 0也就是 CPOL0、CPHA0空闲时 SCK 为低电平数据在第一个边沿采样。PIC32 对应的是 CKP0、CKE0。这样在逻辑分析仪上看波形最直观也不容易和后续其他 SPI 设备交叉影响。初始化代码可以这么写void spi1_init(unsigned int desired_khz) { unsigned int pb_clock_khz, brg; // 关闭 SPI1 SPI1STATbits.SPIEN 0; // 主模式Mode 08位数据空闲时钟低电平 SPI1CONbits.MSTEN 1; SPI1CONbits.CKP 0; SPI1CONbits.CKE 0; SPI1CONbits.ON 1; SPI1CONbits.MODE32 0; SPI1CONbits.MODE16 0; // 计算波特率BRG (PBCLK / (2 * desired_khz)) - 1 // page clock 取 20MHz 举例实际按你的分频配置来 pb_clock_khz 20000; brg (pb_clock_khz / (2U * desired_khz)) - 1; SPI1BRG brg; // 清标志使能 SPI IFS0CLR _IFS0_SPI1EIF_MASK; SPI1STATbits.SPIEN 1; }注意一个容易犯错的地方PIC32 的 SPI 波特率公式是Fpb / (2 * (BRG 1))不是直接除 BRG。如果你希望 SPI 跑 10MHzPB 时钟是 20MHz那么 BRG 算出来是 0。如果你希望跑 5MHzBRG 是 1。我建议调试阶段先跑 1MHz 左右确认读写没问题再往上提因为 10MHz 以上的 SPI 对跳线、杜邦线已经非常敏感工业现场最好不要图快。发送和接收一个字节的函数可以统一封装成unsigned char spi1_exchange(unsigned char data) { SPI1BUF data; while (!(SPI1STAT _SPI1STAT_SPIRBF_MASK)); return (unsigned char)SPI1BUF; }SPI 是全双工协议主设备发一个字节的同时会收到从设备返回的一个字节。这个特性在读取 MRAM 时尤其重要——你要往 SPIxBUF 里写一个任意值才能把时钟打起来让 MRAM 把数据送到 MISO 线上。很多人第一次调读取的时候只往缓冲里写地址忘了发“假字节”作为时钟结果读出来的永远是 0xFF这种问题很典型。3.2 实现 MR25H40CDF 的读写命令MR25H40CDF 的 SPI 命令集和普通 SPI Flash 很像我实际用到的主要是这几个WREN 0x06 写使能、WRDI 0x04 写禁止、RDSR 0x05 读状态寄存器、WRSR 0x01 写状态寄存器、READ 0x03 读数据、WRITE 0x02 写数据。地址是 24 位。先看最基本的状态寄存器读取unsigned char mram_read_status(void) { unsigned char status; CS_LO(); spi1_exchange(0x05); // RDSR status spi1_exchange(0x00); // 来一个时钟读出状态字节 CS_HI(); return status; }MRAM 的 CS 片选时序比普通 Flash 还重要因为读写一个字节不需要等待内部周期但 CS 拉高后内部也会复位接收逻辑。READ 命令的完整流程是CS 拉低、发送 0x03、发送 24 位地址高字节到低字节、连续读取 N 个字节、最后 CS 拉高。注意在整个读取过程中 CS 必须保持低电平不能中间拉高再拉低否则这一次读取直接失效。写数据的完整流程是CS 拉低、发送 WREN 0x06、CS 拉高然后再一次 CS 拉低、发送 WRITE 0x02、发送 24 位地址、发送数据、CS 拉高。我建议把 WREN 单独发不要和 WRITE 命令连在一起。虽然 MR25H40CDF 的手册上允许一定的连续时序但单独发 WREN 更保险代码也更清晰。完整读写函数我这样写#define MRAM_CMD_WREN 0x06 #define MRAM_CMD_WRDI 0x04 #define MRAM_CMD_RDSR 0x05 #define MRAM_CMD_WRSR 0x01 #define MRAM_CMD_READ 0x03 #define MRAM_CMD_WRITE 0x02 void mram_write_enable(void) { CS_LO(); spi1_exchange(MRAM_CMD_WREN); CS_HI(); } void mram_read(unsigned long addr, unsigned char *buf, unsigned int len) { unsigned int i; CS_LO(); spi1_exchange(MRAM_CMD_READ); spi1_exchange((addr 16) 0xFF); spi1_exchange((addr 8) 0xFF); spi1_exchange(addr 0xFF); for (i 0; i len; i) { buf[i] spi1_exchange(0xFF); } CS_HI(); } void mram_write(unsigned long addr, const unsigned char *buf, unsigned int len) { unsigned int i; mram_write_enable(); CS_LO(); spi1_exchange(MRAM_CMD_WRITE); spi1_exchange((addr 16) 0xFF); spi1_exchange((addr 8) 0xFF); spi1_exchange(addr 0xFF); for (i 0; i len; i) { spi1_exchange(buf[i]); } CS_HI(); }这段代码里有两个地方值得讲一下第一WRITE 命令一次最多能写多少字节取决于 MRAM 内部是否支持地址自动回卷。为了保险我习惯在一次写命令里限制最大 256 字节超过就分多次。MR25H40CDF 容量只有 512KB业务数据通常很小256 字节足够一次完整写一条日志。第二写完之后最好立刻回读校验。虽然 MRAM 的写入是即时的不会出现 Flash 那样的编程失败但系统总线上的噪声或者电源跌落仍然可能导致某个字节没写上。工业场景里“写完不信、读回才算”是基本的存储卫生。可以封装一个mram_write_verify函数写完之后用mram_read读同一段地址逐字节比对不一致就重试三次再失败就上报错误。这个函数是很多嵌入式面试题看不出来的隐藏考点实际产品里特别有用。3.3 用 SPI Flash 的 RDID 指令做调试抓手调试 SPI 设备最好用的办法是先读设备 ID确认通信链路没问题。MR25H40CDF 同样支持 RDID 指令命令码是 0x9F读回来三个字节。不过要提醒一句MRAM 厂商的 ID 和你常用的 Winbond、Macronix SPI Flash 肯定不一样不要拿 Flash 的厂商表去比对。直接把三个字节打印出来跟 datasheet 里的对照一次哪怕只是确认收到的不是全 0xFF 或者全 0x00也说明 SCK、MOSI、MISO、CS 四条线基本打通了。调试代码void mram_read_id(unsigned char id[3]) { CS_LO(); spi1_exchange(0x9F); id[0] spi1_exchange(0x00); id[1] spi1_exchange(0x00); id[2] spi1_exchange(0x00); CS_HI(); }如果读到全 0xFF检查 MISO 到 PIC32 SDI 的连线以及模式是否配错。如果读到全 0x00检查 SI 连线或者芯片供电。如果读到的 ID 每次都不一样大概率是 SPI 时钟太快或者 WP/HOLD 引脚悬空先降到 1MHz 再测。4. 工业应用中的掉电保存与日志设计4.1 参数存储结构魔数、版本、校验和把 MRAM 接到 PIC32 上只是第一步真正的工业设计是“怎么存数据才能扛得住恶劣环境”。我最常用的是“首部校验 双备份”结构。每个参数块在 MRAM 里连续存放开头固定几个字段4 字节魔数、2 字节版本号、4 字节数据长度、2 字节 CRC、然后是数据本体。读数据时先检查魔数再检查版本最后算 CRC。任何一步不对就认为这块数据失效去读备份区。备份区是另一块同样大小的区域。写入时先在备份区写新数据校验 CRC 通过后再写主区。读取时优先读主区主区校验失败就读备份区。这样即使写入过程中突然掉电主区和备份区也不会同时处于半写状态系统重启后至少能拿到一份完好的数据。为什么不用 Flash 那种“先写标志再写数据”的方式因为 MRAM 没有擦除限制双备份的代价只是容量翻倍换来极大的容错空间。512KB 容量拿来存参数哪怕每个参数块 64 字节双备份也足够存几千组。4.2 用环形缓冲记录运行日志工业现场另一个高频应用是运行日志。以前用 SPI Flash 记日志要不断做扇区擦除和磨损均衡写满一个扇区再搬数据代码量不亚于一个小型文件系统。用 MRAM 可以把整个日志区看成一个环形缓冲每次启动时读一个索引地址知道上一次写到哪里然后就往后面追加写满回绕。这个设计的关键在于日志的索引本身也要存一份并且带校验避免索引损坏导致整个日志不可用。每条日志固定长度比如 16 字节或者 32 字节这样回绕计算就是简单的取模运算。写入顺序是“先写日志数据再更新索引”。如果掉电发生在中间最多丢一条日志索引指向的旧数据不会被覆盖到错误位置。因为 MRAM 写寿命极高这个环形缓冲可以完全不做磨损均衡。你只需要保证代码里没有死循环不停写同一个地址就行剩下的随便造。我在一个连续振动监测的小设备上跑过一个 128KB 日志区每 100ms 写一条 16 字节日志连续跑了两个月没有出现过数据错乱。4.3 掉电瞬间的写保护策略掉电保护不能只靠 MRAMMCU 侧也要配合。PIC32MX675F512L 虽然有内置的上电复位和掉电检测但你不应该在掉电瞬间还让它继续执行复杂的多字节写入。最稳妥的方案是硬件上加一个电源监测芯片比如 Microchip 的 MCP101 或者其他复位监控器件当 VCC 跌落到阈值以下时拉低 PIC32 的复位脚或者 MRAM 的 CS/WP 脚。如果硬件改动不方便软件里至少要做到在主循环里周期性检查 ADC 采样到的电源电压一旦发现电压低于某个预设值立刻停止接收新的日志写入请求等在写过程中做一次的当前帧写入并尽快拉高 CS。不要尝试在掉电期间做双备份的完整流程因为你根本不知道还剩几个毫秒写一半就断电反而最容易产生脏数据。我个人经验是MRAM 本身掉电保持数据的能力很强真正会出问题的往往是“软件还在写电已经断了”的半程状态。把写入流程设计成“先写数据后更新指针”再加上双备份绝大多数情况下即使掉电重启后数据也是可恢复的。5. 常见问题与排查实录5.1 典型故障速查表我把这几年用 MR25H40CDF PIC32 调试遇到的典型问题整理成了一张表方便现场同事照着查故障现象可能原因排查方向读 ID 全 0xFFSPI 模式不匹配 / MISO没接对 / 芯片没供电先用万用表量 VCC再用逻辑分析仪看 MISO读 ID 有数据但和手册不一致读的是其他 SPI 设备 / 地址线问题确认片选是否唯一MCU 是否把命令发给了正确从机写数据后读回全是旧的没有执行 WREN / WP引脚被拉低 / 状态寄存器块保护开启连上调试器打印状态寄存器检查 WP 电平写数据后偶尔读错一两个字节SPI 频率过高 / 电源噪声 / HOLD 引脚受干扰降 SPI 频率检查去耦电容HOLD 上拉掉电重启后数据损坏写入过程中掉电 / 数据块没有校验上电后做一个扇区自检确认双备份和 CRC系统运行一段时间后通信卡死HOLD 引脚悬空受干扰 / CS 拉高时序错误检查 HOLD 是否上拉CS 释放是否有毛刺5.2 用逻辑分析仪看波形时的关键判据现场排查 SPI 问题逻辑分析仪比示波器好用尤其是抓长时间偶发故障的时候。抓 MRAM 读写波形我一般只看四个通道SCK、CS、MOSI、MISO。重点看三个地方第一个是 CS 拉低后SCK 的第一个边沿和 MOSI 上第一个字节的最高位是否对齐。如果 CS 刚拉低就采到一堆乱七八糟的数据大概率是 SCK 配置反了PIC32 的 CKP/CKE 位和从机要求的模式不匹配。第二个是整个命令期间 CS 是否一直保持低电平。有些 SPI 外设封装库会在发送每个字节之间自动拉高 CS这在 MRAM 上不行。MRAM 要求从命令到数据结束必须是连续的低电平片选中间一旦拉高整个事务被中断读出来的数据就是乱的。第三个是读取结束时 CS 拉高的位置。不能在最后一个字节还没收完就拉高也不能多拉几个时钟再拉高。用逻辑分析仪能看到指令结束边界如果发现数据移位就让 WRITE/READ 的长度严格等于 命令、地址、数据的总长度。5.3 我踩过的两个印象最深的坑第一个坑是状态寄存器写保护。有一版程序我参考了某开源项目里的 SPI Flash 驱动初始化时调用了WriteStatusRegister把状态寄存器设为 0x00。按理说 0x00 是取消保护但那次我在读取状态寄存器后发现 BP0 被置 1 了。查到最后发现是我把 WRSR 指令和 WREN 指令的顺序搞反了MRAM 要求先 WREN 才能 WRSR否则写入无效而原来的状态寄存器在硬件上电时已经被之前烧录器写成了非零值。从那以后我就把“上电读状态寄存器并把 BP 清零”写成了固定动作。第二个坑是掉电瞬间的脏数据。最初我认为 MRAM 非易失不需要双备份结果在一次过压测试里重启后数据区大量乱码。分析原因发现软件在掉电瞬间还处于一个很长的日志写入循环里写到一半电压掉没了。虽然 MRAM 本身没坏但数据帧只有一半是有意义的程序把半帧当完整帧解析自然就乱了。加了帧头、CRC、双备份之后再也没出现过这种问题。这个教训我记到现在MRAM 只保证“写进去的字节能保存”不保证“你刚好写完一个完整的帧”。5.4 给新手的三个调试建议如果你第一次在 PIC32MX675F512L 上驱动 MR25H40CDF我建议按这个顺序来先写一个最简单的spi1_exchange函数固定发 0xA5 到 MOSI同时接收 MISO。打开调试器观察两个方向的字节。这一步能确认 SPI 时钟、接线、方向是否正常。然后调 RDID。读不到设备 ID 不要往下走因为后面所有读写逻辑都建立在这条链路上。ID 读出来了说明 SPI 基本没问题。接着在 MRAM 的某个地址写一段固定数据比如{0xA5,0x5A,0xAA,0x55}再读回来比对。通过了再去封装mram_write_verify和上层应用千万不要一上来就写日志系统否则出了故障你分不清是驱动问题还是业务逻辑问题。最后还要提醒一下PIC32MX675F512L 的 SPI 引脚在不同封装里可能有多组映射编译链接前确认头文件里的外设定义和实际接线一致。我见过有人把 SDO1 和 SDO2 搞混程序看起来跑通了换一块板子就全废其实就是第二路 SPI 没初始化。这个组合看起来不复杂但越简单的方案越考验细节。MRAM 省掉了擦除和磨损均衡的复杂度PIC32 的 SPI 又很稳定剩下的就是老老实实把时序、校验、掉电保护做到位。我在实际项目中用这套组合存参数和日志两年多没有因为存储问题被客户找过这大概就是它最值得推荐的理由。

相关新闻

ESP32引脚与串口避坑指南:GPIO功能矩阵与UART硬件真相

ESP32引脚与串口避坑指南:GPIO功能矩阵与UART硬件真相

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:19:13 阅读更多 →
Qt开发Excel文件:qxlsx库原理与高性能实践指南

Qt开发Excel文件:qxlsx库原理与高性能实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:19:13 阅读更多 →
MR25H40CDF与PIC18F4525的SPI接口MRAM存储方案详解

MR25H40CDF与PIC18F4525的SPI接口MRAM存储方案详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:19:13 阅读更多 →

最新新闻

GQA数据集详解:从语言先验到视觉推理的评测革命

GQA数据集详解:从语言先验到视觉推理的评测革命

1. 为什么需要GQA:VQA评测中的“语言偏见”问题1.1 老数据集的问题做过多模态或者视觉问答(VQA)的朋友,大概率都踩过这套坑:模型在VQAv2上刷分刷得飞起,一换到真实场景就露馅。原因并不神秘,VQA…

2026/10/4 1:49:33 阅读更多 →
如何用UniMate实现文生动画?从文本提示到3D角色动作的完整流程

如何用UniMate实现文生动画?从文本提示到3D角色动作的完整流程

如何用UniMate实现文生动画?从文本提示到3D角色动作的完整流程 【免费下载链接】UniMate [SIGGRAPH Asia 2026] UniMate: One Unified Model to Animate Diverse Skeletons 项目地址: https://gitcode.com/GitHub_Trending/un/UniMate UniMate 是一个"文…

2026/10/4 1:49:33 阅读更多 →
基于SPI MRAM的工业掉电数据保存方案:MR25H40CDF与TM4C1299实战

基于SPI MRAM的工业掉电数据保存方案:MR25H40CDF与TM4C1299实战

直接讲正事。最近在做一块工业控制板,需要在掉电瞬间把运行参数、故障日志和校准数据可靠地存下来。项目里选了 MR25H40CDF 这颗 4Mbit SPI MRAM,搭配 TM4C1299KCZAD 主控。两个器件搭起来的这套存储方案,在工业和嵌入式场景里用起来很顺手&a…

2026/10/4 1:49:33 阅读更多 →
Vue Flow 拖拽式节点编辑器实战:DnD Sidebar 完整实现指南

Vue Flow 拖拽式节点编辑器实战:DnD Sidebar 完整实现指南

前端UI组件 【免费下载链接】vue-flow A highly customizable Flowchart component for Vue 3. Features seamless zoom & pan 🔎, additional components like a Minimap 🗺 and utilities to interact with state and graph. 项目地址:…

2026/10/4 1:49:33 阅读更多 →
STM32+MRAM工业存储实战:替代Flash实现高频写入与掉电保存

STM32+MRAM工业存储实战:替代Flash实现高频写入与掉电保存

做了这么多年嵌入式,存储方案来来去去选了不下七八种,从 I2C EEPROM、SPI NOR Flash 到铁电存储器,各有各的脾气。这次的活儿是要给一块以 STM32F446RE 为主控的工业采集板做非易失存储,刷进去的是设备运行状态、传感器采样值和配…

2026/10/4 1:49:33 阅读更多 →
talebook 写作审查输出格式规范(review-output.md):Findings 表、严重级别与裁决机制的完整解析

talebook 写作审查输出格式规范(review-output.md):Findings 表、严重级别与裁决机制的完整解析

后端前端CMS 【免费下载链接】talebook 一个简单好用的个人书库 项目地址: https://gitcode.com/gh_mirrors/ta/talebook 点击查看 免费下载 写作审查(writing review)是 talebook 前端体验工程中用于评估界面文案质量的标准流程&#xff0c…

2026/10/4 1:48:33 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →