在嵌入式系统开发中,面对引脚资源紧张且需连接多个传感器的场景,One-Wire(单总线)协议凭借其仅需单根信号线即可实现双向通信的特性,成为节省硬件成本的理想选择。本文将作为一份详尽的技术实战指南,深入剖析One-Wire协议的底层时序逻辑,结合经典的DS18B20温度传感器,系统讲解从总线初始化、设备搜索到数据读写的完整实现流程,帮助开发者掌握这一简洁高效的外围扩展技术。


一、概述

OneWire(单总线)是一种由Dallas Semiconductor(现Maxim Integrated)开发的通信协议,它只需要一根数据线(加上地线)即可实现双向通信。这种协议广泛应用于温度传感器(如DS18B20)、存储器、ADC/DAC等设备。LuatOS支持OneWire协议,允许开发者方便地与各种单总线设备进行通信。

1.1 OneWire协议简介

协议特点:单线双向通信,节省IO资源

通信速率:标准模式16kbps,高速模式142kbps

拓扑结构:总线型拓扑,支持多设备并联

设备类型:温度传感器、存储器、ADC、DAC等

供电方式:支持寄生供电和外部供电

1.2 硬件接口特性

GPIO映射:可参考各型号复用表,配置GPIO作为OneWire总线

上拉电阻:需要4.7kΩ上拉电阻到VCC(3.3V)

总线电容:建议总线电容不超过1000pF

电缆长度:标准模式下可达100米

1.3 设备地址说明

OneWire设备地址由8字节组成:

二、核心示例

1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

三、常量详解

核心库常量,顾名思义是由 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

每个常量对应的常量取值仅做日志打印时查询使用,不要将这个常量取值用做具体的业务逻辑判断,因为LuatOS内核固件可能会变更每个常量对应的常量取值;

如果用做具体的业务逻辑判断,一旦常量取值发生改变,业务逻辑就会出错;

onewire核心库无常量

四、函数详解

4.1 onewire.init(id)

功能

初始化OneWire总线;

注意事项

初始化硬件单总线,每个ID对应一个硬件单总线;

参数

id

返回值

无返回值

示例

4.2 onewire.timing(id, is_tick, clk_div, tRSTL, tRSTH, tPDHIGH, tPDLOW, tSLOT, tStart, tLOW1, tRDV, tREC)

功能

配置OneWire总线时序参数,用于匹配不同的单总线设备;

注意事项

1、如果不配置,默认情况下是直接匹配DS18B20;

2、标准模式通信距离更远,高速模式速度更快;

3、需要在初始化后调用;

4、影响所有后续通信的时序;

5、从Maxim Integrated官网或其他芯片供应商处获取对应传感器的官方数据手册,重点关注"Timing Diagrams"或"Electrical Characteristics"章节,来查找时序图,芯片手册定义了芯片的理论能力范围;

6、DS18S20/DS18B20/DS1822/DS28EA00,这四种温度传感器请参考第六章节;

参数

id

is_tick

clk_div

tRSTL

tRSTH

tPDHIGH

tPDLOW

tSLOT

tStart

tLOW1

tRDV

tREC

返回值

无返回值

示例

4.3 onewire.reset(id, need_ack)

功能

发送复位脉冲并检测设备是否存在;

注意事项

1、复位脉冲的使用策略:

- 设备初始化阶段:建议发送复位脉冲确保设备就绪;

- 关键命令前:如温度转换、ROM操作等建议复位;

- 连续数据传输:已知设备在线可省略复位以提高效率;

- 错误恢复:通信失败时应重新发送复位脉;

2、返回值表示是否有设备响应;

3、会重置总线上的所有设备;

参数

id

need_ack

返回值

local present = onewire.reset(id, need_ack)

有一个返回值 present

present

示例

4.4 onewire.bit(id, send1bit)

功能

硬件单总线发送或接收1bit;

注意事项

1、可以发送或接收单个位;

2、发送单个位时,send1bit参数为要发送的值;

3、接收单个位时,send1bit参数为nil或留空;

参数

id

send1bit

返回值

local result = onewire.bit(id, send1bit)

有一个返回值 result

result

示例

4.5 onewire.tx(id, data, is_msb, need_reset, need_ack)

功能

发送数据到OneWire设备;

注意事项

1、支持发送整数、字符串或zbuff数据;

2、如果是整数则是1个字节数据,如果是zbuff则是从开头到指针前的数据;

3、可以控制是否需要先发送reset信号;

参数

id

data

is_msb

need_reset

need_ack

返回值

local result = onewire.tx(id, data, is_msb, need_reset, need_ack)

有一个返回值 result

result

示例

4.6 onewire.rx(id, len, cmd, buff, is_msb, need_reset, need_ack)

功能

硬件单总线读取N字节数据;

注意事项

1、可以返回字符串或zbuff数据;

2、如果是zbuff,则是从开头到指针前的数据;

3、可以控制是否需要先发送reset信号;

参数

id

len

cmd

buff

is_msb

need_reset

need_ack

返回值

local succ, rx_data = onewire.rx(id, len, cmd, buff, is_msb, need_reset, need_ack)

有两个返回值 succ 和 rx_data

succ

rx_data

示例

4.7 onewire.debug(id, onoff)

功能

单总线调试开关;

注意事项

1、开启后会输出详细的调试信息;

2、有助于排查通信问题;

3、量产环境建议关闭;

参数

id

onoff

返回值

无返回值

示例

4.8 onewire.deinit(id)

功能

关闭单总线;

注意事项

1、释放相关资源;

2、关闭后不能再使用该总线,除非重新初始化;

3、建议在程序退出或不再需要时调用;

参数

id

返回值

无返回值

示例

五、模组支持列表

支持 LuatOS 开发的所有模组都支持onewire核心库。

六、参考资料

DS18B20 datasheet:https://www.analog.com/media/en/technical-documentation/data-sheets/DS18B20.pdf

DS18S20 datasheet:https://www.analog.com/media/en/technical-documentation/data-sheets/DS18S20.pdf

DS1822 datasheet:https://www.analog.com/media/en/technical-documentation/data-sheets/DS1822.pdf

DS28EA00 datasheet:https://www.analog.com/media/en/technical-documentation/data-sheets/DS28EA00.pdf

今天的内容就分享到这里了~

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐