100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 基于51单片机+DS18B20温度测温器+LCD1602显示

基于51单片机+DS18B20温度测温器+LCD1602显示

时间:2021-11-25 15:45:13

相关推荐

基于51单片机+DS18B20温度测温器+LCD1602显示

DS18B20温度传感器

DS18B20相关介绍学习视频推荐DS18B20特性封装形式与引脚说明供电方式(外部电源供电、寄生电源供电、寄生电源强上拉)内部结构温度存储格式及配置寄存器(模式和分辨率)DS18B20指令(ROM指令操作)指令的使用注意事项时序图初始化写时序(写0或1)读时序(读0或1)程序代码LCD1602显示温度main.c(主函数)项目展示

DS18B20相关介绍

学习视频推荐

我看的是B站的从零学电子。网址

DS18B20特性

1.独特的单总线接口,就需一条线则可实现双向通信(测温)

2.测温范围:-55℃~+125℃,可通过编程设定9—12位分辨率,对应分辨温度分别为0.5、0.25、0.125、0.0625℃。

3.支持多点组网(可连接多个DS18B20温度传感器),多个DS18B20可以并联(3或2线)实现多个组网测温,但注意超过8个要解决好供电问题,否则电压过低会导致传输不稳定,从而数据不准确。

4.工作电压:3.0~5.5V(寄生电源方式下可由数据线供电)

5.在使用过程中不需要外围电路,全部传感元件及转换电路都在芯片内了。(上拉电阻)

6.测温结果直接是数字量输出,单总线串行传送方式,同时可传送CRC校验码(校验数据采集是否正确),具有极强的抗干扰和纠错能力。

7.在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字。

8.负压特性:电源极性接反时,芯片不会因发热而烧毁, 但不能正常工作。

封装形式与引脚说明

供电方式(外部电源供电、寄生电源供电、寄生电源强上拉)

内部结构

DS18B20内部结构如图所示,其中与操作有关的是:64位光刻ROM、温度传感器、9个字节的RAM存储器、EEPROM(温度报警寄存器TH和TL、配置寄存器)。

光刻ROM中64位序列号是出厂前就光刻好的,相当地址序列号。排列是低位开始,低8位(产品类型标号),接着48位(自身序列号,)相当于身份证号、最高8位(前面56位的循环亢余校验码)。

如果一条总线挂接多个DS18B20需要MCU(微控制器)通过单总线对多个DS18B20进行寻址。

温度存储格式及配置寄存器(模式和分辨率)

DS18B20温度传感器进行测温,测温是以16位的二进制形式提供。

存放格式:

16位中 低4位是温度的小数部分、最高5位是温度的正负(全为0为正,全为1为负),中间的7位则是温度的整数部分。小数部分十进制等于16进制乘0.0625。

例子:

注意:如果是负数温度,那么得按位取反+1。

比如数据为 1111 1100 1001 0000

首先低4位都为0.所以温度小数部分为0。最高5位为1,所以温度是负数,所以我们得按位取反才是正确的数, 温度的整数部分为 100 1001——>按位取反得:011 0110 再+1 则结果是 011 0111 ——>0x37(16进制)——>55℃(十进制)

配置寄存器

TM:测试模式位,用于设置是在工作方式还是测试模式。在DS18B20出厂时该位设为0,用户不要改动。

R1 R0:分辨率设置

DS18B20指令(ROM指令操作)

注:每个指令在写都是 低位在前 高位在后 DS18B20发送也是先发低位,再发高位。

比如发送跳过ROM指令(CCH) 二进制位:1100 1100 。发送顺序为

0、0 、1、1、 0、 0、 1、 1 。

指令的使用

多个DS18B20情况:对某一个操作时,主机先逐个与DS18B20挂接-搜索ROM——(F0H),发出匹配ROM指令(55H),紧接着提供64位序列号,之后操作就是针对DS18B20的了。

单个DS18B20情况:不需要搜索ROM指令,读ROM指令以及匹配ROM等操作,直接跳过ROM指令(CCH),温度转换(44H),读温度操作(8EH)。

注意事项

一、DS18B20硬件是简单,但软件就比较复杂,特别是时序要求。

二、连接DS18B20线长限制:部分资料显示:

采用普通信号电缆传输超50m时,测温数据不稳定。

采用带屏蔽层双绞线电缆,正常通讯距离可达到150m。

采用每米绞合次数更多的带屏蔽层双绞线电缆时,通讯距离进一步加长。

三、距离长了测温要考虑总线分布电容和阻抗匹配问题。

在测温程序设计中,一般如果硬件没什么问题,可以采用延时来跳过检测,但是如果要检测是否有应答要注意不要进入了死循环。

时序图

初始化

/*DS18B20初始化函数*/void initDs18b20(){DS18B20 = 1;delay20us();DS18B20 = 0; //拉低电平 delay480us(); //480us-960us之间均可DS18B20 = 1; //拉高电平delay50us(); //等待15us-60usif(DS18B20 == 1) //如果未响应{ds18b20Flag = 1; //DS18B20未响应 标志位置1}delay240us();}

写时序(写0或1)

/*DS18B20写命令函数*/void ds18b20WriteData(unsigned char com){unsigned char i;for(i=0;i<8;i++){DS18B20 = 0; //拉低电平//延时至少1usDS18B20 = com&0x01;delay60us(); //至少60us直到周期结束DS18B20 = 1;com = com>>1; //右移一位}}

读时序(读0或1)

/*DS18B20读数据函数*/unsigned char ds18b20ReadData(){unsigned char i;unsigned char dat = 0; //接收数据for(i=0;i<8;i++){DS18B20 = 0; //拉低电平至少1usdat=dat>>1; //右移一位DS18B20 = 1; //释放总线if(DS18B20 == 1) //如果是1{dat = dat|0x80;}delay45us(); //保持45usDS18B20 = 1; //释放总线}return dat;}

程序代码

每一次进行写ROM相关命令都记得初始化。

对于单个DS18B20我们可以直接跳过ROM指令 直接温度转换。读取温度

步骤:

1.初始化

2.跳过ROM指令

3.启动温度转换(需要时间)

4.延时(等待温度转换)

5.初始化 (记得每写ROM相关命令记得需要从初始化开始)

6.读取温度

7.显示温度

LCD1602显示温度

main.c(主函数)

#include <reg52.h>#include "delay.h"#include "lcd1602.h"sbit DS18B20 = P3^7; //DS18B20引脚unsigned char ds18b20Flag; //DS18B20是否响应标志位unsigned char temperature[2] = {'\0'}; //存放温度整数和小数unsigned char code array[14] = {"DS18B20 error!"};unsigned char code array1[5] = {"Temp:"};/*DS18B20初始化函数*/void initDs18b20(){DS18B20 = 1;delay20us();DS18B20 = 0; //拉低电平 delay480us(); //480us-960us之间均可DS18B20 = 1; //拉高电平delay50us(); //等待15us-60usif(DS18B20 == 1) //如果未响应{ds18b20Flag = 1; //DS18B20未响应 标志位置1}delay240us();}/*DS18B20写命令函数*/void ds18b20WriteData(unsigned char com){unsigned char i;for(i=0;i<8;i++){DS18B20 = 0; //拉低电平//延时至少1usDS18B20 = com&0x01;delay60us();DS18B20 = 1;com = com>>1;}}/*DS18B20读数据函数*/unsigned char ds18b20ReadData(){unsigned char i;unsigned char dat = 0; //接收数据for(i=0;i<8;i++){DS18B20 = 0; //拉低电平至少1usdat=dat>>1; //右移一位DS18B20 = 1; //释放总线if(DS18B20 == 1){dat = dat|0x80;}delay45us(); //保持45usDS18B20 = 1; //释放总线}return dat;}/*读取温度函数*/void readTemperature(){unsigned char temperatureLow; //温度低字节unsigned char temperatureHigh; //温度高字节unsigned char tempFlag = 0; //温度正负标志位unsigned char disposeValue; //处理值initDs18b20();//初始化DS18B20ds18b20WriteData(0xcc); //跳过ROMds18b20WriteData(0x44); //启动温度转换指令//延时一段时间delay800ms();initDs18b20(); //每一次写命令都需要初始化ds18b20WriteData(0xcc); //跳过ROMds18b20WriteData(0xbe); //读暂存器内容temperatureLow = ds18b20ReadData(); //获取温度的第一个字节temperatureHigh = ds18b20ReadData(); //获取温度的第二个字节disposeValue = (temperatureHigh<<4)|(temperatureLow>>4); //获取温度整数部分if(disposeValue>=128) //温度是负数{disposeValue = ~disposeValue+1;tempFlag = 1;}temperature[0] = disposeValue; //温度整数temperature[1] = temperatureLow & 0x0f; //温度小数 }void displayTemperature(){write_com(0x85);write_data((temperature[0]/100) + 0x30); //温度百位write_com(0x86);write_data((temperature[0]/10%10) + 0x30); //温度十位write_com(0x87);write_data((temperature[0]%10) + 0x30); //温度个位write_com(0x88);write_data('.');write_com(0x89);write_data((temperature[1]*10/16) + 0x30);//小数第一位//write_data((tempterature[1]*625/1000));write_com(0x8a);write_data((temperature[1]*100/16%10) + 0x30);//小数第二位//write_data((tempterature[1]*625/100%10));/* 显示 ℃ */write_com(0x8b);write_data(0xdf);write_com(0x8c); write_data('C');}void main(){unsigned char i;init_lcd(); //初始化1602write_com(0x80);for(i=0;i<5;i++){write_data(array1[i]);}while(1){readTemperature(); //读取温度if(ds18b20Flag == 1) //如果初始化错误{for(i=0;i<14;i++){write_com(0x80);write_data(array[i]);//显示DS18B20 error!}}else{displayTemperature(); //温度显示}}}

项目展示

如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈

需要整个工程代码,欢迎大家打赏,评论区留上你的邮箱 或者+我Q:844797079orvxorqq。o( ̄︶ ̄)o

继续加油!!!

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