900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > STC51单片机学习9--DS18B20温度传感器

STC51单片机学习9--DS18B20温度传感器

时间:2023-03-11 13:22:04

相关推荐

STC51单片机学习9--DS18B20温度传感器

一、DS18B20

DS18B20是Dallas半导体公司的一款数字温度传感器芯片;

DS18B20是一款支持 1-wire总线接口的温度传感器;

DS18B20能测量的温度范围-55℃--125℃,精度是±0.5℃;

DS18B20可以将分辨率设定为9到12位;

DS18B20的工作电压范围3--5.5V

二、DS18B20与STC89C51的连接

单片机的P4.1引脚用来接DS18B20的数据引脚

sbit DS = P4^1;

三、DS18B20的内部构成

以下是友台半导体的DS18B0结构图,内部有9个模块

1、电源与寄生电源

2、ROM:存DS18B20 的系列号,也就是那个64位的编码,

3、存储器控制逻辑

4、Scratchpad(高速暂存器)

高速暂存器就是用来存各种数据的,一共可以存9个字节的数据,存的就是下面5、6、7、8、9这几个模块的数据。

5、温度传感器

Byte0和Byte1存的是温度,就是传感器已经换算好的数字温度,Byte0是温度的低8位,Byte1是温度的高8位,上电默认的温度是0550 = 0000 0101 0101 0000 =1360, 因为默认的分辨率是12位(0.0625℃),所以开机默认的温度是1360*0.0625 ==85℃。

DS18B20采用16位补码的形式来存储温度数据,单位是摄氏度。两个字节一共是8*2=16位,温度的换算表格如下所示:

高字节的5个S是符号位,S=1表示温度为正,S=0表示温度为负;

12位分辨率,最后一位是1/16==0.0625,所以最小的温度分辨率是0.0625℃;

11位分辨率,最后一位是1/8==0.125,所以最小的温度分辨率是0.125℃;

10位分辨率,最后一位是1/4==0.25,所以最小分辨率是0.25℃;

9位分辨率,最后一位是1/2==0.5,所以最小分辨率是0.5℃;

正温度的读取

因为存的温度是补码,正数的原码和补码是一样的,直接读数

比如+85摄氏度:0000 0101 0101 0000 = 1360; 1360*0.0625 =85

比如+25.0625摄氏度:0000 0001 1001 0001 = 401;401*0.0625=25.0625

负温度的读取

因为存的温度是补码,负数的补码转化为原码步骤:先取反,再+1

比如-55摄氏度的补码是:1111 1100 1001 0000(高5位是符号位);

所以真实的补码为100 1001 0000;

补码取反之后,再+1;011 0110 1111+1=011 0111 0000 = 880;

880*0.0625 == 55

几个温度所对应的补码

6、报警触发寄存器

Byte2对应的是TH,也就是高温报警值,用户自己设置

Byte3对应的是TL,也就是低温报警值,用户自己设置

7、配置寄存器

Byte4对应的计时配置寄存器的值;

配置寄存器是用来配置温度的分辨率,可以把温度的分辨率配置为9bit、10bit、11bit、12bit,分别对应的实际温度分辨率为0.5℃、0.25℃、0.125℃、0.0625摄氏度。默认是12位分辨率(0.0625摄氏度)

配置寄存器的内容是这样的

温度的精度和配置

8、用户Byte

有两个Byte,也是留给用户自己用的,不同厂家的设计可能不一样

9、CRC

CRC发生器产生校验码,存在Byte8,是64位ROM中的前56位编码的校验码,由CRC

四、DS18B20的处理序列,也就是工作步骤

1、初始化DS18B20

初始化就是先把总线拉高;

然后检查总线上是否存在DS18B20 ,如果有的话,总线会返回一个低电平脉冲,如果没有DS18B20,那总线一直就是高电平,似乎有点像IIC通讯的应答信号。

2、执行ROM指令:

这个ROM指令就是查询DS18B20 的64位序列号,相当于设备地址,在多个DS18B20总线连接,需要区分每个DS18B20设备。如果是单个的18B20就不需要查询这个序列号了。你不查询也要发一条指令0xCC,表示跳过ROM指令。

ROM指令有哪些

3、执行DS18B20功能指令

4、DS18B20 初始化的C语言实现

void DS18b20_Init(void){bit flag=1;while (flag){while (flag){DQ = 1;delay(1);DQ = 0; //MCU拉低总线480us以上delay(50); // 大约550usDQ = 1; // MCU释放总线,等待DS18B20的应答delay(6); // 等待66us左右才开始读DS18B20的应答flag = DQ; // MCU读总线,只有读到低电平,才表示成功,跳出循环}delay(45); //延时500usflag = ~DQ;//初始化成功了还是要释放总线,把总线拉高}DQ=1;}

5、DS18B20数据读取

DS18B0的数据线只有1根,在这一根线上完成读和写,那就需要的时序更加严格,资源少,命就得硬。

DS18B20的读写时序

MCU 往DS18B20写一个BIT的“0”:

MCU把总线拉低,拉低时间要持续到60--120us之间,然后释放总线(释放总线,上拉电阻就把总线拉高了)。

MCU往DS18B20写一个BIT的“1”:

MCU把总线拉低,,拉低时间要大于1us,然后在15us内拉高总线。

MCU从DS18B20中读一个BIT的:

MCU先把总线拉低,DS18B20检测到总线被拉低1us后,边开始往外送数据,如果送出的是“0”,DS18B20就把总线拉低,一直到读周期结束;如果送出的是“1”,就释放总线,让上拉电阻 把总线拉高。

读一个BIT的周期至少是60us,

往DS18B20中写一个字节的数据

/*** 往DS18B20总写一个字节的数据* 因为DS18B20只能一个BIT一个BIT的写,所以要写一个字节就需要循环8次*/void write_byte(unsigned char Dat){unsigned char i;for (i=0; i<8; i++){DQ = 1;//MCU把总线拉高_nop_(); //延时1us,STC89C52单片机,晶振12MHz,一个nop就是1usDQ = 0; //MCU把总线拉低nops(); //拉低持续4usDQ = Dat & 0x01; //最低位移出delay(6); //不管是0还是1,都持续66us左右Dat >>= 1; //右移一位}DQ = 1;delay(1); }

从DS18B20 中读一个字节

/*** 从DS18B20中读一个字节的数据* 因为DS18B20只能一个BIT一个BIT的读,所以要读一个字节就需要循环8次*/unsigned char read_byte(void){unsigned char i, Dat=0;for (i=0; i<8; i++){DQ=1; //MCU把总线拉高,还没开始读_nop_(); //Dat >>= 1;//每次循环数据右移1位DQ = 0; //MCU把总线拉低,nops(); //拉低尺寸4us左右DQ = 1; //MCU再把总线拉高,也相当于释放总线,总线的电平高低由DS18B20来控制了nops(); //再等待4us左右就开始读DS18B20吐出的数据if (DQ)Dat|=0x80; //一个BIT一个BIT的读delay(6);//延时66us就差不多了}DQ=1; //读完成之后把总线拉高,因为空闲的时候总线hi高电平return(Dat);//返回一个字节的数据}

读温度

/*** 读出温度*/void read_temp(void){DS18b20_Init(); // 器件初始化write_byte(0xCC); // 发Skip ROM命令write_byte(0x44); // 启动温度转换DS18b20_reset();//器件再初始化write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //读温度低8位temp_data[1]=read_byte(); //读温度高8位}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。