电赛AD9854实战:频率字计算、SPI时序与FUD脉冲全解析
简介面向STM32F407与HAL库开发者的电赛信号源练习资源聚焦AD9854 DDS模块驱动与扫频实现。从DAC/DMA生成正弦波的实验过渡到集成DDS方案覆盖任意频率正弦产生、幅度平坦度处理等关键点适合参加电子设计竞赛或学习DDS技术的单片机开发者。压缩包共1123个文件核心为C源文件与头文件合计约875个另有IAR/Keil工程配置、DSP数学库、链接映射文件与说明文档整体43.66MB。导入工程后可直接查看外设初始化、AD9854寄存器配置及扫频主循环逻辑便于对照学习。已有2638人学习。通过源码、工程文件与配套文档可复现扫频输出流程理解HAL库下SPI、定时器与DDS模块的协作节省调参与排查时间。1. 电赛AD9854这道题拉开差距的是频率字和FUD脉冲很多人拿到这道题的流程是先找个HAL库例程把SPI配置抄过来能出波形就停手。可真到评测和面试追问评委问的往往是另外两个点扫频起点为什么不对、频率字更新信号FUD到底有没有生效。这两点几乎每届都有人栽原因都出在对AD9854串行时序的理解上。这道题表面是STM32F407加HAL库的外设题实际是DDS原理题你能不能把一个48位频率控制字按正确字节序发出去并在正确时刻用FUD让输出完成切换。答好这两点SPI配置、定时器扫频、DMA方案全成了加分项答错哪怕一个字节顺序输出就完全不是你要的频率。下面按电赛考核顺序拆成五块从频率字算法讲到现场排错适合正在备赛电赛、或者准备嵌入式面试的读者。2. 高频考点频率字算法、SPI时序和“无输出”排查路径2.1 频率字计算48位公式与截断陷阱AD9854的频率控制字是48位内部系统时钟我用40MHz作为基准输出频率记为f_out计算公式是FTW f_out × 2^48 / SYSCLK。公式本身不复杂但真动手算一次才会发现坑在哪2^48大约等于2.8147e14超出32位整数范围很多人直接用int算溢出后频率完全错掉。正确做法是用64位无符号整型接收结果再拆成6个字节。static void ad9854_freq_to_bytes(double freq, uint8_t out[6]) { uint64_t ftw (uint64_t)(freq / 40.0e6 * 281474976710656.0); out[0] (uint8_t)((ftw 40) 0xFF); // 最高字节先发 out[1] (uint8_t)((ftw 32) 0xFF); out[2] (uint8_t)((ftw 24) 0xFF); out[3] (uint8_t)((ftw 16) 0xFF); out[4] (uint8_t)((ftw 8) 0xFF); out[5] (uint8_t)(ftw 0xFF); // 最低字节 }这里要提醒两个细节。第一freq除以40.0e6得到的是占空比乘以2^48后有可能不是整数AD9854硬件是直接截断低位的不需要四舍五入你把小数部分算得再准最终那个频率字也只是近似输出。第二out[0]必须是最先发送的字节厂家手册里明确写了高位在前这和STM32内存里的小端习惯正好相反很多同学栽就栽在低字节先发最后示波器看到的频率比预期大好几倍。面试里这道题经常变成“给你一个输出频率口算大概频率字范围”。这时候不需要精确到个位能说出“先除以系统时钟得到比例再乘2^48拆成6字节高位在前”就已经过了一半。如果还能补一句“系统时钟不是固定40MHzPLL倍频之后分母要跟着变”面试官会默认你看过数据手册。2.2 SPI时序地址和6字节数据要在同一个CS低电平里发完频率字算完只是第一步怎么发出去才是真正的失分重灾区。AD9854串行时序要求CS拉低后先发寄存器地址0x03高频字地址再连续发6字节频率数据整个过程CS必须保持低。很多人习惯一次HAL_SPI_Transmit传一字节地址发完拉一次CS数据发完再拉一次这么写大概率输出乱掉因为AD9854把每次CS上升沿都当成一次事务结束一帧被拆成两段解串就错位了。void ad9854_write_freq_high(const uint8_t data[6]) { uint8_t frame[7] {0}; frame[0] 0x03; // 高频字寄存器地址 for (int i 0; i 6; i) frame[i 1] data[i]; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(hspi1, frame, 7, 50); // 一帧发完 HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(FUD_GPIO_Port, FUD_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(FUD_GPIO_Port, FUD_Pin, GPIO_PIN_RESET); }帧格式对应关系是这样的字节0是寄存器地址0x03字节1是频率字最高8位字节2到字节6依次是低48位里的剩余部分。CubeMX配置SPI时要把数据长度设为8位MSB First模式0即可即CPOL0、CPHA0波特率先压到1MHz以内调试跑通后再提速度。上面代码里FUD的拉高到拉低之间没有延时实际使用时留几个空操作或者几十纳秒延时更稳妥。面试官如果问你FUD是干什么的标准答法是SPI把频率字写进芯片内部的缓冲寄存器FUD上升沿才真正让DDS把频率切换过去不拉FUD输出永远停在旧值。2.3 真题演练初始化之后SMA口测不到输出按什么顺序查这道题几乎是电赛现场的必问场景题上电、配置、写频率字用频谱仪或者示波器却什么都测不到。很多人的第一反应是“代码没跑起来”其实按顺序排查五分钟就能定位。正确的排查顺序是先看CS波形是否在整帧内保持低再看SCLK上有没有时钟然后用示波器单次触发抓FUD脚看写完频率字之后有没有高脉冲。这三步如果都正常去测系统时钟是否锁定最后再考虑控制寄存器里输出使能位有没有配。实际项目中后三步最容易出问题。上电顺序上先给AD9854复位引脚一个完整复位脉冲等几个系统时钟周期再发SPI数据如果复位还没结束就发寄存器写进去的内容会被复位操作清掉。第二步是PLL倍频AD9854外部进来的是低频参考时钟要通过PLL倍频得到内部系统时钟倍频寄存器没写或者写错频率字算出来也不对。第三步才是寄存器读回用SPI回读0x00控制寄存器确认配置确实落在了芯片内部。如果频率输出有但起点不对比如你要10kHz扫到1MHz实际起点偏离很多先别怀疑频率字公式用逻辑分析仪抓MOSI核对帧里第一字节是不是0x03后面6字节是不是高位在前。很多“频率不对”最后都定位在字节序上。2.4 一个值得背的对比DDS内部扫频与MCU逐点扫频这类题追问到最后往往会落到一个更宏观的问题AD9854本身支持线性扫频为什么很多方案还是用STM32循环改频率字这其实是在考你有没有理解DDS的工作模式。AD9854内部扫频依赖专门的RAMP寄存器设置好起始频率、终止频率和扫描速率后芯片自己按节拍更新输出MCU只在开始时配一次参数。MCU逐点扫频则完全由程序控制每个频点都通过SPI下发。两者对比下来内部扫频的优点是频率切换节拍精准不占CPU资源但只能做线性扫频MCU方式可以任意跳跃频点能做跳频、非线性扫频代价是每个频点都要占用SPI传输时间。面试里这么答评委就会觉得你是真用过而不是背过例程。3. 实战核心三种扫频方案的代码骨架从查表到DMA自动扫频3.1 查表延时扫频能跑但驻留时间交给HAL_Delay是隐患最简单的一种写法是预先算好100个频率点放在一个double数组里while循环里依次写频、延时。这种方案在实验室演示时没问题拿到电赛现场就会暴露问题。HAL_Delay基于SysTick实现中断会打断延时按键扫描和屏幕刷新也会抢占CPU实际驻留时间会漂移扫出来的频谱间隔参差不齐。const double freq_list[100] {10e3, 20e3, /* ... */}; while (1) { for (int i 0; i 100; i) { uint8_t bytes[6]; ad9854_freq_to_bytes(freq_list[i], bytes); ad9854_write_freq_high(bytes); HAL_Delay(5); // 名义驻留时间5ms实际会漂 } }这个写法的本质是“用延时凑扫频节拍”简单但缺少工程性。面试官问一句“你的扫频速度是多少”很多同学答不上来因为只写了驻留时间没计算扫频速率。扫频速率等于频率步进除以驻留时间步进10kHz、驻留5ms扫频速率就是2MHz/s。能把驻留时间和扫频速率的关系说清楚比代码本身更能拿分。3.2 定时器中断加主循环改字电赛比较稳的写法把延时换成定时器中断扫频节拍就独立于主循环了。用TIM6做时基中断里只做一件事置一个标志位。主循环检测到标志后计算下一个频点并调用SPI发送函数。这个写法的好处是驻留时间由硬件定时器保证主循环里就算有显示和按键处理也不会影响扫频节奏。static volatile uint16_t scan_index 0; static volatile uint8_t scan_flag 0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM6) { scan_flag 1; // 中断里不碰SPI只置标志 } } while (1) { if (scan_flag) { scan_flag 0; double freq 10e3 (double)scan_index * 1e3; uint8_t bytes[6]; ad9854_freq_to_bytes(freq, bytes); ad9854_write_freq_high(bytes); scan_index; if (scan_index 90) scan_index 0; } }注意中断回调里千万不能直接调HAL_SPI_Transmit因为它是阻塞传输会一直等到发送完成并清忙标志在中断上下文里相当于把整个系统卡在SPI等待上。定时器周期就是驻留时间例如TIM6配置成5ms中断一次频率步进1kHz扫频速率就是1kHz/5ms也就是200kHz/s。这个关系式建议直接背下来评测时很容易被问到。3.3 DMA与AD9854内部扫频更适合面试追问的加分点更高一级的实现是用定时器触发DMA搬运频率帧整个过程CPU几乎不参与。做法是提前生成一张二维数组freq_frame[N][7]每一行是一帧完整的SPI数据包括地址字节和6字节频率字。定时器中断到来时判断SPI不忙就启动一次HAL_SPI_Transmit_DMA发送完成后在回调里推进索引。static volatile uint8_t spi_busy 0; void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi-Instance SPI1) { spi_busy 0; // 上一帧发完允许下一次发送 } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM7 !spi_busy) { spi_busy 1; HAL_SPI_Transmit_DMA(hspi1, freq_frame[tx_index], 7); tx_index (tx_index 1) % FRAME_COUNT; } }这个方案里spi_busy是保护信号防止上一帧还没发完就启动下一帧传输。DMA方式扫频的极限速度取决于SPI时钟和7字节传输时间比定时器中断方式高很多而且主循环可以腾出来做显示、按键、故障处理。不过如果你真想给面试官留个好印象还可以补一句AD9854自己就带RAMP扫频功能配置好扫描速率寄存器和上下限寄存器后FUD每触发一次频率自动累加一步MCU完全不需要干预。这一步说出来就把你从“会写HAL库”拉到了“理解DDS架构”的层次。实际选择上线性扫频优先用芯片内部RAMP需要跳频或非线性扫频再用SPI逐点下发。4. 易错题盘点AD9854翻车点从字节序到掉进中断的阻塞传输4.1 字节序搞反频率输出完全是乱的错在哪把频率字的低字节放在帧的最前面发送以为STM32内存里低位在低地址外设也应该先收低位。为什么错AD9854串行接口明确规定高位在前接收端把第一个字节当作频率字的最高字节你按小端发出去芯片解析出来的频率和预期相差极大。怎么答对发送顺序永远是地址0x03然后频率字bit47到bit0顺次排列。如果不确定用逻辑分析仪抓一次MOSI对比目标频率字的十六进制表示一帧一帧核对。4.2 CS没有贯穿整帧一帧数据被拆成多个事务错在哪地址发一个字节CS拉高一次再发数据CS又拉高一次。为什么错AD9854把CS上升沿认定为一次串行事务的结束地址和数据被拆成两帧芯片内部根本拼不出一个完整频率字。怎么答对把地址和6字节数据组成一个7字节的数组一次HAL_SPI_Transmit发完CS只在整帧前后动作。如果确认代码里CS没在中间拉高但依然出错就去检查GPIO初始化看CS配置的是不是推挽输出、默认电平是不是高。4.3 写完SPI忘了FUD频率字写了等于没写错在哪SPI发送函数返回后直接认为输出已经更新示波器上看到的还是旧频率。为什么错AD9854的串行写入只更新内部寄存器缓冲FUD引脚需要一个上升沿芯片才会把频率字真正加载到DDS核心。怎么答对每次写完一帧CS拉高之后把FUD拉高再拉低顺序不能反。FUD高电平持续时间要满足芯片手册的最小要求调试阶段可以用几十纳秒延时不要为了省时间省略这一步。4.4 在定时器中断里调阻塞SPI扫频节奏全乱错在哪直接在HAL_TIM_PeriodElapsedCallback里调用ad9854_write_freq_high回调执行时间远超中断周期。为什么错HAL_SPI_Transmit是阻塞函数会等到TXE标志和BSY标志都满足条件才返回中断里跑这段代码会让系统卡在SPI上其他中断和主循环都被拖住。怎么答对中断只置scan_flag主循环检测到标志后再执行SPI发送。如果你确实需要高频率扫频改用DMA非阻塞发送并且加spi_busy保护上一帧没发完就跳过当前周期。4.5 上电后不配控制寄存器写再多频率字也没输出错在哪跳过控制寄存器、PLL倍频寄存器直接往频率字地址里写数据。为什么错AD9854默认寄存器状态不保证输出通道使能PLL倍频值也可能是未定义的芯片可能根本没有可用的系统时钟。怎么答对上电后先复位延时再配置0x00控制寄存器和0x01倍频寄存器最后写频率字并触发FUD。调试时先固定输出一个低频点比如1kHz或者10kHz确认DAC输出正常再做扫频不要一上来就扫全频段否则定位问题非常痛苦。5. 答题技巧一张时序图和三句话把电赛题答成送分题5.1 交卷前先画三线时序草图电赛评测和面试答题嘴上说得再流利都不如一张草图有用。建议在草稿纸上画出CS、SCLK、MOSI、FUD四根线在一帧时间内的相对关系CS整帧为低SCLK在MOSI稳定时产生上升沿MOSI上依次是地址0x03和6字节频率数据CS拉高后FUD产生一个高脉冲。这张图你能画出来证明你理解了串行写入的完整过程而不是只背了函数调用。画完时序图再回答参数问题频率字由输出频率和系统时钟决定系统时钟受PLL倍频影响扫频速率由步进和驻留时间决定驻留时间由定时器周期控制。把这些数字写在这张图旁边整道题的回答框架就完整了。5.2 三句话口述模板遇到“简述你的扫频方案”这种开放题按三句话组织答案。第一句频率字等于输出频率除以系统时钟再乘2的48次方拆成6字节按高位在前发送。第二句SPI一次传输完成地址加数据共7字节CS全程保持低电平传输完成后FUD拉高触发输出更新。第三句扫频节奏由TIM定时器控制中断置标志、主循环改频率字需要更高速度时用DMA或者AD9854内部RAMP模式。三句话分别对应原理、时序、架构正好覆盖这个题目的全部考点。最后分享一个我的血泪习惯。以前调这类DDS模块每次都是先写代码后看波形出了问题就怀疑这怀疑那改一个参数重烧一次非常玄学。后来强制自己换芯片型号前先画一遍时序草图把CS、FUD、数据有效的先后关系写清楚再写代码从那以后SPI通信几乎没有翻过车。调试时也固定一个流程先单频点验证频率字再扫小范围验证步进最后才放开全频段。这套顺序不是什么高级技巧但能省下评测现场一大半的排错时间希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Java五子棋游戏实战:从棋盘模型到胜负判定与悔棋实现

Java五子棋游戏实战:从棋盘模型到胜负判定与悔棋实现

简介:面向有一定编程基础、对游戏开发与AI算法感兴趣的读者,此教程以完整工程为例,系统讲解五子棋从结构设计到智能对弈的实现过程,涵盖棋盘、棋子、玩家、事件驱动游戏循环等核心模块,并深入介绍极大极小算法与Alpha-…

2026/10/16 2:57:58 阅读更多 →
如何5分钟跑通ClawBench:新手入门你的第一个浏览器智能体评测任务

如何5分钟跑通ClawBench:新手入门你的第一个浏览器智能体评测任务

【免费下载链接】ClawBench Open-source benchmark for browser AI agents on daily tasks. 项目地址: https://gitcode.com/gh_mirrors/cl/ClawBench 点击查看 免费下载 ClawBench 是一个开源的浏览器 AI 智能体评测基准(Benchmark)&#x…

2026/10/16 2:56:58 阅读更多 →
没有z-buffer怎么画建筑?Helios建筑挤出、Lambert着色与画家算法排序详解

没有z-buffer怎么画建筑?Helios建筑挤出、Lambert着色与画家算法排序详解

【免费下载链接】Helios Helios - Make your energy visible, in 2.5D in a Lovelace card for Home Assistant 项目地址: https://gitcode.com/gh_mirrors/helios34/Helios 点击查看 免费下载 Helios 是一个 Home Assistant 的 2.5D 能源可视化卡片,它…

2026/10/16 2:56:58 阅读更多 →

最新新闻

CTF音频隐写解题指南:从‘啊哒~’看振幅、频谱与相位三重分析

CTF音频隐写解题指南:从‘啊哒~’看振幅、频谱与相位三重分析

1. 从一道CTF杂项题名看起:为什么“啊哒~”不是卖萌,而是信号“BugkuCTF-Misc:啊哒~”——第一次在某高校CTF训练平台看到这个标题时,我下意识点开想看看是不是新出的搞笑彩蛋题。结果发现它被归在Misc(杂项&#xff0…

2026/10/16 3:52:10 阅读更多 →
CANN一站式算子开发工具:从工程生成到性能优化的完整实践

CANN一站式算子开发工具:从工程生成到性能优化的完整实践

做AI算子开发的朋友,应该都有过这种体验:需求一句话就说完了——“写个自定义算子”,真正动手却要在工程搭建、参数定义、调试、性能调优上来回折腾。如果恰好是在一款新的AI芯片上跑,工具链又不成熟,那痛苦程度直接翻…

2026/10/16 3:52:10 阅读更多 →
Win10下VMware安装CentOS 7.9并配置静态IP与外网访问

Win10下VMware安装CentOS 7.9并配置静态IP与外网访问

1. 为什么要在Win10上折腾CentOS 7.9虚拟机很多刚接触Linux运维或者后端开发的朋友,第一道拦路虎不是命令本身,而是“我该把系统装在哪”。直接把自己的主力Windows 10笔记本格掉装Linux,显然不现实——办公、聊天、看文档都还得靠它。退而求…

2026/10/16 3:52:10 阅读更多 →
深度学习为何持续流行:从特征学习到端到端训练的范式变革

深度学习为何持续流行:从特征学习到端到端训练的范式变革

1. 从一张老照片说起:深度学习到底改变了什么2012年之前,如果你在一场计算机视觉的学术会议上说“我们用一个端到端的神经网络把图像分类错误率砍掉一半”,大概率会被审稿人反问:“你的特征工程做了什么?为什么不用SIF…

2026/10/16 3:52:10 阅读更多 →
WinUI 3 快速上手指南:6 个里程碑做出 Fluent 风格的 Windows 应用

WinUI 3 快速上手指南:6 个里程碑做出 Fluent 风格的 Windows 应用

WinUI 3 快速上手指南:6 个里程碑做出 Fluent 风格的 Windows 应用 【免费下载链接】microsoft-ui-xaml WinUI: a modern UI framework with a rich set of controls and styles to build dynamic and high-performing Windows applications. 项目地址: https://g…

2026/10/16 3:52:10 阅读更多 →
PL/0编译器C语言实现:从词法分析到解释执行的完整教学级编译流程

PL/0编译器C语言实现:从词法分析到解释执行的完整教学级编译流程

简介:本资源是N.Wirth教授经典PL/0语言编译器的C语言实现源码,面向编译原理初学者、高校计算机专业学生及教学实践者,用于深入理解词法分析、语法分析、语义处理与目标代码生成等编译全流程核心机制。压缩包为11KB的ZIP格式,共含2…

2026/10/16 3:51:09 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →