DS18B20时序解读,51单片机实现
前言
一直在写毕业论文,今天忙里偷闲 ,重新学一下DS18B20
一、DS18B20时序
单总线通信协议,只需要一根数据线即可操作,半双工异步通信
1、初始化
主机将总线拉低至少480us,然后释放总线,等待15—60us后,存在的从机会拉低总线60—240us以响应主机,之后从机将释放总线
注意:初始化时从机不可操作,从机应该是自动释放总线,所以主机释放总线后,延时70us,主机读取总线数据即可,再延时500us满足时间要求,在500us内从机会自动释放
2、发送一位
主机将总线拉低60—120us,然后释放总线,表示发送0;主机将总线拉低1—15us,然后释放总线,表示发送1 。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us
3、接收一位
主机将总线拉低1—15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us末尾),读取为低电平则为接收0,读取为高电平则为接收1,整个时间片应大于60us。
其实就是主机拉低总线,然后一会释放总线,此时若从机想发送0,会拉住总线不让主机释放;若从机发送1,则不理会主机释放总线,总线就拉高了。
4、发送一个字节
连续调用8次发送一位的时序,依次发送一个字节的8位。(低位在前)
5、接收一个字节
连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)
二、具体代码
OneWire.c
#include <regx52.h>
sbit OneWire_DQ=P3^7;
//初始化
unsigned char OneWire_Init()
{
unsigned char i;
unsigned char byte=0;
OneWire_DQ=0;//延时500us
i = 250;
while (--i);
OneWire_DQ=1;//延时65us
i = 30;
while (--i);
byte=OneWire_DQ;//看是否有从机,延时500us
i = 250;
while (--i);
return byte;
}
//发送一位
void OneWire_SendBit(bit Data)
{
unsigned char i;
OneWire_DQ=0;//延时5us
i = 2;
while (--i);
OneWire_DQ=Data;//延时65us,发送1或者0由Data决定
i = 30;
while (--i);
OneWire_DQ=1;//主机释放总线
}
//接收一位
unsigned char OneWire_ReceiveBit()
{
unsigned char i;
unsigned char Data=0;
OneWire_DQ=0;//主机拉低总线延时5us
i = 2;
while (--i);
OneWire_DQ=1;//主机释放总线
i = 2; //延时5us,看从机反映
while (--i);
Data=OneWire_DQ;//主机读取从机数据
i = 25; //延时50us
while (--i);
OneWire_DQ=1;//释放总线
return Data;
}
//循环8次,发送一个字节,先发低位
void OneWire_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(Byte&(0X01<<i))
OneWire_SendBit(1);
else
OneWire_SendBit(0);
}
}
//循环8次接收一个字节,先接受低位
unsigned char OneWire_ReceiveByte()
{
unsigned char i;
unsigned char Byte=0x00;
for(i=0;i<8;i++)
{
if(OneWire_ReceiveBit())
Byte|=(0x01<<i);
}
return Byte;
}
三、仿真
总结
简单写了些DS18B20时序函数,有问题评论即可,跪求点赞收藏