首页 > 编程知识 正文

51单片机温度传感器程序,51单片机温度传感器

时间:2023-05-06 09:26:01 阅读:140779 作者:3389

DS18B20是一种单总线数字温度传感器,具有测试温度范围为-55-125、体积小、硬件开销低、抗干扰能力强、精度高的特点。 单总线意味着没有时钟线,只有一条通信线。 因为在单总线上数据的读写是通过控制开始时间和采样时间来进行的,所以对定时的要求很严格,这也是DS18B20驱动编程的难点。

一. DS18B20温度传感器1.引脚图

2.DS18B20内部结构图

主要由两部分构成。 如图所示,是64位ROM,9字节的寄存器。

)1) 64位ROM。 其内容是64位序列号,可以认为这是该DS18B20的地址序列码,其作用是使每个DS18B20不同,从而能够将多个DS18B20连接到1条总线。

)2) 9字节寄存器包括温度传感器、上限触发TH高温报警器、下限触发TL低温报警器、高速寄存器、8位CRC发生器。

3.64位ROM结构图

8位CRC:是用于单总线设备的代码,DS18B20定义为28H。

48位序列号:唯一的序列号。

8位序列码:由CRC生成器生产,作为ROM高位56位码的校验码。

4.9字节暂存器结构图

以上为内部9字节的临时单元(包括EEPROM )。

字节0至1是温度存储器,用于存储转换后的温度。

字节2到3是用户用于设置最高和最低报警的值。 这可以通过软件来实现。

字节4是用于使转换精度以9~12位进行动作的配置寄存器。

字节5~7保留位。

字节8 CRC奇偶校验。 这是64位ROM前56位代码的校验码。 由CRC发生器发生。

5.温度寄存器结构图

温度寄存器由2字节构成,分为低位8位和高位8位。 一共16人。

其中,从第0位到第3位,保存着温度值的小数部分。

第4位到第10位保存温度值的整数部分。

第11位到第15位是符号位。 全0表示正温度,全1表示负温度。

表中的数值表示对应的位为1时存在。 如果相应的位为0,则表示不存在。

6.配置寄存器

精度值:

9-bit 0.5

10-bit 0.25

11-bit 0.125

12-bit 0.0625

7.温度/数据关系

注意:如果温度是一个负温度,要将读到的数据减一再取反

2 .单总线协议1 .单总线通信初始化

初始化序列包括来自主机的复位脉冲和来自从机的响应脉冲。 主机降低单总线480-960s,产生复位脉冲,然后主机释放总线,进入接收模式。 当主机释放总线时,产生从低电平跳到高电平的上升沿,单总线设备检测到该上升沿后,延迟15~60s,然后单总线设备降低总线60~240s 主机收到从站的响应脉冲后,表示单总线设备处于联机状态,此时初始化完成。 然后,主机可以开始对从站执行ROM命令和功能命令操作。

2 .位写入定时

写时隙—当主机将数据线从逻辑高电平拉到逻辑低电平时,写间隙开始。 有写1时的间隙和写0时的间隙两种。 所有写入间隔必须至少为60us,并且在两个写入周期之间至少包括1us的恢复时间。 当DQ引脚电平下降时,DS18B20在15us到60us的时间窗口内对DQ引脚采样。 如果DQ引脚为高电平,则写1;如果DQ引脚为低电平,则写0。 主机要产生写入1时间隙,必须将数据线拉到低电平,然后释放,允许在写入间隙开始后的15us内将数据线拉到高电平。 要使主机生成写入0插槽,数据线必须引出到低电平,并保持为60us。

3 .位读出定时

主机将总线降至高水平,至少维持1us后释放总线; 15us内读取从DS18B20输出的数据。

4.DS18B20的ROM操作命令

用途:主要用于选定为单总线的DS18B20,分为五个命令

)1)读出代码33H的ROM,读出DS18B20的序列号,即64位激光ROM码。

)2)用于识别(或选择)代码与55H的ROM相匹配并操作某个特定的DS18B20。

)3) .搜索代码F0H的ROM以确定总线上的节点数和所有节点的序列号。

)4)跳过. ROM,如果代码为CCH,总线上只有一个DS18B20,则不需要匹配。

)5) .报警搜索,代码为ECH,主要用于识别和定位超过系统中程序设置的报警温度极限的节点。

3 .驱动程序测试平台:

单片机: STC89C52RC,晶振12MHZ

#includereg51.h#defi

ne uchar unsigned char#define uint unsigned intsbit DQ=P3^7; //定义数据线void delay_us(uchar n) //延时约16微妙{ while(n--); }

1.初始化

void DS18B20_init(){ DQ=1; delay_us(1); //稍作延时 DQ=0; delay_us(80); //延时480到960us DQ=1; i = 0; while(DQ) //等待DS18B20拉低总线 { delay_us(100); i++; if(i>5)//约等待>5MS { return 0;//初始化失败 } }}

2.写字节

void write_byte(uchar dat) //写一个字节{ uchar i; for(i=0;i<8;i++) { DQ=0; //每写入一位数据之前先把总线拉低1us _nop_(); DQ=dat&0x01; //取最低位写入 delay_us(10); //延时68us,持续时间最少60us DQ=1; //然后释放总线 dat=dat>>1; //从低位开始写 } delay_us(10);}

3.读字节

uchar read_byte() //读一个字节{ uchar i,dat=0; for(i=0;i<8;i++) { DQ=0; //先将总线拉低1us _nop_(); DQ=1; //然后释放总线 _nop_();_nop_(); _nop_();_nop_(); if(DQ) dat=dat|0x80; //每次读一位 dat=dat>>1; //从最低位开始读 delay_us(10); //读取完之后等待48us再接着读取下一个数 } return dat;}

4.读温度

uint read_temper (){ uchar a,b; uint t=0; DS18B20_init(); delay_us(15); write_byte(0xcc); //跳过ROM操作命令 write_byte(0x44); //发送启动温度转换命令 DS18B20_init(); delay_us(15); write_byte(0xcc); //跳过ROM操作命令 write_byte(0xbe); //发送读温度寄存器命令 a=read_byte(); //先读低八位 b=read_byte(); //再读高八位 t=b; t<<=8; //左移八位 t=t|a; //t为16位的数,使高八位为b的值,低八位为a的值 return t; //返回温度值}

5.温度转换

uint temper_change(){ uint temper; float tp; temper=read_temper(); if(temper<0) //考虑负温度的情况 { temper=temper-1; temper=~temper; tp=temper*0.0625; //16位温度转换成10进制的温度 temper=tp*100+0.5; //留两个小数点,并四舍五入 } else { tp=temper*0.0625; //16位温度转换成10进制的温度 temper=tp*100+0.5; //留两个小数点,并四舍五入 } return temper;}

注意:在主函数中调用temper_change()函数返回的temper即为温度值。由于单总线对时序要求严格,我们的延时函数可能并不适用于你的单片机,所以请根据需要自行进行修改

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。