1. 项目概述与核心价值在嵌入式开发和精密仪器设计中温度监测是一个绕不开的基础课题。无论是确保CPU不过热还是监控电池组的安全状态一个可靠、精确且易于集成的温度传感器往往是系统稳定性的第一道防线。我接触过不少温度传感方案从早期的模拟输出型到如今的数字接口型深刻体会到选型时在精度、功耗、接口和封装之间做权衡的纠结。今天想和大家深入聊聊一款我个人在多个低功耗项目中反复使用并验证过的“老兵”——德州仪器TI的LM73数字温度传感器。LM73是一款集成了增量式Delta-Sigma模数转换器ADC的芯片它通过SMBus/I2C兼容的两线接口与主控制器通信。其核心价值在于它在一个仅有2.9mm x 1.6mm的SOT-23-6微型封装内实现了从-40°C到150°C的宽温范围测量在-10°C至80°C的常用区间内精度可达±1°C。更吸引人的是它允许用户在11位0.25°C/LSB到14位0.03125°C/LSB之间动态编程分辨率从而在转换速度和测量灵敏度之间取得最佳平衡。默认的11位模式下最快14毫秒即可完成一次转换这对于需要快速上电并获取温度读数的应用至关重要。而其典型工作电流仅320微安在完全关断模式下更是能低至1.9微安这种特性让它成为电池供电的便携设备、物联网节点和需要长期待机的系统的理想选择。2. 核心特性与设计思路拆解2.1 为何选择Delta-Sigma ADC架构在深入寄存器操作之前理解LM73的核心——增量式Delta-Sigma ADC——至关重要。这与我们常见的逐次逼近型ADCSAR ADC在设计哲学上截然不同。SAR ADC追求的是单次采样的高速和精确而Delta-Sigma ADC的核心思想是“用过采样和噪声整形来换取高分辨率”。你可以把它想象成一位非常谨慎的统计员。它不以单次快速测量为准而是在一个周期内进行极高频率的采样远高于奈奎斯特频率然后将这些大量的、低精度的采样结果进行累加和数字滤波最终输出一个高精度的结果。这种架构天生对噪声不敏感因为噪声被“平均”掉了并且通过噪声整形技术将量化噪声推到了高频段再通过数字滤波器轻松滤除。这正是LM73能够实现高达14位分辨率0.03125°C和“非常稳定、低噪声数字输出”的根本原因。当然代价就是转换时间随分辨率提升而线性增加从11位的14毫秒到14位的112毫秒。注意这里的“增量式”前缀意味着每个转换周期都是独立的从零开始积分这简化了设计避免了传统Delta-Sigma ADC中可能存在的初始状态残留误差问题保证了每次读数的独立性。2.2 接口兼容性SMBus与I2C的微妙平衡LM73宣称兼容SMBus和I2C这对于工程师来说是极大的便利但我们必须清楚其中的细微差别。SMBus是基于I2C的但更“严格”和“电源友好”。电气特性SMBus规定了更严格的逻辑电平VIH/VIL和更低的上下拉电流这使得它在混合电压系统中更安全。LM73的输入逻辑门限0.7VDD和0.3VDD以及最高400kHz的时钟频率完全满足SMBus 2.0规范。其数据线SMBDAT和时钟线SMBCLK内部集成了低通滤波器这是应对工业环境或长走线中噪声干扰的贴心设计。超时复位功能这是LM73一个非常实用的SMBus特性。如果SMBDAT或SMBCLK线因任何原因被意外拉低超过15-45毫秒tTIMEOUT芯片内部的SMBus状态机会自动复位释放总线。这意味着即使主控制器程序跑飞或硬件故障导致总线死锁LM73也能自行恢复无需处理器干预或断电重启极大地增强了系统的鲁棒性。不支持时钟拉伸需要明确的是LM73作为从设备永远不会主动拉低SMBCLK线即不支持Clock Stretching。所有时序完全由主控制器主导。2.3 低功耗设计的精髓关断与单次转换模式低功耗不是一句空话LM73通过硬件和寄存器配置提供了清晰的实现路径。完全关断模式通过配置寄存器的Bit 7PD为1并保持至少一个完整转换周期的时间LM73会进入完全关断模式。此时典型电流仅1.9µA最大8µA。这对于99%时间处于睡眠仅需周期性唤醒测温的系统来说是节省电池电量的关键。单次转换模式这是关断模式下的“黄金搭档”。当芯片处于关断状态时向配置寄存器的Bit 2ONE SHOT写入1会触发一次且仅一次温度转换。转换完成后结果更新到温度寄存器芯片自动回到关断状态。这样你可以精确控制测温的频率比如每分钟、每十分钟唤醒一次将平均功耗降至极低水平。计算一下假设每10分钟600秒进行一次14位精度的转换最长112ms工作电流按495µA算关断电流按8µA算那么平均电流 ≈ (0.112s * 495µA 599.888s * 8µA) / 600s ≈ 8.1µA。这个数字对于依靠纽扣电池工作数年的设备来说是完全可以接受的。3. 硬件设计与电路连接要点3.1 引脚定义与地址配置LM73采用SOT-23-6封装引脚极其精简VDD (Pin 3)2.7V至5.5V供电推荐在靠近芯片引脚处放置一个0.1µF的陶瓷去耦电容到GND。GND (Pin 2)电源地。SMBDAT (Pin 6)开漏输出的双向数据线必须外接上拉电阻。SMBCLK (Pin 4)时钟输入线同样建议外接上拉电阻。ALERT (Pin 5)开漏输出的报警中断引脚当温度超过THIGH寄存器设定值时拉低或拉高取决于极性配置。ADDR (Pin 1)地址选择引脚。这是实现多设备同总线共存的关键。它支持三态输入接地GND 对应地址位A01悬空Floating 对应地址位A00接VDD 对应地址位A02(逻辑高) 结合芯片本身的版本LM73-0或LM73-1由固定位区分最多可在一条总线上挂载6个不同的LM73。具体7位从机地址格式为1001 A2 A1 A0 R/W。其中A2 A1是芯片型号固定位LM73-0为00LM73-1为01A0由ADDR引脚状态决定。3.2 上拉电阻的选择与计算SMBDAT和SMBCLK线的上拉电阻Rp选择是个权衡艺术它直接影响通信速率、功耗和噪声容限。下限值Rp_min由总线电容Cb和最大上升时间要求决定。SMBus规范对上升时间Tr有要求。公式近似为Rp_min Tr / (0.8473 * Cb)。对于400kHz总线上升时间通常需小于300ns。假设总线电容为200pF包括PCB走线、连接器和所有器件输入电容则Rp_min 300ns / (0.8473 * 200pF) ≈ 1.77 kΩ。我们不能低于这个值太多否则上升沿会太缓。上限值Rp_max由逻辑低电平的VOL最大0.4V和LM73的最大下拉电流IOL3mA决定。根据欧姆定律Rp_max (VDD - VOL) / IOL。假设VDD3.3V则Rp_max (3.3V - 0.4V) / 3mA ≈ 967 Ω。注意这个计算基于LM73作为输出时的驱动能力。实际上总线上所有设备的下拉晶体管是并联的总电流可能更大所以Rp需要更小以满足所有设备的VOL要求。功耗与自热考虑电阻越小当总线被拉低时从VDD到GND的电流路径电阻就越小电流越大I VDD / Rp功耗也越大。这部分功耗不仅消耗系统电量如果电阻离LM73太近产生的焦耳热还可能轻微影响其温度测量精度。因此在满足上升时间和VOL要求的前提下应尽可能选择较大的阻值。实操建议对于3.3V系统总线电容在100-200pF的典型应用一个4.7kΩ到10kΩ的电阻是一个很好的起点。你可以用示波器观察一下SCL和SDA信号的上升沿确保其干净、陡峭。如果总线上设备较多、走线较长电容增大可能需要减小到2.2kΩ甚至1kΩ。3.3 ALERT中断引脚的应用设计ALERT引脚是开漏输出需要上拉电阻通常与SMBDAT共用上拉或单独使用一个10kΩ电阻。其工作逻辑如下触发每次转换结束后芯片将测量温度与THIGH寄存器值比较仅比较高11位。若超过则ALERT引脚有效默认低电平有效。清除条件三者之一温度回落测量温度低于TLOW寄存器值。软件复位主机向配置寄存器的ALERT Reset位Bit 3写1。SMBus警报响应地址ARA主机通过广播特定的ARA0001 100来查询是哪台设备报警被查询的设备会自动清除其ALERT状态。极性设置通过配置寄存器的ALERT Polarity位Bit 4可以设置报警有效电平为高或低方便连接不同极性中断输入的MCU。这个功能非常适合用于系统过热保护。你可以将THIGH设置为85°CTLOW设置为80°C这样当温度超过85°C时产生中断MCU收到后可以启动风扇或降低系统性能直到温度回落到80°C以下报警才自动解除避免了在临界点附近的频繁中断。4. 寄存器详解与软件驱动实现驱动LM73的本质就是通过I2C读写其内部寄存器。理解每个寄存器的位定义是编写稳定驱动程序的基础。4.1 指针寄存器Pointer Register - 地址选择器这是一个8位寄存器但只有低3位P2, P1, P0有效用于选择接下来要访问的6个功能寄存器之一。这是一个关键但易错点指针寄存器具有“锁存”功能。一旦设置它会记住最后一个被访问的寄存器地址直到你下次更改它。这带来了两种读数据的方式方式A预设指针如果之前已经设置过指针比如指向温度寄存器00h那么后续的读操作可以直接发送设备地址读并读取数据无需再次发送指针字节。效率最高。方式B设置指针后读在一次复合操作中先发送设备地址写指针字节然后发送重复起始条件Repeated Start设备地址读最后读取数据。这是最通用、最不易出错的方式。注意数据手册明确警告向指针寄存器写入无效地址非000-111的操作将不会被应答NACK且指针寄存器内容保持不变。你的驱动代码必须确保只发送合法的指针值。4.2 温度数据寄存器Temperature Data Register - 00h这是最常访问的寄存器只读16位。数据以二进制补码形式、左对齐格式存储。数据格式解析假设我们读取到两个字节0x0C和0x80。合并为16位0x0C80。二进制0000 1100 1000 0000。这是左对齐的。最高位Bit 15是符号位0为正。在11位分辨率下默认有效数据是Bit 15到Bit 5共11位。所以我们取高11位000 1100 1000。将其右移5位因为低5位是未用的得到0000 0001 1001即十进制25。因此温度是 25°C。 在14位分辨率下有效数据是Bit 15到Bit 2右移2位即可精度达到0.03125°C。上电与单次转换状态上电后或单次转换进行中数据可用标志DAV为0此时读取温度寄存器会得到固定值0x7FFC255.96875°C或0x8000-256°C这显然是无意义的数据。因此在首次读取或单次转换后读取前务必检查控制/状态寄存器04h的Bit 15DAV是否为1。4.3 配置寄存器Configuration Register - 01h这是一个可读写的8位寄存器控制芯片的核心工作模式。Bit 7 (PD): 关断使能。1关断0正常工作。Bit 6: 保留位必须写1。Bit 5 (ALRT_EN): ALERT输出使能。0使能默认1禁用。Bit 4 (ALRT_POL): ALERT极性。0低电平有效默认1高电平有效。Bit 3 (ALRT_RST): ALERT复位。写1清零ALERT引脚和状态位读始终为0。Bit 2 (ONE_SHOT): 单次转换。仅在关断模式PD1下有效写1触发一次转换。Bit 1-0: 保留位必须写0。配置示例想让芯片进入关断模式并使能高电平有效的ALERT中断应写入0b110100000xD0。4.4 阈值寄存器THIGH - 02h, TLOW - 03h与控制/状态寄存器Control/Status - 04hTHIGH/TLOW寄存器用于设置温度报警的上下限。格式与温度寄存器类似但**只使用高11位Bit 15:5**进行对比低5位保留。例如要设置上限为85°C11位模式下85/0.253400x154需要将0x154左移5位得到0x1540然后写入THIGH寄存器先高字节0x15后低字节0x40。控制/状态寄存器04hBit 15 (DAV): 数据可用标志。1温度寄存器数据有效0数据无效转换中或未开始。Bit 6-5 (RES1, RES0):分辨率设置位。这是LM73的精髓所在。00: 11位0.25°C/LSB转换时间14ms01: 12位0.125°C/LSB转换时间28ms10: 13位0.0625°C/LSB转换时间56ms11: 14位0.03125°C/LSB转换时间112msBit 4 (THI): 温度过高标志。比较结果锁存需软件清零通过读寄存器或特定操作。Bit 3 (TLO): 温度过低标志。同上。Bit 2 (ALRT_STAT): ALERT引脚状态镜像。与ALERT引脚电平一致。4.5 实操代码示例基于模拟I2C以下是一个用C语言编写的、针对STM32 HAL库的LM73基础驱动函数示例涵盖了初始化、设置分辨率、读取温度和报警处理的核心逻辑。// 根据ADDR引脚接线定义设备地址 #define LM73_I2C_ADDR_BASE 0x48 // 1001 000假设是LM73-0ADDR悬空 // 实际地址需要根据A0状态组合 (LM73_I2C_ADDR_BASE | (addr_pin_state 0x07)) 1 // addr_pin_state: 0GND, 1Floating, 2VDD (需根据实际电压判断通常按1处理) #define LM73_REG_TEMP 0x00 #define LM73_REG_CONFIG 0x01 #define LM73_REG_THIGH 0x02 #define LM73_REG_TLOW 0x03 #define LM73_REG_CTRLSTAT 0x04 typedef enum { LM73_RES_11BIT 0, // 0.25°C LM73_RES_12BIT, // 0.125°C LM73_RES_13BIT, // 0.0625°C LM73_RES_14BIT // 0.03125°C } LM73_Resolution_t; // 初始化LM73设置分辨率 HAL_StatusTypeDef LM73_Init(I2C_HandleTypeDef *hi2c, uint8_t dev_addr, LM73_Resolution_t res) { uint8_t config_data[2] {LM73_REG_CONFIG, 0x40}; // 默认配置ALERT使能低有效正常工作模式 uint8_t ctrl_data[3] {LM73_REG_CTRLSTAT, 0x00, 0x00}; // 准备设置分辨率 // 1. 首先读取当前控制状态寄存器以保留其他位 uint8_t read_buf[2]; if (HAL_I2C_Mem_Read(hi2c, dev_addr, LM73_REG_CTRLSTAT, I2C_MEMADD_SIZE_8BIT, read_buf, 2, HAL_MAX_DELAY) ! HAL_OK) { return HAL_ERROR; } // 2. 修改分辨率位Bit6, Bit5 ctrl_data[1] read_buf[0] 0x9F; // 清空RES1, RES0位 (Bit6, Bit5) ctrl_data[1] | (res 5); // 设置新的分辨率 ctrl_data[2] read_buf[1]; // 低字节保持不变 // 3. 写入新的控制状态寄存器值 if (HAL_I2C_Master_Transmit(hi2c, dev_addr, ctrl_data, 3, HAL_MAX_DELAY) ! HAL_OK) { return HAL_ERROR; } // 4. 可选设置温度阈值例如THIGH85°C, TLOW80°C (11-bit mode) uint16_t thigh_val (85 / 0.25) 5; // 85°C - 0x1540 uint8_t thigh_buf[3] {LM73_REG_THIGH, (uint8_t)(thigh_val 8), (uint8_t)(thigh_val 0xFF)}; if (HAL_I2C_Master_Transmit(hi2c, dev_addr, thigh_buf, 3, HAL_MAX_DELAY) ! HAL_OK) { // 阈值设置非关键可记录错误但不一定返回失败 } uint16_t tlow_val (80 / 0.25) 5; // 80°C - 0x1400 uint8_t tlow_buf[3] {LM73_REG_TLOW, (uint8_t)(tlow_val 8), (uint8_t)(tlow_val 0xFF)}; HAL_I2C_Master_Transmit(hi2c, dev_addr, tlow_buf, 3, HAL_MAX_DELAY); // 忽略错误 return HAL_OK; } // 读取温度阻塞式等待数据就绪 float LM73_ReadTemperature(I2C_HandleTypeDef *hi2c, uint8_t dev_addr, LM73_Resolution_t res) { uint8_t temp_data[2]; uint8_t ctrl_data[2]; int16_t raw_temp; float temperature; // 1. 等待数据就绪 (DAV bit 1) do { if (HAL_I2C_Mem_Read(hi2c, dev_addr, LM73_REG_CTRLSTAT, I2C_MEMADD_SIZE_8BIT, ctrl_data, 2, HAL_MAX_DELAY) ! HAL_OK) { return -273.15f; // 返回绝对零度表示错误 } // DAV是控制状态寄存器的高字节最高位 } while ((ctrl_data[0] 0x80) 0); // 2. 读取温度寄存器 if (HAL_I2C_Mem_Read(hi2c, dev_addr, LM73_REG_TEMP, I2C_MEMADD_SIZE_8BIT, temp_data, 2, HAL_MAX_DELAY) ! HAL_OK) { return -273.15f; } // 3. 合并数据并转换 raw_temp (temp_data[0] 8) | temp_data[1]; // 将16位左对齐的补码转换为带符号整数 raw_temp (16 - (11 res)); // 根据分辨率右移11位分辨率下右移5位14位下右移2位 // 4. 转换为摄氏度 // 11位: LSB 0.25°C; 12位: 0.125°C; 13位: 0.0625°C; 14位: 0.03125°C float lsb_size 0.25f / (1 res); // 计算当前分辨率下的LSB值 temperature raw_temp * lsb_size; return temperature; } // 进入关断模式 HAL_StatusTypeDef LM73_EnterShutdown(I2C_HandleTypeDef *hi2c, uint8_t dev_addr) { uint8_t shutdown_cmd[2] {LM73_REG_CONFIG, 0xC0}; // 设置PD1, 保留位1 return HAL_I2C_Master_Transmit(hi2c, dev_addr, shutdown_cmd, 2, HAL_MAX_DELAY); } // 触发单次转换必须在关断模式下调用 HAL_StatusTypeDef LM73_TriggerOneShot(I2C_HandleTypeDef *hi2c, uint8_t dev_addr) { uint8_t oneshot_cmd[2] {LM73_REG_CONFIG, 0xC4}; // PD1, ONE_SHOT1 return HAL_I2C_Master_Transmit(hi2c, dev_addr, oneshot_cmd, 2, HAL_MAX_DELAY); }5. 高级应用与低功耗策略实战5.1 优化功耗的实战策略仅仅知道有关断和单次转换模式是不够的如何将其融入系统级功耗管理才是关键。策略一周期性唤醒测温这是最常见的模式。系统主MCU大部分时间处于深度睡眠通过RTC定时器如每10秒唤醒。唤醒后MCU先给I2C总线上电如果之前为了省电彻底关闭了。发送命令让LM73退出关断模式PD0。等待至少一个最大转换时间根据你设置的分辨率如14位模式需等待112ms。这是很多新手忽略的点刚退出关断就读温度得到的是无效数据。读取温度数据。根据温度决定系统行为如继续睡眠或报警。将LM73重新设置为关断模式PD1。MCU自身进入深度睡眠。策略二事件驱动式测温利用ALERT在需要实时监控超温但又想最大限度省电的场景下可以这样设计系统初始化时配置LM73为连续转换模式PD0设置好THIGH和TLOW阈值并使能ALERT输出连接到MCU的外部中断引脚。然后MCU即可进入深度睡眠。当温度超过THIGH时LM73的ALERT引脚产生跳变触发MCU的外部中断。MCU被唤醒通过I2C读取温度寄存器确认状态并执行降温逻辑如开启风扇。由于ALERT会在温度低于TLOW时自动清除MCU可以在处理完报警后选择性地将LM73切回关断模式然后自己继续睡眠。或者如果温度波动频繁也可以让LM73保持连续转换MCU在中断服务程序中快速读取温度后立即返回睡眠功耗依然很低。策略三超低占空比单次转换这是功耗最优的策略适用于对测温实时性要求极低如每小时一次的应用。MCU和LM73长期处于关断/睡眠状态。MCU被超低功耗定时器如RTC Alarm唤醒。MCU唤醒后先不唤醒LM73而是完成一些必要的快速任务。然后MCU通过I2C向已处于关断模式的LM73发送单次转换命令ONE_SHOT1。发送命令后MCU可以立即进入一种轻度睡眠模式保留I2C外设供电或者干脆忙等待。关键点必须等待足够的时间一个完整转换周期少量裕量让LM73完成转换。等待时间到后MCU读取温度数据。读取完成后LM73自动回到关断状态MCU也再次进入深度睡眠。5.2 精度校准与温度补偿虽然LM73出厂精度已经很高±1°C但在某些对绝对精度要求严苛的场合可能需要进行单点或两点校准。单点偏移校准在一个已知的、稳定的温度环境如恒温箱25.0°C下读取LM73的输出值T_read。计算偏移量Offset T_actual - T_read。将这个偏移量存储在MCU的非易失性存储器中。以后每次读取温度后软件加上这个偏移量即可。这种方法主要补偿传感器的零位误差。两点斜率校准如果需要补偿增益误差需要在两个温度点如0°C和50°C进行测量。得到两个读数T1_read和T2_read以及实际温度T1_actual和T2_actual。计算斜率Gain (T2_actual - T1_actual) / (T2_read - T1_read)和偏移Offset T1_actual - (T1_read * Gain)。最终校准公式T_calibrated T_read * Gain Offset。自热效应LM73自身工作会发热。在连续转换模式下典型320µA的电流在3.3V下功耗约1mW。虽然很小但在静止空气、热阻较大的PCB布局中仍可能导致芯片结温比环境温度高零点几度。在关断单次转换模式下由于平均功耗极低自热效应基本可以忽略。为了最小化自热影响除了优化功耗模式PCB布局时应避免将LM73靠近MCU、电源芯片等热源并适当增加其焊盘与地平面的连接以帮助散热。6. 常见问题排查与调试心得在实际项目中调试LM73或其他I2C设备时以下几个坑我几乎每次都遇到或看到别人遇到。问题一I2C通信失败无应答NACK。检查清单上拉电阻这是头号嫌疑犯。用万用表测量SCL和SDA线在空闲时的电压是否接近VDD如果电压只有一半或更低说明上拉电阻太大或总线电容太大导致上升沿太慢。尝试减小上拉电阻如从10kΩ换为4.7kΩ。地址错误确认7位从机地址是否正确计算。(0x48 | addr_setting)左移一位后写地址是偶数读地址是奇数。用逻辑分析仪抓取波形看主机发送的第一个字节地址写位是什么。电源和地测量LM73的VDD引脚电压是否在2.7V-5.5V范围内GND连接是否牢固有时一个虚焊的GND会导致奇怪的问题。总线冲突总线上是否有其他设备也在驱动确保在访问LM73时其他设备处于高阻态。问题二读取的温度值固定不变或明显错误如-256°C或255.96875°C。原因分析固定为0x8000或0x7FFC这通常是**数据未就绪DAV0**的典型表现。你正在读取上电后的初始值或单次转换尚未完成时的值。务必在读取温度前检查控制/状态寄存器的DAV位Bit 15。值跳变但明显不准检查指针寄存器。你是否在读取温度前意外地写入了其他寄存器地址如配置寄存器由于指针寄存器具有锁存性后续的读操作会一直读那个寄存器而不是温度寄存器。确保每次读温度前指针都正确指向0x00温度寄存器。最稳妥的方式是采用“设置指针后立即读”的复合操作流程。值稳定但偏差大考虑自热效应或PCB布局热耦合。用手触摸芯片附近看读数是否快速变化。确保LM73没有紧贴发热元件。问题三ALERT中断不触发或无法清除。排查步骤配置检查确认配置寄存器01h的Bit 5ALRT_EN是否为0使能Bit 4ALRT_POL是否符合你的中断极性预期。阈值设置确认THIGH和TLOW寄存器的值是否正确写入。记住阈值寄存器只使用高11位。如果你写入的是摄氏度数值务必先除以LSB大小如0.25再左移5位。清除逻辑如果温度已低于TLOW但中断未清除检查TLOW值是否设置得比当前温度高逻辑是“低于TLOW才清除”。软件清除写ALRT_RST1后如果温度仍然超过THIGH在下一个转换周期结束后ALERT会再次触发。这是正常行为不是清除失败。确保你的MCU中断引脚配置正确上拉/下拉、边沿触发等。问题四在关断和单次转换模式下时序混乱。核心原则任何涉及模式切换正常-关断的操作都必须等待足够长的稳定时间。进入关断写PD1后必须等待至少一个当前分辨率下的最大转换时间芯片才会完全关断。在这之前读取配置寄存器PD位可能还未生效。退出关断写PD0后同样必须等待至少一个最大转换时间才能读取到有效的温度数据。单次转换在关断模式下写ONE_SHOT1触发转换必须等待一个完整的转换时间DAV标志才会置1温度数据才有效。建议在驱动程序中将不同分辨率对应的最大转换时间14ms, 28ms, 56ms, 112ms定义为常量并在模式切换函数后调用HAL_Delay()或使用定时器进行精确延时。不要试图去读状态位来“等待就绪”因为在关断模式下I2C通信本身可能是不稳定的。调试利器逻辑分析仪投资一个哪怕是最基础的逻辑分析仪如Saleae的克隆版对调试I2C、SPI等串行总线有巨大帮助。你可以清晰地看到主机发出的起始条件、地址字节、应答位。指针寄存器的值是否正确。读取的数据字节是什么。时序是否符合规范时钟频率、建立保持时间。 很多问题在波形面前一目了然。最后关于LM73这颗芯片我个人的体会是它是一款非常经典且“省心”的数字温度传感器。它的文档清晰功能直击痛点精度、功耗、小尺寸接口简单可靠。虽然在今天看来它的分辨率可能不是最高的速度也不是最快的但在绝大多数需要可靠、精准、低功耗测温的场合它依然是一个不会出错的选择。尤其是在设计需要长期野外工作或电池供电的设备时其超低的关断电流和灵活的单次转换模式能为你省下宝贵的微安级电流而这往往是项目成败的关键之一。把它的寄存器操作、时序要求和低功耗模式吃透你就能在各类嵌入式温度监测项目中游刃有余。