
MY18E20 温度读取MY18E20是一款高精度可编程的数字单总线温度测量芯片其测温范围为-55°C 到 125°C、最高分辨率 0.015°C在-10°C 到 85°C 范围内最大差为 ±0.5°C在极端工作温度的最大误差小于 ±1.5°C芯片内置 80bit 非易失性存储单元用于保存用户自定义信息, 如高低温报警阈值、传感器节点编号、位置信息、温度校准信息等微处理器可以通过一个 GPIO 端口依据单总线协议的软件指令读写芯片的控制寄存器设置测温精度、报警阈值等配置并周期采集数字温度信息。1.MY18E20 传感器通信协议解析需要注意的是数据手册中关于单总线通信的一些名词与我们使用的名词有所不同但指代对象相同主机/设备/控制器指在单总线通信中发起通信的单片机。从机/芯片/传感器指在单总线通信中响应通信的传感器。读时隙指主机发送读信号的通信流程。写时隙指主机发送写信号的通信流程。复位信号/呼叫信号主机发起拉低总线一定时间后释放等待从机响应。存在信号/响应信号主机发起呼叫信号后从机检测到总线上升沿拉低总线一段时间。1.1 MY18E20 传感器的结构和工作原理MY18E20 传感器主要由以下几个部分组成EEPROM主要存储系统参数、64 位 ROM ID 和 10 字节用户存储64 位 ROM 存储了器件的唯一 ID 序列码。单片机 主机通过每个器件的唯一 64 位编码识别并寻址总线上的器件。因为每个器件都有唯一的编码理论上挂在总线上并可以被寻址的设备数量是无限的。8 位循环冗余校验产生器循环冗余校验字节是 MY18E20 的 64 位 ROM 编码的一部分位于暂存器的第 9 个字节。**ROM 编码循环冗余校验是从 ROM 编码的前 56 位计算得来存储在 ROM 的最高位。暂存器的循环冗余校验码是在暂存器内计算得来因此随暂存器内数据改变而改变。**循环冗余校验码给主机从暂存器读取数据提供了一个数据校验方法。要验证数据读取是否正确主机必须自己通过接收到的数据进行计算并将此数据与 ROM 里的循环冗余校验码比较来自于 ROM 读操作或者与暂存器里的循环冗余校验码比较来自于暂存器读操作。如果计算的循环冗余校验码与读取的吻合数据就是正确无误地接收了。温度传感器和 ADC 单元进行温度测量和数据转换产生的温度数据被存储在暂存器的温度寄存器中。数字控制逻辑根据接收的 ROM 指令和功能指令进行对应操作。暂存器暂存器包含了两个字节的温度寄存器存储来自于温度传感器的数字输出。另外暂存器提供了一高一低两个报警触发阈值寄存器TH 和 TL。配置寄存器允许用户设定温度数字转换的分辨率为 9、10、11、12 位分别对应着温度的分辨率为0.5°C0.25°C0.125°C0.0625°C默认为 12 位分辨率。提供另外的数据空间供用户使用。**暂存器中关于配置的相关数据可存入非易失性存储 EEPROM芯片掉电时数据不会丢失在下一次设备上电时EEPROM 的配置相关数据会自动写入暂存器。**单总线接口将单总线接口接收的命令数据进行转换发送到数字控制逻辑单元。电源管理将输入电压进行转换和分流给各个系统进行供电。MY18E20 的工作步骤可以分为三步初始化 MY18E20MY18E20 芯片上电初始化主机发送呼叫信号从机 MY18E20 响应主机发送 ROM 指令跟随任意必需的数据交换访问每个 DS18B20搜索 64 位序列号读取匹配的序列号值然后匹配对应的 DS18B20。如果我们仅仅使用单个 DS18B20可以直接跳过 ROM 指令而跳过 ROM 指令的字节是 0xCC。这里跟随任意必需的数据交换包括主机复位总线、发送功能指令、读取数据等操作。执行 MY18E20 功能指令跟随任意必需的数据交换包括读取温度值、写入报警触发阈值、配置温度测量精度等命令当总线主机检测到从机响应信号时就可以发送 ROM 指令。ROM 指令共有 5 条每个 8 位长。需要注意的是在主机发送 MY18E20 的功能指令之前必须发送一个 ROM 指令当总线主机使用一个 ROM 指令寻址一个它希望与之通讯的 MY18E20 之后主机可以发布 MY18E20 的功能指令之一。这些指令允许主机进行数据读写包括读取温度值、写入报警触发阈值、配置温度测量精度等命令。这里Copy Scratchpad[48h] 指令和 Recall E2[B8h]指令主要用于以下场景当我们设定 TH 报警阈值上限、TL 报警阈值下限和温度转换精度到暂存器时我们会希望当设备停机掉电后保存我们设定的数据并在下一次设备上电后读取上一次配置数据到暂存器中。此时要把 TH、TL 和配置数据从暂存器传输到 E2PROM主机必须发出 CopyScratchpad[48h] 指令。E2PROM 寄存器中的数据掉电会保持上电时会自动加载到相应的暂存器位置。数据也可以通过 RecallE2[B8h]指令随时重新加载。主机可以在 RecallE2[B8h]指令随后发送读时隙然后芯片会返回状态如果重新加载还在进行中会返回 0如果已经完成会返回 1。ROM 指令流程图如下功能指令流程图如下1.2 MY18E20 的存储器组织MY18E20的存储器包含一个SRAM暂存器以及非易失性存储E2PROM寄存器MY18E20的存储组织如下图所示其中字节 0 和字节 1 是只读的用于存储转换后的温度数据字节 2 和字节 3 用于访问 TH 和 TL 寄存器存储报警的温度上下限字节 4 包含配置寄存器数据用于配置温度转换精度字节 5、6 和 7 可以读写提供数据空间供用户使用字节 8 为只读寄存器字节 0 到 7 产生的循环冗余校验码数据可以通过WriteScratchpad[4Eh]和WriteUser [66h]指令写入到字节 2,3,4,5,6 和 7 中。数据传输必须始于字节 2 的最低位即主机发送数据从 LSB 到 MSB。为了验证数据完整性可以在数据写操作之后读取暂存器通过Read Scratchpad [BEh]指令。读取暂存器的时候单总线的数据传输始于字节 0 的最低位即从机发送数据从 LSB 到 MSB。1.3 MY18E20 传感器应用电路MY18E20 通过 VDD 引脚由外部电源供电如下图所示。这种模式的优点是不需要 MOSFET 上拉而且单总线在温度转换过程中可以任意进行其他操作。1.4 单总线通信时序和电气特性1.4.1 主机发送呼叫信号和从机应答1.4.2 主机读写数据位1.5 直接温度测量功能MY18E20采用 16 位补码的形式来存储温度数据温度是摄氏度。当温度转换命令发布后经转换所得的温度值以二字节补码形式存放在暂存器的第 0 和第 1 个字节。高字节的五个 S 为符号位温度为正值时 S1,温度为负值时 S0。剩下的 11 位为温度数据位对于 12 位分辨率所有位全部有效对于 11 位分辨率位 0(bit0)无定义对于 10 位分辨率位 0 和位 1 无定义对于 9 位分辨率位 0、位 1 和位 2 无定义需要注意的是温度以大端序进行发送即高位 MS 字节在前而低位 LS 字节在后。温度计算方法如下当五个符号位 S0 时温度为正值直接将后面的 11 位二进制转换为十进制再乘以 0.0625(12 位分辨率)就可以得到温度值当五个符号位 S1 时温度为负值先将后面的 11 位二进制补码变为原码(符号位不变数值位取反后加 1)再计算十进制值。再乘以 0.0625(12 位分辨率)就可以得到温度值以上表为例讲解温度计算125℃ 的数字输出07D0(00000111 11010000)转换成 10 进制是2000对应摄氏度0.0625x2000125°C-55℃ 的数字输出为FC90首先取反然后 1转换成原码为11111011 01101111数值位转换成 10 进制是870对应摄氏度-0.0625x870-55°C1.6 温度采集分辨率配置在配置寄存器中我们可以通过 R0 和 R1 设置 ME18E20 的转换分辨率ME18E20 在上电后默认 R01 和 R11(12 分辨率)寄存器中的第 7 位和第 0 位到 4 位保留给设备内部使用。1.7 报警功能MY18E20 完成一次温度转换后将该温度值和用户定义的二进制补码报警触发值比较该值存储在 TH 和 TL 寄存器中TH 和 TL 寄存器是非易失性的(E2PROM)所以当设备掉电时数据会保持。TH 和 TL 可以通过暂存器的第 2 和第 3 字节访问。由于TH和TL是 8 位寄存器因此在温度比较中只用到 11 到 4 位。如果测量到的温度小于等于TL或大于等于TH则报警条件成立芯片内部会设立一个标志位。该标志位每次温度测量都会被更新所以如果报警条件不再满足标志位就会在下次温度转换之后被关闭。主机可以通过发布一个AlarmSearch[ECh]指令来检查所有挂在总线上的温度芯片的标志位状况。任何设立了标志位的芯片都会响应该指令这样主机可以知道具体哪一个芯片进入了报警条件。如果报警条件成立并且 TH 或者 TL 设置被更改则应该再进行一次温度转换来验证报警条件。1.8 循环冗余校验码生成循环冗余校验字节是MY18E20的 64 位ROM编码的一部分位于暂存器的第 9 个字节。ROM 编码循环冗余校验是从ROM编码的前 56 位计算得来存储在ROM的最高位。暂存器的循环冗余校验码是在暂存器内计算得来因此随暂存器内数据改变而改变。**循环冗余校验码给主机从暂存器读取数据提供了一个数据校验方法。要验证数据读取是否正确主机必须自己通过接收到的数据进行计算并将此数据与 ROM 里的循环冗余校验码比较来自于 ROM 读操作或者与暂存器里的循环冗余校验码比较来自于暂存器读操作。**如果计算的循环冗余校验码与读取的吻合数据就是正确无误地接收了。循环冗余校验的比较以及是否继续操作都完全取决于主机。如果芯片的循环冗余校验ROM 或暂存器与总线主机计算的值不匹配芯片内没有电路阻止指令进一步执行。CRC 校验码计算方式如下2. MY18E20 传感器驱动代码这里由于MY18E20传感器工作流程与DS18B20传感器相兼容我们直接使用 DS18B20 传感器驱动代码即可。我们首先定义一个 DS18X20 类DS18 系列温度传感器有许多不同型号通信流程大体相似这个类的主要功能如下:初始化初始化DS18X20类时需要传入一个OneWire类的实例通过组合关系DS18X20类可以使用 OneWire 类的方法进行单总线通信。设置供电模式支持两种供电模式包括独立供电和寄生供电寄生供电模式下需要通过powerpin引脚为传感器供电。扫描传感器扫描单总线上的所有DS18X20传感器并返回它们的 ROM 地址列表。启动温度转换启动温度转换操作通过发送温度转换命令CMD_CONVERT实现。 读取和写入暂存器读取和写入传感器的暂存器数据包括温度值、分辨率等配置信息。计算和返回温度值读取传感器的温度值并支持摄氏度、华氏度和开氏度三种单位根据传感器的型号DS18B20、DS18S20等进行不同的温度计算。设置温度分辨率设置温度转换的分辨率支持 9 位到 12 位之间的设置。这里DS18X20类和OneWire类采用组合关系而非继承关系主要是基于以下几点考虑单一职责原则:OneWire类专注于单总线通信的底层实现,提供了一系列读写数据、复位等基本操作。DS18X20类则专注于针对DS18X20温度传感器的上层逻辑,如温度转换、读取温度等并且封装了DS18X20传感器的特定命令如温度转换命令CMD_CONVERT、读取暂存器命令CMD_RDSCRATCH等。这样的设计遵循了单一职责原则,使得两个类分工明确,责任清晰。可复用性:OneWire类是一个通用的单总线通信类,可以被多种设备类复用,比如其他类型的 1-Wire 设备。如果采用继承关系DS18X20类就会与OneWire类过于耦合,降低了OneWire类的可复用性灵活性:在组合关系中DS18X20类可以自由选择使用哪个OneWire类的实例根据实际需求进行配置。而如果采用继承关系DS18X20类就必须继承OneWire类无法自由选择使用哪个单总线通信类。可测试性:在组合关系中DS18X20类可以独立于OneWire类进行测试有利于提高测试的覆盖率和可靠性。如果采用继承关系DS18X20类的相关测试就会与OneWire类的实现细节耦合在一起,降低了测试的独立性。这里我们首先定义DS18X20传感器使用的功能指令常量和初始化方法# 定义DS18X20温度传感器类 class DS18X20: DS18X20 温度传感器类用于与 DS18B20、DS18S20 等单总线温度传感器进行通信。 该类封装了温度传感器的功能包括温度转换、读取温度、设置分辨率等。 Attributes: ow (OneWire): 单总线通信类的实例。 buf (bytearray): 用于存储暂存器数据的缓冲区9 字节。 config (bytearray): 用于存储用户配置数据的缓冲区3 字节。 power (int): 电源模式1 为独立供电0 为寄生供电。 powerpin (machine.Pin): 供电引脚对象用于寄生供电模式。 Methods: powermode(powerpin: machine.Pin) - int: 设置 DS18X20 的供电模式。 scan() - list[bytearray]: 扫描单总线上的 DS18X20 传感器返回 ROM 地址列表。 convert_temp(rom: bytearray) - None: 启动传感器温度转换。 read_scratch(rom: bytearray) - bytearray: 读取传感器暂存器数据。 write_scratch(rom: bytearray, buf: bytearray) - None: 写入传感器暂存器数据。 read_temp(rom: bytearray) - float: 读取传感器温度。 resolution(rom: bytearray, bits: int) - int: 设置或读取传感器温度转换分辨率。 fahrenheit(celsius: float) - float: 将摄氏度转换为华氏度。 kelvin(celsius: float) - float: 将摄氏度转换为开氏度。 # DS18X20 功能命令 CMD_CONVERT const(0x44) # 转换温度命令 CMD_RDSCRATCH const(0xbe) # 读暂存器命令 CMD_WRSCRATCH const(0x4e) # 写暂存器命令 CMD_RDPOWER const(0xb4) # 读电源命令 CMD_COPYSCRATCH const(0x48) # 拷贝暂存器命令 # 上拉电阻控制 PULLUP_ON const(1) PULLUP_OFF const(0) def __init__(self, onewire: OneWire) - None: 初始化 DS18X20 类传入使用的单总线通信类。 Args: onewire (OneWire): 单总线通信类的实例。 self.ow onewire # 存储暂存器的9个字节数据 self.buf bytearray(9) # 存储用户配置的3个字节数据 self.config bytearray(3) # 默认独立供电 self.power 1 self.powerpin None然后定义了用于设置 DS18X20 温度传感器的供电模式的方法def powermode(self, powerpin: Pin None) - int: 设置 DS18X20 的供电模式。 Args: powerpin (machine.Pin): 供电引脚对象用于寄生供电模式。如果为 None则使用默认模式。 Returns: int: 电源模式1 为独立供电0 为寄生供电。 # 如果已经设置了 powerpin,则将其拉低,关闭上拉电阻 if self.powerpin is not None: self.powerpin(DS18X20.PULLUP_OFF) # 发送CMD_SKIPROM命令 self.ow.writebyte(OneWire.CMD_SKIPROM) # 发送读取电源模式命令 self.ow.writebyte(DS18X20.CMD_RDPOWER) # 读取电源模式 self.power self.ow.readbit() # 读取完毕后将powerpin设置为推挽输出模式拉低 if powerpin is not None: assert type(powerpin) is Pin, powerpin must be a Pin object self.powerpin powerpin self.powerpin.init(modePin.OUT, value0) # 返回电源模式 return self.power可以看到其主要实现就是靠OneWire实例进行指令的收发。同时定义了scan()方法用于扫描单总线上连接的DS18X20温度传感器,并返回它们的 ROM 地址列表这个列表可以在后续的操作中使用,比如读取温度值或设置传感器参数。通过检查 ROM 地址的前几个字节,可以识别出 DS18X20 系列的温度传感器,并将其与其他可能连接在总线上的设备区分开来。def scan(self) - list[bytearray]: 扫描单总线上的 DS18X20 传感器返回 ROM 地址列表。 Args: None Returns: list[bytearray]: 传感器 ROM 列表每个 ROM 为 8 字节的 bytearray。 if self.powerpin is not None: self.powerpin(DS18X20.PULLUP_OFF) # 通过单总线扫描得到的ROM列表中筛选出那些以0x10、0x22或0x28开头的ROM return [rom for rom in self.ow.scan() if rom[0] in (0x10, 0x22, 0x28)]DS18X20 类的核心方法是convert_temp()方法用于启动 DS18X20 温度传感器的温度转换操作。需要注意的是,调用这个方法只是启动了温度转换操作,并不会直接返回温度值。要获取转换完成后的温度值,需要调用**read_temp()方法。**def convert_temp(self, rom: bytearray None) - None: 启动传感器温度转换。 Args: rom (bytearray): 目标温度传感器的 ROM 地址。如果为 None则对所有传感器广播。 Returns: None if self.powerpin is not None: self.powerpin(DS18X20.PULLUP_OFF) # 主机重启总线 self.ow.reset() # 当rom不为空时,则发送CMD_SKIPROM命令 # 在总线上只有一个温度传感器时,可以发送CMD_SKIPROM命令 if rom is None: self.ow.writebyte(OneWire.CMD_SKIPROM) else: # 根据给定的ROM地址选择对应传感器 self.ow.select_rom(rom) # 写入转换温度命令 self.ow.writebyte(DS18X20.CMD_CONVERT, self.powerpin)其具体流程如下图所示然后我们定义了读写暂存器的方法暂存器中存储了温度数据、用户自定义数据和相关配置数据温度转换分辨率、报警上下限阈值等def read_scratch(self, rom: bytearray) - bytearray: 读取传感器暂存器数据。 Args: rom (bytearray): 目标温度传感器的 ROM 地址。 Returns: bytearray: 暂存器数据9 字节。 Raises: AssertionError: 如果 CRC 校验失败。 if self.powerpin is not None: self.powerpin(DS18X20.PULLUP_OFF) # 主机重启总线 self.ow.reset() # 根据给定的ROM地址选择对应传感器 self.ow.select_rom(rom) # 写入CMD_RDSCRATCH命令 self.ow.writebyte(DS18X20.CMD_RDSCRATCH) # 读取暂存器数据保存到buf中 self.ow.readinto(self.buf) # 进行CRC校验 assert self.ow.crc8(self.buf) 0, CRC error return self.buf def write_scratch(self, rom: bytearray, buf: bytearray) - None: 写入传感器暂存器数据。 Args: rom (bytearray): 目标温度传感器的 ROM 地址。 buf (bytearray): 写入暂存器的数据9 字节。 Returns: None if self.powerpin is not None: self.powerpin(DS18X20.PULLUP_OFF) # 主机重启总线 self.ow.reset() # 根据给定的ROM地址选择对应传感器 self.ow.select_rom(rom) # 写入CMD_WRSCRATCH命令 self.ow.writebyte(DS18X20.CMD_WRSCRATCH) # 写入暂存器数据 self.ow.write(buf)需要注意的是,在读写暂存器数据之前,都会先重置单总线,并根据给定的 ROM 地址选择对应的传感器然后我们定义了读取温度数据的read_temp()方法主要通过读写暂存器来实现需要注意的是该方法还会进行 CRC 校验,以确保读取的数据是完整可靠的如果 CRC 校验失败,则会抛出 AssertionError 异常,并返回 None。def read_temp(self, rom: bytearray) - float: 读取传感器温度。 Args: rom (bytearray): 目标温度传感器的 ROM 地址。 Returns: float: 温度值摄氏度。如果读取失败返回 None。 try: # 读取暂存器数据 buf self.read_scratch(rom) # 当rom中第一个数据为0x10时为另一个型号的DS18x20传感器 if rom[0] 0x10: # 如果温度为负值 if buf[1]: t buf[0] 1 | 0x80 t -((~t 1) 0xff) # 如果温度为正数 else: t buf[0] 1 # 计算温度值,包括小数部分 return t - 0.25 (buf[7] - buf[6]) / buf[7] # 当rom中第一个数据为0x22、0x28时为DS18B20传感器 elif rom[0] in (0x22, 0x28): # 从缓冲区中读取两个字节将它们组合成一个16位的无符号整数 t buf[1] 8 | buf[0] # 检查这个整数是否大于0x7fff如果是那么就将其转换为负数 if t 0x8000: # 先将后面的11位二进制补码变为原码(符号位不变数值位取反后加1)再计算十进制值 t -((t ^ 0xffff) 1) # 除以16即乘以系数0.0625 return t / 16 else: return None # 抛出断言异常 except AssertionError: return None这里在温度值解码方面代码通过对不同型号传感器的数据处理逻辑进行区分,可以适用于多种 DS18X20 系列传感器具体流程如下图所示我们还定义了用于设置和读取温度转换分辨率的resolution()方法该方法主要是通过将更新后的配置数据写入到传感器的暂存器中来实现温度转换分辨率的设置def resolution(self, rom: bytearray, bits: int None) - int: 设置或读取传感器温度转换分辨率。 Args: rom (bytearray): 目标温度传感器的 ROM 地址。 bits (int): 温度转换分辨率9~12 位。如果为 None则读取当前分辨率。 Returns: int: 设置或读取的分辨率位数。 if bits is not None and 9 bits 12: # 将分辨率信息设置为bits变量的值 # self.config的第3位用于设置分辨率 self.config[2] ((bits - 9) 5) | 0x1f self.write_scratch(rom, self.config) return bits else: data self.read_scratch(rom) return ((data[4] 5) 0x03) 9具体流程如下图所示需要注意的是分辨率越高,温度值的精度越高,但相应的转换时间也会更长。通过调整分辨率,可以在精度和转换速度之间进行权衡,满足不同应用场景的需求。对于DS18系列传感器来说转换精度和时间如下最后我们定义了用于摄氏度、开氏度和华氏度的转换方法。其中摄氏度是最广泛使用的温度单位,适用于大多数日常生活和工业应用场景。华氏度主要局限于北美地区。而开氏度则主要用于科学研究和一些高精度的工业应用。三者关系如下开氏度与摄氏度的转换公式为K °C 273.15**华氏度与摄氏度的转换公式为**°F °C × 1.8 32def fahrenheit(self, celsius: float) - float: 将摄氏度转换为华氏度。 Args: celsius (float): 摄氏度。 Returns: float: 华氏度。如果输入为 None返回 None。 return celsius * 1.8 32 if celsius is not None else None def kelvin(self, celsius: float) - float: 将摄氏度转换为开氏度。 Args: celsius (float): 摄氏度。 Returns: float: 开氏度。如果输入为 None返回 None。 return celsius 273.15 if celsius is not None else None3.应用实验在下面实验中我们需要将**风雅一号板-Grove接口扩展板插入到风雅一号板-通用兼容扩展板上同时使用HY2.0-4P排线连接风雅一号板-通用兼容扩展板上DIO0接口和GraftSense-基于DS18B20的温度传感器模块**上的DIO0数字接口使用的引脚情况如下表所示以下代码可以在我们提供的资料包中elegance-devkit v1\Demo\38 OneWire_DS18B20文件夹找到。在软件代码中我们导入相关模块# Python env : MicroPython v1.23.0 # -*- coding: utf-8 -*- # Time : 2024/7/22 下午3:01 # Author : 李清水 # File : main.py # Description : DS18B20温度类实验使用单总线通信完成数据交互 # 导入相关模块 # 导入硬件相关的模块 from machine import Pin # 导入时间相关的模块 import time # 导入单总线通信相关的模块 from onewire import OneWire # 导入温度传感器类 from ds18x20 import DS18X20在初始化配置中我们定义了单总线通信引脚ow_pin同时创建DS18X20对象并绑定到ow_pin用于与DS18B20传感器进行通信# 全局变量 # 功能函数 # 自定义类 # 初始化配置 # 延时等待设备初始化 time.sleep(3) # 打印调试信息 print(FreakStudio : Using OneWire to read DS18B20 temperature) # 定义单总线通信引脚 ow_pin OneWire(Pin(14)) # 定义温度传感器 ds18x20 DS18X20(ow_pin)在主程序中我们进行以下操作准备工作:延迟 3 秒钟以确保系统稳定扫描总线上的 DS18B20 传感器设备获取设备地址列表roms_list打印 DS18B20 传感器设备的 ROM ID触发所有 DS18B20 传感器启动温度转换温度读取循环:每 500 ms 读取一次温度遍历 roms_list 中的每个设备地址读取对应设备的温度值并打印再次触发所有 DS18B20 传感器启动温度转换示例代码如下# 主程序 # 扫描总线上的DS18B20获取设备地址列表 roms_list ds18x20.scan() # 打印设备地址列表 for rom in roms_list: print(ds18b20 sensor devices rom id:, rom) # 让所有挂载在总线上的DS18B20转换温度 ds18x20.convert_temp() # 循环读取温度 while True: time.sleep_ms(500) for rom in roms_list: # 转换并打印温度 temp ds18x20.read_temp(rom) # 打印温度 print(ds18b20 sensor {} devices temp {}.format(rom, temp)) # 启动温度转换 ds18x20.convert_temp()烧录代码连接终端用手轻捏传感器可以看到终端输出如下