特点如下:
◉测量温度范围为-55 ~ +125℃ 。
◉在-10 ~ +85°C范围内, 精度为±0.5°C。
◉可程序设定 9~12 位的分辨率。
◉3.0 ~ 5.5V 的工作电压范围。
◉自带EEPROM,可用于存储设定分辨率及用户设定的报警温度。
◉转换得到一次数字输出需要750ms(Max)
◉数据线(DQ)也可以用来提供电源(寄生电源,实现方式见datasheet)
直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。它能直接读出被测温度,并且可根据实际要求通过简单的编程实现 9 ~ l2 位的数字值读数方式。采用多种封装形式,从而使系统设计灵活、方便。其ROM 中的 64 位序列号是出厂前被光记好的,它可以看作是该 DS18B20 的地址序列码,每DS18B20 的 64 位序列号均不相同。64 位 ROM 的排列是:前 8 位是产品家族码,接着 48 位是DS18B20 的序列号,最后 8 位是前面 56 位的循环冗余校验码(CRC=X8+X5+X4+1)。ROM 作用是使每一个 DS18B20 都各不相同,这样就可实现一根总线上挂接多个 DS18B20。
可以在总线上只挂载一个DS18B20时使用其的ROM指令来获取这64位的序列号。 一般的电路连接方式如下:
二、通信信号类型的介绍和对应代码的实现
所有的单总线器件要求采用严格的信号时序,以保证数据的完整性。
DS18B20 共有 6 种信号类型:复位脉冲、应答脉冲、写 0、写 1、读 0 和读 1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。 2.1 复位脉冲(单片机发送)
单总线上的所有通信都是以初始化序列开始,这里的初始化序列为复位脉冲。
主机输出低电平,保持低电平时间480~960us,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,并进入接收模式(Rx)。
代码实现
使用的是RT-Thread的BSP开发,使用PIN设备框架来实现对IO的控制。
1///* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
2#define DS18B20_DQ 11 /* PA11 */
3//复位DS18B20
4void DS18B20_Rst(void)
5{
6 rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT);// 引脚为输出模式
7 rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ
8 rt_hw_us_delay(750); //拉低750us(480 ~ 960us)
9 rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //设置为输入,即可释放总线的占用
10 //进入接收模式,等待应答信号。
11}
RT-Thread实现微秒延时的方法:微秒延时:https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=11840&highlight=%E5%BE%AE%E7%A7%922.2 应答信号(DS18B20发送)
在接收到单片机发出的复位脉冲后(其实是检测到上升沿),等待15~60 us后,DS18B20拉低总线60~240us,以产生应答脉冲。接收到此信号说明该通信线挂载有DS18B20。
代码实现
1//等待DS18B20的回应
2//返回1:未检测到DS18B20的存在 返回0:存在
3//等待了30us, 从机回应为108us,正常。
4
5uint8_t DS18B20_Check(void)
6{
7 uint8_t retry=0;
8 //------------------等待时间----------------------------------
9 rt_hw_us_delay(15); //15 ~60us 等待
10 while (rt_pin_read(DS18B20_DQ)&&retry<100) //最多还等待100us
11 {
12 retry++;
13 rt_hw_us_delay(1);
14 };
15 if(retry>=100) return 1; //100us未响应,则判断未检测到
16 else retry=0;
17
18 //----------------------从机拉低时间开始----------------------
19
20 while (!rt_pin_read(DS18B20_DQ)&&retry<240)
21 {
22 retry++;
23 rt_hw_us_delay(1);
24 };
25 if(retry>=240) return 1; //最长拉低240us
26 return 0;
27}
复位与应答的时间序列
2.3 写时序(单片机发送数据)写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。利用输出低电平的时间长短来实现写1或0。 写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。
写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。
代码实现
1//写一个字节到DS18B20
2//dat:要写入的字节
3void DS18B20_Write_Byte(uint8_t dat)
4 {
5 uint8_t j;
6 uint8_t testb;
7 rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); // DQ引脚为输出模式
8 for (j=1;j<=8;j++)
9 {
10 testb=dat&0x01;
11 dat=dat>>1;
12 if (testb) //输出高
13 {
14 rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ,主机输出低电平
15 rt_hw_us_delay(2); //延时2us
16 rt_pin_write(DS18B20_DQ, PIN_HIGH); //主机输出高电平
17 rt_hw_us_delay(60); //延时60us
18 }
19 else //输出低
20 {
21 rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ,主机输出低电平
22 rt_hw_us_delay(60); //延时60us
23
24 rt_pin_write(DS18B20_DQ, PIN_HIGH); //主机输出高电平
25 rt_hw_us_delay(2); //延时2us
26 }
27 }
28 rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //设置为输入,释放总线
29}
2.4 读时序(单片机读取数据)
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。
所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。
典型的读时序过程为:
主机输出低电平,延时2us
然后主机转入输入模式,延时12us
然后读取单总线当前的电平,然后延时50us
代码实现
1//从DS18B20读取一个位
2//返回值:1/0
3uint8_t DS18B20_Read_Bit(void) // read one bit
4{
5 uint8_t data;
6 rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); // DQ引脚为输出模式
7 rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ,主机输出低电平
8 rt_hw_us_delay(2); //延时2us
9 rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //设置为输入,释放总线
10 rt_hw_us_delay(1);//延时1us
11
12 if(rt_pin_read(DS18B20_DQ))
13 data=1;//读取总线数据
14 else
15 data=0;
16 rt_hw_us_delay(60); //延时60us(读一位至少60us)
17 return data;
18}
19
20//从DS18B20读取一个字节
21//返回值:读到的数据
22uint8_t DS18B20_Read_Byte(void) // read one byte
23{
24 uint8_t i,j,dat;
25 dat=0;
26
27 for (i=1;i<=8;i++)
28 {
29 j=DS18B20_Read_Bit();
30 dat=(j<<7)|(dat>>1);
31 }
32 return dat;
33}
读写时间序列(读写一个位作为一个周期,至少60us)
三、温度获取的代码实现
DS18B20的各个ROM命令:datasheet上有说明,或者DS18B20的ROM指令中文
DS18B20的典型温度读取过程为:
1、MCU发送复位信号,发SKIP ROM命令(0XCC,匹配指令)。// 每次对设备发指令都需要这两步。
注:该匹配命令只适合挂载一个设备的情况下,即不需要匹配DS18B20的64位的地址编码。
2、发开始转换命令(0X44),温度一次转换指令,DS18B20内部实现温度转换成数字量。
3、延时一段时间(12bit分辨率时需要750ms)。
4、MCU发送复位信号,发送SKIP ROM命令(0XCC)。
5、发读存储器命令(0XBE),读取暂存器内容。
注:读取将从第1个字节开始,一直进行下去,直到第9(CRC)字节读完。如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。其中第0、1个字节分别为温度值的低位、高位。
6、连续读出两个字节数据(即温度)。
7、对得到的温度值进行转换。
转化后得到的12位数据(采用二进制补码的方式),采用如下方法进行温度换算。
1、二进制中的前面5位是符号位,如果测得的温度大于0, 这5位为0,只要将测到的数值乘于0.0625即可得到实际温度。
2、如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。
温度代码实现
1//从ds18b20得到温度值
2//精度:0.5度
3//返回值:温度值 (-550~1250)
4int16_t DS18B20_Get_Temp(void)
5{
6 uint8_t temp; //用来判断符号
7 uint8_t TL,TH;
8 uint16_t tem;
9 rt_base_t level;
10
11 level = rt_hw_interrupt_disable(); //API:进入临界区,退出前系统不会发生任务调度
12 // ds1820 start convert
13 DS18B20_Rst();
14 DS18B20_Check();
15 DS18B20_Write_Byte(0xcc); // skip rom
16 DS18B20_Write_Byte(0x44); // convert
17 rt_hw_interrupt_enable(level); //API:退出临界区
18
19 rt_thread_mdelay(800); //等待转换完成,至少750ms
20
21 level = rt_hw_interrupt_disable(); //API:进入临界区,退出前系统不会发生任务调度
22 DS18B20_Rst(); //复位
23 DS18B20_Check();
24 DS18B20_Write_Byte(0xcc); // skip rom
25 DS18B20_Write_Byte(0xbe); // 读取命令
26 TL=DS18B20_Read_Byte();
27 TH=DS18B20_Read_Byte();
28 rt_hw_interrupt_enable(level); //API:退出临界区
29 if(TH>7)
30 {
31 TH=~TH;
32 TL=~TL;
33 temp=0;//温度为负
34 }else temp=1;//温度为正
35 tem=TH; //获得高八位
36 tem<<=8;
37 tem+=TL;//获得底八位
38 tem=(float)tem*0.625;//转换
39
40 if(temp)
41 return tem; //返回温度值
42 else
43 return -tem;
44}
四、RT-Thread实现
其实很简单,就是创建了一个线程,然后在入口函数上调用温度获取函数,得到温度值。
1/*
2说明:ds18b20温度获取线程的入口函数
3*/
4void ds18b20_tid_entry(void *parameter)
5{
6 int16_t dat;
7 while(1)
8 {
9 rt_thread_mdelay(1000); //1s读取一次
10 dat = DS18B20_Get_Temp();
11 rt_kprintf("temp:%d\n",dat); //读取温度数据并发送到串口。 温度扩大十倍
12 }
13}
14void ds18b20_init(void)
15{
16 ds18b20_tid = rt_thread_create("ds18b20_thread", //线程名字
17 ds18b20_tid_entry, //线程入口函数
18 RT_NULL, //线程入口参数
19 THREAD_STACK_SIZE, //堆栈大小,
20 THREAD_PRIORITY, //线程优先级
21 THREAD_TIMESLICE); //时间片长度
22 /* 如果获得线程控制块,启动这个线程 */
23 if (ds18b20_tid != RT_NULL)
24 rt_thread_startup(ds18b20_tid);
25}
效果如下:(得到的结果是扩大了十倍,由于目的仅仅是测试一下,就懒得美化结果了)
五、使用DS18B20注意事项
1、12bit分辨率的转换时间最大为750ms(别的分辨率看手册),需延时大于此值。
2、The power on reset register value is +85°C
3、TH, TL, and CONFIG必须同时连续被写(不能只写一个),
4、CONFIG控制分辨率,分辨率越高,转换时间越长(默认12bit,时间为750ms)
5、初始化信号:每次通信必须初始化一次,
过程,主机一个复位脉冲触发,从机用一个脉冲响应,表示线上有ds18b20存在且准备操作。
6、Read ROM [33h]
读序列号,要求总线上只有一个从机。
7、Match ROM [55h]
匹配序列号
8、Skip ROM [CCh]
无需序列号即可读,适用于只有一个从机的情况。
9、Write Scratchpad [4Eh]
写TH、TL和CONFIG寄存器,三个必须一起写。
10、Convert T [44h]
温度开始转换命令,发送此命令,需要转换时间(12bit 750ms)
11、写时序
一位至少60us,且每个写周期至少有1us恢复时间。
ds18b20在检测到DQ下降沿后15~60us内采集该线信号,若为高,则为1,若为低,则为0.
12、读时序
从主机将DQ线从高拉低开始,保持最低1us,然后释放改为输入模式,也是从这个下降沿开始的15us,从机输出的电平就是有效值(我们要读的高或者低)。之后从机会释放总线
13、the sum of T INIT , T RC(上升时间) , and T SAMPLE must be less than 15 µs(读一位的时间),尽量留给采样最多的时间。
作者:GlYoung
RT-Thread
让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。
长按二维码,关注我们