news 2026/10/2 1:25:11

STM32+LAN8720A以太网模块设计:从原理图到LWIP移植实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32+LAN8720A以太网模块设计:从原理图到LWIP移植实战

嵌入式项目里一旦需要联网,很多人第一反应就是上W5500或者ESP8266。但如果你手里已经有STM32F407、F429这类带MAC控制器的芯片,那用LAN8720A搭以太网通信模块其实是性价比最高、性能也最稳的一条路,这也是很多工业产品、物联网网关、边缘计算设备里最常见的硬件组合之一。

这篇内容我就结合自己开发过程中的实际经验,完整梳理一遍STM32+LAN8720A从原理图设计到LWIP协议栈通信的整个流程。核心思路是:先用通俗的方式讲清楚MAC和PHY是什么、为什么这么搭,再一步步画出RMII接口的原理图,最后把软件配置、LWIP移植、调试踩坑全部过一遍。不管你是刚接触以太网的新手,还是准备给现有项目加一个有线网口的开发者,这篇内容都可以直接当作“抄作业”的参考。

1. 方案选型与整体设计思路

1.1 为什么是STM32+LAN8720A:先从MAC和PHY说起

先解决一个很多人一开始会搞混的问题:网络通信到底需要什么硬件?

以太网通信接口从逻辑上分两层,一是MAC层(媒体访问控制层),负责数据帧的封装、错误检测、流量控制;二是PHY层(物理层),负责把MAC层处理好的数字信号转换成能在网线上传输的模拟差分信号。打个比方,MAC层相当于你写好了一封信,PHY层就是邮递员,负责把信按特定方式塞进邮筒、走邮路送出去。

有些芯片把这两层做在一起,比如W5500,它内部有硬件TCP/IP协议栈,单片机通过SPI跟它通信,省心但灵活性一般。而STM32F407、STM32F429、F767这些芯片,内部已经集成了符合IEEE 802.3标准的MAC控制器,只是没有物理层电路。所以只需要外接一颗PHY芯片,比如LAN8720A,用RMII接口把两边连起来就行。

为什么要选LAN8720A?因为它在同类PHY芯片里实在太常见了。ST官方的不少评估板、正点原子、野火这些主流开发板都是用这颗芯片,资料多、例程全、价格便宜,还支持10M/100M自适应。相比DP83848、KSZ8081这些同类芯片,LAN8720A在功耗和外围电路复杂度上更有优势,一颗25MHz晶振加几个电容电阻就能跑起来,对新手非常友好。

1.2 接口选择:MII、RMII还是SPI?RMII为什么最适合

PHY和MAC之间的数据接口有几种常见的:MII、RMII、GMII、RGMII。对我们用的100M以太网来说,MII和RMII是主要选择。

MII接口需要16根数据线,发送8根、接收8根,加上控制信号大约二十几根引脚,对MCU引脚压力很大。而RMII(Reduced Media Independent Interface,精简媒体独立接口)把数据线砍到了4根,发送2根、接收2根,加上时钟和控制信号,总共也就七八根线,大大解放了PCB布局空间和GPIO资源。

代价是什么呢?RMII模式下数据位宽变窄,所以时钟频率必须从25MHz提高到50MHz,也就是每一位数据只占用一个时钟周期。这就引入了RMII一个关键要求:MAC和PHY必须使用同一个50MHz参考时钟源,否则接收端采样会发生漂移,导致数据错乱。

在实际项目里,我强烈建议直接用RMII,原因很简单:引脚少、原理图好画、STM32CubeMX配置快、性能完全够100Mbps跑满。至于MII,除非你有特殊需求,否则没必要碰。

2. 原理图拆解与关键设计细节

2.1 模块结构总览和器件清单

整个以太网通信模块的原理图可以分成几个板块:STM32的ETH外设、LAN8720A PHY芯片、25MHz晶振或外部时钟、网络变压器、RJ45连接器、供电与复位电路。

下面是一份典型的器件清单,按这个准备物料基本不会出错:

模块器件型号/参数数量说明
主控STM32STM32F407VET61带MAC控制器,100脚
PHYLAN8720ALAN8720A-CP110/100M以太网PHY
晶振25MHz无源晶振±10ppm以内1接XTAL1/XTAL2
连接器带变压器RJ45HR911105A1集成网络隔离变压器
供电3.3V LDOAMS1117-3.3或同类1给PHY和电路供电
退耦电容0.1uF/10uF若干PHY电源引脚滤波
复位电容电阻10K+0.1uF1产生PHY上电复位脉冲

这个清单里最值得留意的是RJ45连接器选型。市面上RJ45分为两类,一类是自带网络变压器的,比如HR911105A;另一类是纯机械连接器,需要外接单独的变压器,比如H1102。新手画原理图建议选集成变压器的一体式座子,外围电路简单,画完板子焊接也方便,不容易因为变压器绕线方向搞错而翻车。

2.2 时钟方案设计:25MHz晶振方案与外置50MHz方案怎么选

这是LAN8720A设计里最容易出错的地方,我单独拿出来讲。

LAN8720A有三种时钟输入模式,对应三种硬件接法:

方案A:25MHz无源晶振接XTAL1/XTAL2(最推荐)

这是最经典的方案。25MHz晶振接在LAN8720A的XTAL1和XTAL2引脚之间,PHY内部自带的PLL会把25MHz倍频到50MHz,然后通过REF_CLK引脚输出给STM32的ETH_REF_CLK。也就是说,STM32这边只需要把PA1引脚配置成输入模式,等着接收PHY送来的50MHz时钟即可。

为什么这套方案最省心?首先,25MHz无源晶振是最常见的规格,采购容易、价格便宜;其次,PHY内部PLL产生的时钟经过整形,信号质量有保障;最后,STM32的时钟树不会受任何牵连,主频随便配,不用操心MCO输出的联动关系。

方案B:STM32的MCO引脚输出50MHz给PHY

这种方案的思路是省掉PHY侧单独的一颗晶振,由STM32的MCO1引脚(PA8)输出50MHz时钟,直接接到LAN8720A的REF_CLK/CLKIN引脚。此时LAN8720A工作在外部时钟输入模式,XTAL1不再接晶振。

这个方案在ST官方一些示例代码里确实出现过,CubeMX的ETH配置里也有MCO选项,但实际踩下来有几个坑:一是MCO的输出频率和主频PLL配置强相关,一旦你想调整主频,得重新算PLL分频系数,非常容易配错;二是MCO是CMOS方波输出,驱动能力有限,如果PCB走线过长,时序余量会变差;三是如果MCO和PHY的时钟线没有做等长、阻抗控制,丢包概率会上升。

方案C:外部50MHz有源晶振单独供给PHY

这个方案可以理解为方案B的变体,用一颗50MHz有源晶振提供高品质时钟,LAN8720A再把时钟从REF_CLK回送给STM32的ETH_REF_CLK。信号质量比MCO好,但多花钱、多占PCB面积,一般在要求特别高的场合才会用。

我的结论是:如果没有特殊原因,直接用方案A。这也是目前绝大多数开发板的做法,原因就是稳定、成熟、不折腾。

2.3 电源电路:3.3V与1.2V核心电压的处理

LAN8720A的供电相对简单,因为芯片内部集成了一个1.2V稳压器,型号叫REG_OUT,外部不需要额外设计1.2V电源电路。你需要做的是:

  • 给VDD引脚(3.3V)各放一个0.1uF去耦电容,紧靠引脚放置;
  • 给模拟电源引脚和数字电源引脚分开走线,最后在电源入口处汇合;
  • REG_OUT引脚接0.1uF和10uF电容到地,这就是内部1.2V的输出去耦;
  • 变压器中心抽头的供电,也就是PLL和模拟前端用的AVDD,同样加去耦电容。

还有一个时容易忽略的点:LAN8720A的电源有个上电时序要求,即VDD必须先于或同时于其他IO电源建立。如果PCB上用LDO统一供电,通常自然满足,但如果你用DC-DC,要关注一下启动时电源爬升情况,防止PHY莫名其妙进入异常状态。

2.4 PHY地址、复位电路与RMII信号线连接

原理图电气连接是整个模块的核心。RMII接口的信号线不多,我直接列一张表,方便对照着接:

信号STM32引脚LAN8720A引脚功能说明
REF_CLKPA1REF_CLK50MHz参考时钟,由PHY输出给MAC
MDIOPA2MDIO管理数据输入输出
MDCPC1MDC管理时钟,由MAC输出
CRS_DVPA7CRS_DV载波侦听/数据有效
RXD0PC4RXD0接收数据位0
RXD1PC5RXD1接收数据位1
TX_ENPB11TX_EN发送使能
TXD0PG13TXD0发送数据位0
TXD1PG14TXD1发送数据位1
nRST任意GPIO(如PD3)nRST硬件复位,低有效

这里特别注意三个点:

第一,PHY地址。LAN8720A的PHY地址由REF_CLKIN/PHYAD0引脚和nINTSEL/PHYAD1引脚在上电复位时的电平决定。我的原理图中把PHYAD0通过10K下拉接地,PHYAD1通过10K上拉到3.3V,这样PHY地址就是二进制的01,也就是0x01。不同开发板设计可能不一样,有的是0x00,所以软件里配置的PHY地址必须和你的原理图一致,这是很多新手上电后读写MDIO全都失败的原因之一。

第二,复位电路。LAN8720A的nRST引脚需要拉低至少1ms才能可靠复位。我一般不用纯粹的RC复位,而是用STM32的普通GPIO来控制PHY复位,这样可以在软件里灵活地做复位时序:上电后拉低nRST、延时、拉高、再延时等PHY稳定。PD3作为复位控制引脚,初始化时默认输出高电平。

第三,网络变压器连接。以HR911105A为例,RJ45这一侧,差分发送对接到PHY的TX+/TX-引脚,差分接收对接到RX+/RX-引脚。PHY侧的中心抽头按照LAN8720A数据手册要求接3.3V,同时并联一个0.1uF电容到地;RJ45侧中心抽头通过RC并联网络接地,用于EMI滤波。连接器的金属屏蔽壳也要可靠接地,这能明显改善网口的抗静电能力。

3. 硬件焊接与初始化验证

3.1 焊接要点与上电检查

原理图画完、PCB打样回来之后,第一步不是烧代码,而是先检查硬件焊接质量。

LAN8720A是QFN封装,底部有散热焊盘,手工焊接建议先用热风枪把焊盘吹平,再用拖焊法处理引脚,最后用万用表逐个测量引脚间有没有连锡短路。特别注意REF_CLK引脚,这个引脚如果虚焊,现象非常隐蔽:晶振起振、PHY其它寄存器也能读,但MAC收不到数据,因为时钟根本没有到达STM32。

上电后的静态检查按这个顺序来:

  1. 用万用表测LAN8720A的3.3V电源是否正常;
  2. 用万用表测REG_OUT引脚是否输出1.2V左右电压,如果这个电压异常,说明芯片内部稳压器工作不正常;
  3. 用示波器看25MHz晶振是否有波形,幅度一般在0.8V到3.3V之间;
  4. 检查RJ45的Link指示灯有没有动作。插上网线后,Link灯应该会亮起来,Speed灯会指示协商速率是100M还是10M。

这一步看起来很基础,但能帮你把“硬件问题”和“软件问题”在第一时间隔离开,避免后面调试时两头抓瞎。

3.2 用STM32CubeMX快速配置ETH外设

硬件没问题后,进入软件配置阶段。我用STM32CubeMX为例演示,因为它生成的初始化代码非常省事。

在CubeMX里选好MCU型号(比如STM32F407VET6),然后做以下几步:

第一步,开启ETH外设。在Pinout页面找到ETH,设置为RMII模式。打开后,CubeMX会自动把PA1、PA2、PA7、PC1、PC4、PC5、PB11、PG13、PG14这些引脚复用为ETH功能。

第二步,配置时钟树。ETH外设本身需要50MHz的参考时钟输入,如果是25MHz晶振方案,这个50MHz是PHY送过来的,所以CubeMX里ETH时钟来源选择External即可。同时打开ETH的DMA接收中断或全局中断,方便后续LWIP及时处理数据包。

第三步,设置PHY地址。在ETH参数配置里找到PHY Address,填写和原理图一致的地址。我的板子设的是0x01,如果你的PHYAD0是下拉,那就是0x00。这一步错误会让你后面读取PHY ID全部失败。

第四步,生成工程代码。生成的代码里已经包含ETH初始化、GPIO复用配置、DMA描述符初始化,不需要自己再写底层的寄存器操作,非常省时间。

3.3 先做物理层环回测试:验证PHY芯片工作

在移植LWIP之前,我强烈建议先做一次PHY物理层的环回测试。这个测试的目的很简单:验证MCU的MAC和LAN8720A之间的数据路径是否通畅。

方法是往PHY的控制寄存器(寄存器0,也就是BMCR)写入0x4000,开启Digital Loopback模式。这样数据从MAC发出来,经过PHY之后不往网线上走,而是直接原路返回到MAC的接收通道。

配套的测试代码思路是这样的:MCU通过内部DMA发一个自定义的以太网帧,然后等待接收中断,如果收回来的帧内容和发出去的一致,说明MAC到PHY这一段通路完全正常。CubeMX生成的以太网驱动里通常有现成的检查PHY ID函数,比如HAL_ETH_ReadPHYRegister,可以先读寄存器2和3,确认读到的PHY ID是0x0007C0F1,这一步过了就说明MDIO通信没问题。

这个测试可以过滤掉大量后期疑难杂症。如果环回测试能过,物理层基本稳了,后面LWIP跑不通大概率就是协议栈配置问题。如果环回测试都过不了,趁早回到硬件去查,别急着调协议栈。

4. LWIP协议栈移植与网络测试

4.1 LWIP选择:NO_SYS还是RTOS

物理层验证通过后,接下来就是让以太网真正跑起来,核心工作是移植LWIP协议栈。

LWIP是一个开源的轻量级TCP/IP协议栈,专门为嵌入式系统设计,也是STM32生态里最常用的选择。用CubeMX生成代码时,可以直接在Middleware里勾选LWIP,它会自动把协议栈源码和适配层代码集成好。

LWIP有两种运行模式,一种是无操作系统的NO_SYS模式,另一种是配合RTOS的多线程模式。

如果你的项目里没有跑RTOS,或者只是做简单测试,直接用NO_SYS模式就够了。这种模式下,整个协议栈在主循环里通过MX_LWIP_Process()函数周期性地轮询处理网络数据包,代码简单、内存占用小,适合CPU资源不紧张的场景。

如果你的项目用了FreeRTOS或者RT-Thread,那建议开RTOS模式。LWIP在RTOS模式下会为协议栈创建专用的tcpip线程,使用邮箱和信号量跟应用线程通信,网络收发的实时性更好,不容易因为某个应用层函数的阻塞而影响协议栈处理。

4.2 关键配置项:IP地址、MAC地址与内存池

在CubeMX的LWIP配置页面,有几个参数看起来不起眼,实际对稳定性影响巨大。

第一个是IP地址、子网掩码、网关。我测试阶段直接用静态IP,比如IP设为192.168.1.10,掩码255.255.255.0,网关192.168.1.1。如果要用DHCP动态获取,需要确保LWIP的DHCP选项开启,并且你的网络上确实有DHCP服务器,否则设备会一直处于获取不到地址的状态。

第二个是MAC地址。每个以太网设备的MAC地址必须是全球唯一的,不能和同一局域网内的其它设备重复。在测试阶段,建议设置成类似02:00:11:22:33:44这种本地管理地址,避免和某些设备的厂商前缀冲突。

第三个是内存池的大小。LWIP需要为数据包分配内存,核心参数是MEM_SIZE、PBUF_POOL_SIZE。如果设置太小,高负载下会出现丢包;设置太大,又会浪费RAM。以STM32F407VET6的192KB RAM来说,MEM_SIZE设为1600字节左右、PBUF_POOL_SIZE设成10到16个,足够跑一个轻量级TCP服务器。

第四个是PHY地址。在LWIP的eth.c或类似适配文件里,会有一个PHY地址的宏定义,比如STM32_PHY_ADDRESS。这个必须和你在CubeMX ETH配置里填的保持一致。我调试时踩过一次坑,CubeMX里填0x00,但LWIP适配层写死0x01,结果就是两个模块各读各的,PHY始终处于异常状态。

4.3 Ping通、TCP通信与简单HTTP服务器的实现

配置生成代码之后,第一步当然是验证最基本的网络连通性:Ping。

烧录程序后,把开发板的网口用网线直连电脑,把电脑的有线网卡IP设置成同一个网段,比如192.168.1.2,然后打开命令行执行:

ping 192.168.1.10

如果一切正常,你应该能看到来自192.168.1.10的回复。这里有一个判断技巧:如果Ping请求超时,不要急着去查TCP/IP,先确认Link灯是否亮、速率是否协商到100M,再用逻辑分析仪抓一下RMII信号看有没有数据,一步一步缩小范围。

Ping通之后,网络底层的收发通道已经没问题了,接下来就可以加应用层。最常用的测试是TCP服务器。用LWIP的RAW API实现一个简单的TCP Server,监听8080端口,当有客户端连接进来时,把收到的数据原样回传(也就是回环服务器)。用电脑端的网络调试助手就可以直接测试。

如果想把演示效果做得更直观,可以接着实现一个HTTP服务器。原理也不复杂,用LWIP的HTTPD模块,把网页内容做成数组或者放在文件系统里,当浏览器访问设备IP时,MCU返回一个HTML页面,页面上可以实时显示CPU温度、ADC采样值或者某个GPIO的状态。这个功能在毕业设计和项目演示里非常加分。

5. 踩坑实录与排查技巧

5.1 常见问题速查表

做以太网通信模块,最耗时间的往往不是原理设计和代码编写,而是出问题之后的排查过程。我把这些年踩过的坑整理成一个速查表,方便你按图索骥:

现象可能原因检查项与解决办法
Link灯不亮网线/RJ45焊接问题、变压器中心抽头接错、PHY供电异常换网线、用万用表查PHY电压、核对变压器接线
MDIO读不到PHY IDPHY地址配置错误、MDIO引脚虚焊、PHY未复位核对PHYAD0/PHYAD1上下拉、确认nRST时序、检查MDC/MDIO波形
晶振不振晶振负载电容不匹配、芯片虚焊换晶振、改负载电容值、用示波器直接测XTAL1/XTAL2
只有本机Ping通设备,外部不通PHY开启了Digital Loopback检查PHY寄存器0,确保没有写入0x4000
PING丢包严重时钟质量差、RMII走线太长、电源纹波大检查50MHz信号质量、缩短走线、加强电源滤波
协商速率只有10MTX/RX差分线极性接反、变压器抽头接错检查PHY到RJ45的1/2、3/6线序
初始化挂死PHY地址错误、软件复位循环等待超时核对PHY地址、看HAL_ETH_Init返回值

这张表不能覆盖所有情况,但覆盖了绝大多数初级项目中会出现的问题。

5.2 时序问题的排查:时钟不准导致丢包

在所有以太网问题里,最隐蔽、最让人崩溃的就是“Ping能通但丢包”这类时序问题。因为这不是完全不通,而是间歇性丢包,很容易让人误以为是软件问题,反复调LWIP配置却毫无进展。

实际排查下来,根因往往出在50MHz参考时钟上。RMII标准对时钟精度要求很严格,通常要求50MHz的误差在正负50ppm以内,而且占空比不能太差。如果你用的是MCO输出方案,主频PLL配置稍微偏一点,MCO频率就不是精确的50MHz,丢包率就会明显上升。

另一个隐蔽问题就是时钟相位。RMII模式不要求MAC和PHY的参考时钟严格同相,但要求它们的时钟是同一个来源。如果你的设计用了两个独立晶振分别给MAC和PHY供时钟,即使频率都是50MHz,只要有微小频偏,长时间运行后采样点就会漂移,表现为丢包率随时间缓慢增长。所以,务必保证MAC和PHY参考时钟同源,这是我反复强调的一点。

排查方法:用示波器或频率计测REF_CLK引脚的频率和占空比,确认是50MHz、占空比尽量接近50%。如果频率偏差超过0.01%,就要回头改时钟配置。

5.3 关于性能与稳定性的几点补充

最后再说几个和长期稳定性相关的细节。

第一,DMA描述符数量。CubeMX默认生成的ETH DMA描述符数量是4个RX和4个TX,在高吞吐量场景下不太够。我一般把RX描述符增加到8个,可以在一定程度上缓冲数据风暴时的压力。修改后注意LWIP的PBUF_POOL也要相应匹配,避免内存不足。

第二,中断优先级。ETH的中断优先级如果设得过高,可能频繁打断其它关键任务;设得太低,又可能导致网络数据包处理延迟。一般建议把ETH中断优先级设在中等偏高的水平,同时确认LWIP的tcpip线程优先级合适。实际项目中,我习惯把ETH中断设置为比系统心跳略高的优先级,既能及时收包,又不会把低优先级任务饿死。

第三,发热问题。LAN8720A本身功耗不高,但如果长时间高负载跑100Mbps全双工,芯片会轻微发热,这属于正常现象。如果你的产品有散热要求,可以在PCB上给PHY芯片的散热焊盘预留过孔,连接到地平面,帮助导热。

第四,静电防护。如果你的板子要接到工业环境,RJ45的金属壳必须可靠接地,最好在差分线对上并联TVS管,比如PESD1ETH或同类器件。否则雷击浪涌或者静电脉冲很可能直接打坏PHY芯片,这种损坏是不可逆的,返修成本很高。

结尾

关于STM32+LAN8720A,我最后想分享的一点个人体会是:这个方案的本质并不复杂,真正难的在于把每一个细节都抠到位。原理图阶段把时钟方案定清楚、把PHY地址固化下来,硬件阶段把电源和信号质量弄扎实,软件阶段老老实实按物理层环回、Ping、TCP这样的节奏一步步验证,绝大部分问题都能在早期被拦截住。

如果你按照这篇内容从头到尾操作一遍,大概率能在半天之内跑通网络通信。后续想扩展的话,还可以在这个基础上加MQTT上云、TFTP固件升级、SNMP设备管理这些功能,底层通信架构完全不需要改动。希望这篇文章能帮你少走一些弯路,祝你一次点亮。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 1:24:32

GCC O2优化原理与工程实践:从编译器视角理解性能与正确性

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

作者头像 李华
网站建设 2026/10/2 1:23:37

TexGen导出ABAQUS的inp文件没有材料?三步补齐材料定义实战指南

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

作者头像 李华
网站建设 2026/10/2 1:23:32

Project与Office 365冲突排查指南:从文件锁到许可证的全面解析

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

作者头像 李华
网站建设 2026/10/2 1:22:46

HDMI-CEC实战指南:从物理层到Android框架的全链路调试

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

作者头像 李华
网站建设 2026/10/2 1:22:36

Nav2参数调优实战:从nav2_params.yaml读懂每个关键参数

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

作者头像 李华
网站建设 2026/10/2 1:22:14

OpenCV实战:USB摄像头图像采集与参数配置全攻略

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

作者头像 李华