51单片机DS18B20温度采集与NRF905无线传输实战

简介:这是一套面向单片机爱好者、电子类专业学生与DIY玩家的温度采集与无线传输实践方案,基于51单片机搭配NRF905无线模块,解决短距离温度数据采集与无线收发的问题,适合具备一定电子技术基础、能看懂基础电路图并了解C语言设计原理的读者。压缩包共34个文件,约80KB,以C语言源文件、头文件、Keil工程文件(uvproj、uvopt)及编译产物(hex、obj、lst、m51)为主,另含大量bak备份文件,完整保留了发射机与接收机两套工程。资源围绕DS18B20温度采集与LCD1602显示展开,配合NRF905完成无线数据发送与接收,读者可通过查看电路学习电路设计原理,通过阅读代码理解代码编写逻辑,并借助编译输出文件快速验证程序运行效果。目前已有173人学习,适合作为课程设计、毕业设计或电子DIY项目的参考素材。

1. 从一块“哑巴”温度节点说起:51单片机配NRF905到底能跑出什么效果

前阵子帮一个做农业大棚环境监测的朋友看方案,他手里有一批老式温度采集节点,主控是51单片机,无线部分用的是NRF905。问题很典型:节点能采到温度,但数据传不回来,串口助手上一片空白。我拿过来一看,程序里NRF905的收发模式切换根本没做对,配置寄存器写进去的值和实际读出来的对不上。这个项目就是解决这类问题的——一套完整的51单片机温度采集加NRF905无线传输程序,包含发送端和接收端两套代码,能直接把DS18B20采到的温度通过NRF905发出去,接收端还原成可读数据。适合正在做无线传感节点、课程设计或者想搞懂NRF905底层时序的开发者。它不依赖复杂协议栈,全是寄存器级操作,跑通之后你对无线模块的理解会扎实很多。

2. 硬件链路与工程结构:先看清数据从传感器到空中的完整路径

2.1 发送端与接收端的硬件组成

发送端核心是51单片机最小系统加DS18B20温度传感器,再挂一片NRF905模块。DS18B20走单总线,接在任意一个IO口上,程序里用位操作模拟时序。NRF905和单片机之间是SPI接口,但51没有硬件SPI,所以用普通IO口模拟,这点很关键,后面代码里会看到。接收端同样是51单片机加NRF905,区别在于它不需要传感器,而是把收到的数据通过串口送到电脑,方便用串口助手看结果。

供电部分要注意,NRF905模块对电源纹波比较敏感,我一般会在模块VCC和GND之间并一个10uF电解电容加一个0.1uF瓷片电容。很多“发送正常但接收距离短”的问题,根源就在电源上。天线也要匹配,模块自带的弹簧天线在空旷环境能到几十米,室内穿墙会打折扣,这是物理规律,不是程序能解决的。

2.2 工程目录与文件职责

拿到源码包,目录结构通常是这样组织的:

NRF905_Temp/ ├── Sender/ │ ├── main.c // 主循环:初始化、读温度、发数据 │ ├── ds18b20.c // 单总线时序与温度换算 │ ├── nrf905.c // NRF905寄存器配置与收发 │ └── delay.c // 短延时与毫秒延时 ├── Receiver/ │ ├── main.c // 主循环:初始化、收数据、串口输出 │ ├── nrf905.c // 与发送端一致,保证配置匹配 │ ├── uart.c // 串口初始化与发送 │ └── delay.c └── Common/ └── nrf905_reg.h // 寄存器地址与命令字定义

发送端和接收端的nrf905.c内容基本一致,因为NRF905的配置必须完全对称才能通信。常见做法是把配置参数抽到一个头文件里,两边都包含,避免改了一边忘了另一边。我一般会把频道、地址、有效数据宽度这几个参数单独拎出来,放在nrf905_reg.h顶部,改的时候一眼就能看到。

2.3 数据流与关键参数

整个链路的数据流是:DS18B20转换温度 -> 单片机读取 -> 格式化成一个字节数组 -> 写入NRF905发送缓冲区 -> 拉高TRX_CE触发发送 -> 接收端NRF905收到后拉低DR引脚 -> 单片机读缓冲区 -> 串口打印。

NRF905有几个参数必须两边一致:频道频率、接收地址、有效数据宽度。频道频率决定载波,地址相当于“门牌号”,数据宽度决定一次传几个字节。温度数据我一般用4个字节:两个字节放温度整数部分和小数部分,另外两个字节放节点ID和校验。这样接收端能区分是哪个节点发的,也能判断数据有没有出错。

3. 核心模块拆解:DS18B20时序与NRF905寄存器配置

3.1 DS18B20单总线时序实现

DS18B20最容易被忽略的是延时精度。51单片机在不同晶振下机器周期不同,延时函数必须根据实际晶振调整。下面这段是11.0592MHz晶振下的典型实现:

// ds18b20.c #include "ds18b20.h" #include "delay.h" // 复位DS18B20,检测存在脉冲 bit ds18b20_reset(void) { bit presence; DQ = 0; // 拉低总线 delay_us(480); // 保持至少480us DQ = 1; // 释放总线 delay_us(60); // 等待15-60us presence = DQ; // 读取存在脉冲,低电平表示存在 delay_us(420); // 等待复位完成 return presence; } // 写一个字节,低位先写 void ds18b20_write_byte(unsigned char dat) { unsigned char i; for(i = 0; i < 8; i++) { DQ = 0; delay_us(2); DQ = dat & 0x01; // 写数据位 delay_us(60); // 保持60us DQ = 1; // 释放总线 dat >>= 1; } } // 读一个字节 unsigned char ds18b20_read_byte(void) { unsigned char i, dat = 0; for(i = 0; i < 8; i++) { DQ = 0; delay_us(2); DQ = 1; // 拉高,准备读 delay_us(2); dat >>= 1; if(DQ) dat |= 0x80; // 读到1则置高位 delay_us(60); } return dat; }

逻辑说明:复位函数先拉低总线480us以上,再释放,如果DS18B20存在会拉低总线60us左右,读DQ为0说明器件在线。写字节时每个位先拉低2us,然后放数据位,保持60us,最后释放。读字节时拉低2us后释放,在2us内采样总线电平。参数上,delay_us的精度直接决定成败,如果晶振换了,这三个延时值都要重新算。我见过有人用12MHz晶振但延时按11.0592MHz写,结果温度读出来永远是85度,这就是时序错位的典型翻车现场。

3.2 NRF905寄存器配置与收发切换

NRF905通过SPI接口配置,51用IO模拟SPI。下面这段是配置和发送的核心代码:

// nrf905.c #include "nrf905.h" #include "nrf905_reg.h" // 模拟SPI写一个字节 void nrf905_spi_write(unsigned char dat) { unsigned char i; for(i = 0; i < 8; i++) { MOSI = dat & 0x80; // 高位先出 SCK = 0; dat <<= 1; SCK = 1; // 上升沿写入 } } // 写配置寄存器 void nrf905_config(void) { CSN = 0; // 片选拉低 nrf905_spi_write(W_CONFIG); // 写配置命令 nrf905_spi_write(0x00); // 配置字节,根据实际设置 // 依次写入频道、地址、数据宽度等 nrf905_spi_write(CHANNEL); nrf905_spi_write(0xE7); // 接收地址,两边必须一致 nrf905_spi_write(0xE7); nrf905_spi_write(0xE7); nrf905_spi_write(0xE7); nrf905_spi_write(PAYLOAD_WIDTH); // 有效数据宽度 CSN = 1; } // 发送一包数据 void nrf905_tx_packet(unsigned char *buf, unsigned char len) { unsigned char i; CSN = 0; nrf905_spi_write(W_TX_PAYLOAD); // 写发送缓冲区命令 for(i = 0; i < len; i++) { nrf905_spi_write(buf[i]); } CSN = 1; TRX_CE = 1; // 触发发送 delay_ms(1); // 等待发送完成 TRX_CE = 0; }

逻辑说明:nrf905_spi_write在SCK上升沿把数据移出,高位先出。配置时先发W_CONFIG命令,然后依次写配置字节、频道、地址、数据宽度。地址四个字节必须和接收端完全一致,否则收不到。发送时先写TX_PAYLOAD命令,再把数据逐个写入,最后拉高TRX_CE触发。参数上,PAYLOAD_WIDTH要和实际发送字节数匹配,我一般设成4,对应温度数据包。TRX_CE拉高后不要立刻拉低,给模块一点时间,1ms是保守值,实际可以更短,但没必要省这点时间。

3.3 接收端中断与串口输出

接收端用DR引脚判断是否有数据,可以用查询也可以用中断。下面是用查询方式的接收代码:

// Receiver/main.c 片段 void main(void) { unsigned char rx_buf[4]; unsigned char i; uart_init(); // 串口初始化,波特率9600 nrf905_config(); // 配置NRF905,与发送端一致 while(1) { if(DR == 1) // 收到数据 { CSN = 0; nrf905_spi_write(R_RX_PAYLOAD); // 读接收缓冲区命令 for(i = 0; i < 4; i++) { rx_buf[i] = nrf905_spi_read(); } CSN = 1; // 串口打印温度 uart_send_byte(rx_buf[0]); // 整数部分 uart_send_byte('.'); uart_send_byte(rx_buf[1]); // 小数部分 uart_send_byte('\r'); uart_send_byte('\n'); } } }

逻辑说明:DR为高表示接收缓冲区有数据,先发R_RX_PAYLOAD命令,然后连续读4个字节。串口部分把整数和小数分开打印,中间加点号。参数上,串口波特率要和电脑端一致,9600是最常用的。如果DR一直不拉高,先检查发送端是否真的发出去了,再检查两边地址和频道是否一致。我一般会在发送端加一个LED闪烁指示发送动作,接收端加一个LED指示接收,这样调试时不用看串口也能判断链路是否通。

4. 避坑与排查:NRF905调试中最容易翻车的五个点

4.1 现象:发送端正常但接收端毫无反应

原因:最常见的是两边地址或频道不一致。NRF905的地址是4个字节,配置时如果只改了发送端忘了改接收端,或者频道值写错,模块根本不会响应。另一个可能是PAYLOAD_WIDTH设置不同,发送端设4接收端设2,数据对不上。

解决:把地址和频道参数抽到头文件里,两边包含同一个头文件。调试时先用固定地址0xE7E7E7E7和频道0x01,确认通了再改。用示波器看DR引脚,如果发送时接收端DR有脉冲但读不到数据,就是PAYLOAD_WIDTH的问题。

4.2 现象:温度读出来永远是85度

原因:DS18B20复位后默认输出85度,如果时序不对,单片机读到的就是默认值。常见于延时函数按12MHz写但实际用11.0592MHz晶振,或者delay_us精度不够。

解决:用示波器测DQ线上的复位脉冲宽度,确保拉低时间在480us到960us之间。延时函数用定时器做,不要用循环计数,循环计数在不同优化等级下时间不一样。我一般会在复位后读一次温度,如果连续三次都是85度,直接报传感器故障。

4.3 现象:通信距离短,隔一堵墙就断

原因:电源纹波大、天线匹配差、发射功率配置低。NRF905的发射功率可以通过配置寄存器调整,默认可能是最低档。另外模块供电如果和单片机共用一路,电机或继电器动作时电压跌落会导致模块复位。

解决:模块VCC并10uF加0.1uF电容,供电单独走一路LDO。配置寄存器里把发射功率调到最大,具体值看模块手册。天线尽量远离金属和人体,弹簧天线竖直放置效果最好。如果还不行,降低空中速率,速率越低距离越远,这是无线通信的基本规律。

4.4 现象:数据偶尔出错,串口打印乱码

原因:没有校验机制,NRF905本身有CRC但配置时可能没使能。另外电源波动导致某个字节翻转。

解决:在数据包里加一个校验字节,比如前三个字节异或。接收端算一下,不对就丢弃。NRF905的CRC使能位在配置寄存器里,建议打开。串口乱码还要检查波特率误差,11.0592MHz晶振配9600波特率误差为0,12MHz晶振会有误差,尽量用11.0592MHz。

4.5 现象:程序烧进去后单片机不跑

原因:51单片机的P0口作为普通IO时没有内部上拉,如果NRF905的SPI线接在P0口,没有外接上拉电阻,电平拉不高,SPI通信失败。另外看门狗没关,程序跑飞后不断复位。

解决:P0口接4.7K到10K上拉电阻,或者换到P1、P2口。看门狗在初始化时先关掉,调试完成再决定是否开启。烧录时注意晶振频率设置,有些下载软件默认12MHz,实际板子是11.0592MHz,烧进去延时全错。

5. 二次开发与改造:从固定节点到可配置传感网络

5.1 增加节点ID与多节点区分

原始程序是点对点,发送端固定,接收端固定。要改成多节点,最直接的办法是在数据包里加一个字节的节点ID。发送端从拨码开关或EEPROM读ID,接收端根据ID区分不同节点。下面是一个改造示例:

// 发送端数据包结构 typedef struct { unsigned char node_id; // 节点编号 unsigned char temp_int; // 温度整数 unsigned char temp_dec; // 温度小数 unsigned char checksum; // 校验 } temp_packet_t; // 填充数据包 temp_packet_t pkt; pkt.node_id = read_dip_switch(); // 从拨码开关读ID pkt.temp_int = temp >> 4; // DS18B20原始值转换 pkt.temp_dec = (temp & 0x0F) * 10 / 16; pkt.checksum = pkt.node_id ^ pkt.temp_int ^ pkt.temp_dec; nrf905_tx_packet((unsigned char *)&pkt, sizeof(pkt));

逻辑说明:结构体打包后直接发送,接收端按同样结构体解析。node_id用拨码开关读取,3位拨码可以支持8个节点。checksum用异或,简单有效。参数上,sizeof(pkt)是4,和PAYLOAD_WIDTH一致。如果节点多了,可以改成轮询发送,每个节点分配不同时间片,避免空中碰撞。

5.2 接收端增加数据解析与上位机协议

接收端收到数据后,除了串口打印,还可以按一定协议打包发给上位机。我一般用简单的帧头加数据加帧尾格式:

// 接收端串口输出协议 void uart_send_packet(temp_packet_t *pkt) { uart_send_byte(0xAA); // 帧头 uart_send_byte(pkt->node_id); uart_send_byte(pkt->temp_int); uart_send_byte(pkt->temp_dec); uart_send_byte(pkt->checksum); uart_send_byte(0x55); // 帧尾 }

逻辑说明:帧头0xAA和帧尾0x55用于上位机同步,中间是有效数据。上位机收到后先找0xAA,再读5个字节,最后验证0x55和校验和。这样即使串口有噪声也能恢复。参数上,帧头帧尾可以换成其他值,只要不和有效数据冲突就行。我一般会在上位机加一个超时重同步机制,超过一定时间没收到完整帧就重新找帧头。

5.3 低功耗改造思路

如果节点用电池供电,低功耗是必须的。51单片机本身功耗不低,但可以通过休眠模式加定时唤醒降低平均功耗。NRF905也有掉电模式,发送间隙可以关掉。改造步骤:把主循环改成定时器唤醒,唤醒后读温度、发数据、然后进入休眠。NRF905在发送完成后拉低TRX_CE和PWR_UP,进入掉电模式。注意DS18B20转换需要时间,可以在转换期间让单片机休眠,转换完成用外部中断唤醒。

5.4 验证方法与调试习惯

改造完成后怎么验证?我一般分三步:第一步,用串口助手看接收端输出,确认数据格式正确;第二步,用另一个NRF905模块做嗅探,看空中数据是否和发送端一致;第三步,长时间跑,看有没有丢包或校验错误。调试时我会在关键位置加LED指示,比如发送时闪一下,接收时闪一下,这样不用接串口也能判断程序有没有跑到那里。

从那以后我每次调NRF905,都强制先跑一遍地址和频道一致性检查,再确认电源纹波,最后才看代码逻辑。这个顺序帮我省了很多来回改代码的时间。希望帮到你。

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

相关新闻

YOLOv8/YOLO26目标检测实战:从环境搭建到模型部署完整指南

YOLOv8/YOLO26目标检测实战:从环境搭建到模型部署完整指南

作为一个前前后后用YOLO折腾过不止一个项目的人&#xff0c;我太清楚新手第一次接触YOLO时那种“明明照着教程一步步点&#xff0c;怎么到我这就疯狂报错”的无助感了。这个标题里说的“全网最稳”&#xff0c;其实并不是空话——它邀请你走的&#xff0c;是一条我踩了无数坑之…

2026/10/21 3:09:09 阅读更多 →
DeepSeek Harness 实操:从零跑通智能体框架,25 分钟搭好 Web 界面与第一个插件

DeepSeek Harness 实操:从零跑通智能体框架,25 分钟搭好 Web 界面与第一个插件

DeepSeek Harness 实操:从零跑通智能体框架,25 分钟搭好 Web 界面与第一个插件 【免费下载链接】deepseek-harness DeepSeek Harness: Everything is a Plugin. 项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness DeepSeek Harness(dsh)是 DeepSeek 开源的…

2026/10/21 3:09:09 阅读更多 →
数学建模竞赛真题解读与源码实战:从模型构建到论文输出全链路

数学建模竞赛真题解读与源码实战:从模型构建到论文输出全链路

简介&#xff1a;一套面向高校数学建模竞赛的完整培训材料&#xff0c;涵盖基础理论、建模方法、真题解析与源代码实现&#xff0c;适合从入门到备赛冲刺的各阶段学生。压缩包共61个文件&#xff0c;约2.02MB&#xff0c;以30个MATLAB脚本、16个Word文档和6个Excel表格为主&…

2026/10/21 3:09:09 阅读更多 →

最新新闻

单图生成3D高斯泼溅实战:API接入与交互展示

单图生成3D高斯泼溅实战:API接入与交互展示

1. 从一张图到可交互3D&#xff1a;这个项目到底在做什么单图生成3D高斯泼溅&#xff08;3D Gaussian Splatting&#xff0c;后面统一简称3DGS&#xff09;这个方向&#xff0c;最近半年热度一直没降下来。原因很直接&#xff1a;传统摄影测量或者多视角重建&#xff0c;你得围…

2026/10/21 3:52:33 阅读更多 →
Docker存储卷实战:三种挂载方式与数据持久化指南

Docker存储卷实战:三种挂载方式与数据持久化指南

容器跑起来只是第一步&#xff0c;真正麻烦的是数据往哪儿放。不少新手用 Docker 跑了个数据库或文件服务&#xff0c;重启容器后数据“凭空消失”&#xff0c;或者多个容器想共享同一份配置、日志&#xff0c;结果各写各的互不相通。这个问题的标准解法就是 Docker 存储卷&…

2026/10/21 3:52:33 阅读更多 →
Linux高级存储管理实战:LVM、RAID、磁盘配额与Swap调优

Linux高级存储管理实战:LVM、RAID、磁盘配额与Swap调优

1. 从“磁盘满了”说起&#xff1a;为什么基础分区不够用了很多人第一次接触Linux存储&#xff0c;都是从fdisk分区、mkfs格式化、mount挂载这三板斧开始的。这套流程应付单块磁盘、固定容量的场景确实够用&#xff0c;但只要你的机器开始承载真实业务&#xff0c;很快就会撞上…

2026/10/21 3:52:33 阅读更多 →
AI大模型落地制造业:六大系统智能化改造路径与避坑指南

AI大模型落地制造业:六大系统智能化改造路径与避坑指南

这两年跑过不少制造企业的数字化项目&#xff0c;发现一个很有意思的变化&#xff1a;ERP、MES、SRM、APS、WMS、EMS这些系统&#xff0c;能上的基本都上了&#xff0c;可多数老板仍然说不清“系统到底帮我省了多少钱、提了多少速”。数据是有了&#xff0c;但站在数据面前做决…

2026/10/21 3:52:33 阅读更多 →
C#手动拼PDU发短信:串口AT指令硬核实践

C#手动拼PDU发短信:串口AT指令硬核实践

简介&#xff1a;这是一份面向C#中级开发者与通信协议学习者的PDU短信发送实战项目&#xff0c;聚焦GSM底层通信原理在Windows平台的落地实现。资源通过完整的SMSCSharp工程&#xff0c;封装了PDU编码/解码核心类、Submit PDU构造逻辑、MSISDN与SMSC号码二进制转换、多段长短信…

2026/10/21 3:52:33 阅读更多 →
Excel中ROW与COLUMN函数:从自动编号到矩阵运算的实战指南

Excel中ROW与COLUMN函数:从自动编号到矩阵运算的实战指南

做了十年表哥表姐&#xff0c;我最常听的一句话是&#xff1a;“帮我把这个表重新排个序&#xff0c;序号也跟着变一下。”如果序号是手工敲进去的&#xff0c;那接下来就是一场手动改号的噩梦。但如果从一开始就用ROW函数生成序号&#xff0c;就算数据排序翻来覆去&#xff0c…

2026/10/21 3:51:33 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →