DE1-SoC双芯架构:FPGA配置启动与HPS-FPGA桥接实践

发布时间:2026/11/3 22:58:12

DE1-SoC双芯架构:FPGA配置启动与HPS-FPGA桥接实践 简介面向使用 DE1-SoC 开发板的嵌入式工程师、FPGA/ARM 学习者及高校实验教学人员这份硬件原理图与开发手册用于解决开发板接口定位、系统配置和板载外设调试缺少权威依据的问题适合课程实验、项目开发与硬件排错场景。压缩包仅含 1 个 PDF 文件大小约 7.1MB内容以英文用户手册为主体便于在电脑或平板上随查随用。已有 1323 人学习下载说明其对入门与工程实践均有参考价值。手册从开发套件包装清单、系统光盘和获取帮助讲起继而解析板卡布局、组件与块图重点覆盖 FPGA 配置模式、Cyclone V SoC FPGA 配置、LED/按键/开关等状态与复位元素、时钟电路以及与 FPGA 相连的 7 段数码管、2×20 GPIO、24 位音频 CODEC、I2C 多路复用器、VGA、TV 解码和红外收发等外设。读者可据此快速熟悉硬件结构、核对原理图信号并为嵌入式与 FPGA 项目设计打下基础尤其适合需要按图核对接口与配置流程的读者。1. 双芯同板为什么手册的第一课是“配置模式”做过 STM32 或者普通单片机的人第一次翻开这份手册大概会愣一下第三章第一节不是点灯而是 FPGA 配置模式设置第 8 章整章在讲怎么把 .SOF 转成 .JIC 再烧进 EPCS。一块开发板上电之后连“程序在哪”都要先讲一章这在单片机世界里不可想象——上电从固定地址取第一条指令规则谁也改不了。DE1-SoC 不一样。板上坐着两套系统Cyclone V SoC 里的硬核双核 ARM Cortex-A9HPS和 85K 逻辑单元的 FPGA 阵列。FPGA 掉电即失忆上电时是一片空白 SRAM必须先由外部把配置数据喂进去它才知道自己该变成什么电路。这条配置链路是整份手册真正的起点搞不清它后面所有外设、桥接、中断都是空中楼阁。2. 上电失忆FPGA 配置链路与 EPCS 的持久化逻辑2.1 MSEL 与配置模式上电那一刻板子听谁的Cyclone V 的配置流程由几根专用引脚控制nCONFIG 拉低让芯片进入复位释放后芯片拉低 nSTATUS 表示忙紧接着采样 MSEL[4:0] 这组模式引脚。采样结果决定它去哪里找配置数据——主动串行AS、被动串行PS、快速被动并行FPP还是干脆停在 JTAG 等着外部灌数据。DE1-SoC 走的常规路径是 AS板载一颗 EPCS128 串行配置器件FPGA 自己当 SPI 主机用 DCLK、ASDI、nCSO 几根专用脚去读它。整个过程中不需要任何主机参与上电即自举。这条路径的价值在于“固化”——设备交付时不用带电脑插电就能变成设计好的那套电路。需要留意的是 MSEL 的采样时机。这 5 根脚只在复位释放后的很短一个窗口内被读取之后随便怎么变都不影响本次启动。所以如果板上是用跳线帽或拨码开关设 MSEL改完必须重新上电热插拔无效。这一点我在实验室见过太多次有人改完跳线直接按复位键发现逻辑没起来以为是烧写出错其实芯片压根没重新采样。JTAG 模式则是另一回事MSEL 设成 JTAG 后FPGA 停在等待状态USB-Blaster II 通过 TCK、TMS、TDI、TDO 把比特流直接打进配置 SRAM。这种方式下载快、迭代方便但掉电全丢。DE1-SoC 板上自带 USB-Blaster II省了一根下载线代价是 Quartus 版本和驱动必须对得上否则识别出来的 Cable 名字会莫名其妙变成别的型号。2.2 从 .sof 到 .jicEPCS128 里到底存了什么Quartus 编译的产物默认是 .sofSRAM Object File本质就是一份原始比特流。它能被 JTAG 直接写进 FPGA 的配置 SRAM。但 EPCS128 挂的是 FPGA 的专用配置引脚压根没连到 USB 或者任何主机接口上PC 无法直接对它寻址。这就产生了一个绕不开的问题想让配置持久化数据怎么进 EPCS。Quartus 给的答案是 JIC——JTAG Indirect Configuration。这个格式的关键在于“间接”USB-Blaster 先把 FPGA 通过 JTAG 置于一种特殊状态让 FPGA 的配置引脚临时变成访问 EPCS 的通道然后下载算法借着这条通道把数据一位一位写进 EPCS 的存储阵列。整个过程对用户透明看起来就像“烧了个文件”。# 1) 把编译生成的比特流转成可间接烧写 EPCS 的 JIC # -c 表示执行转换-d 指定目标配置器件型号 quartus_cpf -c -d EPCS128 de1_soc_top.sof de1_soc_top.jic # 2) 通过 JTAG 把 JIC 写进 EPCS掉电后仍可自举 quartus_pgm -c USB-Blaster II -m jtag -o p;de1_soc_top.jic # 3) 开发阶段想快速验证逻辑直接把 .sof 打进 SRAM 就够了 quartus_pgm -c USB-Blaster II -m jtag -o p;de1_soc_top.sofquartus_cpf的-d参数必须和板上实际器件一致写成 EPCS64 会直接报容量不匹配。quartus_pgm里-c指定下载器-m指定链路类型-o后面的p;表示 program 操作分号后面跟文件路径。第三条命令是我平时用得最多的改一行 Verilog 就烧一次 SRAM几秒钟的事不用等 EPCS 擦写那一两分钟。EPCS128 的容量是 128 Mbit也就是 16 MB。Cyclone V 5CSEMA5 的比特流通常只有几 MB剩下的空间理论上有余量但别指望拿它当通用 Flash 存数据——它是配置专用器件访问时序和寿命都不适合。2.3 两条启动链FPGA 配置完了HPS 才刚开始板子上其实跑着两条互不干涉的启动链很多人第一次接触会混在一起。FPGA 这条链是上电 → MSEL 采样 → 从 EPCS 读比特流 → 配置 SRAM → 用户逻辑开始运行。整条链在毫秒级完成全程不需要软件介入。HPS 那条链是上电 → 片内 Boot ROM 执行 → 从 SD 卡或其它介质读 Preloader → Preloader 初始化 DDR3 和时钟 → 加载 U-Boot → 加载 Linux 内核。这条链要几百毫秒到几秒取决于镜像大小和 DDR 训练时间。两条链的交汇点在“桥”上。HPS 想访问 FPGA 侧的任何东西前提是 FPGA 里已经加载了包含桥和 PIO 的比特流。如果只烧了 SD 卡镜像而 FPGA 侧是空的HPS 里去 mmap 那段地址就会直接触发总线异常。反过来只烧 JIC 不准备 SD 卡串口上什么都不会打印。这两件事必须都做对系统才算真正起来。3. 打拍子与归零四路时钟、两种复位和外设归属3.1 四路 50MHz 同源时钟与 PLL 的取舍手册 3.5 节写明板载时钟发生器提供四路 50MHz 时钟源。为什么不干脆一路扇出原因有几层。FPGA 的全局时钟网络资源有限一路时钟要驱动整片逻辑扇出和偏斜都会变差不同 IO bank 到时钟源的走线长度不同分开布能把偏斜控制在可控范围内板上还有音频 CODEC 这类对时钟抖动敏感的器件独立一路能少受数字逻辑开关噪声的干扰。50MHz 对 Cyclone V 来说只是个起点。芯片里有 6 个 fractional PLL可以把 50MHz 倍频到几百 MHz也可以做非整数分频。SDRAM 控制器就靠这个64MB SDRAM 挂在 FPGA 侧16 位数据总线控制器时钟通常跑到 100MHz 以上靠 PLL 从 50MHz 倍频得到。真正麻烦的是相位。SDRAM 的数据和 DQS 之间有一个建立保持窗口控制器输出的时钟和送到 SDRAM 芯片的时钟如果完全同相采样点很容易落在跳变沿上。常见的做法是让 PLL 输出两路一路 0° 给控制器内部逻辑另一路偏移 -75° 或 -90° 送给 SDRAM 芯片人为把采样点推进数据有效窗口的中央。这个偏移值不是拍脑袋定的得看板级走线延迟和器件手册的时序参数不同批次的板子可能要微调。3.2 冷复位与热复位HPS_RESET_n 和 HPS_WARM_RST_n 的差别DE1-SoC 的 HPS 侧有两个复位按钮对应两根信号HPS_RESET_n 和 HPS_WARM_RST_n。名字只差一个词行为差得很远。HPS_RESET_n 是冷复位。它把整个 HPS 复位域拉低包括 DDR3 控制器。释放后芯片重新走一遍 Boot ROMDDR3 要重新做初始化训练整个过程几百毫秒起步。效果等同于断电重启只是不用拔电源。HPS_WARM_RST_n 是热复位。它只复位 Cortex-A9 核和一部分外设DDR3 控制器和内存里的内容都保留。这意味着启动时跳过了 DDR 训练速度快得多而且内存里的现场还在——调试内核崩溃时这一点特别有用热复位之后还能从保留的内存区域里捞日志。提示热复位保留 DDR 内容这一点在排查“内核 panic 后想看看崩溃瞬间的内存”时非常关键。但别指望它保留所有外设状态UART、USB 这些通常也会被重置。FPGA 侧没有这种区分用户按键KEY0~KEY3就是普通 IO接不接进复位逻辑完全由设计者决定。我一般会在顶层给按键加个简单的同步器和消抖直接当异步复位用经常会在释放沿上出 metastability。3.3 外设归属地址空间决定一切板子上的外设不是随便挂的FPGA 侧和 HPS 侧的划分背后是总线结构和引脚复用的硬约束。外设挂载侧接口与总线由谁驱动64MB SDRAMFPGA16 位数据总线Avalon-MM用户逻辑或 Nios II1GB DDR3HPS32 位数据总线硬核内存控制器LinuxVGA DAC8 位三路FPGA并行像素数据线用户逻辑24-bit 音频 CODECFPGA串行音频接口用户逻辑TV 解码器FPGA视频输入总线用户逻辑PS/2、IR 收发FPGA自定义 IO用户逻辑ADC8 通道、12 位、500KSPSFPGASPI用户逻辑千兆以太网HPS硬核 MAC 外部 PHYLinuxUSB 2.0 Host ×2HPSULPILinuxMicro SDHPSSDMMCLinuxG-sensorHPSI2C 中断Linux两个 40pin 扩展口FPGA直连 IO bank用户自定义划分逻辑很清楚高速、协议复杂、需要成熟驱动的接口全部交给 HPS 的硬核控制器DDR3、千兆以太网、USB、SD 卡这些在 Linux 下有现成驱动开箱能用。需要灵活重定义、或者对时序有特殊要求的接口留给 FPGAVGA、音频、ADC、扩展口都属于这一类代价是每次改逻辑都得重新烧配置。从嵌入式硬件的角度看这个划分还照顾了信号完整性。DDR3 的走线要等长、阻抗匹配必须尽量贴近 HPS 的专用 IO bank走线越短越好。而 VGA 和音频这类低速接口走线容差大得多放到 FPGA 侧随便布。4. HPS 看见 FPGA轻量级桥、System Builder 与一次 mmap 的完整路径4.1 三条桥HPS 和 FPGA 之间的通道Cyclone V 把两个世界的连接做成了三条独立的桥。HPS-to-FPGA 桥是 AXI 主接口转 Avalon-MM方向是 HPS 访问 FPGA 侧外设。它的带宽高适合大数据量传输比如 HPS 往 FPGA 侧的 FIFO 里灌视频数据。FPGA-to-HPS 桥方向反过来FPGA 逻辑可以主动读写 HPS 的 DDR 或者外设。做硬件加速时这条桥很关键FPGA 算完的结果直接写进 Linux 能看到的内存省一次拷贝。FPGA-to-SDRAM 桥专门给 FPGA 侧那 64MB SDRAM 用绕过 HPS 直接访问。还有一条轻量级桥Lightweight HPS-to-FPGA32 位宽带宽不高专门给 PIO 和状态寄存器这类小数据量访问用。它的存在是为了不占主桥的带宽——HPS 每隔几毫秒读一次 LED 状态走主桥纯属浪费。地址上HPS 的内存映射里有一段固定窗口留给 FPGA 侧外设轻量级桥的基址在 Cyclone V 上是固定的后面各个 IP 的偏移由 Platform Designer 在系统生成时分配。4.2 System Builder 到底生成了什么手册第 4 章介绍的 DE1-SoC System Builder 是个配置生成工具。输入是板级选项——DDR3 的时序参数、引脚复用选择、外设使能输出是一整套东西Platform Designer 系统文件、顶层 HDL、Preloader 源码模板、设备树源码。为什么必须用它因为 Cyclone V HPS 的配置项多到离谱。DDR3 控制器光时序参数就有几十个tRCD、tRP、tWR、刷新周期、ODT 设置……引脚复用有上百个可选功能。手写这些配置不现实而且错一个参数就是启动不了还看不出错在哪。System Builder 生成的东西里最容易被忽略的是设备树。Linux 内核靠设备树知道“哪个地址上有哪个外设”如果设备树和实际比特流对不上驱动加载了也访问不到正确的寄存器。改完 FPGA 侧逻辑重新生成系统之后设备树必须跟着更新dtb 也要重新编译。4.3 一次完整的 HPS 写 LED 链路手册 7.1 节的示例叫 HPS Control LED and HEX看起来简单实际把整条链路都串起来了。从用户态一行代码到引脚电平中间要穿过六层。/* Linux 用户态直接访问 FPGA 侧 PIOmmap 物理地址后按 32 位读写 */ #include stdio.h #include fcntl.h #include sys/mman.h #include unistd.h /* 轻量级 HPS-to-FPGA 桥的基址在 Cyclone V 上是固定的 */ #define LW_BRIDGE_BASE 0xFF200000UL /* 具体偏移由 System Builder 在 Platform Designer 里分配 */ #define LED_PIO_OFFSET 0x00000010UL int main(void) { int fd open(/dev/mem, O_RDWR | O_SYNC); if (fd 0) { perror(open /dev/mem); return 1; } volatile unsigned int *led_pio (unsigned int *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, LW_BRIDGE_BASE LED_PIO_OFFSET); if (led_pio MAP_FAILED) { perror(mmap); return 1; } for (int i 0; i 10; i) { *led_pio 1u i; /* 逐位点亮 10 个用户 LED */ usleep(200000); } munmap((void *)led_pio, 0x1000); close(fd); return 0; }O_SYNC是必须的不加的话 write 可能停在 CPU 缓存里不落到总线上读回来是旧值。volatile告诉编译器别优化掉这次访问——这个地址背后是硬件不是普通内存。mmap的长度参数必须是页大小的整数倍0x1000 是 4KB够覆盖一个 PIO 的寄存器空间。整条链路的顺序是用户态写指针 → CPU 发出对虚拟地址的写 → MMU 翻译成物理地址 0xFF200000 偏移 → 该地址落在轻量级桥窗口内 → AXI 事务被路由到 FPGA 侧 → FPGA 里的 PIO IP 的 Avalon-MM 从接口接住 → PIO 输出寄存器更新 → 引脚电平变化 → LED 亮。任何一个环节断掉现象都是“LED 不亮”但原因可能完全不同。所以排查时要从后往前先在 Platform Designer 里确认 PIO 的偏移再看设备树里的地址最后才怀疑代码。5. 避坑与排查手册不会写在你面前的那些翻车点5.1 配置与启动相关的坑现象Programmer 显示烧写成功进度条走完提示 100%。断电重启之后FPGA 逻辑完全没反应LED 不闪逻辑分析仪上也没波形。原因MSEL 还停在 JTAG 模式。烧写成功只能说明数据进了 EPCS但 FPGA 上电后如果采样到 JTAG 模式它根本不会去读 EPCS而是乖乖等着 JTAG 灌数据。等不到就一直是空白。解决把 MSEL 调到 AS 模式重新上电。这一步做完之后建议先别急着改逻辑烧一次 JIC、断一次电、看一次现象确认固化路径真的通了再往下做。现象串口终端一片空白或者内核打印停在 “Waiting for root device”。原因Preloader 里的 UART 引脚复用和板子实际接线对不上或者 SD 卡分区偏移和 Preloader 里写死的不一致。DE1-SoC 的 HPS 启动链是 Boot ROM → Preloader → U-Boot → Linux前一级找不到下一级就停在那里串口上什么都不出。解决用 System Builder 重新生成 Preloader核对串口波特率和引脚复用用分区工具确认 SPL 存放的偏移和镜像里的一致。血泪经验是改完任何和启动相关的配置先烧最低限度能打印一行字的镜像验证通路别一上来就烧完整系统。5.2 总线与地址映射相关的坑现象C 程序第一次往指针写数据就收到 SIGBUSdmesg 里有 unhandled page fault。原因访问的物理地址不在轻量级桥窗口内或者比特流里压根没加桥和 PIO。MMU 翻译成功不代表总线上有设备响应没有从设备应答的访问会变成总线错误。解决从 System Builder 生成的 .sopcinfo 或者设备树里读出实际分配的偏移改代码里的LED_PIO_OFFSET。别抄别人的偏移值每个工程的分配都可能不同。现象网口有链路灯但ifconfig看不到 eth0或者能起来但收不到包。原因System Builder 里 PHY 的 MDIO 地址或者引脚复用选错生成的设备树和实际硬件对不上。这种错很难从现象上判断因为 PHY 自己上电后会亮灯看起来一切正常。解决对比设备树里 ethernet 节点的 phy-handle 和手册 3.7.2 节的引脚定义重新生成 dtb。有条件的话用示波器看一眼 MDC/MDIO 上有没有波形没波形就是控制器根本没使能。5.3 时序与存储相关的坑现象跑 SDRAM Test in Verilog 时大部分地址读写正确个别单元读回来全是 0 或者全是 1。原因PLL 的相位偏移没覆盖住 dq 的建立保持窗口或者刷新周期配置偏大导致个别行漏刷新。这种错是概率性的跑一遍可能过跑十遍错一次。解决调 PLL 相位从 -75° 往 -60° 和 -90° 两个方向试同时确认 SDRAM 的时序参数和器件手册一致。测试程序要跑随机地址、连续地址、跨行地址三种模式只跑顺序读写会漏掉很多问题。6. 设计取舍这块板子为什么宁可难用一点也不肯牺牲灵活如果让我评价 DE1-SoC 的设计取向一句话它把“可重配置”看得比“开箱即用”重得多。最明显的是内存的不对称分配。FPGA 侧只有 64MB SDRAM、16 位总线HPS 侧却是 1GB DDR3、32 位。这个组合乍看很奇怪为什么不让两边共享大内存因为 FPGA 侧的逻辑通常不需要大容量它要的是确定性和低延迟——每拍都能预测的访问周期比容量重要得多。而 HPS本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/11/3 22:58:12

Univer深度解析:开源在线表格的架构与集成实战

最近追踪开源办公套件的动向时,发现“univer”这个搜索词的热度涨得很快,不少人都在问Univer在线到底能不能替代Excel、集成到自己产品里要花多少功夫。这个项目我从早期版本一路玩到现在,可以负责任地说,它不是一个“又一款电子表…

2026/11/3 22:58:12

小型固定翼无人机自主飞行:飞控架构、坐标系与控制闭环

简介:这份PDF是Randal W. Beard与Timothy W. McLain合著的英文教材,面向无人机飞控、导航制导与状态估计方向的高年级本科生、研究生及MAV开发工程师,帮助读者把小型无人机的理论推导与工程实践联系起来。包内仅1个PDF文件,约4.89…

2026/11/3 22:58:12

龟兔赛跑算法解析与C语言实现

1. 龟兔赛跑算法解析 龟兔赛跑这个经典寓言在编程领域被赋予了新的生命。这道PTA题目要求我们模拟龟兔赛跑的过程,通过算法计算给定时间内两者的跑步距离。让我们从底层逻辑开始拆解这个有趣的编程问题。 1.1 题目核心需求 题目给出比赛总时间n(分钟&a…

2026/11/3 23:48:17

HarmonyOS小数除法教学工具:动态分物模型解析

1. 项目概述这个基于HarmonyOS开发的小数除法动态分物模型,是一个专为小学数学教学设计的交互式可视化工具。作为一名长期从事教育科技开发的工程师,我发现很多小学生在学习小数除法时都存在理解障碍——他们能机械地完成竖式计算,却无法真正…

2026/11/3 23:48:17

CEI-05.2抖动预算机制解析:从玄学调试到可验证高速互连工程

简介:本资源为光学互联论坛(OIF)于2024年1月正式发布的最新版CEI高速电气接口标准——OIF-CEI-05.2实施协议官方PDF文档,面向芯片设计、高速互连系统开发、光模块与交换机硬件工程师及通信标准研究人员。该标准定义了6Gbps至112Gb…

2026/11/3 23:48:17

Obsidian与GitHub结合的项目文档管理实践

1. 为什么选择 Obsidian GitHub 管理项目文档在软件开发和技术写作领域,文档管理一直是个令人头疼的问题。我经历过太多因为文档混乱导致的团队协作灾难:找不到最新版本、误删重要内容、多人编辑冲突等等。经过多年实践,我发现 Obsidian 和 …

2026/11/3 23:48:17

PostgreSQL服务就绪检测:容器化部署的可靠解决方案

1. 项目背景与核心需求在容器化部署和自动化运维场景中,服务启动顺序依赖是个经典难题。PostgreSQL作为最受欢迎的开源关系型数据库,常被用作微服务架构的后端存储。当你的应用容器启动时,如果PostgreSQL服务还未完成初始化,就会导…

2026/11/3 23:48:17

ClawHub CLI:AI技能管理的npm式解决方案

1. 项目概述:ClawHub CLI技能管理工具作为一名长期从事AI工具开发的工程师,我一直在寻找能够高效管理AI技能的工具链。ClawHub CLI的出现完美解决了OpenClaw生态中的技能管理痛点。这个命令行工具就像AI领域的npm,让我们能够像管理Node.js包一…

2026/11/3 23:43:17

Java+Vue+SpringBoot构建高校成绩管理系统实践

1. 项目概述 这个毕业设计成绩管理系统采用JavaVueSpringBoot技术栈开发,是一个面向高校教务管理的全栈Web应用。我在实际开发过程中发现,这类系统需要同时满足教师评分、学生查询、管理员统计三大核心需求,而市面上很多开源方案要么功能单一…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

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

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

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

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

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

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑