news 2026/9/25 2:08:24

STM32环境监测项目全套开源:代码、原理图与仿真

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32环境监测项目全套开源:代码、原理图与仿真

做嵌入式这几年,最烦的一件事就是:网上找了半天,终于看到一个看着不错的STM32项目,结果要么只有代码没有原理图,要么原理图画得乱七八糟,跟代码根本对不上。更别提仿真的东西了,十个开源项目里能有一个带仿真就算运气好。所以这次我把一个完整可跑的环境监测项目全套开源出来:代码、原理图、仿真三件套齐活。主控用的最常见的STM32F103C8T6,搭配DHT11温湿度传感器和HC-SR04超声波测距模块,数据实时显示在0.96寸OLED屏上,两个按键切换页面,一个蜂鸣器做距离报警,串口同时把数据吐给电脑上位机。适合正在做课程设计、毕业设计,以及刚入门嵌入式想找一份完整参考项目的老哥直接抄作业。

先说一下这个项目开源的范围和价值。代码是基于标准外设库写的,从GPIO配置到传感器驱动全部手撸,没有用CubeMX一键生成,所以每一行都能看懂。原理图用嘉立创EDA画的,包含了最小系统、电源、传感器接口、蜂鸣器驱动这些完整模块,不是那种网上流传的残缺图。仿真部分我做了两套:一套在Wokwi在线平台跑逻辑验证,一套在Proteus里跑电路仿真。你要是想复现,手里只要有块十几块钱的STM32F103C8T6蓝板或者核心板就能上手,成本撑死五十块。

1. 项目整体设计与规划思路

1.1 需求拆解与功能定位

很多人拿到一个项目就开始写代码,这是错误的。我习惯先把需求拆成功能点,再对照着做技术选型。这个环境监测终端最核心的功能有四块:采集温湿度、测量障碍物距离、本地显示、数据上报。围绕这四个功能,我把系统分成传感器层、处理层、展示层和输出层,层次之间通过明确的接口解耦。

  • 传感器层:DHT11负责温湿度采集,HC-SR04负责超声波测距,两者都是嵌入式入门最常见的传感器,资料多、便宜、驱动逻辑有代表性。
  • 处理层:STM32F103C8T6做主控,负责传感器时序驱动、数据计算、按键扫描、页面状态切换。
  • 展示层:0.96寸OLED屏幕,I2C接口,SSD1306驱动芯片,实时显示当前温湿度和距离。
  • 输出层:串口1接到电脑,用printf把数据格式化打印出来,方便调试和二次开发。

这样拆完,每个模块的职责就很清晰了。你在写代码的时候,不会出现"这个变量到底是给谁用的"这种混乱。后续不管是加蓝牙、加Wi-Fi模块,还是在OLED上增加图标,都只要在对应的层里改动就行。这个架构本身也是面试时能拿出来讲的亮点:说明你有模块化设计的意识,不是把代码堆一坨。

1.2 芯片选型与外设资源规划

选STM32F103C8T6不是因为它强,而是因为它够用且皮实。这颗芯片有64KB Flash、20KB RAM,主频72MHz,价格在正规渠道不过十块钱上下,开发板和学习资料多得离谱。对于这个项目,20KB RAM跑几个传感器加OLED绰绰有余,64KB Flash塞下整个标准库工程也毫无压力。

选完芯片,紧接着要做的一件事是引脚分配。GPIO资源是嵌入式项目的硬约束,分配不好后期要么飞线要么改板子,极其痛苦。这个项目的引脚分配如下,我直接放表给大家抄:

外设引脚说明
DHT11 数据线PB0单总线,需要上拉电阻
HC-SR04 TRIGPA0触发信号,输出10us以上高电平
HC-SR04 ECHOPA1回波信号,输入捕获/电平检测
OLED SCLPB10I2C时钟线
OLED SDAPB11I2C数据线
蜂鸣器PB12低电平驱动或加三极管
按键KEY1PB13页面切换,内部上拉
按键KEY2PB14报警开关,内部上拉
串口1 TX/RXPA9/PA10调试与数据上报

这里有个容易被新手忽略的细节:分配引脚时要观察芯片手册里的复用功能冲突表。比如你既要使用串口又要使用USART1的引脚做PWM,那就得提前避开。我的习惯是先把所有外设列出来,标注它们最常用的默认引脚,然后再检查有没有冲突。这个项目里PA9/PA10默认就是USART1,PB10/PB11是I2C2,所以直接复用默认功能,省去了重映射的麻烦。

2. 原理图设计核心细节

2.1 最小系统与电源电路

原理图是整个项目的硬件根基,我先说最小系统。STM32F103C8T6的最小系统包含四块:供电、时钟、复位、启动模式选择。很多人从网上随便抄一份最小系统图,结果画完板子焊上芯片不跑,十有八九是VDDA没滤波、VCAP电容没接或者BOOT引脚悬空。

电源部分我用的是USB 5V输入,经过AMS1117-3.3稳压到3.3V给MCU供电。AMS1117虽然老,但稳定性足够、成本低、焊起来也容易。这里要注意输入和输出端都要加10uF和100nF的滤波电容,缺一个高负载下就可能出现电压纹波导致单片机随机重启。VDDA引脚也要单独接一个1uF电容到地,模拟数字转换器的参考电压才干净,否则ADC采样数据会跳动。

时钟部分外接8MHz晶振,两个22pF负载电容,这是F103的标准接法。晶振下面尽量铺地隔离,不要在晶振下方走数字信号线。复位电路用10k电阻上拉复位脚到3.3V,按键接地,这是最常规的设计。启动模式上BOOT0串10k电阻下拉到地,BOOT1不用管,因为BOOT0为0时芯片从Flash启动,也就是正常运行状态。我见过有人把BOOT0悬空,结果芯片上电偶尔不跑程序,这就是典型的下拉没做好的问题。

2.2 传感器接口与电平匹配

原理图里最容易出问题的不是MCU本身,而是外设的电平匹配。DHT11数据线直接接PB0,但要额外加一个4.7k到10k的上拉电阻到3.3V。DHT11是单总线协议,数据线在空闲时必须保持高电平,设备靠拉低总线来发起通信。如果没有上拉,通信时序在边界处会不稳定,表现出来就是读取的湿度值偶尔跳变、隔几分钟丢一次数据。

HC-SR04超声波模块这里有个大坑,我一定要重点说。这个模块官方建议VCC接5V,ECHO输出电平也是5V,但F103的GPIO参考电压是3.3V,直接把5V灌进PA1虽然F1系列引脚标称5V容忍,但长期用不放心,而且如果你换了一块没有5V容忍特性的型号,比如某些F0、F4的引脚,立马烧。正确的做法是在ECHO到PA1之间加一个电阻分压,我用的是1k串330欧分压,把5V降到3.3V以内。TRIG是输入引脚,STM32输出3.3V的触发信号,模块识别没问题,所以不用管。

OLED模块就比较省心了,主流的0.96寸I2C OLED模组自带4.7k上拉电阻,直接接PB10、PB11就行。但要注意模块供电接3.3V,DHT11也是3.3V供电,统一在一个电源域下最省事。USB口的串口转换芯片不一定每个板子都有,如果你的开发板没有板载USB转串口,原理图里可以预留一个4Pin排针——TX、RX、GND、5V,方便外接CH340小板。

2.3 原理图绘制工具与经验

这个项目我用的是嘉立创EDA画原理图,原因很实在:免费、中文、元件库全、能直接打样,对于学生和个人开发者来说是最省钱省力的方案。如果你是第一次画原理图,有两点经验直接决定你后面会不会返工。

第一,网络标签要命名规范。电源用3V3、5V、GND,并把相同网络名的引脚用标签连起来,而不是跨越很长的线去连,这样图面干净,检查起来一目了然。千万不要画一根线从屏幕左边拉到右边,那既难改图也容易连错。我画到传感器接口时,直接用标号DHT11_DATA、TRIG、ECHO,后面写代码时一一对应,不用再去猜。

第二,画完一定要跑电气规则检查,也就是ERC。嘉立创EDA里有这个功能,会自动报出未连接的引脚、输出短路、电源接地异常等常见问题。另外出图前养成习惯:检查一下每个电源引脚是否都接了去耦电容,特别是MCU的VDD和VDDA。很多新手画的原理图看着功能都对,但忘记了MCU每个VDD脚对应的滤波电容,高速切换IO时电源电压会被拉出毛刺,这就属于电气规则检查也发现不了的隐患。

3. 代码架构与实现

3.1 工程搭建与开发环境配置

代码开发环境我选了Keil MDK5,这基本是ST生态最广泛的IDE。但很多新手装完Keil会发现Device列表里根本没有ST的芯片,这不是安装失败,而是没装器件支持包。你需要在Pack Installer里搜索并安装STM32F1系列的DFP,或者去Keil官网直接下载对应Pack包安装,否则第一关就卡死。选完器件后,工程配置里还要在C/C++选项卡的Define中添加USE_STDPERIPH_DRIVER和STM32F10X_MD,前者是标准外设库需要的宏,后者告诉库文件当前编译的芯片是中等容量型号。编译选项里把MicroLIB勾上,这样printf重定向的时候可以省下不少Flash空间。

我在这份开源代码里刻意不用HAL库,全程用标准外设库。原因有三:第一,这个项目的驱动逻辑并不复杂,寄存器操作更直观,对于学习GPIO、定时器、串口这些基础外设反而更有帮助;第二,网上DHT11、HC-SR04的成熟驱动例程绝大多数是标准库的,你如果遇到问题,一搜就能找到对照参考;第三,标准库编译出来的二进制比HAL小很多,烧录和运行也更快。如果你是用CubeMX建工程,也没关系,把外设底层换成你的HAL初始化就行,应用层代码可以直接搬。

工程目录结构我也做了分层,不搞乱七八糟的一堆裸文件:

project/ ├── App/ # main.c、主循环状态机、中断处理 ├── BSP/ # 板级驱动:led、key、buzzer ├── Driver/ # 传感器驱动:DHT11、HC-SR04、OLED ├── StdPeriph/ # ST标准外设库 └── Output/ # 编译生成的hex/bin

驱动层的头文件里统一暴露初始化函数和读写函数,应用层只调接口不看寄存器细节。这样的好处是后期换传感器型号时,只需要改Driver层,App层一行不动。

3.2 驱动代码的关键时序

DHT11看着简单,其实时序非常讲究。通信的第一步是主机拉低总线至少18ms(我写的20ms,留余量),然后释放总线并延时20到40us,等待DHT11应答。DHT11会先把总线拉低80us,再拉高80us,表示准备好发数据了。接着输出40bit数据:1字节湿度整数、1字节湿度小数、1字节温度整数、1字节温度小数、1字节校验和。每个bit的编码方式是高电平持续的时间长短:26到28us代表0,70us左右代表1。

读取代码里最怕的就是用纯粹的延时函数去卡时间,比如delay_us(30),因为延时函数本身就有误差,碰上中断还可能被截断。我采用的方案是用STM32内部的DWT计数器,它是个32位的硬件计数器,每经过一个CPU时钟周期就加一,精确度非常高。读取的时候,先等待总线变低表示bit开始,然后延时30us做中间采样,这时候如果是0,总线已经拉低了;如果是1,总线还在高电平。采样完成后等待本次bit结束,继续下一个bit。

uint8_t DHT11_Read_Byte(void) { uint8_t val = 0; for (uint8_t i = 0; i < 8; i++) { while (DHT11_DQ_IN() == 0); // 等待50us的低电平结束 delay_us(30); // 在bit中间点采样 if (DHT11_DQ_IN() == 1) val |= (0x80 >> i); // 高电平长则判定为1 while (DHT11_DQ_IN() == 1); // 等待本次bit结束 } return val; }

读完之后必须做校验和判断:前四个字节求和后的低8位,应该等于第五个字节。不相等就直接丢弃这次数据,返回上一个有效的温湿度值,而不是把脏数据传给应用层。这相当于给传感器数据加了一层保险,能大幅减少偶发的跳变显示。

HC-SR04的驱动核心是测高电平时间。TRIG引脚给一个大于10us的高电平脉冲,模块会自动发出8个40kHz的超声波脉冲并等待回波,然后把ECHO引脚拉高。距离越远,高电平持续的时间就越长。距离和时间的换算公式是距离等于声速340米每秒乘以时间再除以2,简化成厘米每微秒就是0.017厘米。我在项目里用的是DWT计数法:先等ECHO变高,记录当前计数值,再等ECHO变低,记录结束计数值,相减后除以系统内核时钟频率,换算成微秒。

这块有一个非常关键的细节:读出时间后必须加超时判断。如果传感器前方没有障碍物,或者接线松动,ECHO可能一直保持高电平不下降,程序就会卡在等待低电平的while循环里出不来。我设置的超时上限是150ms,超过这个时间强制将本次测量标记为无效,距离显示为0或显示"OUT"。转账到实际应用中,这个超时判断就是程序健壮性的分水岭,很多人的超声波测距程序在自己板子上测得好好的,装到小车上一跑就死机,多半就是卡死在这个地方。

3.3 应用层逻辑与状态机

主循环的结构我用了一个简单的状态机来管理UI页面,而不是直接线性执行。状态机的好处是扩展性好,以后想加页面就多一个枚举和分支,不会把main函数堆成面条。这个项目一共三个页面:

  • 页面一:温湿度大数字显示,顶部是湿度,中间是温度,底部排显示测量的时间序列号。
  • 页面二:距离显示,大数字显示当前距离,旁边用字符画模拟一个柱状图,直观显示距离远近。
  • 页面三:串口状态页,显示串口上报的累计次数和当前蜂鸣器开关状态。

按键扫描放在SysTick中断里,每5毫秒触发一次,检测到电平变化后延时10ms再次采样确认,这是最基础的消抖。同时按键状态用边缘触发,按下瞬间执行动作,而不是高电平期间反复执行,这样就不会按一次键却连续切换三个页面。

蜂鸣器报警逻辑也放在主循环里:当距离小于阈值比如30厘米并且报警开关打开时,蜂鸣器以1Hz频率鸣叫;距离大于阈值或者报警关闭时静音。这里用GPIO翻转加SysTick计时实现PWM效果,没有用定时器的PWM输出,因为对于单纯报警来说,硬件PWM反而浪费一个定时器资源。当然这是取舍问题,项目里我特意把PWM控制的注释留在代码里,如果谁想让蜂鸣器音调渐变,可以直接改成定时器PWM方案。

串口部分用重定向fputc把printf定向到USART1,波特率设置为115200。代价是勾选Keil的MicroLIB选项,这样就不用额外移植printf。注意芯片的主频配置,外部8MHz晶振经PLL倍频到72MHz,如果这个配置不对,串口的波特率会实际偏移,表现出来就是字符乱码或者莫名丢字节。烧录后我一般先用逻辑分析仪抓TX引脚的电平宽度,确认一帧起始位和停止位的时间是否符合115200的规定,这一步排查效率比瞎猜高得多。

4. 仿真环境的搭建与验证

4.1 仿真平台怎么选

做仿真的目的不是替代实物,而是让你在画板子投钱之前,先把代码逻辑和电路结构验证一遍。我对仿真平台做了一个对比,直接放结论:

平台优势劣势适用场景
Wokwi在线免安装、代码一键跑、支持DHT11/OLED等模型传感模型理想化、外设种类有限快速验证代码逻辑、学习阶段
Proteus电路仿真完整、元件库大、可模拟单片机外围安装麻烦、仿真速度一般验证原理图、教学演示
嘉立创EDA仿真与原理图无缝衔接元件库中STM32模型支持有限偏硬件的电路验证

对于这个项目,我在Wokwi里跑的是逻辑仿真,目的是验证DHT11的读时序、OLED显示、按键和蜂鸣器这些纯代码逻辑。Wokwi里可以直接放置一个STM32F103C8T6芯片,先初始化GPIO,连上一颗DHT11模型和SSD1306 OLED模型,代码写好直接编译运行。网页版的好处是省去搭建开发环境的功夫,而且模型是可视化的,温湿度变化在界面上能直接看到。Wokwi的DHT11组件有个很有意思的交互,你可以直接拖动界面上温湿度的滑块改变传感器数值,代码里读到的数据会随之变化,这就把传感器仿真的体验做实了。

HC-SR04超声波模块在Wokwi平台上没有现成的模型,我采用的是自定义GPIO模拟方案:用两个按键分别模拟回波信号的产生和结束。按下"回波开始"按键,PA1引脚拉高,代码里DWT计数器启动;按下"回波结束"按键,PA1引脚拉低,计数器停止,这样就能在仿真环境里模拟不同时长的ECHO信号,进而验证距离计算公式和超时机制。虽然在按钮时序上要手动操作不如真实模块方便,但关键代码路径是实打实跑过的。

4.2 Proteus电路仿真实操记录

如果想把原理图层面的电路也仿真验证一遍,我推荐Proteus。Proteus里直接搭建一个STM32F103C8T6的原理图工程,把晶振、复位、电源这些最小系统都放上去,再把DHT11、OLED和按键连好。需要强调的一点是,Proteus里的DHT11模型默认好像也只有固定数值,但总比完全没有强,至少能验证上拉电阻和引脚连接是否正确。

Proteus的主流流程是把Keil编译出来的hex文件加载到单片机模型上,然后点运行。很多人会卡在"加载hex后单片机没反应"这一步,原因大多数不是因为电路错误,而是Target芯片型号和Proteus里的器件配置不一致。Keil选的是STM32F103C8,Proteus里放的也必须是同一型号,晶振频率也要对应上。如果这些都对了,OLED不会立刻显示出来,因为它要等代码里的初始化完成,代码里如果有个几百毫秒的延时或者启动按键检测,界面上看起来就是"等几秒才有反应",这属于正常流程。

我在Proteus里比较看重的是虚拟示波器和虚拟终端这两个工具。虚拟终端接在USART1的TX上,能直接看到printf打出来的温湿度数据和测距结果,检查数据是否和代码里预期一致。如果你在调试超声波的时间测量,用虚拟示波器挂在ECHO引脚,能观察到高电平持续的波形宽度,配合计算出的距离值确认公式对不对。这个思路比在实物上用万用表或逻辑分析仪来得直接,也适合教学演示场景。

4.3 仿真与实物的差异在哪里

仿真能做的终究有限,这一点必须有清醒的认知。第一个差异是时序的精度。Wokwi和Proteus里传感器模型都是理想化的,DHT11拉低总线的时间和真实传感器完全一致,但你在仿真里读出的温湿度变化曲线是平滑的,而真实DHT11在快速变化的空气环境里,数据可能会有1到2度的波动。实物的抖动才是常态,代码里必须做滤波和数据有效性判断。

第二个差异是电平的电气特性。Proteus不会告诉你5V的ECHO直接接到3.3V引脚上会不会有隐患,它默认你接得对就能跑。仿真跑通不等于实物安全,所以原理图里我依然坚持用电阻分压。同理,你在仿真里看到的OLED只是逻辑电平,不会反映模块供电不足导致白屏这类实际问题。

第三个差异是调试手段。仿真平台里断点随便下、变量随便看,但在实物上要用ST-Link和调试器。我建议的流程是:先用Wokwi把代码逻辑跑通,再用Proteus验证电路连接,最后才打样焊接实物。这个流程能帮你避开至少70%的调试时间浪费。说实话我自己也跳过Proteus直接画板,结果板子回来后DHT11死活读不到数据,查了两天才发现是某个去耦电容少画了一个,教训相当深刻。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

把我在开发过程中踩过的坑,以及群友高频问过的问题整理成一张表,直接对照检查:

现象可能原因排查方向
DHT11读不到数据上拉电阻缺失、引脚配置错、时序延时不准示波器抓DATA引脚,确认起始信号和应答信号
DHT11湿度偶尔跳变校验和没过、数据线过长、供电不稳代码里加强校验,3.3V供电短线连接
超声波总显示0或超时ECHO没接对、TRIG脉冲不够宽、前有障碍物多示波器/仿真截图看ECHO波形,确认触发和回波
OLED一直白屏I2C地址错误、SDA/SCL接反、模块供电不足扫描I2C地址,确认0x3C还是0x3D
串口乱码波特率不匹配、系统时钟配置错误确认PLL倍频正确,换9600测一次
Keil编译报大量错误芯片型号宏没加、库路径没配置好检查Defines里有没有STM32F10X_MD
ST-Link烧录连不上驱动缺失、接线错、BOOT0被拉高设备管理器看USB设备,确认BOOT0接地
烧录完程序不启动没勾选Reset and Run、复位电路有问题手动按一下复位键,Flash Download里勾选

第一行和第四行的坑最常见。DHT11我在实物上踩过最狠的一次是:板子上电后第一次读取正常,第二次开始读到0xFF,最后排查发现是GPIO模式配置错了。单总线协议下数据线要是配置成推挽输出,上拉电阻相当于没有,读的时候引脚被强制拉高或者拉低,自然读不到正确的bit序列。正确做法是主机输出阶段配置成推挽输出,输入阶段要切换为浮空输入或开漏输出再读电平。

5.2 排查工具与思路

我的排查思路始终遵循一条主线:信号在哪一步断了,就抓哪一步的信号。硬件检查用万用表和逻辑分析仪,软件检查用断点调试和串口打印,仿真就靠Wokwi和Proteus的示波器。三个手段配合起来,没有解决不了的嵌入式问题。

给大家推荐一个实用组合工具:ST-Link V2(十几块钱那种就够用)+串口调试助手+逻辑分析仪(或者示波器)。ST-Link既负责烧录也负责在线调试,联合Keil可以设置断点、实时查看全局变量的值。串口调试助手用来验证数据上报。逻辑分析仪在排查I2C时序和DHT11单总线时序时价值极大,几十块钱的采样率就够,抓一个完整的bit流,用插件解析电平宽度,比盯着示波器数格子准确得多。我在调OLED I2C卡了一晚上的时候,就是靠逻辑分析仪发现某一个字节的ACK位时序不对,而这在单纯看代码时根本发现不了。

另外,调试阶段建议把串口打印做成一个统一的调试模块,预留一个宏开关。项目跑稳定后,你可以一键关掉所有printf输出,释放串口资源。否则在实物上做压力测试时,大量的串口打印会干扰时序,尤其是DHT11这种微秒级的单总线协议,打印一个字符就可能错过了电平跳变边缘,辛辛苦苦调好的传感器数据又乱了。这个宏开关是很多成熟工程的标配,但新手往往意识不到。

还有一个很有效的排查技巧:把代码里的关键状态变量暴露在OLED上。比如DHT11的原始数据、校验结果、超声波每次测量消耗的微秒数,这些临时调试信息在页面三上滚动显示。这样不需要接串口线也能在实物上看到程序的运行状态,尤其适合电池供电或板子已经固定在设备里的场景。调试完毕再把调试页面隐藏即可。

最后的经验之谈

这个项目从零开始到整理完开源,前后花了三周。我最大的体会是:做嵌入式项目一定不要想着一次到位,先画出一个能跑的最小版本,然后在这个基础上一点点加功能,每次加一个功能都验证一次。我见过太多人一上来就想把温湿度、测距、蓝牙、Wi-Fi、云端全部集成,结果代码写了一千行,板子画了两版,最后还是点亮一颗LED的水平。

对于刚入门的朋友,我给一条具体的行动路径:先拿到开发板点亮LED,再跑通串口printf,然后是按键中断加消抖,接着用一个传感器比如DHT11采集数据并串口打印,最后把OLED转起来做显示。这五个步骤就是嵌入式入门的核心路径,任何一个步骤卡住,都在网上能搜到海量资料。这个开源项目的代码、原理图和仿真,恰好覆盖了这五个步骤,你可以把它当成一个带索引的脚手架,在自己做课程设计或毕设时直接参考和改写。

最后再分享一个小技巧:如果你打算把这个项目扩展到实际应用,比如做一个家庭的自动通风控制器,只要在这个架构上加一个继电器控制风扇、加一个阈值判断逻辑就能实现。代码里每一个模块都是独立文件,改起来非常顺手。项目的所有文件我都放在一个压缩包里,原理图能直接打开,代码编译一次通过,有任何问题也欢迎在评论区留言交流。

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

STM32MP257异构开发实战:打通A7与M33的OpenAMP通信链路

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

作者头像 李华
网站建设 2026/9/25 2:07:38

Windows TXT文件打不开?实为文件关联断裂的深度修复指南

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

作者头像 李华
网站建设 2026/9/25 2:07:35

Origin 8.0科研数据绘图软件安装教程:从序列号到兼容性全攻略

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

作者头像 李华
网站建设 2026/9/25 2:07:13

安全隔离网闸实战:TopRules原理、配置与排错全解析

简介&#xff1a;张凌云主讲的《天融信网络卫士安全隔离与信息交换系统TopRules技术培训》完整PPT讲义&#xff0c;面向网络安全运维人员、售前/交付工程师及高校信息安全专业学习者&#xff0c;帮助解决网闸选型、部署与常见问题排查等实际需求。内容系统梳理隔离技术起源、协…

作者头像 李华