SmartFusion串口通信实战:从MSS UART驱动到FPGA引脚映射的完整例程

简介:这份资源是面向FPGA初学者与嵌入式开发者的Actel SmartFusion串口通信例程,围绕在混合信号SoC上实现UART功能展开,帮助读者打通从硬件描述语言编程、时钟管理到固件开发的完整链路。压缩包共842个文件,约4.72MB,以vhd、v等HDL源码和c、h等固件代码为核心,辅以prw、psm等工程配置、dbs与dat数据文件、xml与txt说明文档及log、rpt运行报告,完整保留了Libero IDE工程结构。内容覆盖UART收发逻辑、波特率发生器、状态机设计、CMIP时钟配置以及Cortex-M3中断处理等关键环节,并包含仿真验证与JTAG下载调试所需文件。目前已有228人学习下载,适合希望借助真实工程快速理解SmartFusion开发流程、掌握串口通信实现方法的读者参考借鉴。

1. 从一块吃灰的 SmartFusion 开发板说起:这个串口例程到底能跑出什么

手头有一块 Actel(现 Microsemi)的 SmartFusion 开发板,Cortex-M3 硬核加 FPGA 逻辑混搭,性能不差,但很多人拿到手就卡在第一步——串口不通。板子上的 UART 要么没输出,要么乱码,要么干脆连不上终端。这个例程就是解决这个问题的:它把 SmartFusion 的 MSS(微控制器子系统)串口外设驱动、FPGA 侧的引脚分配、以及中断收发逻辑全部打通,烧进去就能在串口助手里看到回显。适合谁?适合手里有 SmartFusion 板子但还没跑通串口的嵌入式开发者,也适合想学 Actel FPGA 软硬协同设计的人。它不炫技,但能让你在半小时内看到第一个字符从板子发到电脑上。

2. 工程结构拆解:从 .c 到 .pdc 的完整链路

2.1 目录里到底放了什么

拿到这个例程包,第一件事是别急着打开 IDE,先看目录结构。典型的 Actel SmartFusion 串口例程会包含这几个核心部分:

uart_demo/ ├── src/ │ ├── main.c # 主循环,串口初始化与回显逻辑 │ ├── uart_driver.c # MSS UART 驱动,寄存器级操作 │ ├── uart_driver.h # 驱动接口声明 │ └── sys_config.c # 系统时钟与引脚复用配置 ├── fpga/ │ ├── top.v # FPGA 顶层,负责引脚映射 │ └── uart_fpga.v # 可选的 FPGA 侧 UART 逻辑 ├── constraints/ │ └── uart_demo.pdc # 物理约束文件,绑定引脚 ├── project/ │ └── uart_demo.prj # Libero 工程文件 └── readme.txt # 版本说明与硬件连接提示

这个结构里,src/是 Cortex-M3 跑的固件,fpga/是 FPGA 逻辑,constraints/决定信号从哪个引脚进出。很多人只改main.c就编译,结果串口没反应,问题往往出在.pdc文件里引脚绑错了。

2.2 启动流程:从复位向量到串口初始化

SmartFusion 上电后,Cortex-M3 先从 Flash 取复位向量,执行启动文件,然后跳到main()。串口例程的main()通常长这样:

#include "uart_driver.h" #include "sys_config.h" int main(void) { // 系统时钟配置:MSS 主频通常设为 100MHz MSS_CLOCK_CONFIG(); // 初始化 UART0,波特率 115200,8N1 UART_init(UART0, 115200, DATA_8BIT, PARITY_NONE, STOP_1BIT); // 使能接收中断,收到字符后触发 UART0_IRQHandler UART_enable_irq(UART0, UART_RX_IRQ); // 发送一个启动提示 UART_send_string(UART0, "SmartFusion UART Demo Ready\r\n"); while (1) { // 主循环空转,实际收发放中断里处理 } }

这段代码的关键在UART_init的第二个参数——波特率。SmartFusion 的 MSS UART 时钟源来自 PLL,如果MSS_CLOCK_CONFIG()里分频设错,实际波特率会偏,终端上就是乱码。常见做法是先用示波器量 TX 引脚,确认位宽是否对应 115200(约 8.68μs 一位),再回头调分频系数。

2.3 中断收发:为什么你的回显会丢字符

串口例程的核心是中断服务函数。轮询方式虽然简单,但一旦主循环里有延时,接收缓冲区就会溢出。这个例程用中断收发:

void UART0_IRQHandler(void) { uint8_t rx_data; // 判断是接收中断还是发送中断 if (UART_get_irq_status(UART0) & UART_RX_IRQ_FLAG) { // 从 FIFO 读一个字节 rx_data = UART_receive_byte(UART0); // 回显:把收到的字符原样发回去 UART_send_byte(UART0, rx_data); // 如果收到回车,额外发一个换行,方便终端显示 if (rx_data == '\r') { UART_send_byte(UART0, '\n'); } // 清中断标志,否则会反复进中断 UART_clear_irq(UART0, UART_RX_IRQ_FLAG); } }

这里有个血泪经验:UART_clear_irq必须放在最后,而且清标志的时机要在读走数据之后。如果先清标志再读 FIFO,某些批次芯片会丢字节。另外,回显逻辑里加\r转\n是为了适配 Windows 终端,Linux 下反而会多一个空行,按需删掉即可。

2.4 FPGA 侧引脚映射:.pdc 文件怎么写

SmartFusion 的串口引脚不是固定死的,得在.pdc里手动绑。典型配置:

# uart_demo.pdc set_io UART0_TXD -pin G12 set_io UART0_RXD -pin G11 set_io UART0_RTS -pin F12 set_io UART0_CTS -pin F11

G12、G11这些是封装引脚号,具体值取决于你用的是哪款 SmartFusion(A2F200、A2F500 等)。绑错引脚的典型现象是:TX 引脚用示波器量不到波形,或者波形幅度只有 1V 左右——那说明绑到了 FPGA 的普通 IO 而非 MSS 专用引脚。MSS UART 只能走特定引脚,查数据手册的“MSS I/O Assignment”表最稳妥。

3. 跑通第一步:Libero 工程配置与烧录

3.1 新建工程还是直接打开 .prj

如果你拿到的例程包里有.prj文件,直接用 Libero 打开最省事。但要注意版本兼容性:老例程可能是 Libero 9.x 建的,你用 11.x 打开会提示升级,升级后约束文件可能失效。我一般会先备份一份原始.pdc,再让工具自动升级,升级完对比引脚绑定有没有变。

如果没有.prj,就手动新建工程,器件选对型号(比如 A2F200M3F-FGG484),然后:

  1. 把src/下的.c和.h文件加入软件工程
  2. 把fpga/下的.v文件加入硬件工程
  3. 把.pdc文件加入约束
  4. 在 Libero 的“Configure Flash”里勾选“MSS UART”作为调试输出

3.2 时钟配置:最容易翻车的地方

SmartFusion 的 MSS 时钟树有点绕:外部晶振 → PLL → 分频器 → 外设时钟。串口例程里通常有个sys_config.c专门管这个:

void MSS_CLOCK_CONFIG(void) { // 假设外部晶振 20MHz,PLL 倍频到 100MHz MSS_PLL_CONFIG(20, 100); // APB0 总线分频,UART 挂在 APB0 上 MSS_APB0_CLOCK_DIV(2); // 100MHz / 2 = 50MHz // 使能 UART0 时钟 MSS_UART0_CLOCK_ENABLE(); }

如果MSS_APB0_CLOCK_DIV设成 1,UART 时钟变成 100MHz,而波特率寄存器是按 50MHz 算的,结果就是实际波特率翻倍,终端收到乱码。排查方法:用示波器量 TX 引脚,如果位宽是预期的一半,就是这里的问题。

3.3 烧录与终端连接

编译通过后,用 FlashPro 烧录.stp文件到 SmartFusion。烧录时注意:

  • 模式选择“MSS 编程”,不是“FPGA 编程”
  • 如果板子上有 JTAG 和 SWD 两种接口,确认例程用的是哪种
  • 烧录完成后给板子断电再上电,有些批次需要冷启动才生效

终端这边,Windows 下用串口助手,Linux 下用minicom或screen:

# Linux 下连接串口 sudo screen /dev/ttyUSB0 115200

如果终端里只看到乱码,先检查波特率、数据位、停止位、校验位是否和代码一致。如果完全没输出,用示波器量 TX 引脚,没波形就是引脚绑错或时钟没使能。

4. 避坑与排查:串口不通时先看这五条

4.1 现象:终端无任何输出,TX 引脚也无波形

原因:MSS UART 时钟未使能,或者引脚绑到了 FPGA 普通 IO 而非 MSS 专用引脚。

解决:检查sys_config.c里有没有MSS_UART0_CLOCK_ENABLE();检查.pdc里绑定的引脚号是否在数据手册的 MSS UART 可选引脚列表内。常见错误是把 TX 绑到了 FPGA 的 bank 0 引脚,那些引脚只能做普通 IO。

4.2 现象:有波形但终端全是乱码

原因:波特率不匹配。要么时钟分频算错,要么终端设置和代码不一致。

解决:用示波器量一个字符的位宽。115200 波特率下,一位约 8.68μs,一个字节(8N1)约 86.8μs。如果量出来是 43.4μs,说明实际波特率是 230400,检查MSS_APB0_CLOCK_DIV是否设成了 1 而非 2。

4.3 现象:能收到字符但丢数据,长字符串尤其明显

原因:接收 FIFO 溢出。中断里处理太慢,或者没及时清中断标志。

解决:把UART_clear_irq放在读数据之后;如果主循环里有长延时,考虑加大 FIFO 触发阈值,或者用 DMA 搬运。SmartFusion 的 MSS UART 有 16 字节 FIFO,触发阈值可设 1/4、1/2、3/4。

4.4 现象:烧录后第一次上电正常,复位后就不行了

原因:复位后时钟配置丢失,或者.pdc约束没被正确加载。

解决:检查启动文件里有没有在main()之前重新配置时钟;有些例程把时钟配置放在SystemInit()里,如果你换了启动文件,这段可能被覆盖。另外确认 FlashPro 烧录时勾选了“MSS 配置”而非仅“FPGA 配置”。

4.5 现象:Libero 编译报错“Cannot find constraint file”

原因:.pdc文件路径变了,或者工程升级后约束文件后缀被改。

解决:在 Libero 的“Design Flow”里手动重新添加约束文件,指向constraints/uart_demo.pdc。如果文件被升级工具改成了.pdcx,改回.pdc或重新绑定引脚。

5. 二次开发:从回显到自定义协议

5.1 改波特率与数据格式

例程默认 115200-8N1,要改成 9600 或加校验位,改UART_init的参数即可:

// 改成 9600 波特率,7 数据位,偶校验,2 停止位 UART_init(UART0, 9600, DATA_7BIT, PARITY_EVEN, STOP_2BIT);

但注意:改完波特率后,MSS_APB0_CLOCK_DIV可能也要跟着调。SmartFusion 的 UART 波特率计算公式是:

波特率 = APB0时钟 / (16 × (波特率分频值 + 1))

如果 APB0 是 50MHz,要 9600 波特率,分频值约 324。驱动里通常有自动计算函数,但如果你手改寄存器,得自己算。

5.2 加一个简单的命令解析

回显只是起点,实际项目里往往要解析命令。比如收到LED ON就点亮板子上的 LED:

#define CMD_BUF_SIZE 32 static char cmd_buf[CMD_BUF_SIZE]; static uint8_t cmd_idx = 0; void UART0_IRQHandler(void) { uint8_t rx_data; if (UART_get_irq_status(UART0) & UART_RX_IRQ_FLAG) { rx_data = UART_receive_byte(UART0); // 收到回车表示一条命令结束 if (rx_data == '\r' || rx_data == '\n') { cmd_buf[cmd_idx] = '\0'; // 解析命令 if (strcmp(cmd_buf, "LED ON") == 0) { GPIO_set_pin(LED_GPIO, 1); UART_send_string(UART0, "LED is ON\r\n"); } else if (strcmp(cmd_buf, "LED OFF") == 0) { GPIO_set_pin(LED_GPIO, 0); UART_send_string(UART0, "LED is OFF\r\n"); } else { UART_send_string(UART0, "Unknown command\r\n"); } cmd_idx = 0; // 清空缓冲区,准备下一条 } else { // 普通字符存入缓冲区,防止溢出 if (cmd_idx < CMD_BUF_SIZE - 1) { cmd_buf[cmd_idx++] = rx_data; } } UART_clear_irq(UART0, UART_RX_IRQ_FLAG); } }

这段代码里,cmd_idx的边界检查很关键。如果不检查,收到超长字符串就会写穿cmd_buf,导致 HardFault。我一般会把CMD_BUF_SIZE设成 2 的幂次,方便后续用环形缓冲区替换。

5.3 用 FPGA 侧逻辑做硬件流控

SmartFusion 的 MSS UART 支持 RTS/CTS 硬件流控,但前提是 FPGA 侧把对应引脚配好。在top.v里:

module top( input wire UART0_RXD, output wire UART0_TXD, output wire UART0_RTS, input wire UART0_CTS ); // MSS UART 信号直连到顶层引脚 // 注意:MSS 外设信号在 Libero 里需要显式例化 MSS_UART uart_inst( .RXD(UART0_RXD), .TXD(UART0_TXD), .RTS(UART0_RTS), .CTS(UART0_CTS) ); endmodule

然后在.pdc里把UART0_RTS和UART0_CTS绑到物理引脚。硬件流控开启后,接收方 FIFO 快满时拉高 RTS,发送方检测到 CTS 变高就暂停发送。这个机制在高速率(如 921600)下尤其有用,能避免丢包。

5.4 验证方法:用 Python 脚本做自动化测试

改完代码后,手动敲命令测试效率低。我一般写个 Python 脚本自动发命令、收响应:

import serial import time # 打开串口,超时设 1 秒 ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1) time.sleep(0.5) # 等板子启动 # 发命令并读响应 def send_cmd(cmd): ser.write((cmd + '\r').encode()) time.sleep(0.1) response = ser.read_all().decode(errors='ignore') return response.strip() # 测试 LED 命令 print(send_cmd('LED ON')) # 期望输出:LED is ON print(send_cmd('LED OFF')) # 期望输出:LED is OFF print(send_cmd('HELLO')) # 期望输出:Unknown command ser.close()

这个脚本能快速回归测试,改完中断逻辑或命令解析后跑一遍,确认没破坏原有功能。注意time.sleep(0.1)是给板子留处理时间,如果命令复杂可以加大。

5.5 一个容易忽略的细节:中断优先级

SmartFusion 的 Cortex-M3 支持嵌套中断。如果串口中断优先级设得太低,被其他中断(比如定时器)打断,接收 FIFO 可能溢出。在UART_enable_irq之后加一句:

NVIC_SetPriority(UART0_IRQn, 1); // 设成较高优先级

具体优先级数值取决于你的系统里有多少中断源。我一般把串口设成 1 或 2,定时器设成 3,这样串口能及时响应。

从那以后我每次调 SmartFusion 串口,都强制走一遍“示波器量 TX → 确认波特率 → 检查 .pdc 引脚 → 跑 Python 回归脚本”的流程,少一步都可能翻车。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

Pikachu靶场实战:暴力破解与验证码绕过全解析

Pikachu靶场实战:暴力破解与验证码绕过全解析

1. 先说清楚&#xff1a;这个模块到底在演练什么暴力破解&#xff0c;很多刚接触安全测试的朋友会觉得"这不就是拿个字典一直撞吗"&#xff0c;但真到自己上手的时候&#xff0c;往往会卡在三个地方&#xff1a;第一不知道爆破目标是什么&#xff0c;第二不知道爆破结…

2026/10/19 17:08:28 阅读更多 →
万可GSDML文件解析:750/753系列组态与IO地址分配实战

万可GSDML文件解析:750/753系列组态与IO地址分配实战

简介&#xff1a;这份资源是德国万可&#xff08;WAGO&#xff09;公司为750与753系列数字输入输出扩展模块提供的GSD硬件配置文件包&#xff0c;版本号为V2.33&#xff0c;发布日期为2021年1月15日&#xff0c;面向从事工业自动化系统集成与设备组态的工程师及技术人员。GSD文…

2026/10/19 17:08:28 阅读更多 →
提示词工程进阶路线:从结构化设计到大师级工程化管理

提示词工程进阶路线:从结构化设计到大师级工程化管理

讲个真实场景&#xff1a;你是不是也收藏过十几个“提示词合集”&#xff0c;里面贴着上百条据说“封神”的模板&#xff0c;真到要用的时候翻来翻去却找不到一条能直接改来用的&#xff1f;或者更尴尬一些——你照着模板改了几个字&#xff0c;结果AI给出的答案驴唇不对马嘴&a…

2026/10/19 17:07:28 阅读更多 →

最新新闻

YOLO26轻量化优化:DualConv双卷积替换主干,mAP涨1.3且参数降27%

YOLO26轻量化优化:DualConv双卷积替换主干,mAP涨1.3且参数降27%

跑完新一轮YOLO26优化实验&#xff0c;我先把结论扔到前面&#xff1a;用轻量化双卷积DualConv替换掉主干网络里一部分标准卷积之后&#xff0c;模型mAP50-95涨了1.3个点&#xff0c;同时参数量从12.9M掉到9.4M&#xff0c;计算量从18.7G降到12.3G。这不是靠蒸馏&#xff0c;也…

2026/10/19 17:39:45 阅读更多 →
开源代码评审工作流:协议驱动的可审计人机协同范式

开源代码评审工作流:协议驱动的可审计人机协同范式

1. 项目概述&#xff1a;这不是一个工具&#xff0c;而是一套可落地的开源代码评审工作流“open-code-review”这个名称乍看像某个具体软件或CLI命令&#xff0c;但实际它代表的是一种正在快速演化的工程实践范式——把传统依赖人工、会议、PR评论的代码评审&#xff08;Code R…

2026/10/19 17:39:45 阅读更多 →
开源CLI代码评审系统:基于LLM Agent的自动化Code Review实践

开源CLI代码评审系统:基于LLM Agent的自动化Code Review实践

1. 这不是又一个“AI写代码”工具&#xff0c;而是一套可嵌入开发流程的开源代码评审系统最近在几个技术团队内部做工具链调研时&#xff0c;发现一个有意思的现象&#xff1a;大家嘴上说着“用AI做code review”&#xff0c;但实际落地时&#xff0c;90%的人还在把diff粘贴进C…

2026/10/19 17:39:45 阅读更多 →
两相流THM热流固耦合建模:COMSOL收敛与求解器配置指南

两相流THM热流固耦合建模:COMSOL收敛与求解器配置指南

简介&#xff1a;基于COMSOL构建的两相流THM热流固耦合模型&#xff0c;面向石油工程、地热开发及二氧化碳地质封存等复杂多物理场耦合问题&#xff0c;适合从事渗流力学与岩土工程仿真的科研人员、工程师与研究生。模型以饱和水和油两相流动为核心&#xff0c;支持温度场—渗流…

2026/10/19 17:39:45 阅读更多 →
基于SpringBoot+Vue的校园管理系统毕业设计实战拆解

基于SpringBoot+Vue的校园管理系统毕业设计实战拆解

毕业设计想选校园管理系统、又不想纯手工从零搓代码的同学&#xff0c;我建议直接找一个 SpringBoot Vue 的前后端分离项目来二次开发&#xff0c;这是目前最稳妥、也最适合拿高分的路子。这套技术栈基本是 Java Web 方向毕设的标配&#xff0c;覆盖了后端接口开发、前端页面交…

2026/10/19 17:39:45 阅读更多 →
RGAT+GRU融合模型解决APT溯源图稀疏漏报问题

RGAT+GRU融合模型解决APT溯源图稀疏漏报问题

简介&#xff1a;本资源是华中科技大学2023届计算机相关专业&#xff08;如计科、人工智能、网络安全等&#xff09;优秀毕业设计成果&#xff0c;聚焦APT攻击检测这一前沿安全问题&#xff0c;提出并实现了一种基于溯源图建模与RGATGRU融合架构的检测方法优化方案。面向在校本…

2026/10/19 17:38:44 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →