版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hu_junhua/article/details/79271810
1.单总线通信初始化
初始化时序包括:主机发出的复位脉冲和从机发出的应答脉冲。主机通过拉低单总线480-960μs产生复位脉冲;然后由主机释放总线,并进入接收模式。主机释放总线时,会产生一由低电平跳变为高电平的上升沿,单总线器件检测到该上升沿后,延时15~60μs,接着单总线器件通过拉低总线60~240μsμ来产生应答脉冲。主机接收到从机的以应答脉冲后,说明有单总线器件在线,到此初始化完成。然后主机就可以开始对从机进行ROM命令和功能命令操作。
void Init_DS18B20(void)
{
DQ = 0; //DQ拉低
Delay480us(); //延时480~960us
DQ = 1; //DQ拉高
Delay60us(); //延时15~60us
if(DQ == 0)//器件应答正确 //如果DQ等于0,则从机应答正确
{
Delay240us(); //延时240us
DQ = 1; //DQ拉高
}
}
2.写时序:
当主机把数据线从逻辑高电平拉到逻辑低电平的时候,写时间隙开始。有两种写时间隙:写1的时间隙和写0时间隙。所有写时间隙必须最少持续60us,包括两个写周期间至少1us的恢复时间。DQ引脚上的电平变低后,DS18B20在一个15us到60us的时间窗口内对DQ引脚采样。如果DQ引脚是高电平,就是写1,如果DQ引脚是低电平,就是写0。主机要生成一个写1时间隙,必须把数据线拉到低电平然后释放,在写时间隙开始后的15us内允许数据线拉到高电平。主机要生成一个写0时间隙,必须把数据线拉到低电平并保持60us。
/******************************************************************/
/* 写一个字节 先写低位 */
/******************************************************************/
void WriteOneByte(unsigned char dat)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
DQ = 0; //DQ先拉低
_nop_(); //在15us以内写对应值,从机进行采样
if(dat & 0x01) //如果是写1则DQ变为1
{
DQ = 1;
}
else
{
DQ = 0; //否则DQ为0
}
Delay60us(); //延时60us
DQ = 1; //释放总线
dat >>= 1; //写下一位数据
}
}
3.读时序:
当主机把总线从高电平拉低,并保持至少1us后释放总线;并在15us内读取从DS18B20输出的数据。
/******************************************************************/
/* 读一个字节 , 低位开始 */
/******************************************************************/
unsigned char ReadOneByte(void)
{
unsigned char i;
unsigned char value = 0;
for(i = 0; i < 8; i++)
{
value >>= 1;
DQ = 0;
_nop_();
DQ = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(DQ)
{
value |= 0x80;
}
Delay60us();
}
return value;
}
4.温度处理过程
1.初始化
2.0XCC
3.0X44
4.延时一段时间
5.初始化
6.0XCC
7.0XBE
8.读取温度寄存器低字节和高字节值
9.数值处理
/******************************************************************/
/* 读取温度 */
/******************************************************************/
unsigned int ReadTemperature(void)
{
unsigned int a, b, t;
Init_DS18B20();
WriteOneByte(0xcc);
WriteOneByte(0x44);
delay_ms(200);
Init_DS18B20();
WriteOneByte(0xcc);
WriteOneByte(0xbe);
a = ReadOneByte(); //低字节
b = ReadOneByte(); //高字节
b = b << 8;
t = a + b;
return t;
}