单总线one-Wire
概述
One-Wire总线是
DALLAS
公司研制开发的一种协议
特点:
它是由一个总线主节点,一个或多个从节点组成系统,通过一根信号线对从芯片进行数据的读取
每一个符合One-Wire协议的从芯片都有一个唯一的地址,包括48位的序列号8位的家族代码和8位的CRC代码。主芯片对各个从芯片的寻址依据这64位的不同来进行。
One-Wire总线利用一根线实现双向通信(异步半双工)
。因此其协议对时序的要求较严格,如应答等时序都有明确的时间要求。
工作原理
由一根数据线,系统中的数据交换,控制都由这跟线完成。
单总线通常要求外接一个约为4.7k的上拉电阻
,这样,当总线闲置时,其状态为高电平1
由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问One-Wire器件都必须严格遵循单总线命令序列,即初始化、ROM命令、功能命令。
如果出现序列混乱,One-Wire器件将不响应主机(搜索ROM命令、报警搜索命令除外)。
信号方式
复位和应答
- 将DQ主线拉低持续500us DQ=0
- 释放DQ主线的控制权 DQ=1
- 持续20us判断DQ状态
– 1.250us没有处于高电平 复位异常
– 2.250us没有处于低电平 复位异常
one-Wire读写原理图
代码实现
#include "one_wire.h"
#include "intrins.h"//内核用来进行低延时的头文件_nop_();
static u8 _ReadBit(void);//定义一个个读取字节的函数
void OneWire_Init(void)//初始化 因为有一个上拉电阻所以默认是高电平初步初始化无所谓
{
DQ = 1;
}
u8 OneWire_Reset(void)//返回0:成功,返回1:失败
{
u8 u8timeout = 0;
//主机低位复位
DQ = 0;
delay_10us(50);//主机发送复位信号500us
DQ = 1; //主机释放DQ线,等待从机回应
delay_10us(2);//主机等待20us后读取DQ状态
//两个250us处于高低电平来判断是否复位成功
//主机判断DQ是否被从机拉低250us
while(DQ)
{
u8timeout++;
if(u8timeout>25)return 1;//复位异常
delay_10us(1);
}
//主机判断从机有没有释放DQ线
u8timeout = 0;
while(!DQ)
{
u8timeout++;
if(u8timeout>25)return 1;//复位异常
delay_10us(1);
}
return 0;//复位成功
}
//低位先读
void OneWire_WriteByte(u8 u8data)//LSB
{
u8 i = 0;
u8 u8temp = 0;//当前读取的字节
for(i=0;i<8;i++)
{
u8temp = u8data & 0x01;//取低位
u8data>>=1;//读取低位
if(u8temp)//写1当前位写1的话 拉低电平持续2us,在拉高电平持续60us
{
DQ = 0;
_nop_();_nop_();
DQ = 1;
delay_10us(6);
}
else//写0当前位写0的话 拉低电平持续60us,在拉高电平持续2us
{
DQ = 0;
delay_10us(6);
DQ = 1;
_nop_();_nop_();
}
}
}
//读取字节
u8 OneWire_ReadByte(void)//LSB
{
u8 i;
u8 u8val = 0,u8temp = 0;
for(i=0;i<8;i++)
{
//因为是一个个字节读取
u8temp = _ReadBit(); //每次读取一个bit
u8val += (u8temp<<i);//总数据
}
return u8val;
}
//单个比特读取
static u8 _ReadBit(void)
{
u8 u8val = 0;
DQ = 0;
_nop_();_nop_();
DQ = 1;
_nop_();_nop_();
if(DQ)
{
u8val = 1;
}
else
{
u8val = 0;
}
delay_10us(6);
return u8val;
}
ROM命令
在主机检测到应答脉冲后,就可以发出 ROM 命令。这些命令与各个从机设备的唯一64位ROM代码相关,允许主机在单总线上连接多个从机设备时,指定操作某个从机设备。
常走是一对1也就是一号线
搜索ROM[F0h]
当系统初始上电时,主机必须找出总线上所有从机设备的ROM代码,这样主机就能够判断出从机的数目和类型。主机通过重复执行搜索ROM 循环(搜索ROM命令跟随着位数据交换),以找出总线上所有的从机设备。如果总线只有一个从机设备则可以采用读ROM命令来替代搜索ROM命令。在每次执行完搜索ROM循环后,主机必须返回至命令序列的第一步(初始化)
读ROM[33h](仅适合于单节点)
该命令仅适用于总线上只有一个从机设备。它允许主机直接读出从机的64位ROM 代码,而无须执行搜索ROM过程。
如果该命令用于多节点系统,则必然发生数据冲突,因为每个从机设备都会响应该命令。
匹配ROM[55h]
匹配ROM命令跟随64位ROM 码,从而允许主机访问多节点系统中某个指定的从机设备。仅当从机完全匹配64位ROM代码时,才会响应主机随后发出的功能命令;其它设备将处于等待复位脉冲状态。
跳越ROM[CCh] (仅适合于单节点)
主机能够采用该命令同时访问总线上的所有从机设备,而无须发出任何ROM代码信息。例如,主机通过在发出跳越ROM命令后跟随转换温度命令[44h],就可以同时命令总线上所有的DS18B20 开始转换温度,这样大大节省了主机的时间。值得注意,如果跳越ROM命令跟随的是读暂存器[BEh]的命令(包括其它读操作命令),则该命令只能应用于单节点系统,否则将由于多个节点都响应该命令而引起数据冲突。
报警搜索[ECh](仅少数1-wire 器件支持)
除那些设置了报警标志的从机响应外,该命令的工作方式完全等同于搜索ROM命令。该命令允许主机设备判断那些从机设备发生了报警(如最近的测量温度过高或过低等)。同搜索ROM命令
DS18B20功能命令
命令 | 描述 | 命令代码 | 响应消息 | 注释 |
---|---|---|---|---|
转换温度 | 启动温度转换 | 0x44 | 无 | 1 |
读暂存器 | 读全部的暂存器内容,包括CRC字节 | 0xBE | DS18B20传输至多9个字节 | 2 |
写暂存器 | 写暂存器第2、3和4个字节的数据(即TH、TL和配置寄存器) | 0x4E | 主机传输3个字节数据 | 3 |
复制暂存器 | 将暂存器中的TH、TL和配置字节复制到EEPROM中 | 0x48 | 无 | 1 |
回读EEPROM | 将TH、TL和配置字节从EEPROM回读至暂存器中 | 0xB8 | DS18B20传送回读状态至主机 | |
读取供电方式 | 0xB4 | 1bit:0 = 寄生电源,1 = 提供外部电源 |
注释:
- 在温度转换和复制暂存器数据至EEPROM期间,主机必须在单总线上允许强上拉。并且在此期间,总线上不能进行其它数据传输;
- 通过发出复位脉冲,主机能够在任何时候中断数据传输;
- 在复位脉冲发出前,必须写入全部的三个字节。