概述
1-wire总线是一个具有单总线主机和一个或者多个从机的系统,一般在任何情况下单总线设备(如18B20)都是从机设备,主机一般是一颗MCU。它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的。
1、初始化(复位和应答)
主机通过拉低单总线480 ~ 960 us产生复位脉冲,然后释放总线,进入接收模式。主机释放总线时,会产生低电平跳变为高电平的上升沿,单总线器件检测到上升沿之后,延时15 ~ 60 us,单总线器件拉低总线60 ~ 240 us来产生应答脉冲。主机接收到从机的应答脉冲说明单总线器件就绪,初始化过程完成。
2、写信令(写0和写1)
当数据线拉低后,在15 ~ 60 us的时间窗口内对数据线进行采样。如果数据线为低电平,就是写0,如果数据线为高电平,就是写1。主机要产生一个写1时间隙,就必须把数据线拉低,在写时间隙开始后的15 us内允许数据线拉高。主机要产生一个写0时间隙,就必须把数据线拉低并保持60 us。
3、读信令(读0和读1)
读时序最少需要拉低总线1us,然后释放总线,从设备会在15-45us操作总线,主机进行采样读取数据。
单总线代码示例(18B20):
扫描二维码关注公众号,回复:
3757155 查看本文章
bit Init_DS18B20(void)
{
bit flag; //检测DS18B20是否存在的标志,flag=0,存在;flag=1,不存在
DQ = 1; //先将数据线拉高
for(time=0;time<2;time++); //略微延时约6微秒
DQ = 0;
for(time=0;time<200;time++) ; //向DS18B20发出一持续480~960us的低电平复位脉冲
DQ = 1; //释放数据线(将数据线拉高)
for(time=0;time<10;time++) ; //释放总线后需等待15~60us让DS18B20输出存在脉冲
flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在)
for(time=0;time<200;time++) ; //延时足够长时间,等待存在脉冲输出完毕
return (flag); //返回检测成功标志
}
Void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=0; i<8; i++)
{
DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ=0; //将数据线从高拉低时即启动写时序
DQ=dat&0x01; //与运算取出要写二进制数据,并将其送到数据线上等待DS18B20采样
for(time=0;time<10;time++);//DS18B20在拉低后的约15~45us期间从数据线上采样
DQ=1; //释放数据线
for(time=0;time<1;time++);//延时3us,两个写时序间至少需要1us的恢复期
dat>>=1; //将dat中的各二进制位数据右移1位
}
for(time=0;time<4;time++); //稍作延时,给硬件一点反应时间,两个字节之间
}
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat; //储存读出的一个字节数据
for (i=0;i<8;i++)
{
DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
_nop_(); //等待一个机器周期
DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备
for(time=0;time<2;time++) ; //延时约6us,使主机在15us内采样
dat>>=1;
if(DQ==1)
dat|=0x80; //如果读到的数据是1,则将1存入dat
else
dat|=0x00; //如果读到的数据是0,则将0存入dat
for(time=0;time<8;time++); //延时3us,两个读时序之间必须有大于1us的恢复期
}
return(dat); //返回读出的十六进制数据
}