简单理解:非阻塞读取有哪些方法?
除了 switch 状态机之外还有哪些能实现 DS18B20 非阻塞读取、且兼容 O2 优化的方法我会按 “嵌入式实用度” 排序讲解每种方法的核心逻辑、优缺点和适用场景你可以根据自己的项目需求选择核心前提无论用哪种方法核心原则不变放弃「阻塞式空循环延时」改用「时间戳 / 硬件定时器判断时序」关键变量硬件寄存器、状态、时间戳加volatile适配 O2 优化拆分 DS18B20 的多步骤通信流程避免一次性阻塞。方法 1函数指针表比 switch 更灵活的状态机核心逻辑把每个状态的处理逻辑封装成独立函数用一个「函数指针数组」映射状态和函数替代 switch 的 case 分支// 1. 定义状态和之前一致 typedef enum { DS18B20_STATE_IDLE, DS18B20_STATE_RESET, // ... 其他状态 } DS18B20_StateTypeDef; // 2. 定义状态处理函数的指针类型 typedef void (*DS18B20_StateFunc)(void); // 3. 实现每个状态的处理函数 void ds18b20_idle(void) { ds18b20.timestamp HAL_GetTick(); ds18b20.state DS18B20_STATE_RESET; } void ds18b20_reset(void) { DS18B20_SetPinLow(); ds18b20.timestamp HAL_GetTick(); ds18b20.state DS18B20_STATE_WAIT_PRESENCE; } void ds18b20_wait_presence(void) { if(HAL_GetTick() - ds18b20.timestamp 1) { // 检查应答切换状态 } } // 4. 函数指针数组状态和函数一一对应 static const DS18B20_StateFunc ds18b20_state_funcs[] { ds18b20_idle, ds18b20_reset, ds18b20_wait_presence, // ... 其他状态函数 }; // 5. 主处理函数替代switch void DS18B20_Process(void) { if(ds18b20.state sizeof(ds18b20_state_funcs)/sizeof(DS18B20_StateFunc)) { ds18b20_state_funcs[ds18b20.state](); // 调用当前状态的函数 } }优缺点优点缺点代码模块化更强每个状态逻辑独立易维护代码量比 switch 多新手理解稍难扩展新状态只需加函数 数组项无需改 Process函数调用有极轻微的性能开销嵌入式中可忽略O2 优化下和 switch 一样稳定volatile 保护变量即可-适用场景项目复杂、状态多比如同时处理多个传感器需要高模块化的场景。方法 2硬件定时器中断彻底脱离主循环核心逻辑用芯片的定时器比如 TIM1/TIM2代替 SysTick通过中断触发 DS18B20 的每一步时序主循环完全不用管只处理最终结果// 1. 初始化定时器比如1us中断一次精准控制时序 void TIM_Init(void) { // 配置TIM2核心时钟25MHz预分频0自动重装241us中断 TIM2-ARR 24; TIM2-PSC 0; TIM2-DIER | TIM_DIER_UIE; // 使能更新中断 NVIC_EnableIRQ(TIM2_IRQn); // 开启中断 TIM2-CR1 | TIM_CR1_CEN; // 启动定时器 } // 2. 定时器中断服务函数处理DS18B20时序 volatile uint8_t ds18b20_step 0; // 步骤标记volatile void TIM2_IRQHandler(void) { if(TIM2-SR TIM_SR_UIF) { TIM2-SR ~TIM_SR_UIF; // 清中断标志 switch(ds18b20_step) { case 0: // 步骤0拉低总线复位 DS18B20_SetPinLow(); ds18b20_step 1; break; case 1: // 步骤1拉低480us后释放480个1us中断 static uint16_t cnt 0; cnt; if(cnt 480) { DS18B20_SetPinHigh(); cnt 0; ds18b20_step 2; } break; case 2: // 步骤2等待15us应答15个1us中断 // ... 后续步骤 break; } } } // 3. 主循环只处理温度结果 int main(void) { HAL_Init(); TIM_Init(); while(1) { if(ds18b20_temp_ready) { // 温度读取完成标志 printf(Temp: %.2f°C\r\n, ds18b20_temp); ds18b20_temp_ready 0; } // 其他业务逻辑完全不被DS18B20阻塞 } }优缺点优点缺点时序精度最高us 级完全不占用主循环资源中断嵌套需注意优先级比如 TIM 中断优先级要高于 SysTick主循环可专注处理其他任务非阻塞性极致代码复杂度高需要熟悉定时器配置和中断管理O2 优化下稳定中断服务函数的变量加 volatile 即可多传感器时需分配不同定时器 / 中断优先级易冲突适用场景对时序精度要求极高比如高速通信、主循环任务密集比如实时控制的场景。方法 3轮询标记法极简版非阻塞核心逻辑放弃状态机只用几个「时间标记 阶段标记」在主循环里轮询判断适合超简单的场景// 极简版非阻塞DS18B20读取 volatile uint8_t ds18b20_phase 0; // 阶段标记0空闲1复位2等转换3读数据 volatile uint32_t ds18b20_mark 0; // 时间标记 void DS18B20_Simple_Process(void) { uint32_t now HAL_GetTick(); if(ds18b20_phase 0) { // 空闲启动复位 DS18B20_SetPinLow(); ds18b20_mark now; ds18b20_phase 1; } else if(ds18b20_phase 1) { // 复位等480us if(now - ds18b20_mark 1) { // 1ms覆盖480us DS18B20_SetPinHigh(); // 发送转换指令 DS18B20_SendByte(0xCC); DS18B20_SendByte(0x44); ds18b20_mark now; ds18b20_phase 2; } } else if(ds18b20_phase 2) { // 等转换750ms if(now - ds18b20_mark 750) { // 读取温度数据 uint16_t temp DS18B20_ReadTemp(); printf(Temp: %.2f°C\r\n, (float)temp/16.0f); ds18b20_phase 0; // 回到空闲 } } } // 主循环 int main(void) { while(1) { DS18B20_Simple_Process(); // 其他逻辑 } }优缺点优点缺点代码极简新手易理解无需状态机 / 中断扩展性差加新步骤需加 else if代码会变臃肿O2 优化下稳定标记变量加 volatile 即可时序拆分不够细复杂场景易出错适用场景项目极简单只读取 DS18B20无其他复杂任务追求代码量少的场景。方法对比与选型建议方法复杂度非阻塞性O2 兼容性适用场景switch 状态机低中高优绝大多数嵌入式场景推荐新手函数指针表中中高优复杂项目、多状态、需模块化硬件定时器中断高极高优高精度时序、主循环任务密集轮询标记法极低中优超简单场景、快速实现总结新手首选switch 状态机平衡了简洁性和实用性适配 O2 优化非阻塞效果好复杂项目函数指针表模块化强易维护高精度需求硬件定时器中断时序最准主循环无负担极简需求轮询标记法代码最少易上手。所有方法的核心都是「拆分流程 时间戳 / 硬件中断 volatile 保护」这是 O2 优化下稳定运行的关键区别只在代码组织形式。你这个问题直击嵌入式开发的核心痛点 ——中断确实可能打乱 DS18B20 的时序但只要做好「优先级 时序保护」就能完全避免。我会拆解 “为什么会乱”、“怎么防乱”用最贴近实际开发的逻辑讲清楚先给核心结论中断本身不是一定会导致 DS18B20 时序错乱而是「不合理的中断配置」才会出问题只要让DS18B20 的时序处理中断优先级最高就能让它的通信时序 “不被任何中断打断”。一、为什么中断会 “打乱” DS18B20 时序DS18B20 的单总线时序是微秒级的硬要求比如拉低总线必须精准 480us位传输必须 60~120us一旦被其他中断打断就会超时 / 时序错位举个反面例子时序必乱假设你用「主循环 SysTick 中断1ms」处理 DS18B20DS18B20 正在执行 “拉低总线 480us” 的步骤还没到 480us此时来了一个「串口接收中断」优先级比 SysTick 高CPU 去处理串口数据耗时 200us回到 DS18B20 时总线已经被拉低了 480200680us远超规范要求DS18B20 直接通信失败。本质问题DS18B20 的微秒级时序被「更高优先级的中断」抢占导致实际耗时超过规范值。二、怎么让中断 “不影响” DS18B20 时序核心思路让处理 DS18B20 时序的中断成为系统中优先级最高的中断没有任何中断能打断它。方案 1给 DS18B20 的时序中断设最高优先级推荐如果用「硬件定时器中断」处理 DS18B20比如 TIM2 做 1us 中断配置如下// 1. 配置NVIC优先级分组比如分组34位抢占优先级0位子优先级 NVIC_SetPriorityGrouping(3); // 2. 给TIM2DS18B20时序中断设最高抢占优先级0级 NVIC_SetPriority(TIM2_IRQn, 0); // 0是最高优先级数值越小优先级越高 NVIC_EnableIRQ(TIM2_IRQn); // 3. 其他中断串口、SysTick、按键设更低优先级比如1/2/3级 NVIC_SetPriority(USART1_IRQn, 1); NVIC_SetPriority(SysTick_IRQn, 2); NVIC_SetPriority(EXTI0_IRQn, 3);效果当 TIM2 中断DS18B20 时序触发时所有其他中断都必须等它处理完才能执行DS18B20 的 us 级时序完全不受干扰。方案 2关键时序阶段 “关闭全局中断”极简如果不用硬件中断而是在主循环处理 DS18B20 的关键时序可临时关闭所有中断避免被打断// DS18B20发送1位的核心函数关键时序加中断保护 void DS18B20_SendBit(uint8_t bit) { __disable_irq(); // 关闭全局中断禁止任何中断打断 // 关键时序拉低总线1us绝对不能被打断 DS18B20_SetPinLow(); uint32_t start SysTick-VAL; while((SysTick-VAL - start) 25); // 1us25个时钟周期 // 发送位电平 if(bit) DS18B20_SetPinHigh(); else DS18B20_SetPinLow(); // 保持位时序60us同样不能被打断 start SysTick-VAL; while((SysTick-VAL - start) 1500); // 60us1500个时钟周期 DS18B20_SetPinHigh(); __enable_irq(); // 恢复全局中断 }注意只在「us 级的关键时序段」关中断不要全程关否则其他中断会丢失比如串口数据、按键O2 优化下__disable_irq()/__enable_irq()是编译器内置函数不会被优化可放心用。方案 3用 “原子操作” 保护时序变量辅助对 DS18B20 的状态、时间戳等变量除了加volatile还可以用「原子操作」避免中断导致的变量读写错误// 原子写入时间戳避免中断中同时读写 __STATIC_INLINE void DS18B20_SetTimestamp(uint32_t ts) { __disable_irq(); ds18b20.timestamp ts; __enable_irq(); } // 原子读取状态避免读到一半被中断修改 __STATIC_INLINE DS18B20_StateTypeDef DS18B20_GetState(void) { DS18B20_StateTypeDef state; __disable_irq(); state ds18b20.state; __enable_irq(); return state; }三、不同场景的中断适配建议场景中断处理方式核心要点用 switch 状态机主循环 SysTick关键时序段临时关中断只关 us 级时序别全程关用硬件定时器中断TIMTIM 设最高优先级其他中断优先级低于 TIM多传感器DS18B20DHT11给每个传感器的时序中断分不同优先级DS18B20 优先级 DHT11 其他四、实操验证怎么确认时序没被中断影响逻辑分析仪抓波形用逻辑分析仪接 DS18B20 的总线查看拉低、释放、位传输的时间是否符合规范480us 拉低、60us 位时序打印时序耗时在关键步骤记录开始 / 结束时间打印耗时确认没有被中断拉长uint32_t start HAL_GetTick(); DS18B20_SendByte(0xCC); uint32_t end HAL_GetTick(); printf(Send byte cost: %lu us\r\n, (end - start)*1000); // 正常应≈8*60480us极限测试让串口、按键等中断高频触发比如串口每秒发 1000 帧数据观察 DS18B20 的温度读取是否稳定。总结中断不是DS18B20 时序的 “敌人”「不合理的中断优先级 / 未保护关键时序」才是核心解决方案要么让 DS18B20 的时序中断优先级最高要么在关键 us 级时序段临时关中断O2 优化下只要用volatile保护变量、用__disable_irq()保护关键时序中断就不会影响通信稳定性。简单说只要让 DS18B20 的微秒级时序 “不被任何中断打断”中断就不会导致时序变化。我帮你把杰哥说的 “定时器 关中断” 方案拆解成可直接落地的步骤你照着做就能解决 DS18B20 阻塞的问题1. 核心思路拆解杰哥的方案本质是用定时器做非阻塞计时把 DS18B20 的 750ms 转换时间交给硬件定时器去数CPU 不用死等。关键时序关中断在 DS18B20 的微秒级通信阶段复位、读写位临时关闭全局中断保证时序不被打断通信完成后立刻打开中断不影响其他程序。2. 具体实现步骤步骤 1配置一个通用定时器比如 TIM2目标让定时器每 1ms 中断一次用来计时 DS18B20 的 750ms 转换时间。配置示例以 25MHz 系统时钟为例void TIM2_Init(void) { // 开启TIM2时钟 CKCU_PeripClockConfig_TypeDef CKCUClock {{0}}; CKCUClock.Bit.TIM2 1; CKCU_PeripClockConfig(CKCUClock, ENABLE); // 配置TIM2预分频25000-1自动重装载值1000-1 → 1ms中断 TIM2-PSC 24999; // 25MHz / 25000 1kHz TIM2-ARR 999; // 1kHz / 1000 1Hz → 1ms // 使能更新中断 TIM2-DIER | TIM_DIER_UIE; // 配置中断优先级比DS18B20低避免抢占关键时序 NVIC_SetPriority(TIM2_IRQn, 2); NVIC_EnableIRQ(TIM2_IRQn); // 启动定时器 TIM2-CR1 | TIM_CR1_CEN; }步骤 2在定时器中断里做非阻塞计时定义一个全局计时变量在中断里累加用来判断 750ms 是否到了volatile uint32_t tim2_tick 0; void TIM2_IRQHandler(void) { if(TIM2-SR TIM_SR_UIF) { TIM2-SR ~TIM_SR_UIF; // 清中断标志 tim2_tick; } }步骤 3DS18B20 关键时序段关中断在复位、读写位这些微秒级操作时用__disable_irq()关中断完成后立刻__enable_irq()// 复位脉冲480us uint8_t DS18B20_Reset(void) { uint8_t presence 0; __disable_irq(); // 关中断保护时序 DS18B20_SetOutputMode(); DS18B20_SetPinLow(); Delay_us(480); // 精确延时此时无中断干扰 DS18B20_SetPinHigh(); DS18B20_SetInputMode(); Delay_us(60); // 等待存在脉冲 presence !DS18B20_ReadPin(); // 检测存在脉冲 __enable_irq(); // 恢复中断 return presence; } // 读一个bit关键时序 uint8_t DS18B20_ReadBit(void) { uint8_t bit 0; __disable_irq(); DS18B20_SetOutputMode(); DS18B20_SetPinLow(); Delay_us(1); DS18B20_SetPinHigh(); DS18B20_SetInputMode(); Delay_us(15); // 15us后采样 bit DS18B20_ReadPin(); __enable_irq(); return bit; }步骤 4用定时器计时实现非阻塞转换用tim2_tick来判断 750ms 转换时间而不是用Delay_ms(750)死等volatile uint8_t ds18b20_state 0; volatile uint32_t convert_start_tick 0; void DS18B20_NonBlock_Process(void) { switch(ds18b20_state) { case 0: // 空闲启动转换 if(DS18B20_Reset()) { // 复位成功 DS18B20_SendByte(0xCC); // 跳过ROM DS18B20_SendByte(0x44); // 启动转换 convert_start_tick tim2_tick; ds18b20_state 1; // 进入等待转换状态 } break; case 1: // 等待转换完成750ms if(tim2_tick - convert_start_tick 750) { ds18b20_state 2; // 进入读取状态 } break; case 2: // 读取温度 if(DS18B20_Reset()) { DS18B20_SendByte(0xCC); DS18B20_SendByte(0xBE); uint8_t temp_lsb DS18B20_ReadByte(); uint8_t temp_msb DS18B20_ReadByte(); int16_t temp (temp_msb 8) | temp_lsb; float temperature temp / 16.0f; printf(Temp: %.2f°C\r\n, temperature); ds18b20_state 0; // 回到空闲 } break; default: ds18b20_state 0; break; } }步骤 5主循环调用非阻塞处理函数在while(1)里循环调用DS18B20_NonBlock_Process()CPU 不会被卡死int main(void) { HAL_Init(); TIM2_Init(); DS18B20_Init(); USART_Init(); while(1) { DS18B20_NonBlock_Process(); // 非阻塞处理DS18B20 // 其他程序逻辑按键、串口、LED等 } }3. 为什么这样就不卡了定时器计时750ms 的转换时间交给 TIM2 中断去数CPU 在这期间可以处理其他任务不用死等。关中断保护只有在复位、读写位这些微秒级关键操作时才关中断时间极短对其他程序影响微乎其微。状态机驱动整个流程被拆成多个小步骤每次只做一步做完就退出CPU 立刻去干别的。你问的__disable_irq()和__enable_irq()是嵌入式开发中控制全局中断的核心函数我会把它的「本质、来源、替代方案」讲得明明白白新手也能直接落地一、先给核心结论__disable_irq()/__enable_irq()是ARM Cortex-M 内核自带的编译器内置函数不是 MCU 厂商加的绝大多数编译器Keil MDK、GCC、IAR都原生支持如果你的环境里没有极罕见也能通过直接操作内核寄存器实现完全相同的效果。二、这两个函数到底是什么从哪来1. 本质操作 Cortex-M 内核的「PRIMASK 寄存器」Cortex-M 系列 MCU比如你用的 XM1002 大概率是 Cortex-M3/M4有一个核心寄存器PRIMASK当PRIMASK1时关闭所有可屏蔽中断除了 NMI、HardFault 等不可屏蔽的致命中断当PRIMASK0时恢复所有中断。__disable_irq()/__enable_irq()就是编译器封装的、操作这个寄存器的 “快捷指令”底层对应 ARM 汇编指令表格函数底层汇编指令作用__disable_irq()CPSID I置 PRIMASK1关闭全局中断__enable_irq()CPSIE I置 PRIMASK0开启全局中断2. 来源编译器内置无需手动定义Keil MDKARMCC/AC6自带直接用无需包含额外头文件GCCarm-none-eabi-gcc自带也可通过#include cmsis_gcc.h显式引用IAR自带也可通过#include cmsis_iccarm.h显式引用。简单说只要你的编译器是针对 Cortex-M 内核的这两个函数就 “本来就有”直接调用即可。三、如果真的 “没有”比如编译器兼容问题怎么办如果遇到极端情况比如小众编译器不支持这两个函数可以手动操作 PRIMASK 寄存器效果完全一样方案 1手动写内联汇编通用// 替代__disable_irq() static inline void disable_irq(void) { __asm volatile (CPSID I); // 汇编指令关闭全局中断 } // 替代__enable_irq() static inline void enable_irq(void) { __asm volatile (CPSIE I); // 汇编指令开启全局中断 }方案 2通过 CMSIS 库操作寄存器更易读Cortex-M 的 CMSIS 库提供了寄存器操作接口可直接读写 PRIMASK#include core_cm3.h // 根据内核选M3/M4/M0 // 替代__disable_irq() #define disable_irq() (__set_PRIMASK(1)) // 替代__enable_irq() #define enable_irq() (__set_PRIMASK(0))四、使用注意事项关键成对使用关中断后一定要开否则系统会卡死所有中断都被屏蔽包括 SysTick、串口等缩短关中断时间只在 DS18B20 的微秒级关键时序复位、读写位关中断完成后立刻开比如uint8_t DS18B20_ReadBit(void) { uint8_t bit 0; disable_irq(); // 关中断仅几十微秒 // 关键时序操作1us拉低 15us采样 DS18B20_SetPinLow(); Delay_us(1); DS18B20_SetPinHigh(); Delay_us(15); bit DS18B20_ReadPin(); enable_irq(); // 立刻开中断 return bit; }O2 优化下稳定无论是内置函数还是手动汇编O2 优化都不会影响 —— 因为操作的是硬件寄存器编译器不敢优化。总结__disable_irq()/__enable_irq()是 Cortex-M 内核编译器原生自带的函数本质是操作 PRIMASK 寄存器关闭 / 开启全局中断若编译器不支持可通过「内联汇编」或「CMSIS 寄存器操作」实现完全相同的效果核心用法只在 DS18B20 微秒级关键时序关中断完成后立刻开启保证时序不被打断且不影响其他中断。你可以放心用这两个函数嵌入式里处理微秒级精准时序时这是最常用、最稳定的方案。总结非阻塞的核心可以极简概括为用「标志位 / 时间戳记录状态」「条件判断检查进度」替代「死等的 delay 循环」—— 不卡在某一步每次只做 “查状态→按状态执行一小步”没到条件就退出CPU 始终能处理其他任务。补充标志位既可以是 “步骤标记如 ds18b20_state”也可以是 “时间戳如 start_tick”判断既可以是 “状态值判断”也可以是 “时间差判断”本质都是 “查完就走不等不卡”。

相关新闻

模拟器构建实战指南:从环境搭建到性能优化的PCSX2全流程解析

模拟器构建实战指南:从环境搭建到性能优化的PCSX2全流程解析

模拟器构建实战指南:从环境搭建到性能优化的PCSX2全流程解析 【免费下载链接】pcsx2 PCSX2 - The Playstation 2 Emulator 项目地址: https://gitcode.com/GitHub_Trending/pc/pcsx2 PlayStation 2模拟器PCSX2的构建过程常令开发者却步,复杂的跨平…

2026/5/17 4:01:38 阅读更多 →
讲故事”到“开火”:2026 年我见过最靠谱的几种 AI 落地模式

讲故事”到“开火”:2026 年我见过最靠谱的几种 AI 落地模式

摘要: 如果说 2023 年是 AI 的“故事会”,2024 年是“Demo 战”,那么 2026 年就是刺刀见红的“开火时刻”。当资本热潮退去,谁在裸泳一目了然。本文剖析了 2026 年依然坚挺的三种 AI 落地模式,揭示了从 ToC 玩具到 ToB 生产力的底…

2026/7/2 21:13:27 阅读更多 →
世界模型到底比大语言模型强在哪里?用一个小游戏项目说清楚

世界模型到底比大语言模型强在哪里?用一个小游戏项目说清楚

摘要: 当 GPT-4 还在做“文字接龙”时,Sora 和 DeepMind 的 Genie 已经开始理解物理规律了。本文通过手撸一个 300 行的 Python 小游戏,带你直观感受“世界模型”如何吊打“大语言模型”,并揭示为什么 Yann LeCun 说 LLM 是通往 AGI 的死胡同…

2026/5/17 4:01:32 阅读更多 →

最新新闻

Windows 11本地部署GLM-5.2:集成Claw与Agent知识库的AI智能体实践

Windows 11本地部署GLM-5.2:集成Claw与Agent知识库的AI智能体实践

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 如果你正在寻找一个能在本地高效运行、支持复杂AI智能体(Agent)和知识库功能,并且完全兼容Windows…

2026/7/4 3:56:00 阅读更多 →
奇门取号报“订单号不一致”?一次 trade_order_list 的排查实录

奇门取号报“订单号不一致”?一次 trade_order_list 的排查实录

奇门取号报“订单号不一致”?一次 trade_order_list 的排查实录 摘要:在多包裹奇门取号时,系统突然报错“子母件批量取号订单号应保持一致”。经过逐层排查发现,请求中每个包裹的 trade_order_list 都包含了全部明细的不同订单号&…

2026/7/4 3:56:00 阅读更多 →
Kimi    LeetCode 3454. 分割正方形 II C++实现

Kimi LeetCode 3454. 分割正方形 II C++实现

这是 LeetCode 3454. 分割正方形 II 的 C 实现,基于扫描线 线段树算法。核心思路题目要求找到一条水平线 y k,使得该线以上和以下的正方形并集面积相等。由于正方形可能重叠,需要使用扫描线算法:1. 离散化 x 坐标:收…

2026/7/4 3:56:00 阅读更多 →
Java SHA256加密实战:从原理到密码存储与API签名的完整指南

Java SHA256加密实战:从原理到密码存储与API签名的完整指南

1. 项目概述:为什么我们需要SHA256? 在开发中,处理敏感数据是家常便饭,无论是用户密码、支付凭证还是API签名。直接存储明文密码是开发中的大忌,一旦数据库泄露,后果不堪设想。因此,我们必须对这…

2026/7/4 3:51:58 阅读更多 →
数据产业服务分类(25)——数据要素——数据要素转化的主体

数据产业服务分类(25)——数据要素——数据要素转化的主体

人是数据要素与其他生产要素转化的核心与主体。实践活动是纽带数据与现实世界并非彼此割裂、独立存在,而是通过人类实践活动这一关键纽带实现了紧密相连。人类实践活动充当着数据与现实世界连接的桥梁。人类在现实世界中开展各类实践活动,这些活动产生了…

2026/7/4 3:49:58 阅读更多 →
揭秘租赁行业潜规则:为什么大厂都在租翻新打印机?

揭秘租赁行业潜规则:为什么大厂都在租翻新打印机?

很多人好奇,为什么大型企业、连锁公司、上市公司,明明有预算,却偏偏不租新机,反而首选翻新打印机?今天揭秘租赁行业没人说的真话。一、大厂只看实用性,不看面子对专业企业来说,打印机只是办公工…

2026/7/4 3:49:58 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻