尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
STM32F103外扩ADS1115 16位ADC例程:I2C驱动与PGA配置实战
简介面向STM32F103开发者这份压缩包提供ADS1115高精度16位ADC的完整驱动与例程解决I2C初始化、增益配置、多通道采样与数据换算等常见问题。资源共150个文件、2.82MB主要包含37个h头文件与35个c源码文件覆盖标准外设库驱动另有hex烧录文件、uvprojx工程文件及uvoptx选项配置可直接用Keil打开编译o、crf等为构建中间产物htm与txt为说明文档bat脚本可用于工程清理。例程涉及I2C时序、ADS1115寄存器配置、PGA可编程增益、16位结果读取及实际电压换算并支持LCD显示适合做传感器数据采集、工业监控等精确测量项目。已有712人学习下载代码结构清晰移植到其他STM32系列也较为方便。1. F1-ADS1115例程_STM32F103_ads1115_给F103外扩16位ADC到底要解决什么“F1-ADS1115例程_STM32F103_ads1115_”这个标题翻译过来就是在STM32F103上跑通TI的ADS1115驱动让这颗16位ADC通过I2C把模拟量读回来。F103内置ADC只有12位分辨率在3.3V参考下约0.8mV量电桥、PT100、电池电压这类小信号时噪声和分辨率都不够ADS1115是Delta-Sigma架构的16位ADC4路输入、内置可编程增益放大器PGAI2C接口只占PB6/PB7两根线。这个例程解决的不只是“读出数据”而是完整走通I2C时序、16位配置字、量程换算和排错流程。适合做传感器采集、变送器、电池监测的嵌入式工程师照着复现。不少人以为I2C读写通了例程就算跑通真正翻车的地方其实是配置字写错、参考电压没搞清、量程系数乘错这三点我会在第3、4章用可复现的方式拆开讲。2. 硬件连接最小系统、5V转3.3V电路和上拉电阻I2C能不能通全看这里ADS1115的例程代码只占一半功夫另一半在硬件连接。F103最小系统、ADS1115供电、I2C上拉电阻、地址引脚配置这些没弄对代码再对也读不出数据。这一章先把硬件链路的每个节点过一遍顺便把例程里默认的引脚和跳线对应上。2.1 STM32F103最小系统与ADS1115供电VDD就是参考电压跑例程之前先确认手头的stm32f103最小系统板是能独立工作的8MHz晶振或内部RC、复位电路、BOOT0拉低、3.3V供电SWD口接ST-Link这套环境是例程能下载调试的前提。ADS1115的供电范围是2.0V到5.5V但例程里几乎都用3.3V。原因有两个一是F103的GPIO电平就是3.3VI2C上下拉电平一致不需要额外转换二是ADS1115没有内部基准电压它的参考电压就是VDD用5V供电会让LSB步进变大小信号分辨率反而变差。如果你拿到的是带板载LDO的ADS1115模块上面通常有一颗3.3V稳压芯片这时可以给模块供5V但要注意模块的SDA/SCL上拉电阻是接到模块自己的VDD还是接到了5V这直接决定F103引脚会不会被灌到5V。我一般建议F103和ADS1115都统一3.3V供电省掉电平转换的麻烦。2.2 ADDR引脚决定I2C地址0x48、0x49、0x4A、0x4B怎么选ADS1115的7位I2C地址由ADDR引脚的电平决定例程里默认地址是0x48对应ADDR接地。ADDR可以接GND、VDD、SDA或SCL四种接法对应四个不同地址具体如下| ADDR引脚接法 | 7位地址 | 写地址左移1位 | 读地址左移1位或|1 | |---|---|---|---| | GND | 0x48 | 0x90 | 0x91 | | VDD | 0x49 | 0x92 | 0x93 | | SDA | 0x4A | 0x94 | 0x95 | | SCL | 0x4B | 0x96 | 0x97 |注意0x90并不等于0x48直接左移一位后那个“写字节”如果你在例程里看到地址宏定义的是0x90而不是0x48说明它已经把读写位拼进去了。很多移植翻车就翻在这里例程里写的是0x90你按0x48去对照数据手册怎么都对不上。多片ADS1115挂同一条I2C总线时把每片的ADDR分别接GND、VDD、SDA、SCL就能得到四个独立地址例程里用ADS1115_ADDR这个宏区分改宏比改代码快。2.3 电平匹配与上拉电阻5V供电时怎么处理SDA/SCLI2C是开漏架构SCL和SDA必须接上拉电阻才能输出高电平。F103的PB6/PB7虽然标注了FT5V容忍但I2C外设的电气特性建议不要超过VDD0.3V所以最稳妥的做法是上拉电阻接到3.3V而不是接到ADS1115模块的VDD。如果模块是5V供电的又不想额外飞线可以用独立的上拉电阻从F103的3.3V接到SDA/SCL前提是模块的SDA/SCL引脚不要自己再对VDD上拉否则两个上拉并联还会产生额外灌电流。上拉电阻阻值方面100kHz标准模式用4.7k400kHz快速模式用2.2k到3.3k例程默认走100kHz4.7k就行。至于网上常说的 stm32f103 5v转3.3v电路如果模块本身没有LDO需要自己降压供电用一个AMS1117-3.3就够了别用电阻分压给ADC供电——负载变化时分压点电压会飘直接体现在读数上。3. 先读懂ADS1115的Config寄存器增益PGA、数据速率DR和单次/连续转换怎么设ADS1115例程的核心不在读取函数而在那个16位的Config寄存器。很多人在例程里改一个量程、改一个采样率改完发现读数不对就是因为只改了配置字里的一两个位其他位被覆盖了。这一章把Config寄存器拆开讲并把例程默认配置0x8583逐位还原。3.1 Config寄存器逐位拆解OS、MUX、PGA、MODE、DR位怎么拼ADS1115的Config寄存器地址是0x0116位每一位含义如下位序号名称含义15OS单次转换启动位写1启动转换读回时0表示转换完成14:12MUX输入多路选择000AIN0-AIN1差分100AIN0-GND单端101AIN1-GND110AIN2-GND111AIN3-GND11:9PGA增益000±6.144V001±4.096V010±2.048V011±1.024V100±0.512V101±0.256V8MODE1单次转换0连续转换7:5DR数据速率0008SPS00116SPS01032SPS01164SPS100128SPS101250SPS110475SPS111860SPS4COMP_MODE比较器模式例程一般不用置03COMP_POL比较器极性置02COMP_LAT比较器锁存置01:0COMP_QUE比较器队列00触发即响应11禁用比较器例程默认11例程默认配置0x8583二进制是1000 0101 1000 0011。逐位拆开OS1启动单次转换MUX000即AIN0-AIN1差分输入PGA101即±0.256VMODE1单次转换DR100即128SPSCOMP_QUE11禁用比较器。这个默认配置意味着例程把输入范围压缩到±0.256V如果你想量0到3.3V的电压不改PGA直接读读满量程也只有0.256V出来的电压值完全不对。这就是大多数“例程读数不对”的根源。3.2 配置字怎么拼用C宏把位数拼出来别手算16进制手算16位二进制很容易错我一般用移位宏把配置字拼出来代码可读性和可维护性都好很多后面想改哪个参数就改哪一行#define ADS1115_OS_START (1 15) // 启动单次转换 #define ADS1115_MUX_AIN0_AIN1 (0 12) // 差分AIN0-AIN1例程默认 #define ADS1115_MUX_AIN0_GND (4 12) // 单端AIN0对GND #define ADS1115_MUX_AIN1_GND (5 12) // 单端AIN1对GND #define ADS1115_MUX_AIN2_GND (6 12) #define ADS1115_MUX_AIN3_GND (7 12) #define ADS1115_PGA_6144 (0 9) // ±6.144V #define ADS1115_PGA_4096 (1 9) // ±4.096V #define ADS1115_PGA_2048 (2 9) // ±2.048V #define ADS1115_PGA_1024 (3 9) #define ADS1115_PGA_512 (4 9) #define ADS1115_PGA_256 (5 9) // ±0.256V例程默认 #define ADS1115_MODE_SINGLE (1 8) // 单次转换 #define ADS1115_DR_128 (4 5) // 128SPS #define ADS1115_DR_860 (7 5) // 860SPS最高速 #define ADS1115_COMP_DISABLE (3 0) // 禁用比较器 #define ADS1115_CONFIG_DEFAULT \ (ADS1115_OS_START | ADS1115_MUX_AIN0_AIN1 | ADS1115_PGA_256 | \ ADS1115_MODE_SINGLE | ADS1115_DR_128 | ADS1115_COMP_DISABLE)这套宏展开后得到0x8583和例程默认值一致。如果你想量单端3.3V把宏换成ADS1115_MUX_AIN0_GND | ADS1115_PGA_6144得到的配置字是0xC183OS启动、MUXAIN0-GND、PGA±6.144V、单次、128SPS、禁用比较器。逻辑说明这三个宏分别负责输入通道、量程和转换模式互不干扰参数说明里最需要注意的是MUX值单端模式下MUX的高三位是100到111不是0到3这个对应关系和STM32的ADC通道号完全是两套别拿F103的ADC规则通道来套。3.3 单次转换与连续转换什么时候用MODE1什么时候用MODE0例程默认MODE1用单次转换原因是省电且行为可预测每次写入Config寄存器触发一次转换转换完成后OS位自动清零结果锁存在Conversion寄存器里。我们只需要估算转换时间约1/DR秒延时后再读就能拿到这次触发对应的确定结果。连续模式MODE0适合需要持续监测的场景上电后自动循环转换读Conversion随时能拿到最新值但问题是你不知道读数对应的是哪个时刻的模拟输入在输入快速变化时会有“新旧数据混读”的错觉。我一般把单次模式用在例程调试和电池监测这类低频场景把连续模式用在需要配合ALERT/RDY引脚做中断唤醒的场景。另外注意单次模式下OS位写1启动转换如果你把这位置成0再写进Config转换根本不会触发读回来的数据是不会更新的旧值。4. 在STM32F103上把例程跑通软件I2C的完整读取流程和最小代码例程通常提供标准库版本的I2C驱动这里有一个选型问题用F103的硬件I2C外设还是用GPIO模拟的软件I2C例程文件里如果不是CubeMX生成的工程很多是软件I2C实现的我强烈建议你优先跑软件I2C版本。原因后面第5章会细说F103的硬件I2C在事件标志处理上容易卡死调试起来像个黑匣子软件I2C每一拍时序都看得见逻辑分析仪一抓就知道问题在哪。这一章给出最小可用的软件I2C代码。4.1 用CubeMX初始化两个开漏GPIO然后在例程文件夹里找到引脚定义F103的I2C引脚例程默认是PB6SCL和PB7SDA如果你用CubeMX重新生成工程只需要把这两个引脚配置成开漏输出、速度50MHz、上拉使能。CubeMX工程生成之后例程文件夹里main.c的MX_GPIO_Init函数就是引脚初始化入口不要自己再去翻固件库的gpio.c。软件I2C不需要配置I2C外设所以CubeMX里直接跳过I2C选项只用GPIO。__HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct {0}; GPIO_InitStruct.Pin GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; // 开漏输出 GPIO_InitStruct.Pull GPIO_PULLUP; // 内部上拉 GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; // 50MHz HAL_GPIO_Init(GPIOB, GPIO_InitStruct);逻辑说明开漏输出模式下GPIO输出低电平时拉低总线输出高电平时释放总线由外部上拉电阻把电平拉高这正好符合I2C协议对开漏的要求。参数说明内部上拉和外部上拉可以共存协同提供上拉电流速度选HIGH是为了让沿更陡但软件I2C实际跑100kHz左右LOW也够用关键是开漏这一条不能改。4.2 软件I2C四段基础时序起始、停止、发送字节和应答检测软件I2C的核心是SCL高电平时SDA的跳变。起始条件是SCL高时SDA从高拉低停止条件是SCL高时SDA从低拉高发送字节则是SCL低时改变SDA电平SCL高时被采样。这四段代码是例程里最底层的东西写完基本不用再动static void I2C_Delay(void) { for (volatile uint32_t i 0; i 200; i); // 72MHz下约2us } static void I2C_Start(void) { SDA_HIGH(); SCL_HIGH(); I2C_Delay(); SDA_LOW(); I2C_Delay(); // SCL高期间SDA下降沿 SCL_LOW(); I2C_Delay(); // 拉低SCL准备传数据 } static void I2C_Stop(void) { SDA_LOW(); SCL_HIGH(); I2C_Delay(); SDA_HIGH(); I2C_Delay(); // SCL高期间SDA上升沿 } static void I2C_SendByte(uint8_t byte) { for (uint8_t i 0; i 8; i) { if (byte 0x80) SDA_HIGH(); else SDA_LOW(); byte 1; I2C_Delay(); SCL_HIGH(); I2C_Delay(); // 从设备在SCL高电平采样 SCL_LOW(); I2C_Delay(); } }逻辑说明I2C_Delay决定了SCL时钟周期每个bit高低电平各一次延时8个bit加一个ACK位一个字节大概要9个延时周期算下来100kHZ左右完全符合ADS1115的I2C时序要求。参数说明如果你把主频改到不同的值I2C_Delay里的200要按实际主频缩放否则SCL频率会偏离预期在快速模式设备上可能直接通信失败。SDA_HIGH和SDA_LOW就是HAL_GPIO_WritePin的封装不再展开。4.3 完整读取一次电压写指针寄存器、写配置、等待转换、读两字节ADS1115的读流程是固定的四步先写指针寄存器指向Config写入配置字触发转换等待转换完成再写指针寄存器指向Conversion最后连续读两个字节合成16位结果。下面是完整函数uint8_t ADS1115_WriteConfig(uint16_t config) { I2C_Start(); if (!I2C_SendByte(ADS1115_ADDR 1)) { I2C_Stop(); return 1; } // 写地址0x90 I2C_SendByte(0x01); // 指针指向Config寄存器 I2C_SendByte((config 8) 0xFF); // 先写高字节 I2C_SendByte(config 0xFF); // 再写低字节 I2C_Stop(); return 0; } int16_t ADS1115_ReadConversion(void) { int16_t raw 0; I2C_Start(); if (!I2C_SendByte(ADS1115_ADDR 1)) { I2C_Stop(); return 0; } I2C_SendByte(0x00); // 指针指向Conversion寄存器 I2C_Start(); // 重复起始切换为读 I2C_SendByte((ADS1115_ADDR 1) | 1); // 读地址0x91 uint8_t hi I2C_ReadByte(1); // 主机回复ACK继续读 uint8_t lo I2C_ReadByte(0); // 主机回复NACK结束 I2C_Stop(); raw (int16_t)((hi 8) | lo); return raw; } float ADS1115_GetVoltage(uint16_t config, float lsb_mv) { ADS1115_WriteConfig(config); HAL_Delay(10); // 128SPS对应7.8ms留余量 int16_t raw ADS1115_ReadConversion(); return raw * lsb_mv; // 单位mV }逻辑说明写配置时主机发送设备地址0x90后ADS1115会在第9个SCL时钟拉低SDA应答I2C_SendByte的返回值就是ACK位读转换结果时必须在读到第二个字节时回NACK否则ADS1115会继续输出下一个字节总线上数据错位。参数说明HAL_Delay(10)是按默认128SPS设置的如果你把DR改成860SPS延时可以缩到3ms改到8SPS时则要等130ms以上延时不够会读到上一次的旧数据这是例程移植时最常见的时序坑。4.4 电压换算表PGA不同LSB系数就不同别乘错ADS1115是16位ADC带符号输出每个数字量对应的电压由PGA决定。例程默认PGA±0.256V但实际项目里经常改成±4.096V或±6.144V换算系数如下PGA配置满量程范围电压分辨率LSB000±6.144V0.1875mV001±4.096V0.125mV010±2.048V0.0625mV011±1.024V0.03125mV100±0.512V0.015625mV101±0.256V0.0078125mV注意LSB的单位是mV不是V。例程里如果你直接拿raw * 0.1875去算6.144V档出来的单位是mV再除以1000才是V。另外int16_t是有符号数差分输入时负电压读出来是负数直接用这个数乘LSB就得到带符号电压如果误用了uint16_t负电压会变成65535附近的巨大正数这也是例程里读数突变的一个隐蔽原因。5. 例程移植中的5个坑从I2C死锁到Pack路径每条都是经验换来的跑通例程之后移植到自己的板子或改成自己的应用场景时问题才会真正暴露。这一章把我在F103和ADS1115组合上实际踩过的坑按“现象、原因、解决”写清楚帮你省掉逐个排查的时间。每条都可以直接对号入座。5.1 读数永远是0xFFFF或0x0000先查地址再查上拉现象例程编译下载后串口打印的原始值是65535或者0怎么触发都变不了。原因最常见的是I2C地址不对。例程宏ADS1115_ADDR通常定义成0x48但代码里写的是ADS1115_ADDR 1也就是0x90有些移植者直接把0x48当写地址用导致总线上没有设备应答读回的数据总线被上拉电阻拉到高电平得到0xFFFF。另一个常见原因是模块上的ADDR引脚被接了VDD实际地址变成了0x49例程里却还是0x48。解决拿起原理图或万用表确认ADDR引脚电平然后改宏。改完之后用逻辑分析仪抓ACK位在第九个时钟看SDA有没有被拉低这是判断I2C设备是否存在的最快方法。还有一种隐蔽情况只接了SCL和SDA忘了接VDD或GNDADS1115根本不上电这时候抓总线会发现SDA一直是高没有任何ACK。5.2 硬件I2C卡死在EV5/EV6事件标志死等是F103的老问题现象用CubeMX生成硬件I2C工程程序运行到while (__HAL_I2C_GET_FLAG(I2C1, I2C_FLAG_SB) RESET)之类的地方再也不往下走看仿真器PC指针停在等待循环里。原因F103的硬件I2C外设对总线状态很敏感总线上的毛刺或者上拉太弱会导致起始条件没被正确识别标志位永远不置位。标准库和HAL库生成的代码绝大部分都是死等标志没有超时机制一旦卡住没有后悔药。解决有三种做法。第一种是给所有等待加超时计数超时后复位I2C外设并重试第二种是干脆不用硬件I2C直接用上一章的软件I2C这是最可靠的做法第三种是降低I2C时钟到100kHz以下。我自己的习惯是从一开始就用软件I2CADS1115采样率最高860SPS数据量不大软件I2C完全扛得住省下的调试时间远超那点CPU开销。5.3 电压读数比万用表偏低PGA选太大参考电压其实是VDD现象用例程默认配置量3.3V读出来只有0.25V左右量0V倒是准的。原因这就是第3章说的默认PGA±0.256V输入超过满量程ADC输出饱和在32767附近按LSB换算后自然不对。还有一种情况是PGA选对了但读数仍偏低那是信号源内阻太大——ADS1115内部采样电容充电需要时间高阻信号源会拉低采样电压。解决先根据你要量的最大电压选PGA量0-3.3V就选±6.144V或±4.096V然后把配置字里的PGA宏对应改掉。高阻信号源前面加一级运放跟随器。最后记住一个关键点ADS1115没有独立基准引脚它的参考电压就是VDDVDD如果是LDO输出的3.28V实际LSB就是3.28/32768不是理论值。要求高时用万用表实测VDD把换算公式里的lsb_mv改成VDD/32768*1000。5.4 连续模式读数跳变、毛刺多DR太高数字滤波来不及现象连续模式下打印的电压值偶尔跳几十个LSB甚至瞬间跳变几百LSB看起来像接触不良。原因ADS1115的DR设为860SPS或475SPS时内部数字滤波器带宽宽噪声明显增加这是Delta-Sigma ADC的正常特性。如果你在读取的同时发生了一次转换更新还可能读到新旧数据交界的瞬时值。电源纹波大时参考电压VDD上的扰动会直接耦合进测量结果。解决把DR降到128SPS或64SPS这个档位下数字滤波效果明显变好。程序上做两次读取连续读两个结果如果差值超过几个LSB就再读一次取最后一次或者做简单的滑动平均。电源方面ADS1115的VDD引脚靠近放一个1uF陶瓷电容加一个0.1uF电容如果和你板子上的电源是一根走线单独飞线供电也比共用好。5.5 Keil工程打开报错或找不到芯片Pack路径和例程文件夹别搞混现象下载的“F1-ADS1115例程_STM32F103_ads1115_”用Keil5打开后Device栏是空的或者编译报错找不到芯片头文件下载时提示No Target。原因多半是没装STM32F1系列DFP pack包或者例程对应的芯片型号和你的板子不一致。例程文件夹里可能包含多个工程文件有的是针对F103C8有的是针对F103ZET6打开错了工程自然报错。中文路径或路径里带空格也会让Keil的芯片数据库索引出问题。解决先去Keil官网或Pack Installer里装最新的Keil.STM32F1xx_DFP包然后打开例程目录下带MDK-ARM字样的uvprojx工程在Options for Target里把Device改成你板子实际用的型号。如果例程文件夹里同时有Src目录和MDK-ARM目录用后者不要自己新建工程去把Src里的文件一个个加进来那会漏掉启动文件和系统时钟配置。那篇“stm32f103 keil mdk工程搭建与st-link调试全流程”讲的就是这套环境的完整搭法照着走一遍能少踩不少坑。另外尽量把整个例程文件夹拷贝到纯英文路径再打开keil对中文目录支持很差。6. 把例程改成多通道轮询MUX切换、单次触发和均值滤波例程默认只读AIN0-AIN1一组差分输入实际项目里往往要同时监测好几路电压这时不需要改太多代码只要动MUX位就行。我的做法是把配置字拆成“固定部分”和“通道部分”用循环依次写入通道配置单次转换并读取最后对每个通道取三次平均值const uint16_t config_fixed ADS1115_OS_START | ADS1115_PGA_6144 | ADS1115_MODE_SINGLE | ADS1115_DR_128 | ADS1115_COMP_DISABLE; const uint16_t mux_table[4] { ADS1115_MUX_AIN0_GND, ADS1115_MUX_AIN1_GND, ADS1115_MUX_AIN2_GND, ADS1115_MUX_AIN3_GND }; for (uint8_t ch 0; ch 4; ch) { uint32_t sum 0; for (uint8_t i 0; i 3; i) { ADS1115_WriteConfig(config_fixed | mux_table[ch]); HAL_Delay(10); sum ADS1115_ReadConversion(); } int16_t raw_avg (int16_t)(sum / 3); float volt_mv raw_avg * 0.1875f; printf(CH%d: %ld mV\r\n, ch, (long)(volt_mv)); }注意每次切换通道都要重新写Config寄存器因为MUX位是在写入时被采样的。三次采样后取平均能滤掉大部分随机噪声但不要平均太多次超过几十次会把真实变化也抹掉。验证方法很简单拿一个精密可调电源或电位器分压给每个通道输入已知电压看读数误差是否在2个LSB以内。我最早做这个例程移植时图省事用了硬件I2C结果卡死在事件标志上查了一下午最后换成软件I2C才通从那以后我拿到任何例程第一件事就是检查GPIO配置和地址宏改完任何配置字都会先读回Config确认写进去的值。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

机器学习驱动的物理约束干旱建模方法

机器学习驱动的物理约束干旱建模方法

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

📅 2026/10/28 9:20:30
嵌入式Linux与安卓驱动开发实战:从内核模块到HAL层全链路解析

嵌入式Linux与安卓驱动开发实战:从内核模块到HAL层全链路解析

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

📅 2026/10/28 9:15:26
STM32C5嵌入式开发实战:从CubeMX配置到调试踩坑全记录

STM32C5嵌入式开发实战:从CubeMX配置到调试踩坑全记录

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

📅 2026/10/28 9:15:26
MORE NEWS

更多资讯

📰

我的电视(my-tv):免注册、开箱即用的电视直播软件,把老电视变成直播入口

我的电视(my-tv):免注册、开箱即用的电视直播软件,把老电视变成直播入口 【免费下载链接】my-tv 我的电视 电视直播软件,安装即可使用 项目地址: https://gitcode.com/GitHub_Trending/my/my-tv 家里只想看央视…

📰

为什么你的断点续传总是从 0 开始:Hutool 大文件下载避坑实战

为什么你的断点续传总是从 0 开始:Hutool 大文件下载避坑实战 【免费下载链接】hutool 🍬A set of tools that keep Java sweet. 项目地址: https://gitcode.com/gh_mirrors/hu/hutool 用 Hutool 做文件下载,几 MB 的包一行 HttpUtil.…

📰

Codex 免配置一键安装包|本地部署不用敲一行命令

前言 做开发的朋友应该都有体会,想要本地部署 Codex,最麻烦的不是软件本身,而是前期环境准备。手动安装 Node.js、处理依赖版本冲突,还要打开终端输入多条命令,稍有不慎就会报错,很多新手卡在这一步直接放…

📰

HarmonyOS 通知点开只进首页?让通知直接跳到指定业务页面【鸿蒙心迹】

👋 你好,欢迎来到我的博客!我是【菜鸟学鸿蒙】我是一名在路上的移动端开发者,正从传统“小码农”转向鸿蒙原生开发的进阶之旅。为了把学习过的知识沉淀下来,也为了和更多同路人互相启发,我决定把探索 Harmo…

📰

my-tv:免费电视直播软件,电视盒子装上就能看

my-tv:免费电视直播软件,电视盒子装上就能看 【免费下载链接】my-tv 我的电视 电视直播软件,安装即可使用 项目地址: https://gitcode.com/GitHub_Trending/my/my-tv my-tv 是一款开源的电视直播软件,免注册、不收费&#…

📰

【HarmonyOS 7新能力|008】互动卡片入门实战:从能力边界到最小可运行链路

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

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬