news 2026/10/22 1:02:54

STM32与PJ85718DM的I2C温度采集实战:本地远程双通道设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32与PJ85718DM的I2C温度采集实战:本地远程双通道设计

做嵌入式温度采集这块有些年头了,这次聊一个我调过的组合:STM32F205RB 搭配 PJ85718DM 这颗 I2C 数字温度传感器,用在嵌入式和 HVAC 场景里同时监测本地与远程温度。这套组合听起来不花哨,但真正做起来会遇到不少值得记录的细节,从器件选型、硬件设计到软件时序和现场排查,每一层都有坑。这篇文章把我实际调试过程中的思路和踩坑记录整理出来,给正在做温控、环境监测、设备热保护或者 HVAC 控制器的朋友们一个可落地的参考。

先说清楚这套系统到底在做什么。所谓本地温度,指的是主控板附近的温度,通常用来监测嵌入式设备自身的板级温度,防止控制盒、驱动电路或功率器件过热;远程温度则是指通过线缆延伸到设备外部、安装在风管、管道、冷柜或室内其他位置的传感器所测得的温度,用于 HVAC 系统的环境采样。STM32F205RB 负责把这两类温度数据读回来,做滤波、阈值判断和报警输出。PJ85718DM 作为数字温度传感器,通过 I2C 接口直接输出温度数据,免去了模拟传感器需要的放大、线性化电路,非常适合这种需要多点采集且对一致性和可维护性有要求的场合。

适合看这篇文章的读者,我默认是有一定嵌入式基础、但可能第一次做温度采集或者第一次在长距离线路上跑 I2C 的朋友。如果你已经用过 DS18B20 一类的单总线传感器,或者正在纠结数字传感器和 NTC 之间怎么选,那这篇内容对你应该会有价值。

1. 项目解读与选型思路

1.1 本地与远程温度同时监测到底在解决什么问题

很多嵌入式产品并不是单点测温就能满足需求的。拿 HVAC 系统来说,控制器本身装在控制箱里,环境温度传感器装在房间或风管内,两者相距可能几米甚至几十米。如果只在控制器内部测一次温度,你得到的只是设备自身的发热情况,跟实际温控对象的温度完全是两回事。反过来,如果只测远端温度而不看板级温度,设备内部过热、散热风扇失效这些隐患就很难及时发现。

所以这套设计本质上是在做两个层面的监测。第一层是设备保护,本地传感器贴近 MCU 和主控电路,一旦温度异常可以及时降频、关断输出,避免硬件毁损;第二层是工艺控制,远程传感器反映真实的环境或介质温度,HVAC 压缩机、风机、加热器的启停都要依据这个值来决策。两个温度通道的意义完全不同,不能互相替代。

我实际调过的某个项目里,远程传感器安装在风管内部,本地传感器贴在控制板背面,两者温差在极端工况下能到 15 摄氏度以上。如果只保留一个通道,要么误触发报警,要么控制滞后,所以双通道同时采集在这类系统里不是可有可无的功能,而是基本要求。

1.2 为什么 MCU 选了 STM32F205RB

STM32F205RB 在 F2 系列里属于性价比比较均衡的型号。F2 系列基于 Cortex-M3 内核,主频最高 120MHz,资源上比我经常用来做简单采集的 F103 要宽裕不少。温度采集本身不复杂,但加上滤波算法、报警管理、通信协议栈以及可能的人机交互逻辑之后,主频和内存空间就开始有实际意义了。

这颗芯片带多个 I2C、SPI、USART 外设接口,硬件 I2C 完全可以承担传感器读取的任务。同时它有足够多的 GPIO 和 EXTI 中断线,传感器的 ALERT 报警引脚可以直接连到中断输入,故障发生时 MCU 不用轮询等待,响应更快。另外 F2 系列的工作温度范围覆盖 -40 到 +85 摄氏度,对于 HVAC 这种可能安装在户外或者设备内部的场景,工业级温度范围比普通消费级芯片更让人放心。

还有一点是成本和供货方面的考量。F2 系列虽然不是最新产品,但在工控和暖通行业里存量很大,参考设计多,踩坑资料也容易找到。选一款资料充分、生态成熟的 MCU,比追求顶配但没把握吃透的新型号要稳妥得多。

1.3 PJ85718DM 这颗传感器为什么够用

PJ85718DM 是典型的 I2C 接口数字温度传感器,量程通常覆盖 -40 到 +125 摄氏度,分辨率可以做到 12 位,对应 0.0625 摄氏度的最小分辨率,精度一般在正负 0.5 摄氏度级别。对于 HVAC 和嵌入式设备保护这个精度等级完全够用,毕竟温控系统本身还有继电器、四通阀这些机械执行机构的死区,传感器的误差远小于系统整体的控制误差。

选数字传感器而不是 NTC、PT100 这类模拟方案,核心原因是设计复杂度。NTC 需要上拉电阻、分压网络、AD 采样和查表线性化,温度长线传输时模拟信号还会被线缆电阻和干扰影响;PT100 倒是精度高,但需要恒流源或桥式电路,成本一下子上去了。PJ85718DM 这类 I2C 数字传感器把敏感元件和信号调理电路集成在芯片内部,直接输出数字量,MCU 通过 I2C 总线读取,硬件上简洁很多。

支持多地址配置也是我选它的一个重要理由。这颗芯片通常具备多个地址引脚,可以在一根 I2C 总线上挂载多片传感器,这对于做多点温度采集非常方便。我在这套方案里用两片,一片作为本地传感器,一片作为远程传感器,地址不同,共用一组 SDA 和 SCL 引脚,节省了 MCU 宝贵的引脚资源。

2. 硬件电路设计与接口细节

2.1 传感器接线与 MCU 引脚分配

先明确一下硬件拓扑。MCU 使用的是其中一个硬件 I2C 外设,假设配置在 I2C1 上,对应引脚是 PB6(SCL)和 PB7(SDA)。两片 PJ85718DM 都接在这组总线上,地址分别设置成不同的值。ALERT 引脚按需接到 MCU 的 EXTI 中断引脚上,当传感器检测到温度超过配置的上限或下限阈值时,ALERT 拉低触发中断,MCU 可以立刻执行保护动作,而不是等待下一次轮询。

远程传感器的接口端子建议做成可插拔的连接器,方便现场安装和维护。远程传感器和主控板之间的线缆至少预留三根线:SCL、SDA 和电源地,电源线单独走一根。线缆长度不要和通信距离混为一谈,I2C 本身是为板内通信设计的,但在实际工程中拉到两三米也有不少人在用,前提是做好下面这些配套措施。

MCU 的引脚定义我习惯在头文件里集中管理,尽量避免后续改板时到处找引脚导致改漏。代码上可以像下面这样定义:

#define PJ85718DM_ADDR_LOCAL (0x48 << 1) #define PJ85718DM_ADDR_REMOTE (0x49 << 1) #define I2C_SCL_PORT GPIOB #define I2C_SCL_PIN GPIO_PIN_6 #define I2C_SDA_PORT GPIOB #define I2C_SDA_PIN GPIO_PIN_7 #define ALERT_EXTI_PORT GPIOB #define ALERT_EXTI_PIN GPIO_PIN_5

这样两片传感器的地址一目了然,接线上也不容易搞混。

2.2 上拉电阻与远程布线的工程计算

I2C 总线是开漏结构,SCL 和 SDA 都需要上拉电阻才能输出高电平。上拉电阻的取值不是随便选的,它和总线电容、通信速率之间有直接的制约关系。I2C 协议规定,在快速模式下(400kHz)信号上升沿时间不能超过 300ns,而上升沿时间大约等于上拉电阻乘以总线电容。

计算公式可以简化成:

t_rise = R_pull_up * C_bus

如果总线上挂了两个传感器,加上 MCU 引脚和 PCB 走线电容,总线电容大概在 100pF 量级。如果远程线缆再加长,每米线缆电容约 100pF 左右,两米就是 200pF,总电容可能接近 300 到 400pF。

按 400kHz 快速模式、允许 300ns 上升沿来算:

R_pull_up = 300ns / 350pF,大概取 860 欧姆左右

这个阻值太小的话,总线在空闲时消耗的电流会变大,而且会增加 SDA 低电平时的灌电流负担;阻值太大的话,上升沿就变慢了,通信就容易出错。实际工程里我建议先把通信速率降低到 100kHz 标准模式,然后用 4.7k 或者 3.3k 的上拉电阻,这样兼容性最好。远程线超过一米时我一般直接降到 100kHz,宁可速度慢一点也要保证通信稳定。

注意:远程传感器的线缆优先使用带屏蔽的双绞线,屏蔽层单端接地。绝对不要把 I2C 线和大功率负载的电源线捆在一起走,这一点在后面实测部分会再次验证。

2.3 供电、去耦与异常保护

PJ85718DM 这类传感器一般支持 2.7V 到 5.5V 供电,但既然 MCU 是 3.3V 系统,我统一用 3.3V 给传感器供电,这样 I2C 电平匹配不需要额外处理。每片传感器的电源引脚旁边都要放一颗 100nF 的去耦电容,而且这颗电容要尽可能靠近传感器引脚。远程传感器那边,由于线缆本身有一定的电阻和电感,远程端的供电在瞬态负载下可能出现波动,去耦电容能起到一定的缓冲作用。

远程供电还要考虑线压降的问题。普通的 26AWG 线电阻大约为 0.13 欧姆每米,假设电流 3mA,线长 3 米,单程压降只有 1mV 左右,这确实可以忽略。但如果现场用的是很细的长线,或者传感器功耗较高,压降就不能视而不见。稳妥的做法是在远程端子侧加一颗 1 到 10uF 的电解电容或者钽电容,对供电稳定性有明显帮助。

另外,户外或工业现场环境比较复杂,远程端子处还可能遇到静电放电和浪涌。我会在远程接口端子的电源和信号线上各加一串 100 欧姆左右的串联电阻,并配合 5V 齐纳二极管或者 TVS 管做钳位,虽然这么做会增加一点点硬件成本,但能避免现场静电打坏传感器或 MCU 引脚。

3. 软件实现与温度控制逻辑

3.1 传感器读取:寄存器结构与温度转换

PJ85718DM 的寄存器布局和常见的 I2C 数字温度传感器类似。温度数据以 16 位寄存器形式存储,通过 I2C 读命令从传感器中取出。温度值的换算和分辨率直接相关。当分辨率配置为 12 位时,每个 LSB 代表 0.0625 摄氏度,数据以二进制补码形式存储。读取出来的 16 位数据需要先做符号扩展,再乘以 0.0625 才能得到最终的温度值。

下面是一个用标准外设库实现的读取函数,我把寄存器地址按照常见的数据手册布局来写,具体地址字段以你拿到的 PJ85718DM 手册为准:

uint8_t pj85718dm_read_temp(uint16_t dev_addr, float *temperature) { uint8_t reg_addr = 0x00; uint8_t raw_data[2] = {0}; if (HAL_I2C_Mem_Read(&hi2c1, dev_addr, reg_addr, I2C_MEMADD_SIZE_8BIT, raw_data, 2, 100) != HAL_OK) { return 0; } int16_t raw_value = (int16_t)((raw_data[0] << 8) | raw_data[1]); *temperature = (float)raw_value * 0.0625f; return 1; }

需要注意的是,如果分辨率不是 12 位,LSB 对应的温度值会变,比如 9 位分辨率对应 0.5 摄氏度,11 位对应 0.125 摄氏度。前期调试时先把配置寄存器确认清楚,否则后面数据对不上会浪费很多时间。

3.2 双通道轮询与超时管理

本地和远程两个传感器在 I2C 总线上是分时访问的。由于两个传感器从机地址不同,MCU 可以用完全相同的代码逻辑去读取两个地址,只是目标地址不同而已。主循环里的轮询安排可以是 500ms 采样一次,远程传感器读取一次,本地传感器也读取一次,每次读取之间保留一点时间间隔,避免同一时刻连续启动两次 I2C 传输导致总线冲突。

关键点在超时管理。I2C 通信在正常工作时很可靠,但远程线路一旦接触不良或者传感器损坏,HAL 库的等待超时机制就必须兜底。我的习惯是每次通信都设置一个明确的最短超时时间,比如 50ms,超时后直接释放总线并记录一次通信错误计数。如果连续多次读取失败,就不再盲目重试,而是进入故障处理逻辑,把该通道的温度值标记为无效,同时点亮故障指示灯或上报上位机。

#define SENSOR_POLL_PERIOD_MS 500 uint8_t read_all_sensors(void) { float local_temp = 0.0f; float remote_temp = 0.0f; uint8_t local_ok = 0; uint8_t remote_ok = 0; local_ok = pj85718dm_read_temp(PJ85718DM_ADDR_LOCAL, &local_temp); delay_ms(5); remote_ok = pj85718dm_read_temp(PJ85718DM_ADDR_REMOTE, &remote_temp); if (local_ok) { process_local_temperature(local_temp); } else { handle_sensor_fault(SENSOR_CHANNEL_LOCAL); } if (remote_ok) { process_remote_temperature(remote_temp); } else { handle_sensor_fault(SENSOR_CHANNEL_REMOTE); } return (local_ok && remote_ok); }

本地传感器通常比较稳定,问题往往出在远程通道,所以远程通道的失败计数阈值可以设得比本地通道更严格一些,毕竟远程线路受到环境干扰和机械老化的概率更大。

3.3 数据滤波与报警回差

温度信号不是理想稳定的。HVAC 设备运行时,风机振动、压缩机启停、热气流流动都会让温度读数出现幅度不大的跳动。如果直接把原始采样值用于阈值判断,就可能出现报警频繁翻转的尴尬局面。

我对每个通道做两层处理。第一层是滑动平均滤波,保留最近 8 到 16 个采样值,取平均值作为当前显示和控制用温度。第二层是报警阈值判断时引入回差,也就是滞回控制。假设高温报警阈值设为 75 摄氏度,不是温度到 75 摄氏度就立刻报警,而是超过 75 摄氏度之后要持续一段时间,比如连续 3 次采样都超过阈值才报警;当温度回落到 70 摄氏度以下时,报警才解除。这个 5 摄氏度的回差能有效避免继电器在临界点反复吸合。

滑动平均的代码写起来很直观:

#define FILTER_WINDOW_SIZE 8 typedef struct { float buffer[FILTER_WINDOW_SIZE]; uint8_t index; uint8_t count; float sum; } temp_filter_t; void temp_filter_init(temp_filter_t *filter) { filter->index = 0; filter->count = 0; filter->sum = 0.0f; } float temp_filter_add(temp_filter_t *filter, float sample) { if (filter->count < FILTER_WINDOW_SIZE) { filter->count++; } else { filter->sum -= filter->buffer[filter->index]; } filter->buffer[filter->index] = sample; filter->sum += sample; filter->index = (filter->index + 1) % FILTER_WINDOW_SIZE; return filter->sum / (float)filter->count; }

3.4 总线异常与传感器断线处理

I2C 最让人头疼的问题之一是总线锁死。SCL 或者 SDA 线被拉死后,后续所有通信全部瘫痪。系统上电时如果总线上有残留电平,或者通信过程中远程线缆受到干扰,都可能导致总线状态异常。软件复位外设并不能解决所有问题,因为从设备的内部状态可能已经乱了。

我的处理方法是分段恢复。首先尝试重新初始化 I2C 外设,如果还不行,就把 SCL 引脚临时配置为 GPIO 输出,手动翻转 9 个时钟周期,让总线上的从设备完成状态复位,然后再把引脚恢复为 I2C 复用功能。这个方法在大多数 I2C 从设备上都有效,专门用来对付那种从设备卡死在内部状态的非正常情况。

断线检测也要做。远程传感器线缆松脱时,I2C 总线的上拉电阻会把 SDA 拉高,MCU 读取时如果没有设备应答,HAL 会返回超时错误。但有一种特殊情况是传感器断线后总线悬空,上拉电阻起作用,SDA 和 SCL 看起来都是高电平,此时只要读取失败,就按断线处理并给出明确提示,不要让温度数据沿用上一次的旧值。旧值满天飞是工程上很危险的一件事,可能系统保护逻辑已经失效了但显示看起来还正常。

4. 实测数据、标定与常见问题排查

4.1 实测场景与数据记录

我把这套系统搭起来之后做过一段时间的数据记录。测试条件是:本地传感器贴在控制板背面,远程传感器通过一根 2 米长的屏蔽双绞线连接,远端传感器探头悬在室内空气中,I2C 通信速率设置为 100kHz,采样周期 500ms。

在常温环境下,两个传感器放在同一个位置时的读数差值一直在 0.1 摄氏度以内。把远程传感器移到风管出风口附近、系统开始工作后,远端读数会随着气流变化出现 0.3 摄氏度左右的波动,这是正常的,滑动平均后波动减小到 0.1 摄氏度以内。而本地传感器受 MCU 发热影响,读数稳定后比环境温度高 2 到 4 摄氏度,这也是预期的结果。

测试场景本地温度读数远程温度读数备注
两传感器同一位置,无气流25.125.0差值小于 0.1 摄氏度
远程探头放入风管,风机开启31.218.6风管温度明显低,温差合理
远程线缆增加至 3 米,400kHz31.0通信错误降低到 100kHz 后恢复正常
远程端子松动半插入31.1读取失败故障标志上报,未沿用旧值

第二组数据说明了一个问题:远程线缆超过一米且速率 400kHz 时,通信可靠性会明显下降。不是芯片不行,而是 I2C 上升沿受到线缆电容拖累,协议时序满足不了。这类问题在现场非常容易遇到,而且表现很随机,时好时坏。

4.2 两点偏移与噪声标定

数字传感器虽然出厂时做过校准,但毕竟每颗芯片的个体差异和安装位置的系统误差都会带来偏差。如果应用对绝对精度要求比较高,可以自己做一个简单的两点校准。

做法不复杂。找两个已知温度的基准点,最简单的是冰水混合物接近 0 摄氏度,以及一个精确控温的恒温槽或者经过标定的水银温度计作为第二个点。将传感器分别放到两个基准环境中,读取输出值,计算出偏移和增益系数,再写入系统的补偿公式。

比如传感器在基准温度 A 点读数为 A_raw,在基准温度 B 点读数为 B_raw,实际温度分别为 A_true 和 B_true,那么两点校准可以换算成:

gain = (B_true - A_true) / (B_raw - A_raw) offset = A_true - gain * A_raw

校正后的温度值就是:

temp_corrected = gain * temp_measured + offset

我在项目里把校准参数保存在 MCU 的 Flash 中,每次上电读取,并允许通过串口指令在线修正,这样生产时不需要反复烧录固件。

4.3 温度读数跳动问题

读数跳动可能来自好几个方面,不要一上来就改滤波参数,先排查硬件。先把传感器探头放在静止空气中,观察原始读数。如果跳动在正负 0.1 摄氏度以内,属于正常噪声;超过 0.2 摄氏度,问题就值得查了。

最常见的元凶是供电噪声。传感器电源线上如果有较大的纹波,读数就会周期性抖动。我在一个项目里发现传感器读数随着发热丝 PWM 开关同步跳动,用示波器看电源纹波达到了 200mV,后来在传感器电源前加了一颗小电感配合电容做了一级 LC 滤波,读数立刻稳定下来。

还有一个容易忽略的因素是 I2C 读取时序对转换值的影响。数字温度传感器内部会有一次温度转换过程,如果在转换尚未完成时就读取温度寄存器,读到的是上一次的数甚至是不完整的数据。稳妥做法是读取配置寄存器中的转换状态位,确认转换完成后再次读取;或者在固定采样周期里,读取操作和转换时段错开,避免竞态。

4.4 I2C 总线锁死与恢复

远程线缆场景下,I2C 总线锁死的概率比板内通信高得多。常见诱因包括线缆插拔瞬间信号线上出现毛刺、静电放电导致从设备逻辑错乱、电源跌落导致从设备进入不确定状态。

我的现场恢复策略分为三级。第一级:通信超时后执行外设复位,重新初始化 I2C。第二级:如果复位后仍然通信失败,启动 GPIO 模拟时钟恢复序列,翻转 SCL 9 次并释放 SDA,把从设备从内部死锁中解救出来。第三级:连续恢复失败后主动标记传感器故障,进入报警和维护状态,不能无限重试导致主循环卡死。

void i2c_bus_recover(void) { GPIO_InitTypeDef gpio_init = {0}; /* 配置 SCL 为普通推挽输出 */ gpio_init.Pin = I2C_SCL_PIN; gpio_init.Mode = GPIO_MODE_OUTPUT_PP; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(I2C_SCL_PORT, &gpio_init); HAL_GPIO_WritePin(I2C_SCL_PORT, I2C_SCL_PIN, GPIO_PIN_SET); for (uint8_t i = 0; i < 9; i++) { HAL_GPIO_WritePin(I2C_SCL_PORT, I2C_SCL_PIN, GPIO_PIN_RESET); delay_us(5); HAL_GPIO_WritePin(I2C_SCL_PORT, I2C_SCL_PIN, GPIO_PIN_SET); delay_us(5); } /* 重新配置为 I2C 复用功能 */ GPIO_InitTypeDef i2c_init = {0}; i2c_init.Pin = I2C_SCL_PIN | I2C_SDA_PIN; i2c_init.Mode = GPIO_MODE_AF_OD; i2c_init.Pull = GPIO_PULLUP; i2c_init.Speed = GPIO_SPEED_FREQ_HIGH; i2c_init.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &i2c_init); HAL_I2C_DeInit(&hi2c1); HAL_I2C_Init(&hi2c1); }

注意:这个恢复过程必须在系统主循环中同步执行,不能在中断服务函数里做,否则可能因为阻塞中断而引入更复杂的时序问题。

4.5 远程杂散干扰与线材经验

远程传感器最怕的其实是现场布线。我在调试一个 HVAC 控制器时就碰到过一种诡异现象:远程传感器读数偶发跳变到异常值,但很快又恢复正常。后来排查发现,远程线缆有一段和 220V 供电线同路径走了大概半米,而且那段线缆没有采用双绞结构,供电线在启动的瞬间产生了较强的电磁耦合,干扰直接串进了 I2C 信号线。

换用双绞屏蔽线并且单独走线之后,问题彻底消失。经验就是:远程 I2C 线缆尽量短、尽量双绞、尽量远离强电和感性负载;如果距离确实超过 3 米,就不要硬撑 I2C 了,直接改用 RS485 总线加 Modbus 协议,成本虽然高一点,但可靠性提升是质变。

另外,防水和端子可靠性也值得重点检查。HVAC 现场可能出现冷凝水,端子裸露或没有做防水处理,铜线氧化后接触电阻增大,通信时好时坏,温度数据偶尔也会跟着失真。我在远程端子上统一选用了带密封圈的航空插头或防水接线盒,后期维护省事很多。

4.6 常见问题速查表

现象可能原因解决方案
本地数据正常,远程读取超时远程线缆接触不良、线过长检查端子,降低 I2C 速率或改用 RS485
温度读数周期性跳动电源纹波干扰、转换状态未确认电源加 LC 滤波,确认转换完成再读取
两通道读数同时异常上拉电阻失效或总线锁死检查上拉电阻,执行 GPIO 时钟恢复
数据偶发跳变,不是持续错误线缆强电耦合干扰换双绞屏蔽线,单独走线
报警频繁翻转阈值无回差,滤波深度不足增加滞回判断,加长滑动平均窗口
换上新的传感器模块后读数偏移芯片个体差异或安装热阻不同重新做两点校准,写入 Flash 修正系数

最后说点实际体会

这套 STM32F205RB 加 PJ85718DM 的方案,我在多个项目里复用下来,整体稳定性是有保证的。最关键的经验就一条:温度采集的核心瓶颈往往不在芯片本身,而在远程通道的物理链路设计上。I2C 虽然是板级总线,但把它用到一米以上的场景时,一定要在速率、上拉电阻、线缆选型上做足够的预留。另外一个容易被忽略的点是报警逻辑的回差设计,温度控制最怕在临界点反复切换,这比传感器精度对系统可靠性的影响更大。如果你正在计划类似的方案,建议先拿一套开发板加两颗传感器做最小验证,把远程线缆的实际传输距离和现场干扰摸底测一遍,再确定最终硬件方案。这样后面量产和现场调试都会少很多意外。

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

PJ85718DM+ATmega2560工业温控架构设计与实战

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

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

【Tensorflow实战系列】Tensorflow:TypeError: pred must not be a Python bool

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

作者头像 李华
网站建设 2026/10/21 23:59:20

从模糊标识符到可复用模块:以rea为例的工程实践

1. 当标题只剩三个字母时&#xff0c;我在想什么第一次看到这个项目标题的时候&#xff0c;我盯着屏幕愣了好几秒。就三个字母&#xff0c;"rea"。没有正文&#xff0c;没有关键词&#xff0c;没有摘要描述&#xff0c;什么都没有。这种输入状态其实挺有意思的&#…

作者头像 李华
网站建设 2026/10/21 23:58:55

基于Spring Boot的旅游推荐系统设计:从行为采集到协同过滤落地

1. 项目拆解与技术选型1.1 先搞清楚这个系统要干什么先把标题翻译成人话&#xff1a;这是一个基于 Spring Boot 的 Web 旅游推荐系统&#xff0c;编号 11757。这类系统在大学里出现的频率非常高&#xff0c;因为它同时覆盖了后端开发、数据库设计、推荐算法、前端交互几个大块&…

作者头像 李华
网站建设 2026/10/21 23:57:41

PyInstaller打包勒索病毒样本分析:拆包、修复pyc头与反编译实战

拿到一个勒索病毒的Python打包样本&#xff0c;第一件事就是想办法把它还原成能看的源码。这个套路我已经跑过几轮了&#xff0c;涉及的工具链基本固定&#xff1a;pyinstxtractor负责拆包&#xff0c;uncompyle6负责反编译&#xff0c;中间还有一步很容易被忽略——修复pyc头。…

作者头像 李华