工业嵌入式存储选型:用MRAM替代EEPROM与Flash的实战方案
最近在做一套工业现场设备改版时处理器选了 PIC32MX695F512L需要在嵌入式系统里安全地存储和读取一批运行参数、事件日志与校准数据。刚开始我也按老办法打算直接用片上 Flash 或 SPI EEPROM但仔细核算频率、寿命和掉电一致性之后发现常规方案很难同时满足“频繁改写”和“绝不丢数”这两个要求。最后把存储器件换成 Everspin 的 MR25H40CDF4Mbit SPI MRAM配合 PIC32MX695F512L 的一个 SPI 外设整套存储方案从设计到落地不到两周。写这篇文章把选型逻辑、电路连接、驱动封装、参数区和日志区的设计思路以及实际调试中踩过的几个坑整理出来给正在做工业嵌入式存储的同行一个可以少走弯路的参考。1. 为什么工业存储不能只盯着 EEPROM 和 Flash1.1 PIC32MX695F512L 项目里实际遇到的问题PIC32MX695F512L 是一颗 80MHz MIPS 内核、512KB Flash、128KB RAM 的 100 脚 MCU。512KB 片上 Flash 用来放固件和启动加载程序剩下能自由使用的非常有限。工业设备的非易失存储需求其实很“细碎”PID 参数、累计运行时间、故障码、最近 N 条事件记录、校准系数单条数据通常只有几十字节但改写得非常频繁。最初我用的是 25LC256 SPI EEPROM32KB价格不高按字节写也方便。可上系统测试后发现两个痛点第一EEPROM 页写需要 5ms 等待偶尔一两秒内连续来几十条告警记录时根本来不及同步写第二把设备参数按每小时一次刷新来算三年就是两万多次虽然看似不多但 EEPROM 通常在百万次级如果日志也往同一片 EEPROM 里写寿命余量会迅速缩水。后来考虑过 FRAM但当前选型周期里容量、接口和供货都不如 MRAM 顺手。MR25H40CDF 是 Everspin 的 SPI MRAM最大优势是写入不需要擦除、不需要等待几乎跟读一样快而且写寿命没有实际损耗上限。这正好解决“频繁改写”和“掉电保存”两个最让人担心的点。1.2 MR25H40CDF 的关键参数速览我把项目里最关心的参数列了一张表方便和 EEPROM/Flash 对比参数MR25H40CDF常规 SPI FlashSPI EEPROM容量4Mbit / 512KB常见 8~64Mbit常见 32~256Kbit接口SPI Mode 0/3SPISPI写前擦除不需要需要按扇区擦除不需要单字节写周期无额外等待约一个 SPI 帧页写数毫秒典型 5ms写寿命理论无限次10 万~100 万次100 万次数据保持20 年以上75℃20 年20 年工作电压2.7V~3.6V常用 3.3V常用 3.3V工作温度工业级 -40℃~85℃同同封装DFN-8 / SOIC-8SOIC-8 等SOIC-8 等注意 MR25H40CDF 的“CDF”后缀通常对应 DFN-8 封装体积很小PCB 上不占地方。虽然它的最高 SPI 时钟能到 40MHz但工程上并不一定要跑满稳定优先我在最终方案里把时钟定在 10MHz。1.3 “无限次写入”到底带来多大简化做过 Flash 日志的人都知道Flash 频繁写入前要考虑擦除、磨损均衡、坏块管理、掉电可能导致半页脏数据。这些事在工业产品上每一条都要认真处理。而 MRAM 没有擦除动作任何地址都可以直接覆盖写寿命又足够长所以驱动逻辑可以退化成“先写使能再按地址写字节”不需要维护擦写均衡表也不需要在管理员模式下批量搬家。这并不代表数据一致性可以不考虑了掉电那一刻若正好在写一条记录仍然可能留下半个记录的数据。只是 MRAM 至少把“硬件层限制”大部分移除了剩下的是软件协议设计问题复杂度低很多。这点对我吸引力最大。2. 硬件连接与 SPI 初始化把 MR25H40CDF 正确接进 PIC32MX695F512L2.1 八根引脚的接法每一根都不能省MR25H40CDF 只有 8 个引脚但往往越简单的器件越容易在接线上翻车。先列一下我的接法MR25H40CDF 引脚接到 PIC32MX695F512L说明CS普通 GPIO例如 RD8命令开始和结束必须由 MCU 控制SCLKSPI2_SCK主模式输出10MHzMOSI/SISPI2_SDO主出从入MISO/SOSPI2_SDI主入从出WP3.3V 或 GPIO平时拉高需要硬件保护时拉低HOLD3.3V直接接 VCC 最稳切忌悬空VCC3.3V并联 0.1uF 10uF 去耦VSSGND铺地后短引线到 MCU 地CS 不用硬件自动片选因为 MRAM 每个命令都要求 CS 在一次传输中拉低、结束拉高软件 GPIO 控制最可靠。HOLD 引脚是暂停串行通信用的如果悬空工业现场噪声很容易把它抖动到有效电平导致读写不正常。我在产测阶段就被这个坑坑过一次后续所有板子上都把 HOLD 直接上拉到 VCC再没复发。SCLK 和 MOSI 上可以各串联 22Ω 电阻用来抑制信号反射和振铃。工业设备里 SPI 线往往不会太长几十毫米内不需要做阻抗匹配但串电阻能改善波形成本又低值得加上。2.2 PIC32MX695F512L 的 SPI2 初始化PIC32MX695F512L 的 SPI 有可重映射功能需要先配置 PPS外设引脚选择再配置 SPI 控制器本身。下面是一段简化版的初始化示意MPLAB Harmony 生成的工程可以直接替换成 SPI2 标准 API。void spi2_init(void) { // 1. 先把要用作 SPI2 的引脚配置成数字 I/O清掉模拟复用 ANSELDbits.ANSD8 0; // CS 用数字输出 ANSELBbits.ANSB0 0; // SCLK具体管脚以实际 PPS 映射为准 ANSELBbits.ANSB1 0; // SDO ANSELBbits.ANSB2 0; // SDI // 2. PPS 重映射根据数据手册把 SPI2 信号绑定到目标引脚 // (不同 PCB 引脚不同这里只示意不照抄) // 3. 配置 SPI2 为主模式SPI Mode 0 SPI2CON 0; SPI2BRG 1; // 外设时钟 40MHz 时约得到 10MHz SCK SPI2CONbits.MSTEN 1; // Master SPI2CONbits.CKP 0; // 时钟空闲为低 SPI2CONbits.CKE 0; // SPI Mode 0 的边沿组合 SPI2CONbits.MODE16 0; // 8-bit 模式 SPI2CONbits.SMP 0; SPI2CONbits.ON 1; // 打开 SPI }这段代码不是唯一写法重点是要理解为什么用 10MHzPIC32MX695F512L 外设时钟典型 40MHzSPI2BRG 1时 SCK 约等于 40 / (2 * (1 1)) 10MHz。如果希望用更高速率可以改 BRG 值但要关注 MISO 采样时序和 PCB 走线质量。2.3 电源、去耦和工业现场的抗干扰考虑MRAM 静态电流很小但连续高速读时峰值电流会比待机高一个数量级。在 3.3V 电源入口处加一只 10uF 钽电容再在 VCC 引脚旁边放一只 0.1uF 陶瓷电容布局上尽量贴近器件。如果现场电源本身波动大还可以在 VCC 上并联一个 TVS 管防止浪涌尖峰打坏 MRAM 控制器。很多 SPI 通信异常其实不是逻辑错误而是电源地回路太长、MISO 采样点落在信号翻转沿上。工业设备机柜里变频器多开关噪声大这时优先降低 SPI 频率而不是加滤波。3. MR25H40CDF 读写指令与驱动封装3.1 指令表和地址空间MR25H40CDF 的指令很精简和常见 SPI NOR Flash 类似但没有擦除指令。核心命令如下指令名称操作码功能WREN0x06写使能WRDI0x04写禁止RDSR0x05读状态寄存器WRSR0x01写状态寄存器READ0x03读取数据WRITE0x02写入数据地址是 24 位协议格式但 MR25H40CDF 只有 4Mbit实际有效地址为 0x00000 到 0x7FFFF共 512KB。发送地址时只需要填 19 个有效位其余高位填 0 即可。连续读或连续写时内部地址自动递增越过 0x7FFFF 后会回绕到 0。这个回绕行为非常关键驱动层必须自己拦住不能依赖硬件。3.2 状态寄存器与写使能的正确姿势MRAM 没有像 Flash 那样的“忙等待”因为写入本身实时完成。但状态寄存器仍然存在给软件一个兼容层bit0 通常为 WIP 位在 MRAM 上意义不大基本恒为 0bit1 是 WEL写使能锁存每次执行 WRITE 或 WRSR 前都必须先发 WRENbit2/bit3 是 BP0/BP1用于写保护范围设置默认上电为 0不保护WP 引脚拉低时硬件写保护生效BP 位无法通过软件修改。所以每次写操作的标准流程是CS 拉低发 0x06CS 拉高再 CS 拉低发 0x02、地址、数据CS 拉高。写完后 WEL 会被自动清掉如果程序没有重新 WREN下次写入会被忽略。3.3 驱动代码按 512KB 边界自动分段下面是一段精简驱动重点在mram_write和mram_read中对地址回绕的处理。spi2_xfer封装了 PIC32MX695F512L SPI2 的一次字节交换。#define MRAM_SIZE 0x80000u #define MRAM_CMD_WREN 0x06u #define MRAM_CMD_READ 0x03u #define MRAM_CMD_WRITE 0x02u static void mram_cs_low(void) { LATDbits.LATD8 0; } static void mram_cs_high(void) { LATDbits.LATD8 1; } static uint8_t spi2_xfer(uint8_t byte) { SPI2BUF byte; while (!SPI2STATbits.SPIRBF) ; return (uint8_t)SPI2BUF; } static void mram_wren(void) { mram_cs_low(); spi2_xfer(MRAM_CMD_WREN); mram_cs_high(); } void mram_write(uint32_t addr, const uint8_t *buf, uint32_t len) { while (len 0) { uint32_t chunk MRAM_SIZE - addr; if (chunk len) chunk len; mram_wren(); mram_cs_low(); spi2_xfer(MRAM_CMD_WRITE); spi2_xfer((addr 16) 0xFF); spi2_xfer((addr 8) 0xFF); spi2_xfer(addr 0xFF); for (uint32_t i 0; i chunk; i) { spi2_xfer(buf[i]); } mram_cs_high(); addr chunk; buf chunk; len - chunk; } } void mram_read(uint32_t addr, uint8_t *buf, uint32_t len) { while (len 0) { uint32_t chunk MRAM_SIZE - addr; if (chunk len) chunk len; mram_cs_low(); spi2_xfer(MRAM_CMD_READ); spi2_xfer((addr 16) 0xFF); spi2_xfer((addr 8) 0xFF); spi2_xfer(addr 0xFF); for (uint32_t i 0; i chunk; i) { buf[i] spi2_xfer(0x00); } mram_cs_high(); addr chunk; buf chunk; len - chunk; } }可能有人问为什么不写一个通用 SPI 驱动层因为我量产后固件里就是要用最直接的轮询方式等后面的日志系统和参数槽跑起来后你会发现 CPU 等待时间非常短一个 32 字节记录在 10MHz 下也就是几十微秒完全够用。3.4 初始化时要不要读一次状态寄存器强烈建议上电初始化时先读一次状态寄存器确认 WEL 为 0、BP 为 0。很多“明明写进去了但读出来还是旧值”的故障都是因为上电时 BP 位被历史数据污染导致写保护悄悄开启。执行一次 WRSR 把 BP 清 0 再继续业务整个过程只需要几条命令非常值得。4. 存储和读取数据的实际架构参数槽、事件日志与掉电一致性4.1 512KB 怎么分配MR25H40CDF 有 512KB对一块工业设备主板来说相当宽裕。我按功能分区地址范围用途0x00000 ~ 0x003FF参数槽 A1KB0x00400 ~ 0x007FF参数槽 B1KB0x00800 ~ 0x03FFF事件日志区16KB0x04000 ~ 0x7FFFF校准数据、用户扩展、临时缓存事件日志只留了 16KB按每条 64 字节计算可以存 256 条。如果客户要求更多还可以把后面区域重新划分。工业现场真正重要的是参数槽的原子更新而不是日志容量。4.2 参数槽用双槽交替写解决原子性问题MRAM 虽然字节直接可写但一个参数结构体包含 timestamp、PID 值、累计运行时间等多个字段写入过程中一旦掉电可能只写了一半。解决方案不是靠硬件而是靠双槽备份。我把参数区做成两个同样大小的槽每个槽头部如下typedef struct { uint32_t magic; // 固定为 0xA5A5A5A5用于识别有效槽 uint32_t seq; // 单调递增序号越大表示越新 uint32_t crc32; // 对 data 区域的校验 uint32_t data_len; uint8_t data[496]; } param_slot_t;更新流程读两个槽的头部解析 magic、seq、crc32 是否有效当前有效槽是 seq 较大的那一个把新参数整体打包到临时缓冲区计算 CRC写入另一个非当前槽先写头部、数据最后再写 magic写完后回读头部确认 seq 和 magic 正确下次上电比较两个槽选择有效且 seq 较大的槽。这里 MRAM 的作用非常明显写旧槽不需要先整片擦除直接覆盖即可。双槽切换时如果新槽写到一半掉电那么新槽 magic 不会成功回读时会被判定无效系统会继续使用旧槽参数不会丢。4.3 事件日志环形缓冲 commit 标记事件日志更适合用环形结构而不是双槽。我在日志区开头放一个固定大小的头部记录当前写指针和最新的日志序号后面数据按记录偏移写入。单条记录结构typedef struct { uint32_t seq; // 自增序号 uint32_t ts; // 事件时间戳 uint16_t len; // payload 长度 uint8_t payload[]; // 实际事件数据 uint16_t crc; // 对 payload 的校验 uint8_t valid; // 0x5A 表示完整记录 } log_record_t;写日志时先把整条记录除valid外的内容写入固定位置再单独写最后一个字节valid 0x5A。这样如果掉电发生在写 payload 中途valid不会被置 1启动扫描时遇到valid不是 0x5A 或 CRC 失败就认为后续记录全部无效直接从有效记录末尾继续写。环形缓冲回卷时MRAM 的免擦除特性再次体现旧记录被新记录覆盖不需要搬移整个 block。同样 16KB 的日志区如果换成 SPI Flash你还要额外处理擦除调度代码量会多出一大截。4.4 存储读取与业务代码的解耦为了让主程序不受具体存储介质影响我把 MRAM 封装成两个接口int nvs_param_load(param_slot_t *out); int nvs_param_save(const param_slot_t *param); int nvs_log_append(const uint8_t *payload, uint16_t len); int nvs_log_iterate(uint32_t from_seq, log_callback_t cb);上层业务只关心存参数、读日志不关心底层是 MRAM 还是 EEPROM。后面如果客户要求换存储介质只需要重写这一层业务代码完全不用动。这种解耦在嵌入式项目里非常实用至少省掉了一轮全局替换的返工。5. 实测踩坑记录当场写不进去、读出全 0、偶发乱码5.1 “写完 CS 拉高太早”导致数据丢失这是我第一次把驱动从 ARM 平台迁移到 PIC32 时遇到的。调用spi2_xfer读回最后一个字节后看似传输完成但如果没有确认移位寄存器已经把最后一个 bit 送完立刻拉高 CSMRAM 可能丢掉最后一个字节。解决办法是确保SPI2STATbits.SPIRBF被置位并且不要在最后一个字节之后立刻翻转 CS而是再做一次读操作或加一个极短的延时。用示波器抓 CS 和 SCLK能很直观地看到 CS 总是在最后一拍结束后才拉高。5.2 SPI Mode 0 和 Mode 3 “都能读对”的错觉MR25H40CDF 数据手册支持 Mode 0 和 Mode 3但这不代表可以随便配。PIC32 的 CKP/CKE 位定义和部分 ARM MCU 手册不完全一致我曾把 CKE 配反结果读出来的数据整体右移一位看起来像随机数。后来我固定用 Mode 0并在驱动初始化后主动写一个 0xA5 再读回来自检通过后才继续业务。这个自检函数后来也作为产线测试的一部分保留了下来。5.3 HOLD 和 WP 悬空带来的随机故障第二批样机里有一台设备在客户现场出现“写了参数重启后参数还是旧值”的问题。板子上 MRAM 的 HOLD 和 WP 引脚都是空的只连了 MRAM 内部上拉。实验室里很难复现一到现场马达启动瞬间就出问题。排查之后发现是 HOLD 悬空受到了干扰。从此所有出厂的板子都强制把 HOLD 接到 3.3VWP 也显式拉高。这个教训特别典型小封装器件的“不接”不等于“安全”关键控制引脚必须处理。5.4 PPS 重映射和模拟输入没有清干净PIC32MX695F512L 的某些复用引脚带模拟输入功能。如果 SPI 引脚没有把模拟通道关闭SPI 时钟线上会残留模拟采样电路的影响导致通信时好时坏。所以初始化顺序应该是先配置 PPS再把 ANSEL 对应的位清 0最后打开 SPI。顺序反了就可能出现初始化一次失败、重新上电又正常的现象。5.5 温度变化后 CRC 偶尔失败问题不在 MRAM有一轮高低温测试设备在 70℃ 环境下日志 CRC 偶发校验失败。一开始怀疑 MRAM 高温性能不行后来用示波器看波形发现 MISO 数据沿和 MCU 采样点太近环境温度变了之后翻转速度变化边沿错开了。解决办法不是换存储器而是把 SPI 时钟从 20MHz 降到 10MHz同时在 MRAM 的 VCC 引脚就近再并联一颗 10nF 陶瓷电容。之后整批测试没有再出现。5.6 “无限次写入”不等于“永远不坏”MRAM 的写寿命确实很长读写次数基本不用顾虑但数据保持时间与温度强相关。手册给出的 20 年保持是在典型温度下如果产品长期工作在 85℃ 以上保存期限会缩短。工业项目里我习惯每年在设备维护周期里对关键参数区做一次“重写校验”即重新写一遍顺便刷新数据保持时间。这种维护成本极低但能避免十年后出现“不出错但数据悄悄老化”的问题。6. 产线自检与后续扩展思路量产不是焊好就能发货。我在产线测试里增加了一项 MRAM 自检对 512KB 全空间写入 0x55、0xAA再回读比对大约一两秒跑完。不要小看这个动作它能提前发现虚焊、电源纹波、PCB 走线不良等隐性故障。自检代码可以在 Bootloader 里运行不影响产品打包流程。后续如果要把这套方案扩展到需要更大容量的场景MRAM 只是第一站。同一片 SPI 总线上还可以挂 SPI NOR Flash 存大块升级包MRAM 存高频参数两者各司其职。MR25H40CDF 最大的价值是把“频繁写、不能丢”这件事从软件协议层里解放出来让我有更多精力去处理真正复杂的数据一致性问题。最后再分享一个小技巧MRAM 上电后我会先读一遍头尾两个地址的握手字节如果握手失败就在日志里标记“MRAM 诊断失败”而不是把业务数据贸然覆盖进去。这个动作虽然简单却帮我在开发期提前发现过两次电源配置错误。

相关新闻

OpenClaw核心交互层实践:统一多IM平台消息接入与适配

OpenClaw核心交互层实践:统一多IM平台消息接入与适配

1. 核心交互层的整体设计思路1.1 为什么非要做一个独立交互层我在本地跑OpenClaw跑了两三个月,最开始是直接用命令行怼着聊,后来又接了几个渠道,结果发现一个很现实的问题:每加一个平台,业务逻辑就得跟着改一遍。微信来…

2026/10/4 19:06:12 阅读更多 →
STM32全景导览:从内核选型到生态工具链与典型项目实战

STM32全景导览:从内核选型到生态工具链与典型项目实战

做嵌入式这些年,ST的STM32可以说是绕不开的一个系列。从学生时代的第一个点灯程序,到量产项目里的FOC电机控制,再到近两年的物联网网关,这个芯片家族几乎贯穿了我整个职业生涯。每次有人问我"想入门单片机选什么"&#…

2026/10/4 19:05:12 阅读更多 →
Agent如何知道自己该学新东西了?从失败信号到学习闭环的工程实践

Agent如何知道自己该学新东西了?从失败信号到学习闭环的工程实践

1. 从"Agent 该不该学新东西"这个问题说起做 Agent 开发的人,早晚会撞上一个很别扭的问题:你辛辛苦苦搭好的 Agent,跑起来之后表现还不错,但过了一段时间你会发现它开始"力不从心"——不是它坏了,…

2026/10/4 19:05:12 阅读更多 →

最新新闻

C#与Golang WebSocket性能对比:并发模型、实测数据与选型指南

C#与Golang WebSocket性能对比:并发模型、实测数据与选型指南

开篇先交代一下背景。最近团队内部做实时通信网关选型,正好赶上“WebSocket性能谁更强”的话题,C#和Golang两个阵营各有拥趸,吵得不可开交。有人拿C#的Async/Await说事,有人搬出goroutine的并发模型,还有人直接甩压测数…

2026/10/4 20:24:53 阅读更多 →
AI编程插件不是扩展,而是可编排的智能服务节点

AI编程插件不是扩展,而是可编排的智能服务节点

1. “plugins”不是功能菜单,而是现代AI编程工具的神经突触你打开Cursor、Codex或Zcode这类AI编程助手,点开设置里那个叫“Plugins”的选项卡,第一反应可能是——这不就是个插件市场?跟VS Code扩展商店差不多,搜个“Pr…

2026/10/4 20:24:52 阅读更多 →
缺陷检测的三个核心战场——**模板比对、拟合测量、Blob分析**——各有各的适用场景和工程陷阱

缺陷检测的三个核心战场——**模板比对、拟合测量、Blob分析**——各有各的适用场景和工程陷阱

缺陷检测的三个核心战场——模板比对、拟合测量、Blob分析——各有各的适用场景和工程陷阱。下面用三个真实产线案例,把它们的实战逻辑讲透。 案例一:模板比对检测印刷品缺陷 场景:药品包装盒印刷质量检测。检测目标:印刷错位、漏…

2026/10/4 20:24:52 阅读更多 →
STM32F103入门实战:点灯、串口调试与项目实践

STM32F103入门实战:点灯、串口调试与项目实践

板子终于到手了。STM32F103这块芯片在嵌入式圈子里真的算“国民级”存在,开发板、最小系统板、教学视频里露脸最多的就是它。买这块板子的理由也很简单:资料多、外设全、价格便宜,哪怕以后不吃这行饭,拿来当业余爱好折腾也完全不亏…

2026/10/4 20:24:52 阅读更多 →
二手设备信息平台怎么设计?从鲲泊联项目拆解业务模型、角色体系与系统架构

二手设备信息平台怎么设计?从鲲泊联项目拆解业务模型、角色体系与系统架构

CSDN的写法要和知乎、百家号再换一个角度。CSDN的人更关心“这个平台到底怎么设计、角色怎么拆、系统怎么实现”,所以不要把重点放在故事和商业宣传上,而要写成一篇“二手设备平台产品架构与系统设计复盘”。我最推荐的标题是:二手设备信息平…

2026/10/4 20:24:51 阅读更多 →
OpenAI Embeddings接入实战:用Ace Data Cloud搭建RAG管线

OpenAI Embeddings接入实战:用Ace Data Cloud搭建RAG管线

今年做AI应用,绕不开的一件事就是把文本变成向量。无论是给知识库做语义检索,让聊天机器人带上自己的业务资料,还是给推荐系统算相似内容,底层几乎都要调用 Embeddings API。我最近在一个项目里正好用 Ace Data Cloud 快速接入了 …

2026/10/4 20:23:50 阅读更多 →

日新闻

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/4 11:40:45 阅读更多 →
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/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练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/4 20:14:29 阅读更多 →