单总线是美国DALLAS公司推出的外围串行扩展总线技术,与SPI、I2C串行数据通信方式不同,它采用单根信号线,既传输时钟又传输数据,而且数据传输是双向的。
单总线英文名1-Wire,传输速率一般是15.3Kbit/s,最大可达142Kbit/s,通常采用100Kbit/s以下的速率传输数据。
最常用的温感DS18B20采用的就是单总线结构。
单总线适用于单主机系统,能够控制一个或多个从机设备。主机可以是微控制器,从机可以是单总线器件,它们之间的数据交换只通过一条信号线。
单总线典型框图
2.2 漏极开路
单总线主机或从机设备通过一个漏极开路或三态端口连接至该数据线,由于是开漏结构,需要在数据线上加一个上拉电阻,一般是4.7K4.7K4.7K;
为了确保总线上的某些器件在工作时(如温度传感器进行温度转换、E2PROM写人数据时)有足够的电流供给,除了上拉电阻之外,还需要在总线上使用MOSFET提供强上拉供电,
大多数的应用这个强上拉是不需要的。
主机或从机将数据线拉低到GND表示数据0,将数据线释放为高表示数据1
单总线典型框图
2.3 寄生供电电路
单总线器件内部设置有寄生供电电路(Parasite Power Circuit)。
当单总线处于高电平时,
一方面通过二极管向芯片供电,另一方面对内部电容C(容值约800pF)充电。
当单总线处于低电平时,
二极管截止,内部电容C向芯片供电。由于电容C的容量有限,因此要求单总线能间隔地提供高电平以能不断地向内部电容C充电,维持器件的正常工作,这就是通过网络线路“窃取”电能的“寄生电源”的工作原理。DS18B20上的寄生电路
2.4 64位ROM ID
主机通过64全球唯一的ROM ID来识别挂在总线网络上的从机。
每个单总线器件都有一个全球唯一的64位ROM ID,该注册码保证唯一的身份,并用于多节点 1-Wire 网络中的器件寻址,64位ROM注册码不可更改,ROM ID由出厂激光刻度在单总线器件内部。
64位 ROM ID组成:前8位是1 WIRE家族码,后48位是唯一的序列号、最后 8 位是由前 56 位 ROM 码所计算出的 CRC 校验码。
64位ROM ID组成
2.5 优缺点
优点:
节省I/O口线、资源结构简单、成本低廉、便于总线扩展和维护等诸多优点。
缺点:
由于所有设备部件均挂在单一总线上,使这种结构只能分时工作,即同一时刻只能在两个设备之间传送数据,这就使系统总体数据传输的效率和速度受到限制,这是单总线结构的主要缺点。
1-Wire器件需要严格的协议来保证数据的完整。
该协议由通过一条线来传送的四种信令组成:包括复位脉冲和在线应答脉冲的复位序列、写 0 时隙、写 1 时隙、读时隙。 除在线应答脉冲以外,所有其它信号都由总线主机发出,并且发送的所有数据和命令都是字节的低位在前。 主机与从机的数据通信是通过时隙完成的,在每个时隙只能传送一位数据。通过写时隙可把数据从主机传送给从机,通过读时隙可把数据由从器件传送给主机,将完成一位传输的时间称为一个时隙。
如下给出了时序的波形图,在后面实测波形会详细介绍时序要求。
3.2 复位/应答复位/应答脉冲
3.3 写时隙
写1和写0时隙
3.4 读时隙
读1和读0时隙
波形定义
4. 实测分析时序
4.1 复位/应答脉冲
复位/应答脉冲要求:
主机拉低总线480~960us来产生复位信号,然后释放总线进入接收模式,接着从机等待15-60us(上拉电阻上拉至高电平),从机再拉低总线60-240us来产生应答信号,主机接收到从机的应答信号后,表明从机准备就绪,初始化过程
完成了。
实测复位应答信号
4.2 写0时隙
写0时隙要求:
写0时隙起始于主机拉低总线,主机拉低总线后,只需在整个时隙期间保持总线低电平在60us以上,一般是60~120us之间。
实测写0时隙
4.3 写1时隙
写1时隙要求:
写1时隙和写0时隙一样,起始于主机拉低总线,在拉低总线15us之内需要将总线拉高,拉高总线需要维持60us以上。
实测写1时隙
4.4 读0时隙
读0时隙要求:
读0时隙由主机发起,且至少拉低总线1us,此时从机才开始在总线上发数据0或者1;
从机发送1,则保持总线为高电平;
从机发送0,则拉低总线。当发送0时,从机在该时隙结束后释放总线,由上拉电阻拉至空闲的高电平状态。从机发出的数据在起始时隙之后,保持有效时间15us,因而,主机在读时隙期间必须释放总线并且在时隙起始后的15us之内采样总线。实测读0时隙
5. DS18B20
5.1 硬件结构
DS18B20是学习51单片机中时,最常用的温感,采用的就是单总线结构。其供电方式有两种,一种是总线寄生电源,一种是使用外部电源。
需要注意,使用总线寄生电源时,18B20的VDD管家需要和GND接在一起。
DS18B20采用寄生电源
DS18B20采用外部电源
DS18B20内部框图
5.1 C语言实现
DS18B20获取温度,四步:初始化(复位/应答)+写字节+读字节+计算温度
#include"delay.h"
#include"18b20.h"
/*------------------------------------------------
18b20初始化
------------------------------------------------*/
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1; //DQ复位
DelayUs2x(5); //稍做延时
DQ = 0; //单片机将DQ拉低
DelayUs2x(200); //精确延时 大于 480us 小于960us
DelayUs2x(200);
DQ = 1; //拉高总线
DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
dat=DQ; //如果x=0则初始化成功, x=1则初始化失败
DelayUs2x(25); //稍作延时返回
return dat;
}
/*------------------------------------------------
读取一个字节
------------------------------------------------*/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
DelayUs2x(25);
}
return(dat);
}
/*------------------------------------------------
写入一个字节
------------------------------------------------*/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
DelayUs2x(25);
DQ = 1;
dat>>=1;
}
DelayUs2x(25);
}
/*------------------------------------------------
读取温度
------------------------------------------------*/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
DelayMs(10);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
附上DS18B20的DATASHEET
永远相信美好的事情即将发生,作者记得诚,写于安徽合肥,时间2020-03-21 PM23:39