新闻详情

新闻详情

首页 / 资讯中心 / 详情

GPIO模拟MDC/MDIO驱动RTL8306MB交换机芯片移植实战

发布时间:2026/9/27 1:09:50来源:尧图网络
GPIO模拟MDC/MDIO驱动RTL8306MB交换机芯片移植实战
1. 项目缘起与整体设计思路RTL8306MB 这颗芯片在嵌入式网络设备里算是老面孔了6 口 10/100M 交换支持 VLAN、QoS、端口镜像性价比很高很多工业网关、IP 摄像头、智能路由器方案里都能见到它。但真正上手过的人都知道这颗芯片的官方 SDK 移植起来并不算省心——尤其是当你用的主控没有原生 MDC/MDIO 控制器或者 MDC/MDIO 引脚被其他外设占用的时候怎么用普通 GPIO 去模拟这套管理接口就成了必须啃下来的硬骨头。我这次接到的需求很典型主控是一颗国产 Cortex-M4片上没有专用 MDIO 控制器硬件工程师把 RTL8306MB 的 MDC 和 MDIO 分别接到了 PA6 和 PA7 两个普通 GPIO 上。这意味着整个 SDK 的底层读写驱动都得自己用 GPIO 翻转来实现。听起来简单但实际做下来时序、方向切换、寄存器地址映射、SDK 适配层改造每一步都有坑。这篇文章就把我完整的移植过程拆开讲清楚从协议原理到代码落地从时序计算到问题排查尽量让拿到类似板子的朋友能直接抄作业。先明确一下这套方案适合谁如果你手上有 RTL8306MB 或同系列交换芯片主控没有硬件 MDIO或者你想把交换芯片的管理口挂到任意 GPIO 上做灵活布局那这篇内容就是为你准备的。需要的基础是能看懂 C 语言、会用示波器或逻辑分析仪、对寄存器读写有基本概念。不需要你精通以太网协议栈因为 MDIO 本身协议很简单我会把关键点都拆开讲。整体设计思路其实就三层最底层是 GPIO 模拟 MDC/MDIO 的位操作层负责产生时钟和串行数据中间层是 RTL8306MB 的寄存器读写封装把 SDK 里的 MDIO 读写函数替换成我们的 GPIO 版本最上层是 SDK 原有的初始化、VLAN 配置、端口管理逻辑这部分基本不用动。这样分层的好处是改动面小SDK 升级时只需要重新适配中间层底层时序逻辑可以复用。为什么选择 GPIO 模拟而不是找别的方案我评估过三种路子一是换主控成本太高不现实二是用 I2C 转 MDIO 的桥接芯片增加 BOM 成本和布线复杂度三是 GPIO 模拟零额外成本只要时序做稳就行。实测下来 GPIO 模拟在 10MHz 以下的 MDC 频率完全够用而 RTL8306MB 的 MDC 最高支持 12.5MHz我们跑 5MHz 左右非常稳。所以最终定了 GPIO 模拟方案。2. MDC/MDIO 协议核心细节与 GPIO 模拟要点2.1 先搞懂 MDC/MDIO 到底怎么通信MDC/MDIO 是 IEEE 802.3 定义的管理接口本质上就是一个同步串行总线。MDC 是时钟由主控产生MDIO 是双向数据线用来读写交换芯片内部寄存器。一次完整的读写操作是 64 个 MDC 时钟周期分成几个阶段前导码、起始码、操作码、PHY 地址、寄存器地址、 turnaround、数据。前导码是 32 个连续的 1作用是让从设备同步时钟。起始码固定是 01操作码 10 表示读、01 表示写。PHY 地址 5 位RTL8306MB 的 PHY 地址通常是 0 到 5 对应 6 个端口但寄存器访问时用的是芯片内部 SMI 地址这个后面细说。寄存器地址 5 位数据 16 位。读操作在数据阶段前有一个 turnaround 周期MDIO 从输出切换到输入由从设备驱动数据。用生活化的类比MDC 就像你敲桌子的节奏MDIO 就像你手上举的牌子。你先举 32 次“1”告诉对方“我要开始说话了”然后举“01”表示“我要读”接着举 5 位地址告诉对方“我要读哪个房间”然后你把手放下turnaround对方把牌子举起来告诉你房间里的内容。整个过程必须严格跟着敲桌子的节奏走快一点慢一点对方都可能看错。2.2 GPIO 模拟的关键时序、方向、电平用 GPIO 模拟这套协议核心要解决三个问题。第一是时序精度MDC 的高低电平持续时间必须满足芯片手册要求。RTL8306MB 要求 MDC 高电平和低电平各至少 40ns也就是频率上限约 12.5MHz。我们跑 5MHz半周期 100ns留足了余量。第二是 MDIO 方向切换写操作时主控驱动读操作时在 turnaround 阶段必须及时把 GPIO 切成输入否则会和从设备抢总线。第三是电平匹配RTL8306MB 的 MDIO 是 3.3V 电平如果主控是 1.8V 就需要电平转换这个硬件上必须确认。时序实现上我建议用 NOP 循环或者 DWT 周期计数器来做微秒级延时不要用系统滴答定时器因为滴答精度通常只有 1ms根本不够。我实测下来用 __NOP() 循环在 168MHz 主频下每次循环约 6ns延时 100ns 大概 16 次循环。但不同编译器优化等级下这个数字会变所以更稳妥的做法是用 DWT 的 CYCCNT 寄存器做精确延时下面代码里我会给出具体实现。方向切换是新手最容易翻车的地方。STM32 的 GPIO 配置成开漏输出加外部上拉是最理想的因为 MDIO 总线本身就需要上拉电阻。如果配置成推挽输出读操作时主控输出高电平会和从设备的低电平打架轻则读不到数据重则烧引脚。我一开始就是推挽输出读回来的数据全是 0xFFFF换成开漏加 4.7k 上拉后立刻正常。这个坑后面还会细说。2.3 RTL8306MB 的 SMI 地址映射RTL8306MB 的寄存器访问和标准 PHY 不太一样它用的是 SMISerial Management Interface地址来区分内部寄存器组。PHY 地址字段在 RTL8306MB 里实际是 SMI 设备地址通常 0 表示全局寄存器1 到 6 表示端口 0 到 5 的寄存器。寄存器地址 5 位但 RTL8306MB 内部寄存器是 16 位地址空间所以需要先写一个地址寄存器来切换页再读写目标寄存器。这个机制在 SDK 里叫 indirect access具体流程是先往 SMI 地址 0 的寄存器 0x1F 写目标寄存器高字节再往寄存器 0x1E 写低字节然后读写寄存器 0x1C 或 0x1D 来操作数据。这个间接访问机制是移植时最容易搞混的地方。我一开始直接按标准 PHY 的 5 位寄存器地址去读结果读出来的全是 0。后来翻 SDK 源码才发现 RTL8306MB 的寄存器是 16 位地址必须走间接访问。所以中间层封装的时候我把读写函数分成两层底层是原始的 5 位地址读写上层是 16 位地址的间接访问封装。这样 SDK 里调用 16 位地址读写时自动转换成两次底层操作。3. 完整移植流程与核心代码实现3.1 硬件确认与 GPIO 初始化动手写代码之前先把硬件确认清楚。用万用表量一下 MDC 和 MDIO 分别接到哪个 GPIOMDIO 上是否有 4.7k 到 10k 的上拉电阻到 3.3V。如果没有上拉必须补上否则读操作一定失败。我这次板子上 MDIO 有 4.7k 上拉MDC 没有上拉但作为输出不需要。另外确认主控 IO 电压和 RTL8306MB 是否一致不一致要加电平转换芯片。GPIO 初始化代码如下以 STM32 HAL 库为例void mdio_gpio_init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); /* MDC 配置为推挽输出高速 */ GPIO_InitStruct.Pin GPIO_PIN_6; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); /* MDIO 配置为开漏输出外部上拉 */ GPIO_InitStruct.Pin GPIO_PIN_7; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); /* 初始状态MDC 低MDIO 释放为高 */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); }这里 MDIO 用开漏输出是关键。开漏模式下输出高电平时引脚实际是高阻态由上拉电阻拉到高电平输出低电平时引脚拉低。这样读操作时把引脚切成输入上拉电阻保证空闲为高从设备可以自由拉低。如果用推挽输出高时引脚强驱动高从设备拉低就会短路。3.2 精确延时函数的实现前面说了延时精度直接决定 MDC 频率是否稳定。我用 DWT 周期计数器实现纳秒级延时void dwt_delay_init(void) { CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk; DWT-CYCCNT 0; DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk; } static inline void delay_ns(uint32_t ns) { uint32_t start DWT-CYCCNT; uint32_t cycles (SystemCoreClock / 1000000) * ns / 1000; while ((DWT-CYCCNT - start) cycles); }SystemCoreClock 是系统主频比如 168MHz那么每纳秒约 0.168 个周期delay_ns(100) 就是约 17 个周期。实测这个延时误差在 5% 以内对 5MHz MDC 来说完全够用。注意 DWT 在有些低端 Cortex-M0 上没有那就只能用 NOP 循环但精度会差一些建议把 MDC 频率降到 1MHz 以下。MDC 时钟的产生就是拉高、延时、拉低、延时static inline void mdc_cycle(void) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); delay_ns(100); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); delay_ns(100); }这样半周期 100ns频率 5MHz。如果想更快把 100 改成 40就是 12.5MHz但建议留余量跑 5MHz 到 8MHz 最稳。3.3 MDIO 位读写与方向切换写一位数据的逻辑是先设置 MDIO 输出电平然后产生一个 MDC 周期。读一位数据的逻辑是产生 MDC 上升沿后延时一段时间再采样 MDIO 电平。注意采样点要在 MDC 高电平中间太早太晚都可能采到错误值。static inline void mdio_write_bit(uint8_t bit) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, bit ? GPIO_PIN_SET : GPIO_PIN_RESET); mdc_cycle(); } static inline uint8_t mdio_read_bit(void) { uint8_t bit; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); delay_ns(50); /* 等电平稳定 */ bit HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7); delay_ns(50); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); delay_ns(100); return bit; }方向切换在读操作的 turnaround 阶段。标准流程是主控发完寄存器地址后释放 MDIO切成输入等一个 MDC 周期然后开始读 16 位数据。代码里这样实现static void mdio_set_input(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; GPIO_InitStruct.Pin GPIO_PIN_7; GPIO_InitStruct.Mode GPIO_MODE_INPUT; GPIO_InitStruct.Pull GPIO_NOPULL; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); } static void mdio_set_output(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; GPIO_InitStruct.Pin GPIO_PIN_7; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); }每次读操作前切输入读完后切回输出。频繁切换 GPIO 模式会有一定开销实测每次约 1us对整体性能影响可以忽略。如果嫌麻烦也可以一直保持开漏输出模式读的时候直接读 IDR 寄存器因为开漏输出高时引脚是高阻外部电平可以读回来。但这样有个风险如果主控同时输出低会干扰从设备。所以稳妥起见还是切换模式。3.4 完整的 MDIO 读写帧实现标准 MDIO 帧是 64 位32 位前导码 2 位起始码 2 位操作码 5 位 PHY 地址 5 位寄存器地址 2 位 turnaround 16 位数据。写操作没有 turnaround 的第二个周期读操作有。static void mdio_write_frame(uint8_t phy, uint8_t reg, uint16_t data) { int i; mdio_set_output(); /* 前导码 32 个 1 */ for (i 0; i 32; i) mdio_write_bit(1); /* 起始码 01 */ mdio_write_bit(0); mdio_write_bit(1); /* 操作码 01 写 */ mdio_write_bit(0); mdio_write_bit(1); /* PHY 地址 5 位MSB first */ for (i 4; i 0; i--) mdio_write_bit((phy i) 1); /* 寄存器地址 5 位 */ for (i 4; i 0; i--) mdio_write_bit((reg i) 1); /* turnaround 10 */ mdio_write_bit(1); mdio_write_bit(0); /* 数据 16 位 */ for (i 15; i 0; i--) mdio_write_bit((data i) 1); } static uint16_t mdio_read_frame(uint8_t phy, uint8_t reg) { int i; uint16_t data 0; mdio_set_output(); for (i 0; i 32; i) mdio_write_bit(1); mdio_write_bit(0); mdio_write_bit(1); /* 操作码 10 读 */ mdio_write_bit(1); mdio_write_bit(0); for (i 4; i 0; i--) mdio_write_bit((phy i) 1); for (i 4; i 0; i--) mdio_write_bit((reg i) 1); /* turnaround主控释放从设备驱动 */ mdio_set_input(); mdio_read_bit(); /* 第一个 turnaround 周期忽略 */ for (i 15; i 0; i--) { data (data 1) | mdio_read_bit(); } mdio_set_output(); return data; }注意读操作里第一个 turnaround 周期读到的值要忽略因为那是总线切换的过渡期从设备还没开始驱动。第二个周期开始才是真正的数据。这个细节很多网上代码都写错了导致读回来的数据整体偏移一位。3.5 RTL8306MB 间接寄存器访问封装前面说了 RTL8306MB 的寄存器是 16 位地址需要间接访问。SDK 里通常有 smi_read 和 smi_write 两个函数我们只需要把这两个函数替换成基于 mdio_read_frame 和 mdio_write_frame 的实现。/* 底层 5 位地址读写 */ static uint16_t smi_read_raw(uint8_t phy, uint8_t reg) { return mdio_read_frame(phy, reg); } static void smi_write_raw(uint8_t phy, uint8_t reg, uint16_t data) { mdio_write_frame(phy, reg, data); } /* 上层 16 位地址间接访问 */ uint16_t rtl8306_read(uint16_t addr) { uint8_t phy (addr 8) 0x1F; /* 高 5 位作为 SMI 地址 */ uint8_t reg addr 0xFF; /* 低 8 位作为寄存器偏移 */ /* 先写地址寄存器 */ smi_write_raw(phy, 0x1F, (addr 8) 0xFF); smi_write_raw(phy, 0x1E, addr 0xFF); /* 再读数据 */ return smi_read_raw(phy, 0x1C); } void rtl8306_write(uint16_t addr, uint16_t data) { uint8_t phy (addr 8) 0x1F; smi_write_raw(phy, 0x1F, (addr 8) 0xFF); smi_write_raw(phy, 0x1E, addr 0xFF); smi_write_raw(phy, 0x1D, data); }这里的地址映射规则是根据 RTL8306MB 手册来的不同批次芯片可能略有差异移植时一定要对照手册确认。我这次用的芯片SMI 地址 0 是全局寄存器1 到 6 是端口寄存器写 0x1F 和 0x1E 设置间接地址读 0x1C 写 0x1D 操作数据。实测读写 VLAN 寄存器、端口状态寄存器都正常。4. SDK 适配与常见问题排查实录4.1 SDK 适配层的改造要点RTL8306MB 的 SDK 通常是一个独立的 C 文件包里面包含 rtl8306_drv.c、rtl8306_reg.h 等。移植时不需要改 SDK 的业务逻辑只需要找到它调用 MDIO 读写的地方替换成我们的实现。一般 SDK 会提供一个函数指针或者宏定义来抽象底层读写比如/* SDK 原始定义 */ extern uint16_t (*smi_read)(uint8_t phy, uint8_t reg); extern void (*smi_write)(uint8_t phy, uint8_t reg, uint16_t data);我们只需要在初始化时把这两个函数指针指向自己的实现void rtl8306_sdk_init(void) { mdio_gpio_init(); dwt_delay_init(); smi_read smi_read_raw; smi_write smi_write_raw; /* 调用 SDK 初始化 */ rtl8306_init(); }如果 SDK 没有提供函数指针而是直接调用某个函数名那就用宏定义替换或者直接改 SDK 源码里的函数实现。我这次用的 SDK 是直接调用 smi_read 和 smi_write 两个函数所以我把这两个函数的实现改成了 GPIO 版本其他代码一行没动。适配完成后先做一个简单的测试读芯片 ID 寄存器。RTL8306MB 的芯片 ID 通常在地址 0x0000 或 0x0001读出来应该是 0x8306 或类似值。如果读出来是 0x0000 或 0xFFFF说明时序或方向切换有问题。我第一次读出来是 0xFFFF排查后发现是 MDIO 推挽输出导致总线冲突改成开漏后立刻读到 0x8306。4.2 常见问题速查表现象可能原因排查方法解决方法读回全 0xFFFFMDIO 推挽输出冲突量 MDIO 空闲电平改开漏输出加上拉读回全 0x0000MDC 无输出或频率过高示波器量 MDC降低频率到 1MHz 测试数据整体偏移一位turnaround 采样错误检查读帧代码忽略第一个 turnaround 周期写寄存器无效间接地址未设置读回地址寄存器先写 0x1F/0x1E 再操作部分寄存器读写正常部分异常SMI 地址映射错误对照手册确认修正 phy 地址计算长时间运行后通信失败GPIO 模式切换未恢复加日志监控读操作后强制切回输出不同板子表现不一致上拉电阻阻值差异量上拉电阻统一用 4.7k这个表里的问题我基本都踩过一遍。最坑的是“数据整体偏移一位”当时读 VLAN 寄存器读出来的值总是实际值的两倍或一半查了两天才发现是 turnaround 周期多读了一位。后来在逻辑分析仪上抓波形对比标准 MDIO 时序才定位到问题。4.3 实操心得与避坑技巧第一个心得一定要用逻辑分析仪抓一次完整波形。MDIO 协议虽然简单但时序问题肉眼看不出来。我用的是 24MHz 采样率的逻辑分析仪抓 64 个 MDC 周期解码后和标准帧对比一眼就能看出哪一位错了。没有逻辑分析仪的话至少用示波器看 MDC 频率和 MDIO 电平是否正常。第二个心得MDC 频率不要一上来就跑最高。RTL8306MB 手册标称最高 12.5MHz但实际跑 12.5MHz 时如果主控 GPIO 翻转速度不够或者延时不准很容易出错。我建议先用 1MHz 调通再逐步提高到 5MHz最后稳定在 5MHz 到 8MHz 之间。实测 5MHz 时读写 1000 次寄存器无一次失败12.5MHz 时偶发失败。第三个心得GPIO 模式切换要加保护。读操作切输入读完后必须切回输出否则下一次写操作时 MDIO 还是输入模式写不出去。我一开始在错误处理分支里忘了切回导致一次读失败后整个通信都挂了。后来在 mdio_read_frame 函数末尾强制调用 mdio_set_output不管中间是否出错都恢复输出模式。第四个心得上拉电阻不能省。有些板子为了省成本MDIO 上不加上拉靠主控内部上拉。但内部上拉通常几十 k 欧上升沿太慢5MHz 时根本来不及拉高。必须用外部 4.7k 上拉这是实测最稳的阻值。10k 也能用但边沿稍慢2.2k 功耗偏大4.7k 是平衡点。第五个心得SDK 初始化顺序要注意。RTL8306MB 上电后需要一定时间稳定建议在 mdio_gpio_init 之后延时 100ms 再开始读写。我一开始上电立刻读芯片 ID读出来全是 0延时 100ms 后就正常了。这个延时在手册里叫 power-on reset time不同芯片不一样RTL8306MB 大概是 50ms 到 100ms。4.4 性能优化与扩展思路GPIO 模拟 MDIO 的性能瓶颈主要在延时函数和 GPIO 操作。如果觉得 5MHz 还不够快可以优化延时函数用汇编 NOP 精确控制或者直接用寄存器操作替代 HAL 库函数。HAL_GPIO_WritePin 内部有参数检查开销约 100ns直接写 BSRR 寄存器可以降到 10ns 以内。我实测用 BSRR 后 MDC 可以稳定跑到 10MHz。扩展方面这套 GPIO 模拟方案可以轻松扩展到多个交换芯片。比如板子上有两颗 RTL8306MB只需要再定义一组 MDC/MDIO 引脚把底层读写函数参数化传入不同的 GPIO 端口和引脚即可。SDK 层完全不用改因为 SDK 只关心 PHY 地址和寄存器地址不关心底层是哪个 GPIO。另外如果主控有多个空闲 GPIO还可以用这套方案做 MDIO 总线的多路复用。比如用两个 GPIO 分别控制两颗芯片的 MDC共用一根 MDIO通过分时复用实现。不过要注意总线冲突同一时刻只能有一颗芯片的 MDC 在活动。最后再分享一个小技巧调试阶段可以在 mdio_read_frame 和 mdio_write_frame 里加打印把每次读写的 PHY 地址、寄存器地址、数据都输出到串口。这样一旦出错对照 SDK 的调用日志就能快速定位是哪个寄存器读写异常。正式发布时用宏定义关掉打印即可不影响性能。我在调试 VLAN 配置时就是靠这个日志发现 SDK 写寄存器顺序和手册不一致调整后才正常。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

opencodex Providers 工作区账户与导航 Rail 集成审计:从 A-gate 合成到 GO-WITH-FIXES 的修复闭环 2026/9/27 2:06:48

opencodex Providers 工作区账户与导航 Rail 集成审计:从 A-gate 合成到 GO-WITH-FIXES 的修复闭环

【免费下载链接】opencodex Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code 项目地址: https://gitcode.com/gh_mirrors/ope/opencodex 点击…

阅读更多 →
嵌入式灰区故障三重排查法:串口假故障、蓝牙断连、烧录异常 2026/9/27 2:06:48

嵌入式灰区故障三重排查法:串口假故障、蓝牙断连、烧录异常

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

阅读更多 →
51单片机温控系统实战:Proteus+Keil+嘉立创PCB全流程开发 2026/9/27 2:06:41

51单片机温控系统实战:Proteus+Keil+嘉立创PCB全流程开发

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

阅读更多 →
做网站要求什么软件?新手入门避坑指南 2026/9/27 2:06:22

做网站要求什么软件?新手入门避坑指南

做网站要求什么软件?新手入门避坑指南 上周半夜三点,手机疯狂震动。客户在微信里发语音,声音都变了:“网站打不开,浏览器显示‘不安全’,后台还能下载个 .exe 文件!你们怎么搞的?”…

阅读更多 →
STM32H743移植SOEM实现EtherCAT主站全流程详解 2026/9/27 2:06:15

STM32H743移植SOEM实现EtherCAT主站全流程详解

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

阅读更多 →
知漫剧入门科普:一句话生成漫剧功能拆解 2026/9/27 2:06:15

知漫剧入门科普:一句话生成漫剧功能拆解

新手第一次听到“一句话生成漫剧”,很容易把它理解成一个全自动按钮:输入一句话,等几分钟,一集漫剧就出来了。实际上它更像一条被压缩过的流水线,把剧本、角色、分镜、配音、成片五个环节收进同一个系统里,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉