版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36278071/article/details/78012518
前期准备
单线接口访问DS18B20的协议如下:
- 初始化
- ROM操作命令
- 存储器操作命令
- 处理/数据
初始化
单线总线上的所有处理均从初始化序列开始。初始化序列包括总线主机发出一复位脉冲,接着由从属器件送出存在脉冲。(我们只有一个温度传感器所以用不到)
1. 数据线拉到低电平“0”。
2. 延时480微秒(该时间的时间范围可以从480到960微妙)。
3. 数据线拉到高电平“1”。
4. 延时等待80微妙。如果初始化成功则在15到60微妙时间内产生一个由DS18B20所返回的低电平“0”.根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时判断。
5. 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(3)步的时间算起)最少要480微妙。
uchar Ds18b20Init()//初始化DS18B20
{
uchar i;
DSPORT=0;//数据线拉低
i=480;
while(i--);//延时480us
DSPORT=1;//数据线拉高
i=80;
while(i--);延时80us
i=60;
while(i--)//判断是否在60us内响应
{
if(DSPORT==0)
{
Delay1ms(480);//延时480us
return 1;
}
}
}
读时序过程时序图
- 将数据线拉低“0”。
- 延时1微妙。
- 将数据线拉高“1”,释放总线准备读数据。
- 延时10微妙。
- 读数据线的状态得到1个状态位,并进行数据处理。
- 延时45微妙。
- 重复1~7步骤,直到读完一个字节。
uchar Ds18b20ReadByte()//读时序
{
uchar bi,byte;
char i,j;
j=0;
for(i=7;i>=0;i--)
{
DSPORT=0;//拉低总线1us
j++;
DSPORT=1;//释放总线
j++;
j++; //延时6us等待数据稳定
bi=DSPORT; //读取数据,从最低位开始读取
//将byte左移一位,然后与上右移7位后的bi
byte=(byte>>1)|(bi<<7);
j=45;
while(j--);
}
return byte;
}
写时序过程时序图
1.数据线先置低电平“0”
2.延时15微妙。
3.按从低位到高位的顺序发送数据(一次只发送一位)。
4.延时60微妙。
5.将数据线拉到高电平。
6.重复1~5步骤,直到发送完整的字节。
7.最后将数据线拉高。
void Ds18b20WriteByte(uchar byte)//向Ds18b20写入一个字节
{
char bi=0x01;
char i,j;
for(i=0;i<8;i++)
{
DSPORT=0;//每写入一位数据之前先把总线拉低1us
j++;
DSPORT=byte & 0x01;//然后写入一个数据,从最低开始
byte>>=1;
j=6;
while(j--);//延时68us至少60us
DSPORT=1; //释放总线,至少1us之后继续写入
}
}
ROM操作命令
指令 | 约定代码 | 功能 |
---|---|---|
读ROM | 33H | 读DS18B20温度传感器ROM中的编码(即64位地址) |
符合ROM | 55H | 发出此命令,接着发出64位ROM编码,访问单总线上与该编码对应的DS18B20使之做出响应,为下一步对该DS18B20的读写做准备。 |
搜索ROM | 0FOH | 用于确定挂接在同一总线上DS18B20的个数和识别64位ROM地址,为操作各器件做好准备。 |
跳过ROM | 0CCH | 忽略64位ROM地址,直接向DS18B20发温度变化命令,适用于单片工作。 |
告警搜索命令 | 0ECH | 执行后只有温度超过设定值上限或下限的片子才做出响应。 |
RAM操作命令
指令 | 约定代码 | 功能 |
---|---|---|
温度变换 | 44H | 启动DS18B20进行温度转换,12位转换时最长为750ms(9位为93.75ms),结果存入内部9字节RAM中。 |
读暂存器 | 0BEH | 读内部RAM中9字节的内容 |
写暂存器 | 4EH | 发出向内部RAM的3、4字节写上、下限温度数据命令,紧跟该命令之后,时传送两字节的数据。 |
复制暂存器 | 48H | 将RAM中第3、4字节的内容复制到EEPROM中。 |
重调EEPROM | 0B8H | 将EEPROM中内容恢复到RAM中的第3、4字节。 |
读供电方式 | 0B4H | 读DS18B20的供电模式,寄生供电时发送0,外接电源供电发送1 |
//让Ds18b20开始转换温度
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);//跳过ROM操作命令
Ds18b20WriteByte(0x44);//温度转换命令
}
//发送读取温度的命令
void Ds18b20ReadTempCom()
{
Ds18b20Init();;
Delay1ms(1);
Ds18b20WriteByte(0xcc);//跳过ROM命令
Ds18b20WriteByte(0xbe);//发送读取温度的命令
}
//主函数
int Ds18b20ReadTemp()
{
int temp=0;
Ds18b20ChangTemp(); //先写入转换命令
Ds18b20ReadTempCom();//然后等待转换完发送读取温度命令
tml=Ds18b20ReadByte();//读取低位
tmh=Ds18b20ReadByte(); //读取高位
temp=tmh;
temp<<=8;
temp|=tml;
return temp;
}
附加
配置寄存器设置
温度寄存器格式