1. 从一道“其他状态机题目”说起为什么这类题总让人卡壳做Verilog笔试题或者课程设计的时候很多人都有过这种体验一段式、两段式、三段式状态机写得滚瓜烂熟交通灯、序列检测、自动售货机这些经典题目也能默写出来可一旦题目换个马甲——比如“检测输入序列中是否出现两个连续高电平且中间至少间隔一个低电平”“设计一个带优先级仲裁的状态机”“实现一个握手协议的状态转移”——立刻就懵了。我自己当年刷题的时候在“其他状态机题目”这一类上栽的跟头比在前面所有基础题上加起来还多。这篇内容就是围绕“其他状态机题目”这个专题展开的。所谓“其他”指的是那些不属于教科书上最经典的几类模板、需要你自己从题目描述里抽象出状态定义和转移条件的状态机设计题。它考察的不是你会不会背三段式模板而是你能不能把一段自然语言需求翻译成状态图再翻译成可综合的RTL代码。适合已经写过基础状态机、正在准备笔试面试或者做课程设计的同学也适合工作几年但想回头把状态机设计功底重新夯实一遍的从业者。我下面会从设计思路、状态编码与转移细节、完整实操流程、常见坑排查几个维度把这类题目的通用解法拆开讲。所有例子都是我自己编的模拟题目不涉及任何真实项目但思路和代码结构你可以直接拿去套。2. 整体设计思路先想清楚“状态是什么”再动手写代码2.1 为什么“其他状态机题目”难在抽象而不是难在语法Verilog写状态机的语法就那么点东西parameter定义状态、always块里写case、时序逻辑更新current_state、组合逻辑算next_state。语法层面几乎没有难度。真正卡人的地方在于题目给的是行为描述你要自己判断“哪些信息需要被记住”而“需要被记住的信息”就是状态。举个我编的模拟题设计一个模块输入是单比特串行数据流当检测到连续三个时钟周期内至少出现两个高电平时输出一个周期的高脉冲。这道题的状态怎么定你不能简单地用“已经收到几个高电平”当状态因为“连续三个周期”是一个滑动窗口窗口在动。这时候状态要表达的是“当前窗口内高电平的计数以及窗口位置”或者换一种思路用移位寄存器加组合判断根本不需要传统状态机。这就是“其他”类题目的第一个坎先判断这道题到底该不该用状态机用的话状态该表达什么。我的经验是拿到题目先问自己三个问题第一输出是否依赖于输入的历史序列第二是否存在明确的“阶段”划分第三状态数量是否可控一般不超过十几个三个问题里有两个答“是”就老老实实画状态图如果只是简单的窗口统计或者计数判断组合逻辑加寄存器可能更省资源。2.2 状态定义的三条实操原则状态定义错了后面代码写得再漂亮也是白搭。我总结下来有三条原则踩过坑之后觉得特别管用。第一条状态必须互斥且完备。互斥是指任意时刻只能处于一个状态完备是指所有可能的输入情况都能从当前状态找到出路。很多题目卡壳是因为状态定义有重叠比如“正在接收数据”和“已经接收完第一个字节”这两个状态如果第一个字节接收完的瞬间还停留在接收态就出现歧义了。解决办法是把“接收完第一个字节”单独设成一个状态用转移边来区分。第二条状态数量宁少勿多但该拆必须拆。有人喜欢把每个细微差别都设成一个状态结果状态图密密麻麻代码里case分支几十个维护起来要命。也有人过度合并把“等待应答”和“等待数据”合成一个“等待”态结果转移条件里要嵌套一堆判断。我的判断标准是如果两个状态的所有出边条件和动作完全一致就合并只要有一条出边不同就拆开。第三条用Moore型还是Mealy型要看输出时机。Moore型输出只跟当前状态有关波形干净、好调试但会晚一个周期Mealy型输出跟当前状态和输入都有关响应快但组合逻辑路径长容易出现毛刺。笔试里如果题目明确说“输出与输入无关”或者“输出寄存一拍”那就是Moore如果说“检测到立即输出”多半是Mealy。实际工程里我倾向于Moore加输出寄存时序好收敛。2.3 一段式、两段式、三段式的取舍逻辑这个老生常谈的话题还是得说因为“其他”类题目里经常有人问该用哪种。一段式把所有逻辑塞进一个always块写起来快但组合逻辑和时序逻辑混在一起综合工具优化空间小调试时波形上分不清哪拍是状态更新哪拍是输出变化出问题很难定位。两段式把时序和组合分开但输出如果是组合逻辑还是有毛刺风险。三段式是时序更新状态、组合计算次态、再时序寄存输出结构最清晰代价是多一拍延迟。我的实际选择是课程设计和笔试答题用三段式因为阅卷和面试官看的就是结构清晰资源极度紧张的小模块用两段式一段式基本只在写一次性测试激励的时候用。有个细节要注意三段式里第二段的组合逻辑always (*)块敏感列表里要把所有读到的信号都列进去用always (*)最省事但有些老工具对*支持不好那就老老实实列全。3. 核心细节解析状态编码、转移条件与输出逻辑的实操要点3.1 状态编码怎么选二进制、格雷码还是独热码状态编码不是随便写个parameter就完事选错了会影响时序和面积。常见三种编码方式对比如下。编码方式特点适用场景注意事项二进制编码状态位宽最小面积省状态数多、资源敏感相邻状态跳变多位翻转功耗略高格雷码相邻状态只翻一位毛刺小状态按顺序循环转移状态转移不是线性顺序时优势消失独热码每个状态一位译码简单速度快FPGA、状态数少于16状态多时寄存器浪费严重我自己的习惯是FPGA上做状态机状态数在4到16之间一律用独热码因为FPGA的寄存器资源相对充裕独热码的组合逻辑译码几乎就是一根线速度最快ASIC或者资源紧张的场景用二进制编码。格雷码我只在状态严格按0到N顺序循环的场合用比如某些计数器型状态机。还有一个实操细节用独热码的时候case语句里最好加default分支把非法状态导向一个安全态。独热码理论上可能出现多位同时为1的非法编码虽然综合工具一般会优化掉但仿真时如果状态寄存器被干扰没有default就会锁死。3.2 转移条件的写法优先级与互斥怎么保证转移条件是状态机里最容易出bug的地方。我见过太多代码case的每个分支里写一串if-else if条件之间还有重叠仿真时看着对综合后时序一跑就出错。核心原则是同一个状态的所有出边条件必须互斥且覆盖所有输入组合。如果题目本身有优先级比如“高优先级请求先响应”那就在if-else if里按优先级排列最后加else兜底如果题目没有优先级那就要保证条件之间用和!把互斥关系写清楚。举个模拟例子一个仲裁状态机在GRANT状态下如果req_a和req_b同时有效题目要求a优先。写法就是GRANT: begin if (req_a) next_state GNT_A; else if (req_b) next_state GNT_B; else next_state IDLE; end这里else if天然保证了互斥。但如果题目要求“a和b同时有效时进入错误态”那就得写成GRANT: begin if (req_a req_b) next_state ERR; else if (req_a) next_state GNT_A; else if (req_b) next_state GNT_B; else next_state IDLE; end顺序不能乱req_a req_b必须放最前面否则永远进不去。这种细节笔试里经常考面试官就看你有没有意识到条件顺序影响优先级。3.3 输出逻辑寄存输出与组合输出的取舍输出逻辑这块我的建议是默认寄存输出除非题目明确要求组合输出。寄存输出的好处是波形上输出和状态对齐毛刺被寄存器滤掉下游模块采样稳定。代价是输出比状态晚一拍如果题目有时序图要求“检测到后同一拍输出”那就得用组合输出或者Mealy型。有个折中方案我经常用状态机本体用三段式Moore输出单独再打一拍但在测试平台里把这一拍延迟考虑进去。这样RTL干净验证也好写。如果题目是笔试题答题时我会在注释里写明“输出寄存一拍如需同拍输出可改为组合逻辑”显示自己知道这个取舍。另外输出逻辑里尽量避免直接引用输入信号做组合输出除非是Mealy型。因为输入信号可能来自其他模块路径延迟不确定组合输出容易产生毛刺。如果非要用加一级寄存器打拍。3.4 复位策略同步复位还是异步复位状态机的复位策略经常被忽略但“其他”类题目里有时会专门考。同步复位的好处是复位信号不需要走全局网络时序分析简单缺点是复位信号必须满足建立保持时间且复位释放时如果靠近时钟沿可能出问题。异步复位响应快但释放时要做同步化处理否则容易产生亚稳态。我的实际做法是异步复位、同步释放。复位信号异步拉低保证任何时刻都能复位释放时经过两级触发器同步到时钟域。代码结构上状态寄存器的always块用posedge clk or negedge rst_n复位分支里赋初态。这个结构在大多数FPGA和ASIC流程里都稳。注意如果题目明确说“同步复位”就别自作聪明写异步笔试按题目要求来。实际工程里如果整个设计统一用同步复位状态机也跟着用同步复位保持一致比个人偏好重要。4. 完整实操流程从题目描述到可综合RTL的六步法4.1 第一步把自然语言拆成“输入、输出、时序约束”三张清单拿到题目别急着写代码先拿张纸列三样东西。输入清单所有输入信号的名称、位宽、有效电平、是否同步于时钟。输出清单所有输出信号的名称、位宽、有效电平、是电平有效还是脉冲有效。时序约束清单时钟频率、复位方式、输出相对输入的延迟要求。拿我编的一道模拟题举例“设计一个串行数据帧检测器输入din为单比特每帧8位帧头为1010检测到帧头后输出frame_valid一个周期高电平同时开始接收后续4位数据输出到dout。”拆解下来输入是din1位同步、clk、rst_n输出是frame_valid1位脉冲、dout4位时序约束是frame_valid在帧头最后一位被采样的下一拍有效。这一步做扎实了后面状态图基本就是水到渠成。我见过有人跳过这步直接画状态图画到一半发现漏了一个输出信号回头重来。4.2 第二步画状态转移图标注每条边的条件和动作状态图画在纸上或者用任意画图工具都行关键是每条转移边旁边要写清楚“条件/动作”。条件就是输入组合动作就是输出变化或者内部寄存器更新。上面那个帧检测器的状态图大致是IDLE态等第一个1收到后进S1S1等0收到进S2收到1留在S1因为可能是新的帧头开始S2等1收到进S3收到0回IDLES3等0收到进RECV并拉高frame_valid一拍收到1回S1RECV态收4位数据收满回IDLE。画图的时候有个技巧先把所有“错误路径”画出来也就是输入不符合预期时往哪走。很多人只画正确路径代码里case的default随便写结果仿真时一个干扰脉冲就把状态机带飞了。错误路径要么回IDLE重新同步要么留在当前态继续等取决于题目对鲁棒性的要求。4.3 第三步确定状态编码和寄存器位宽状态数数一下IDLE、S1、S2、S3、RECV一共5个。独热码需要5位二进制需要3位。FPGA上我选独热码写出来是localparam IDLE 5b00001; localparam S1 5b00010; localparam S2 5b00100; localparam S3 5b01000; localparam RECV 5b10000;用localparam而不是parameter避免被上层例化时意外覆盖。位宽写满5位不省略前导零仿真波形上看状态值一目了然。4.4 第四步三段式代码骨架落地骨架长这样我直接把帧检测器的核心部分写出来module frame_detect ( input wire clk, input wire rst_n, input wire din, output reg frame_valid, output reg [3:0] dout ); localparam IDLE 5b00001; localparam S1 5b00010; localparam S2 5b00100; localparam S3 5b01000; localparam RECV 5b10000; reg [4:0] cur_state, nxt_state; reg [1:0] bit_cnt; // 第一段状态寄存器 always (posedge clk or negedge rst_n) begin if (!rst_n) cur_state IDLE; else cur_state nxt_state; end // 第二段次态组合逻辑 always (*) begin nxt_state cur_state; case (cur_state) IDLE: if (din) nxt_state S1; S1: if (!din) nxt_state S2; S2: if (din) nxt_state S3; else nxt_state IDLE; S3: if (!din) nxt_state RECV; else nxt_state S1; RECV: if (bit_cnt 2d3) nxt_state IDLE; default: nxt_state IDLE; endcase end // 第三段输出与辅助计数 always (posedge clk or negedge rst_n) begin if (!rst_n) begin frame_valid 1b0; dout 4b0; bit_cnt 2d0; end else begin frame_valid 1b0; case (nxt_state) RECV: begin if (cur_state ! RECV) begin frame_valid 1b1; bit_cnt 2d0; end else begin dout {dout[2:0], din}; bit_cnt bit_cnt 1b1; end end default: bit_cnt 2d0; endcase end end endmodule这段代码里有个细节值得说frame_valid是在进入RECV的下一拍拉高因为第三段用的是nxt_state判断。这样输出和状态对齐波形上干净。bit_cnt在RECV态里累加收满4位回IDLE。4.5 第五步写测试平台把边界情况全打一遍测试平台不用写得多花哨但几个关键场景必须覆盖正常帧头加数据、帧头中间被打断、连续两个帧头背靠背、复位中途拉低。我一般用task封装一个“发一帧”的动作然后主initial块里按场景调用。task send_frame; input [7:0] header; input [3:0] data; integer i; begin for (i 7; i 0; i i - 1) begin (posedge clk); din header[i]; end for (i 3; i 0; i i - 1) begin (posedge clk); din data[i]; end end endtask背靠背场景特别容易暴露问题第一帧收完回IDLE的同一拍如果下一帧的帧头第一位正好是1状态机能不能正确识别这取决于IDLE态对din的采样时机。如果RECV回IDLE的那拍din已经是新帧的1而IDLE态的组合逻辑在下一拍才看到就会漏掉一位。解决办法是在RECV收满后直接判断din如果为1就跳S1而不是回IDLE。这种细节只有仿真跑背靠背才能发现。4.6 第六步综合后看资源报告和时序报告代码仿真过了不算完综合一遍看两个东西状态寄存器有没有被优化成非法编码、关键路径延迟多少。独热码状态机综合后如果工具报告“FSM encoding auto”之类的信息说明工具自己重新编码了这时候要检查综合约束里有没有强制保留原编码。关键路径一般在次态组合逻辑上如果状态多、条件复杂路径延迟可能超标那就得考虑把部分条件判断提前一拍寄存或者拆分状态机。提示综合报告里如果看到状态寄存器被识别为“safe FSM”并插入了纠错逻辑说明工具认为你的状态机可能进入非法态。这时候检查default分支是否完备或者显式加上(* safe_implementation yes *)之类的属性不同工具语法不同避免工具自作主张增加面积。5. 常见问题与排查技巧实录5.1 状态机跑飞仿真对、上板错的第一嫌疑人仿真波形完美下载到板子上行为诡异十有八九是复位或者时钟域问题。先查复位复位信号是不是真的拉到了状态机有些设计里复位经过几级逻辑延迟太大状态机在复位释放前就开始跑。再查时钟状态机的时钟是不是和输入数据同步如果输入来自异步源没做同步处理直接进状态机亚稳态会让状态跳变。我遇到过一次状态机在板子上偶尔多输出一个脉冲查了两天才发现是输入信号没同步状态机在S3态采样到亚稳态值误判成0进了RECV。后来加了两级同步器解决。这个坑在“其他”类题目里特别常见因为题目往往只描述功能不描述输入同步要求得自己补上。5.2 输出毛刺组合输出惹的祸用Mealy型或者组合输出时输出信号在状态切换的瞬间可能出现窄脉冲。仿真时因为事件调度顺序毛刺可能被掩盖上板用示波器一抓就现形。解决办法前面说过输出寄存一拍。如果题目要求同拍输出那就在输出后面加个assign到寄存器的路径或者用case的完整赋值避免锁存器。还有一种毛刺来源是case分支里漏赋值。组合逻辑always块里如果某个分支没有给输出赋值综合工具会推断出锁存器输出保持上次值行为不可预测。养成习惯组合逻辑块开头先给所有输出赋默认值case里再按需覆盖。5.3 状态编码被工具改掉综合报告里的隐藏信息前面提过综合工具可能自动重新编码状态机。这在功能上一般没问题但如果你依赖特定编码做调试比如用逻辑分析仪抓状态值就会发现抓到的值和代码里定义的对不上。解决办法是在综合脚本里关掉FSM自动编码或者用(* fsm_encoding one_hot *)之类的属性强制指定。不同工具属性名不一样查对应工具的手册。5.4 常见问题速查表现象可能原因排查方法解决仿真对、上板错输入未同步、复位问题查同步器、查复位路径加两级同步、检查复位释放输出有毛刺组合输出、分支漏赋值示波器抓、查case完备性输出寄存、补默认赋值状态值抓不到预期工具自动重编码看综合报告FSM信息关自动编码或加属性状态机锁死非法态无出口、default缺失仿真注入非法态补default回安全态背靠背漏数据状态回跳时机不对仿真背靠背场景收满后直接判断下一输入5.5 独家避坑状态图先画“错误路径”这个技巧我逢人就推画状态图的时候先把所有“输入不符合预期”的转移画出来再画正确路径。因为正确路径是题目明说的错误路径是题目没说的而bug几乎都藏在没说的部分。比如帧检测器里S1态收到1该去哪题目没说但实际数据流里连续两个1完全可能你得决定是留在S1当作新帧头开始还是回IDLE。这个决定影响后续所有逻辑先想清楚再写代码比写完再改省事得多。另一个经验是状态机的每个状态至少要有两条出边除了终止态如果某个状态只有一条出边说明这个状态可能没必要单独存在可以合并到前一个状态里。这个检查方法能帮你精简状态数量。6. 从题目到工程这类能力真正值钱的地方“其他状态机题目”这个专题表面上是笔试题库里的一个分类实际上练的是把模糊需求转化成精确硬件行为的能力。我在实际工作中做协议解析、接口握手、流程控制用的全是这套东西先拆输入输出清单再画状态图含错误路径然后三段式落地最后测试平台打边界。题目会变这套流程不变。有个体会特别深状态机设计里最贵的不是写代码的时间是调试的时间。而调试时间的长短几乎完全取决于画状态图时有没有把错误路径想全。我现在的习惯是状态图画完之后拿红笔把每条边问一遍“如果输入不是这个值会怎样”问完再动手。这个习惯让我在后来的项目里少熬了很多夜。如果你正在刷这类题目建议别只满足于“仿真波形对了”多问一句“如果输入有毛刺会怎样”“如果复位中途来会怎样”“如果背靠背会怎样”。这三个问题问下来你对状态机的理解会比刷十道题都扎实。后面如果再遇到更复杂的时序约束或者多时钟域的状态机交互这套底子也能直接往上搭。
企业数字化 ERP 产品动态
相关推荐
用C++从零手写CNN恶意软件检测:完整实现与踩坑记录 作为一个平时主要用 Python 写深度学习、但偏偏要在某些场景下用 C 把模型落地的人,我对“C 深度学习”这几个字真是又爱又恨。这个系列前面聊了环境搭建和基础张量操作,这篇“第三弹”我想直接来点硬核的:不聊理论推导,而是逐步用… · 2026/11/3 16:34:55
打造你的arXiv每日分析流程:从订阅到自动化 每天早上打开邮箱,arXiv 的订阅摘要已经躺在那里。标题按分类排好,作者名字熟悉得能认出是哪几个组在动,摘要里混着术语和实验结果。别人刷新闻,我刷的是 arXiv——这个习惯我坚持了快五年,期间把每天刷 arXiv 的时间从… · 2026/11/3 16:34:55
arXiv论文日报实战:从订阅机制到高效筛选的完整攻略 每天早上八点,我做的第一件事不是刷消息,而是打开 arXiv,把当天的论文列表拉下来过一遍。这个习惯坚持了挺久,从最早的“随手翻翻”慢慢变成了固定产出的每日论文分析报告。今天这篇就把这段时间摸出来的门道一次性说清楚… · 2026/11/3 16:34:55
AI不做裁判:无排序无打分讨论系统的设计与实践 最近做了件挺反直觉的事:搭了一个专门用来讨论复杂问题的系统,然后把排序、打分、评选“哪个回答更好”这些功能全砍了。标题就叫“AI 不做裁判”,听起来像是行为艺术,但真正跑起来以后,我发现它解决了不少主流讨论平台… · 2026/11/3 17:25:35
同步FIFO设计避坑指南:格雷码、空满逻辑与时序收敛 1. 为什么“同步FIFO”不是一句空话,而是一个必须亲手拆开的黑盒子 “同步FIFO”这四个字在数字电路设计文档里出现频率极高,但真正把它从教科书概念变成可复位、可仿真、可上板验证的模块,中间隔着至少三道真实工程门槛:第一道是… · 2026/11/3 17:25:35
Nginx图片代理方案:解决HTTPS混合内容与防盗链问题 1. 项目概述在Web开发中,我们经常会遇到两个棘手的图片加载问题:一是HTTPS站点加载HTTP图片会触发浏览器混合内容警告,二是第三方图片资源站的防盗链机制会阻止图片显示。这两个问题看似简单,但实际解决起来却需要一定的技巧。我最… · 2026/11/3 17:25:35
从七个习惯到四象限:高效能人士的时间管理与目标落地 简介:面向职场人士、在校学生及培训讲师准备的读书分享与主题汇报场景,这份《高效能人士的七个习惯》PPT演讲模板围绕积极主动、以终为始、要事第一、双赢思维四个习惯展开,提供从目标设定、优先级排序到时间管理与互利沟通的内容框架&#x… · 2026/11/3 17:25:35
MOSFET数据手册深度解读:从绝对最大额定值到SOA安全工作区 1. 这不是“读说明书”,而是解码功率开关的DNA你手头那本几十页厚、密密麻麻全是英文缩写和曲线图的MOSFET数据手册,真就只是个“参考文档”?不。它本质上是一份器件级设计契约——制造商用它向你承诺:在特定条件下,这… · 2026/11/3 17:25:35
旋转圆叠加方波动画全解析:从傅里叶级数到Python实现 你肯定刷到过那个画面:一个接一个的圆套着圆,圆心之间互相牵着走,最外圈的小笔尖拖出一条不断延伸的波形,最后硬生生拼出一个棱角分明的方波。这几乎是“傅里叶级数”的官方代言图,我第一次看到时第一反应是“这玩意儿… · 2026/11/3 17:24:34
双极步进电机控制实战: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/2 13:10:28
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/3 6:04:24
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/3 5:52:46
STM32F411RE与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:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* 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:01:59
基于MAX14431BAEE+与PIC18F85J10的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:01:59
双极步进电机控制实战: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/2 13:10:28
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/3 6:04:24
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/3 5:52:46