1-wire 总线

1.1-Wire相关介绍

  • 1-wire(单线)意线是美国达拉斯公司推出的一种总线标准,其特点是只用一根物理既传输时钟,也传输数据,且数据通信是双向的,并且还可以利用该总线给器件完成供电的任务。
  • 1-wire总线具有占用VO资源少、硬件简单的优点。1-Wire产品仅仅需要两条连线,即可保证器件全速运行;而I²C存储器需要4条连接、SPI存储器则需要5条连线。
  • 与I2C总线类似,在一条1-wire上可以挂接多个器件,这些器件既可以是主机,也可以是从机器件。

利用l-wire 总线扩展单片机系统外部资源的示意图如图1.1所示。
1-wire 总线_第1张图片


2.典型电路
1-wire 总线_第2张图片
  作为一种单主机多从机的总线系统,在一条1-Wire总线上可挂接的从器件数量几乎不受限制。为了不引起逻辑上的冲突,所有从器件的1-Wire总线接口都是漏极开路的。
  由于是漏极开路,所以这些器件都总线上拉一个5kΩ左右的电阻到VCC,并且如果使用寄生方式供电,为了保证器件在工作状态下都有足够的电量,在总线上还必须连接一个MOSFET管等以存储电能。
  寄生供电方式指1-wire器件不使用外接电源,直接使用数据信号线作为电能传输信号供电方式。


3.1-Wire通信过程
  主机对1-Wire总线的基本操作分为复位、读和写三种,其中所有的读写操作均为低位在前高位在后。复位、读和写是1-Wire总线通信的基础.
下面通过具体程序详细介绍这3种操作的时序要求。

void delay_us(uchar n)					//函数:延时1us	
{
     
	 	_nop_();
}

①1-Wire总线的复位
  复位是1-Wire总线通信中最为重要的一种操作,在每次总线通信之前主机必须首先发送复位信号。

  • 产生复位信号时主机首先将总线拉低480~960μs然后释放,由于上拉电阻的存在,此时总线变为高电平。
  • 1-Wire总线器件在接收到有效跳变的15~60μs内会将总线拉低60~240μs

在此期间主机可以通过对DQ采样来判断是否有从器件挂接在当前总线上。函数Reset()的返回值为0表示有器件挂接在总线上,返回值为1表示没有器件挂接在总线上。
1-wire 总线_第3张图片
1-wire 总线_第4张图片

  • 检查总线上是否有器件
unsigned char DS18B20_RST(void)
{
     
	unsigned char Check;	//检测是否存在DS18B20单总线设备
	DQ = 0delay_us(480);
	DQ = 1;
	delay_us(60);
	Check = DQ;			 //若为0,则接收到DS18B20应答信号
	delay_us(480);		//延时大于480μs,等复位脉冲信号结束
	return Check;
}
  • 手动复位
void init_ds18b20(void) 	//函数:18B20初始化
{
     
	DQ = 0delay_us(480);          //单片机:将数据端拉低,发复位脉冲信号
	DQ = 1;					
	delay_us(60);			//数据端被单片机拉高60us
	delay_us(480);			//延时大于480μs,等复位脉冲信号结束

}

②1-Wire总线的写操作
  由于只有一条I/O线,主机1-Wire总线的写操作只能逐位进行,连续写8次即可写入总线一个字节。如程序1.2所示,

  • 当MCS-51单片机的时钟频率为12MHz时,程序中的语句_nop_();可以产生1μs的延时,调用此函数时需包含头文件“intrins.h”。
  • 向1-Wire总线写1bit至少需要60μs,同时还要保证两次连续的写操作有1μs以上的间隔。

1-wire 总线_第5张图片1-wire 总线_第6张图片

  • 向总线写1bit
    • 若待写位wbit为0则主机拉低总线60μs然后释放,写0操作完成。
    • 若待写位wbit为1,则主机拉低总线并在1~15μs内释放,然后等待60μs,写1操作完成。
void Writebit(uchar wbit)

{
     
	_nop_();//保证两次写操作间隔1μs以上
	DQ=0;
	_nop_();//保证主机拉低总线1μs以上
	if(wbit)
	{
     
		DQ=1;//向总线写1
		delay60μs();
	}
	else
	{
     
		delay60μs();//向总线写0
		DQ=1;
	}
}
  • 向总线写1字节
//DS18B20写一个字节
void DS18B20_Write_Byte(unsigned char data)
{
     
	unsigned char i = 0;
	for(i = 0;i < 8 ;i++)
	{
     

		DQ = 0;
		delay_us(1);
		DQ = data & 0x01;
		delay_us(60);		//延时60us则写1写0都一样了
		data >>= 1;   
		DQ= 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		_nop_();_nop_();

	}
}

③1-Wire总线的读操作

  与写操作类似,主机对1-Wire总线的读操作也只能逐位进行,连续读8次,即可读入主机一个字节。

  • 从1-Wire总线读取1bit同样至少需要60μs,同时也要保证两次连续的读操作间隔1μs以上。

  • 从总线读数据时,主机首先拉低总线1μs以上然后释放,在释放总线后的1~15μs内主机对总线的采样值即为读取到的数据。
    1-wire 总线_第7张图片1-wire 总线_第8张图片

  • 从总线读1bit

uchar Readbit()
{
     
	uchar tdq;
	_nop_();		//保证两次连续写操作间隔1μs以上
	DQ=0;
	_nop_();		//保证拉低总线的时间不少于1μs
	DQ=1;
	_nop_();
	tdq=DQ;			//主机对总线采样
	delay60μs();	//等待读操作结束
	return tdq;		//返回读取到的数据
}
  • 向总线读1字节
    若发送“1”,则保持总线为高电平;
    若发送“0”,则拉低总线并在该周期结束后释放总线
/* 从 DS18B20 读取一个字节,返回值-读到的字节 */
unsigned char Read18B20(){
     
    unsigned char dat;
    unsigned char mask;
    EA = 0; //禁止总中断
    for (mask=0x01; mask!=0; mask<<=1){
      //低位在先,依次采集 8 个 bit
        IO_18B20 = 0; //产生 2us 低电平脉冲
        _nop_();
        _nop_();
        IO_18B20 = 1; //结束低电平脉冲,等待 18B20 输出数据
        _nop_(); //延时 2us
        _nop_();
        if (!IO_18B20){
      //读取通信引脚上的值
            dat &= ~mask;
        }else{
     
            dat |= mask;
        }
        DelayX10us(6); //再延时 60us
    }
    EA = 1; //重新使能总中断
    return dat;
}

你可能感兴趣的:(硬件,单片机,嵌入式硬件,1-wire总线)