简介面向学习EDA与FPGA数字系统设计的高校学生及电子工程师这份文档围绕多功能数字闹钟的完整实现展开涵盖EDA基础、VHDL语法与开发流程、需求分析、模块划分、Quartus仿真综合以及GW48开发板下载测试。内容以时间存储、计时、闹钟设置、比较器、显示和用户交互等模块为主线给出源代码开发与验证思路可用于课程设计、实验报告和小型数字系统入门参考。压缩包共1个doc文件约2.71MB便于集中阅读和打印目录按前言、EDA技术、系统设计与实现流程组织。已有832人学习适合希望从VHDL建模走到FPGA原型验证的读者查漏补缺。1. 答辩演示只给三分钟按下校时键分钟跟着走设到 23:59 等一分钟必须回到 00:00闹钟时间一到扬声器立刻响。这就是基于 FPGA 的闹钟系统设计最扎实的需求起点——不是在板上挂一颗时钟芯片而是用 EDA 工具链把计时、校准、闹铃三件事拆成可单独仿真、可单独测量、再拼回整体的模块用 VHDL 描述成可综合的逻辑。它适合正在做数字电路、EDA 方向课程设计的人需要在 Quartus 里跑通综合与时序仿真再把配置文件下载到实验开发箱上做实物演示也适合需要一个模块化计数与比较设计参照的从业者。下面按交付顺序走需求怎么落成条目模块怎么切代码怎么写坑怎么避最后怎么验。2. 总体架构设计三条计数链、两条控制链、一个输出链数字闹钟看着简单真正动手写之前最容易犯的错是「上来就敲代码」。我一般会先把需求翻译成一张可测的条目表再决定模块切到哪一层。这一步做扎实后面 VHDL 写起来几乎是填空这一步糊弄过去综合能过、仿真能跑一上板就是秒针不走、按键连跳、闹铃不响。2.1 功能清单先落到可测的粒度把「做一个多功能数字闹钟」拆成五条可以单独验证的行为每条都带边界条件这是后面写测试激励的直接依据功能域行为描述边界条件验证方式计时每 1 秒计一次秒→分→时自动进位59 秒进 1 分59 分进 1 时23 时归 00 时仿真里连续跑 86400 个秒脉冲校时显示时间态下进入设置用 SET_M / SET_H 改分和时秒不参与校准分到时 59 再 1 回到 00手工按键看数码管跳变闹钟设定显示闹钟态下进入设置改闹钟的时和分与校时互斥不能同时进入两个使能信号做互锁闹铃当前时间与闹钟时间一致时扬声器发声只比对时和分秒不参与可手动关闭设到当前时间 1 分钟等 60 秒显示切换DISPLAY_EN 在时间显示与闹钟显示之间切换设置过程中不响应切换拨动开关看数码管内容整体变化对应的输入资源一共八个CLR 复位、SET_M 分调整、SET_H 时调整、SET_CLOCK 校时使能、SET_DINGS 闹钟设定使能、DISPLAY_EN 显示切换加上系统时钟和扬声器输出。这套按键定义是原方案的骨架改动它等于重做整个控制逻辑所以先在表里定死。2.2 模块划分三级级联的计数链整体结构是典型的串行进位秒模块自己数到 59产生一个进位信号给分模块当节拍分模块数到 59再产生进位给时模块时模块数到 23 归零。三条计数链并排站着各自输出自己的 BCD 个位和十位最后统一送到显示模块。1Hz 秒脉冲 ──► [秒计数 MIAO] ──进位──► [分计数 FEN] ──进位──► [时计数 HOUR] │ │ │ 秒个/十位 分个/十位 时个/十位 └──────────┬───────────┴──────────┬───────────┘ ▼ ▼ [显示切换 MUX] ◄──── DISPLAY_EN / 闹钟设定值 │ ▼ [动态扫描显示 SEG] 当前时分 ──► [比较器 CMP] ◄── 闹钟时分 / 闹钟使能 ──► [蜂鸣器驱动 BUZZ]两条控制链是并行的一条管校时SET_CLOCK 使能 SET_M/SET_H 步进一条管闹钟设定SET_DINGS 使能 同样的两个步进键。这两条链永远只有一个处于激活状态用互锁逻辑保证——这是最容易漏掉的设计约束一旦两条同时使能分模块的计数分支和写入分支会打架。我为什么坚持串行进位而不是「用一个 17 位二进制计数器数总秒数再转换成 BCD」后者代码短但拆分验证几乎不可能你没法单独证明「秒模块数到 60 归零」这一件事是对的出错时只能整段重来。串行结构每个模块只有十来个触发器波形图上一眼能看出是哪一级没进位这对要写设计文档、要在答辩时讲清原理的人是刚需。2.3 进位信号当时钟用能用但要知道代价原方案里分模块的时钟输入直接接秒模块的进位输出写法上非常自然秒数满 60 那一拍进位线拉高分模块的上升沿到了分加一。仿真跑起来完全正确。问题在后端。这种接法在综合工具眼里是一段「派生时钟」也就是由组合逻辑或普通寄存器输出驱动的时钟网络不在全局时钟树上。Quartus 综合后通常会给一条警告时序分析也会把它归到另一组约束里。开发箱上跑几十赫兹的秒脉冲时看不出毛病因为它慢到任何毛刺都被吞掉了但这个习惯一旦带到高速设计里就是灾难。我的做法是保留「进位脉冲」这个概念但在模块内部改成统一时钟加使能-- 更稳妥的写法所有模块吃同一根系统时钟进位变成使能 process(sys_clk, clr) begin if clr 1 then min_u 0000; min_t 0000; elsif rising_edge(sys_clk) then if sec_carry 1 then -- 1 个时钟周期宽的使能脉冲 if min_u 1001 then min_u min_u 1; else min_u 0000; min_t min_t 1; end if; end if; end if; end process;差别就一行把「进位当 clk」换成「进位当 if 条件」整条链就都挂在同一根全局时钟上时序报告干净跨级联也不会有建立/保持的隐忧。给定点是实验箱、节拍只有 1Hz 的场合两种写法都能演示成功但要写进文档里被人挑刺后者更站得住。2.4 引脚分配与资源估算引脚约束是把设计从仿真拽到现实的那一步也是学生最容易在实验室耗掉一晚上的地方。做法是先确认开发箱的时钟选择区哪个跳线对应 1Hz、哪些按键是带上拉的低有效、数码管是共阴还是共阳再一条条填进引脚分配表。信号名方向开发箱资源说明clk_1hz输入时钟选择区 1Hz 输出秒计数节拍接专用时钟脚clr输入按键 K1全局复位高有效set_m输入按键 K2分 / 闹钟分 步进set_h输入按键 K3时 / 闹钟时 步进set_clock输入按键 K4进入 / 退出校时set_dings输入按键 K5进入 / 退出闹钟设定display_en输入拨码开关 SW1时间显示 / 闹钟显示seg[7:0]输出数码管段选共阴则高电平点亮sel[5:0]输出数码管位选6 位时时分分秒秒buzz输出蜂鸣器闹铃输出资源量算一下秒模块 8 个触发器分模块 8 个时模块 8 个闹钟寄存 8 个扫描计数器 3 个消抖计数器每个按键 5 位共 25 个合起来不到 80 个触发器。任何一款入门级 FPGA 的查找表资源都绰绰有余所以选型的重点不在容量而在开发箱上有没有 1Hz 时钟源、有没有六位数码管、有没有蜂鸣器这三件事。提示共阴共阳搞反是新手第一晚的固定节目症状是「数码管亮但笔画全错」。动手前先用万用表二极管档量一下段选脚比事后改译码表省事得多。3. 核心模块的 VHDL 实现从秒计数到顶层例化这一部分给出可以直接照着敲的源码骨架。全部基于 IEEE 标准库综合工具用 Quartus语法层面没有依赖任何厂商私有包换到别的综合工具也能过。每个模块我都按「端口 → 架构 → 关键判断」的顺序讲方便你改参数。3.1 秒计数模块个位十位分离与 59 归零秒模块是整个系统的节拍源它只做一件事每来一个 1Hz 上升沿加一数到 59 之后回零并吐出一个进位。LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; -- 允许对 std_logic_vector 直接做 和比较 ENTITY MIAO IS PORT( CLR : IN STD_LOGIC; -- 复位高有效 CLK : IN STD_LOGIC; -- 1Hz 秒脉冲 S1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- 秒个位 S2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- 秒十位 CNT : OUT STD_LOGIC -- 59→00 的进位 ); END ENTITY; ARCHITECTURE BEHAV OF MIAO IS BEGIN PROCESS(CLR, CLK) VARIABLE M1, M2 : STD_LOGIC_VECTOR(3 DOWNTO 0); -- 用变量做组合暂存 BEGIN IF CLR 1 THEN M1 : 0000; M2 : 0000; CNT 0; ELSIF CLKEVENT AND CLK 1 THEN IF M1 1001 THEN -- 个位 0~8 直接加 M1 : M1 1; ELSE -- 个位到 9归零并向十位进位 M1 : 0000; M2 : M2 1; END IF; IF M2 0110 THEN -- 十位到 6 说明已满 60 M2 : 0000; CNT 1; ELSE CNT 0; END IF; END IF; S1 M1; S2 M2; END PROCESS; END ARCHITECTURE;三个要点必须说清。第一M1、M2用变量而不是信号是因为同一个进程里先写后读要拿到当拍新值用信号会引入一拍延迟个位到 9 时十位会晚一个周期才进位60 就数成 61 了。第二M1 1001这种写法依赖STD_LOGIC_UNSIGNED包没有这个 USE 语句比较会按字典序而不是数值来1001 0110的结果会让人怀疑人生。第三CNT 的宽度不是「一个脉冲」而是一整个时钟周期——1Hz 时钟下它高一秒。这个细节决定了下一级怎么用它。3.2 分模块计时与校时写入的优先级分模块比秒模块多两件事接收校时按键的步进以及向时模块进位。核心难点在于同一个时钟沿上可能同时发生「自然计时」和「用户按键」两种请求必须有明确的优先级。LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY FEN IS PORT( CLR : IN STD_LOGIC; -- 复位 CLK : IN STD_LOGIC; -- 秒模块进位上升沿有效 EN : IN STD_LOGIC; -- 校时使能1 处于设置态 LOAD : IN STD_LOGIC; -- SET_M 消抖后的单脉冲 S1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- 分个位 S2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- 分十位 CNT : OUT STD_LOGIC -- 59→00 进位 ); END ENTITY; ARCHITECTURE BEHAV OF FEN IS SIGNAL M1, M2 : STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(CLR, CLK) BEGIN IF CLR 1 THEN M1 0000; M2 0000; CNT 0; ELSIF CLKEVENT AND CLK 1 THEN IF EN 1 AND LOAD 1 THEN -- 设置态下按键有效加一 IF M1 1001 THEN M1 M1 1; ELSE M1 0000; IF M2 0101 THEN M2 M2 1; ELSE M2 0000; END IF; END IF; CNT 0; ELSIF EN 0 THEN -- 非设置态正常走时 IF M1 1001 THEN M1 M1 1; ELSE M1 0000; M2 M2 1; END IF; IF M1 1001 AND M2 0101 THEN M1 0000; M2 0000; CNT 1; ELSE CNT 0; END IF; END IF; END IF; END PROCESS; S1 M1; S2 M2; END ARCHITECTURE;这段代码有两个设计决定值得讲。第一个是EN 1 AND LOAD 1这个条件——只有处于设置态且按键脉冲到来才改值。如果没有EN这个约束正常走时的时候误触按键会直接改掉当前时间演示时按一下表就乱了。第二个是ELSIF EN 0这个分支它保证了设置态下走时暂停用户在改分钟的时候秒进位不会偷偷把分加一改完退出正好接上。原方案里用EN去控制「装载」和「计数」两个分支的优先级逻辑上是同一个思路我在这里把它写得更直白是因为见过太多把使能写成独立 if 导致两个条件同时成立时结果不确定的版本。另外注意IF M1 1001 AND M2 0101这句它是拿「当前值」判断而不是「加完的值」因为信号赋值是非阻塞语义这一拍读到的还是旧值符合「数到 59 才归零」的直觉。如果换成变量就得改成「加完等于 60 归零」写法不通用容易翻车。3.3 时模块23 进制与跨天归零时模块的进位规则比分级更麻烦它不是整齐的十进制或六十进制而是 0~23 的二十四进制十位只到 2。ENTITY HOUR IS PORT( CLK : IN STD_LOGIC; -- 分模块进位 CLR : IN STD_LOGIC; EN : IN STD_LOGIC; -- 校时使能 LOAD : IN STD_LOGIC; -- SET_H 单脉冲 H1 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- 时个位 H2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) -- 时十位 ); END ENTITY; ARCHITECTURE BEHAV OF HOUR IS SIGNAL M1, M2 : STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(CLR, CLK) BEGIN IF CLR 1 THEN M1 0000; M2 0000; ELSIF CLKEVENT AND CLK 1 THEN IF EN 1 AND LOAD 1 THEN -- 手动设置23 之后回 00 IF M1 1001 THEN M1 0000; IF M2 0010 THEN M2 0000; ELSE M2 M2 1; END IF; ELSE M1 M1 1; END IF; ELSIF EN 0 THEN -- 自动走时 IF M2 0010 AND M1 0011 THEN -- 23 点跨天归零 M1 0000; M2 0000; ELSIF M1 1001 THEN -- 个位 9 向十位进位 M1 0000; M2 M2 1; ELSE M1 M1 1; END IF; END IF; END IF; END PROCESS; H1 M1; H2 M2; END ARCHITECTURE;判断顺序是这里的关键。如果把M1 1001放在最前面那么 23 点会先被判成「个位进位」变成 30 点然后才想起来要归零时间就飞了。所以必须先判23M22 且 M13再判个位 9最后才是普通加一——这是级联计数器里最容易写反的一段改代码时手一抖就成玄学。手动设置那条分支我单独处理了十位的上限IF M2 0010 THEN M2 0000因为校时的时候用户可以从 23 一路按上去如果不夹住十位会数到 3、4、5显示区直接跑出 2 位数的表达能力。3.4 顶层例化把六个模块连成一张网底层模块各自仿真通过之后顶层只做一件事——连线和例化不写任何逻辑判断。ARCHITECTURE STRUCT OF CLOCK_TOP IS COMPONENT MIAO PORT(CLR, CLK : IN STD_LOGIC; S1, S2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CNT : OUT STD_LOGIC); END COMPONENT; COMPONENT FEN PORT(CLR, CLK, EN, LOAD : IN STD_LOGIC; S1, S2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CNT : OUT STD_LOGIC); END COMPONENT; SIGNAL c_sec, c_min : STD_LOGIC; -- 两级进位 SIGNAL su, st, mu, mt, hu, ht : STD_LOGIC_VECTOR(3 DOWNTO 0); -- BCD 输出 SIGNAL en_min, en_hour, ld_m, ld_h : STD_LOGIC; -- 控制链 BEGIN U_SEC : MIAO PORT MAP(CLR clr, CLK clk_1hz, S1 su, S2 st, CNT c_sec); U_MIN : FEN PORT MAP(CLR clr, CLK c_sec, EN en_min, LOAD ld_m, S1 mu, S2 mt, CNT c_min); -- 时模块、闹钟寄存器、显示扫描等按同样方式例化 END ARCHITECTURE;用位置关联还是名字关联我固定用名字关联PORT MAP(CLR clr, ...)虽然多敲几个字但端口一多就不会把S1和S2接反——位置关联接反了编译照样过只是显示出来的数字个位十位颠倒查起来极其费劲。顶层的信号一律用命名清晰的前缀c_表进位、en_表使能、ld_表装载这样在波形窗口里一搜就能定位。4. 校时、闹钟与显示按键处理与显示切换前面三个模块跑通闹钟其实只完成了一半。剩下的一半全是「人机交互」——按键、显示、发声这部分在仿真里最枯燥在上板时最容易出问题。4.1 按键消抖20ms 与单周期脉冲机械按键按下的一瞬间触点会在几毫秒内反复弹跳FPGA 的采样速度足够把每一次弹跳都当成一次有效按键。症状很直观按一下 SET_M分钟跳了三格。标准做法是用一个 1kHz 的采样节拍连续 20 次采到同一电平才认账然后在「稳定值变化」的那一刻产出一个单周期脉冲。-- key_debounce输入原始按键输出 1 个 clk_1k 周期宽的脉冲 process(clk_1k, clr) begin if clr 1 then cnt (others 0); key_sync 0; pulse 0; elsif rising_edge(clk_1k) then key_sync key_in; -- 一级同步防亚稳态 if key_sync / key_prev then -- 电平还在变计数器重来 cnt (others 0); key_prev key_sync; elsif cnt 19 then -- 连续 20 个 1ms 稳定 key_stable key_sync; pulse key_stable and (not key_stable_d); key_stable_d key_stable; else cnt cnt 1; end if; end if; end process;参数含义clk_1k是 1ms 节拍cnt计到 19 意味着 20 次采样也就是 20ms 的确认窗口pulse只有一拍高所以下一级的计数器一次按键只会加一。把窗口从 20ms 改到 10ms 也能用但按键质量差一点就会连跳改到 50ms 会明显感觉按下去「迟钝」。20ms 是经过大量实验后比较舒服的值。那个key_sync key_in的一级同步不能省。按键是异步信号直接进状态机会有极小概率采到亚稳态表现为「偶尔按一下没反应」——这种偶发问题在答辩现场出现一次就够呛。4.2 显示切换与六位数码管动态扫描显示器要复用平时显示当前时分秒按 DISPLAY_EN 之后显示闹钟设定的时分。做法不是做两套显示驱动而是在译码前加一级数据选择。-- 数据选择disp_en 0 显示当前时间1 显示闹钟设定 d0 hu when disp_en 0 else ahu; -- p a hrefhttps://download.csdn.net/download/mu7xuan/3101117 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
企业数字化 ERP 产品动态
相关推荐
NetApp FAS3200日常维护核心指南:CLI运维、硬件诊断与健康巡检闭环 简介:本资源是一份面向NetApp存储系统运维工程师、IT基础设施管理员及中高级存储技术人员的《FAS系列存储日常维护手册》,聚焦硬件管理、故障诊断与生产环境稳定运行等核心运维场景。手册内容覆盖FAS3200系列硬件说明、System Manager图形界面与CLI命令行… · 2026/11/6 2:48:31
ESXi虚拟化部署群晖NAS:稳定、隔离与快照驱动的生产级方案 1. 项目概述:为什么要在ESXi上跑群晖?这根本不是“白嫖”而是精准控制“ESXi 安装群晖NAS系统”——这个标题背后藏着的,不是一句简单的技术操作,而是一群中小团队、家庭实验室玩家和IT运维人员在资源效率与功能自由之间反复权衡后… · 2026/11/5 5:45:37
Mangos物品任务BOSS NPC编辑器环境配置与数据库避坑指南 简介:面向Mangos服务端数据库维护与私服搭建学习者的图形化数据编辑工具包,主要用于物品、任务、BOSS、NPC及相关游戏数据的查询、修改与批量维护,适合需要频繁调整服务端内容的开发者与运维人员。压缩包共66个文件,约1.63MB&… · 2026/11/5 5:14:34
HFSS特殊曲线天线建模全流程:从参数方程到网格边界 做 HFSS 特殊曲线天线建模这件事,最让人难受的不是理论算不出来,而是脑子里明明有一个漂亮的螺旋或者渐变曲线,落到软件里却怎么都画不顺、扫不出来、算不准。我这些年接手过的模型里,从等角螺旋、阿基米德螺旋,到指数… · 2026/11/6 2:48:08
Redis实现分布式Session管理的核心优势与实践 1. 为什么需要替代传统Session方案在Web应用开发中,用户会话管理一直是个核心问题。传统做法是将Session数据存储在应用服务器内存中,这种方案在单机时代运行良好,但在分布式环境下就会暴露出明显缺陷。我经历过一个电商项目,当用… · 2026/11/6 2:48:08
Oracle迁移KingbaseES实战指南与优化策略 1. Oracle迁移KingbaseES项目概述作为国产数据库领域的标杆产品,KingbaseES凭借其出色的Oracle兼容特性,已经成为企业级数据库国产化替代的首选方案之一。在实际项目中,我们经常需要将运行多年的Oracle系统迁移至KingbaseES平台。这种迁移不仅… · 2026/11/6 2:48:08
基于Spring Boot的校园食堂订餐系统设计与实现:从毕业设计到二次开发 简介:这份资源是面向计算机专业学生与Java Web开发学习者的毕业设计完整文档,聚焦疫情背景下校园食堂就餐拥挤、外卖不健康、点餐不便等现实痛点,给出了一套可落地的订餐系统设计方案。文档围绕Spring Boot轻量框架与B/S架构展开,… · 2026/11/6 2:48:08
2026智能ERP选型指南:核心考量与主流方案测评 1. 智能ERP系统选型核心考量因素在2026年的企业数字化转型浪潮中,智能ERP系统已成为提升运营效率的关键工具。但面对市场上琳琅满目的产品,企业决策者往往陷入选择困境。根据我过去五年为37家企业提供ERP咨询服务的经验,选型时需要重点评估以… · 2026/11/6 2:47:07
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07
三菱PLC数据采集到数据库的时序设计:Python+MC协议实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11
ASIC主模式RTL设计:状态机与三态驱动的流片级实现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11
STM32嵌入式C++开发:GDB调试与Renode仿真实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07