QuecPython+单总线:物联网设备通信指南+应用示例

单总线概述

单总线(1 - Wire)是美国 Dallas 公司推出的一种主从式的串行通信协议,主要用于实现微控制器与单总线器件之间的通信。与 SPI、IIC 串行数据通信方式不同,单总线采用单根信号线,实现数据的双向传输,这种设计大大简化了硬件连接,降低了成本和复杂度。

单总线通信时序介绍

单总线的基本时隙可分为初始化、写 0&1,读 0&1 这三个(本文以 DS18B20 温度传感器的时隙为例)。

初始化

所有与 DS18B20 的通信都始于一个初始化序列,该序列由主机发出的复位脉冲和随后的 DS18B20 发出的存在脉冲组成。当 DS18B20 响应复位并发送存在脉冲时,它向主机发出信号,表明它已连接到总线并准备好运行。

具体过程:总线主机通过将单线总线拉低至少 480μs 来发送 (TX) 复位脉冲。然后,总线主机释放总线并进入接收模式 (RX)。释放总线后,上拉电阻将单线总线拉高。当 DS18B20 检测到该上升沿时,它会等待 15μs 至 60μs,然后通过将单线总线拉低 60μs 至 240μs 来发送存在脉冲。

写 0&1

所有写入时隙的持续时间必须至少为 60μs,且各个写入时隙之间至少有 1μs 的恢复时间。两种类型的写入时隙均由主机将 1-Wire 总线拉低来启动。

写 0:要生成“写 0”时隙,在将 1-Wire 总线拉低后,总线主机必须在整个时隙期间(至少 60μs)继续保持总线低电平。

写 1:要生成“写 1”时隙,在将 1-Wire 总线拉低后,总线主机必须在 15μs 内释放 1-Wire 总线。释放总线后,上拉电阻会将总线拉高。

具体过程:DS18B20 在主机启动写入时隙后 15μs 至 60μs 的窗口期内对 1-Wire 总线进行采样。如果在采样窗口期内总线为高电平,则向 DS18B20 写入 1。如果总线为低电平,则向 DS18B20 写入 0。

读 0&1

所有读取时隙的持续时间必须至少为 60μs,且时隙之间的恢复时间至少为 1μs。读取时隙由主机将 1-Wire 总线拉低至少 1μs,然后释放总线来启动。主机启动读取时隙后,DS18B20 将开始在总线上发送 1 或 0。且仅当主机发出读取时隙时,DS18B20 才能向主机发送数据。

读 0:DS18B20 将在读取时隙结束时释放总线,并通过上拉电阻将总线拉回至高电平空闲状态。

读 1:DS18B20 保持总线为高电平状态。

具体过程:DS18B20 的输出数据在启动读取时隙的下降沿之后的 15μs 内有效。因此,主机必须释放总线,然后在时隙开始后的 15μs 内对总线状态进行采样。

功能概述

主要介绍如何使用单总线(1-Wire)驱动程序的功能合数据类型在 QuecPython 系列模组与 DS18B20 传感器之间建立通信。典型的编程工作流程分为以下几个部分:

  •  创建对象
  • 复位
  • 发送数据
  • 读取数据

创建对象

创建单总线对象时,需要设置 DQ 引脚所连接的 GPIO。

class machine.OneWire(GPIO)

参数介绍请参考构造函数

复位

该方法用于复位总线并检测设备是否响应,使用时需要先调用该接口,再调用读写接口。

OneWire.reset()

API 详情请参考 machine.OneWire.reset

发送数据

该方法用于主机向从机写数据,要写入的 data 为 bytes 类型。

OneWire.write(data)

API 详情请参考 machine.OneWire.write

读取数据

该方法读取的为 DS18B20 原始数据,需按照 DS18B20 的数据格式换算成实际温度。

OneWire.read(len)

API 详情请参考 machine.OneWire.read

应用案例

温度传感器 DS18B20

DS18B20 传感器是一款常用的数字温度传感器,由 Dallas Semiconductor 公司生产,内部包含温度传感器、温度转换电路、非易失性存储器、配置寄存器和单总线接口电路等模块。通过单总线接口电路,DS18B20 传感器与外部主机进行通信,实现数据的传输和命令的接收。

基本命令:

CCh:跳过 ROM(在仅有一个 DS18B20 传感器时可以发送 0xCC 跳过 ROM 匹配)

44h:启动温度转换

4Eh:写暂存寄存器

BEh:读暂存寄存器(一共可读9个寄存器,前2个为温度值)

DS18B20 获取到的的温度值格式如下,需要将其进行转换:

整个通信流程:

  • 复位初始化
  • 主机发送 [0xcc, 0x44] 启动 DS18B20 温度转换
  • 再次复位
  • 主机发送 [0xcc, 0xbe] 读取暂存寄存器中的温度值

获取 DS18B20 温度值的示例代码如下:

from machine import OneWire

data1=bytearray([0xcc,0x44])
data2=bytearray([0xcc,0xbe])

obj=OneWire(OneWire.GPIO46)
obj.reset()
obj.write(data1)
obj.reset()
obj.write(data2)

data = obj.read(2)    # 读取到的为原始数据,需要进行转换

temp_h = data[1]
temp_l = data[0]

if temp_h > 7:    # 负数处理
    temp = (~(temp_h<<8 | temp_l) + 1) * 0.0625
else:
    temp = (temp_h<<8 | temp_l) * 0.0625

print("temperature:", temp)

常见问题

1. 复位初始化失败

  • 这可能是硬件连接问题导致,检查硬件连接,确保创建对象所使用的 GPIO 与 DS18B20 的 DQ 引脚连接至开发板上的引脚一致,并且地线(GND)也要正确连接。
  • DS18B20 传感器损坏,导致无法通信。

2. 可以正常进行收发,但是有错误数据

可能是主机 GPIO 和从机 DQ 引脚电平不一致。当主机电平为3.3V,从机为1.8V,此时从机的高电平是1.8V,但是主机一般认为电平高于1.65V是高电平,容易产生误判。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值