51单片机+oled+ds18b20检测并显示温度第三篇:配置温度检测ds18b20

51单片机+oled+ds18b20检测并显示温度第一篇:配置温度检测ds18b20

前提:

DS18B20是一线总线(单总线)”接口的温度传感器。其引脚只有三个vcc,gnd和dq

vcc接单片机vcc,gnd接单片机gnd,dq接io口P3^6

因此只要封装好想关函数,对dq连接的io口P3^6进行相关操作,即可得到测量温度

可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃ 和0.0625℃,可实现高精度测温。

1.时序图

(1)初始化时序

单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持

低电平时间至少 480us(该时间的时间范围可以从480到960微妙),以

产生复位脉冲。接着主机释放总线,外部的上拉电阻将单总线拉高,延

时 15~60 us,并进入接收模式。接着 DS18B20 拉低总线 60~240 us,

以产生低电平应答脉冲,若为低电平,还要做延时,其延时的时间从外

部上拉电阻将单总线拉高算起最少要480微妙。

扫描二维码关注公众号,回复: 11540515 查看本文章

在这里插入图片描述

(2)写时序

写时序包括写 0 时序和写 1 时序。所有写时序至少需要 60us,且

在 2 次独立的写时序之间至少需要 1us 的恢复时间,两种写时序均起

始于主机拉低总线。写 1 时序:主机输出低电平,延时 2us,然后释放

总线,延时 60us。写 0 时序:主机输出低电平,延时 60us,然后释放

总线,延时 2us。

在这里插入图片描述

(3)读时序

单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主

机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。

所有读时序至少需要 60us,且在 2 次独立的读时序之间至少需要 1us

的恢复时间。每个读时序都由主机发起,至少拉低总线 1us。主机在读

时序期间必须释放总线,并且在时序起始后的 15us 之内采样总线状态

在这里插入图片描述

因此根据相关时序说明及时序图,要封装的函数为:初始化(复位),写操作,读操作

复位→发 SKIP ROM 命令( 0XCC)→发开始转换命令( 0X44)→延时→复位→发送 SKIP ROM 命令(0XCC)→发读存储器命令( 0XBE)→连续读出两个字节数据(即温度)→结束

2.封装初始化函数

void Init_DS18B20(void)
{
DQ=1;
delay(8);
DQ=0;
delay(80);
DQ=1;
delay(5);
delay(20);
}

3.封装读操作函数

unsigned char ReadOneChar(void) //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{
unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
unsigned char dat=0;
for (i=8;i>0;i–) //一个字节有8位
{
DQ=1;
delay(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);

4.封装写操作函数

void WriteOneChar(unsigned char dat)
{
unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
for(i=8;i>0;i–) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。
{
DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
}

5.最后编写获取温度的函数

void ReadTemperature(void)
{
unsigned char a;
unsigned char b;
Init_DS18B20();
WriteOneChar(0xcc);
WriteOneChar(0x44);
delay(125);
Init_DS18B20();
WriteOneChar(0xcc);
WriteOneChar(0xbe);
a=ReadOneChar();
b=ReadOneChar();
temperature=b;
temperature=a+(temperature<<8);
if((temperature&0xf800)==0xf800)
{
temperature=(~temperature)+1;
value=temperature*(-0.125);
}
else
{
value=temperature*0.125;
}
}

最后根据个人需求编写主函数

附上效果图跟源码地址

https://github.com/linxinloningg/51-0.96oled-iic-ds18b20.git

图片3

猜你喜欢

转载自blog.csdn.net/linxinloningg/article/details/107169881