51综合程序02-温度传感器

文章目录

    • 温度传感器
      • 一、温度传感器DS18B20
      • 二、DS18B20驱动程序
      • 三、使用数码管显示
      • 四、使用LCD1602显示
      • 五、使用LCD12864显示

温度传感器

一、温度传感器DS18B20

DS18B20介绍

DS18B20是一款数字温度传感器,是一种高精度、数字输出的温度传感器,被广泛用于各种应用场景,特别是需要测量温度并将数据数字化输出的情况。

以下是DS18B20的一些主要特点和特性:

  1. 数字输出: DS18B20以数字形式输出温度数据,使用1-Wire总线协议进行通信,这使得多个DS18B20传感器可以通过同一根总线进行连接。

  2. 高精度: DS18B20提供高精度的温度测量,通常在±0.5摄氏度范围内。这使得它适用于对温度精度要求较高的应用。

  3. 范围广泛: DS18B20的温度测量范围较广,通常在-55摄氏度到+125摄氏度之间。

  4. 电源和信号共用: 这个传感器通过单一的数据线同时提供电源和传输温度数据,使其在布线上更为简单。

  5. 可编程分辨率: DS18B20允许用户选择不同的温度分辨率,以平衡精度和测量速度之间的需求。

  6. 防水版本: DS18B20也有防水版本,使其适用于需要在潮湿或液体环境中测量温度的应用。

DS18B20广泛应用于温度监测系统、气象站、家用电器、工业自动化等领域。由于其数字输出和方便的接口,它易于集成到各种数字系统中。

二、DS18B20驱动程序

芯片引脚连接图
在这里插入图片描述

DS18B20.h

#ifndef __DS18B20_H_
#define __DS18B20_H_


void Delay1ms(unsigned int y);  //1ms延时
void Delay480us();  //480us延时
unsigned char Ds18b20Init();	//初始化DS18B20
void Ds18b20WriteByte(unsigned char dat);	 //写字节
unsigned char Ds18b20ReadByte();   //读字节
void  Ds18b20ChangTemp();   //温度转换
void  Ds18b20ReadTempCom();  //发送读取温度命令
int Ds18b20ReadTemp();	 //读取温度


#endif

DS18B20.c

#include "DS18B20.h"

sbit DQ=P3^7;

/*1ms延时*/
void Delay1ms(unsigned int y)	
{
	unsigned int x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}

/*480us延时*///@11.0592MHz
void Delay480us()		
{
	unsigned char i, j;
	i = 6;
	j = 38;
	do
	{
		while (--j);
	} while (--i);
}

/*DS18B20初始化*/
unsigned char Ds18b20Init()   
{
	DQ = 0;	//将总线拉低480us~960us
	Delay480us();   //480us的延时
	DQ = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	while(DQ)	//等待DS18B20拉低总线
	{
		Delay1ms(5);
		if(DQ==1)//等待>5MS
		{
			return 0;//初始化失败
		}
	}
	return 1;//初始化成功
}

/*写字节函数*/
void Ds18b20WriteByte(unsigned char dat)   
{
	unsigned char i,j;
	for(j=0; j<8; j++)
	{
		DQ = 0;	     	  //每写入一位数据之前先把总线拉低1us
		i++;
		DQ = dat & 0x01;  //然后写入一个数据,从最低位开始
		i=6;
		while(i--); //延时68us,持续时间最少60us
		DQ = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat >>= 1;
	}
}

/*读取字节函数*/
unsigned char Ds18b20ReadByte()	  
{
	unsigned char byte, bi;
	unsigned int i, j;	
	for(j=8; j>0; j--)
	{
		DQ = 0;//先将总线拉低1us
		i++;
		DQ = 1;//然后释放总线
		i++;
		i++;//延时6us等待数据稳定
		bi = DQ;	 //读取数据,从最低位开始读取
		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
		byte = (byte >> 1) | (bi << 7);						  
		i = 4;		//读取完之后等待48us再接着读取下一个数
		while(i--);
	}				
	return byte;
}

/*让18b20开始转换温度*/
void  Ds18b20ChangTemp()  
{
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
	Ds18b20WriteByte(0x44);	    //温度转换命令 
}

/*发送读取温度命令*/
void  Ds18b20ReadTempCom()   
{	
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
}

/*读取温度*/
int Ds18b20ReadTemp()	 
{
	int temp = 0;
	unsigned char tmh, tml;
	Ds18b20ChangTemp();	//先写入转换命令
	Ds18b20ReadTempCom();  //然后等待转换完后发送读取温度命令
	tml = Ds18b20ReadByte();  //读取温度值共16位,先读低字节
	tmh = Ds18b20ReadByte();  //再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}

三、使用数码管显示

数码管电路引脚连接图
在这里插入图片描述

main.c

#include "reg51.h"			 
#include"DS18B20.h"	

sbit LSA=P2^2;   //数码管位选
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char num=0;
unsigned char DisplayData[8];
unsigned char code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};	 //数码管段选

/*延时函数*/
void delay(unsigned int i)	  
{
	while(i--);	
}

/*温度读取处理转换函数*/	
void datapros(int temp)  
{
   	float tp;  
	if(temp<0)				//当温度值为负数
  	{
		DisplayData[0] = 0x40; 	  //   -
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
  	}
 	else
  	{			
		DisplayData[0] = 0x00;
		tp=temp;     //因为数据处理有小数点所以将温度赋给一个浮点型变量
		temp=tp*0.0625*100+0.5;	
	}
	DisplayData[1] = smgduan[temp/10000];
	DisplayData[2] = smgduan[temp/1000%10];
	DisplayData[3] = smgduan[temp/100%10] | 0x80;
	DisplayData[4] = smgduan[temp/10%10];
	DisplayData[5] = smgduan[temp % 10];
}

/*数码管显示函数*/
void DigDisplay()	 
{
	unsigned char i;
	for(i=0;i<6;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=0;LSB=0;LSC=0; break;//显示第0位
			case(1):
				LSA=1;LSB=0;LSC=0; break;//显示第1位
			case(2):
				LSA=0;LSB=1;LSC=0; break;//显示第2位
			case(3):
				LSA=1;LSB=1;LSC=0; break;//显示第3位
			case(4):
				LSA=0;LSB=0;LSC=1; break;//显示第4位
			case(5):
				LSA=1;LSB=0;LSC=1; break;//显示第5位	
		}
		P0=DisplayData[5-i];//发送数据
		delay(100); //间隔一段时间扫描	
		P0=0x00;//消隐
	}		
}

void main()
{	
	while(1)
	{
		datapros(Ds18b20ReadTemp());	 //数据处理函数
		DigDisplay();//数码管显示函数		
	}		
}

四、使用LCD1602显示

LCD1602电路引脚连接图
在这里插入图片描述

LCD1602.h

#ifndef __LCD1602_h
#define __LCD1602_h

#include<reg51.h>

void delay(unsigned int n);
void WriteStruction(unsigned char date);
void WriteData(unsigned char dat);
void LCDInitiate();


#endif

LCD1602.c

#include "LCD1602.h"


sbit RS=P2^6;  //寄存器选择位
sbit RW=P2^5;  //读写选择位
sbit EN=P2^7;  //使能信号位

/*延时函数*/
void delay(unsigned int n)	    
{
	int i,j;
	for (i=n;i>0;i--)
	for (j=10;j>0;j--);
}

/*LCD写指令函数*/
void WriteStruction(unsigned char date)	
{
	RS=0;	  //选择指令
	RW=0;	  //选择写入
	EN=0;	  //使能端初始化

	P0=date;  //写指令

	delay(1);
	EN=1;	    //写时序,置高电平
	delay(1);
	EN=0;	   //液晶屏出现由1到0的负跳变,使液晶模块开始工作
}

/*LCD写数据函数*/
void WriteData(unsigned char dat)  
{
	RS=1;	   //选择数据
	RW=0;	   //选择写入
	EN=0;	   //初始化使能端

	P0=dat;	   //写数据

	delay(1);
	EN=1;	   //写时序
	delay(1);
	EN=0;	   //液晶屏出现由1到0的负跳变,使液晶模块开始工作
}

/*LCD初始化函数*/
void LCDInitiate()    
{
	WriteStruction(0x38);  //功能设定指令,DL->8位   N->2行  F->5x7
	WriteStruction(0x0c);  //显示开关指令,DCB=100,整体显示,关光标,不闪烁
	WriteStruction(0x06);  //进入模式设置指令,设定输入方式,增量不移位	
	WriteStruction(0x01);  //清屏指令,清除屏幕显示
}

main.c

#include <reg51.h>			 
#include "DS18B20.h"	
#include "LCD1602.h"


unsigned DisplayData[8];
unsigned char code digit[]="0123456789";
unsigned char code D1[]="    Temp:        C";

/*延时函数*/
void delay_us(unsigned int i)	  
{
	while(i--);	
}

/*温度读取处理转换函数*/
void datapros(int temp) 	 
{
   	float tp;  
	if(temp<0)				//当温度值为负数
  	{
		WriteStruction(0x80+0x05);
		WriteData('-'); //   -
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
  	}
 	else
  	{			
		WriteStruction(0x80+0x05);
		WriteData('+');
		tp=temp;     //因为数据处理有小数点所以将温度赋给一个浮点型变量
		temp=tp*0.0625*100+0.5;	
	}
	DisplayData[1] = digit[temp/10000];
	DisplayData[2] = digit[temp/1000%10];
	DisplayData[3] = digit[temp/100%10];
	DisplayData[4] = digit[temp/10%10];
	DisplayData[5] = digit[temp % 10];
}

/*正确显示函数*/
void display_right()   
{
	unsigned char i;
	LCDInitiate();  

	WriteStruction(0x80+0x00);
	i=0;
	while(D1[i]!='\0')
	{
		WriteData(D1[i]);
		i++;	
	}
	WriteStruction(0x80+0x0c);
	WriteData(0xdf);
}

/*LCD1602显示温度*/
void display_temp()
{
	WriteStruction(0x80+0x06);
	WriteData(DisplayData[1]);

	WriteStruction(0x80+0x07);
	WriteData(DisplayData[2]);

	WriteStruction(0x80+0x08);
	WriteData(DisplayData[3]);

	WriteStruction(0x80+0x09);
	WriteData('.');

	WriteStruction(0x80+0x0a);
	WriteData(DisplayData[4]);

	WriteStruction(0x80+0x0b);
	WriteData(DisplayData[5]);
}

void main()
{
	display_right();	
	
	while(1)
	{
		datapros(Ds18b20ReadTemp());	 //数据处理函数
		display_temp();
		delay_us(1000);	
	}		
}

五、使用LCD12864显示

LCD12864电路引脚连接图
在这里插入图片描述
LCD12864.h

#ifndef __LCD12864_H
#define __LCD12864_H


# include <reg51.h>


/*接口定义模块*/
#define LCD12864_DATAPORT P0	  //数据IO口

sbit LCD12864_RS  =  P2^6;             //(数据命令)寄存器选择输入 
sbit LCD12864_RW  =  P2^5;             //液晶读/写控制
sbit LCD12864_EN  =  P2^7;             //液晶使能控制
sbit LCD12864_PSB =  P3^2;             //串/并方式控制
sbit LCD12864_RST =  P3^4;			   //复位端
	
	
/*函数声明模块*/
void LCD12864_Delay1ms(unsigned int c);	//延时函数		
void LCD12864_WriteCmd(unsigned char cmd);	//写指令函数
void LCD12864_WriteData(unsigned char dat);	//写数据函数
void LCD12864_Init();  //12864初始化函数					
void LCD12864_SetWindow(unsigned char x, unsigned char y);  //坐标函数


#endif

LCD12864.c

#include"lcd12864.h"


/*延时函数*/
void LCD12864_Delay1ms(unsigned int c)   
{
	unsigned int a,b;
	for(; c>0; c--)
	{
	    for(b=199; b>0; b--)
		{
	        for(a=1; a>0; a--);	
		}
	}
}

/*写指令函数*/
void LCD12864_WriteCmd(unsigned char cmd)	 
{	
	LCD12864_RS = 0;     //选择命令
	LCD12864_RW = 0;     //选择写入
	LCD12864_EN = 0;     //初始化使能端

	LCD12864_DATAPORT = cmd;   //放置数据

	LCD12864_EN = 1;		   //写时序
	LCD12864_Delay1ms(5);
	LCD12864_EN = 0;    					
}

/*写数据函数*/
void LCD12864_WriteData(unsigned char dat)	  
{
	LCD12864_RS = 1;     //选择数据
	LCD12864_RW = 0;     //选择写入
	LCD12864_EN = 0;     //初始化使能端

	LCD12864_DATAPORT = dat;   //放置数据

	LCD12864_EN = 1;		   //写时序
	LCD12864_Delay1ms(5);				   
	LCD12864_EN = 0;    								
}

/*初始化函数*/
void LCD12864_Init()	
{
	LCD12864_PSB = 1;	  //选择并行输入
	LCD12864_RST = 1;	  //复位
	LCD12864_WriteCmd(0x30);  //选择基本指令操作
	LCD12864_WriteCmd(0x0c);  //显示开,关光标
	LCD12864_WriteCmd(0x01);  //清除LCD12864的显示内容
}

/*在基本指令模式下设置显示坐标。注意:x是设置行,y是设置列*/
void LCD12864_SetWindow(unsigned char x, unsigned char y)	   
{
	unsigned char pos;

	if(x == 0)	   // 第一行的地址是80H
	{
		x = 0x80;
	}
		
	else if(x == 1)  //第二行的地址是90H
	{
		x = 0x90;	
	}
	
	else if(x == 2)  //第三行的地址是88H
	{
		x = 0x88;
	}
	
	else if(x == 3)
	{
		x = 0x98;
	}
	
	pos = x + y;
	LCD12864_WriteCmd(pos);
}

main.c

#include <reg51.h>			 
#include "DS18B20.h"	
#include "LCD12864.h"


unsigned DisplayData[8];
unsigned char code digit[]="0123456789";
unsigned char code D1[]="温度:           ";

void delay_us(unsigned int i)	  /*延时函数*/
{
	while(i--);	
}


/*温度读取处理转换函数*/
void datapros(int temp) 	 
{
   	float tp;  
	if(temp<0)				//当温度值为负数
  	{
		LCD12864_WriteCmd(0x80+0x00);
		LCD12864_WriteData('-'); //   -
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
  	}
 	else
  	{			
		LCD12864_WriteCmd(0x80+0x03);
		LCD12864_WriteData('+');
		tp=temp;     //因为数据处理有小数点所以将温度赋给一个浮点型变量
		temp=tp*0.0625*100+0.5;	
	}
	DisplayData[1] = digit[temp/10000];
	DisplayData[2] = digit[temp/1000%10];
	DisplayData[3] = digit[temp/100%10];
	DisplayData[4] = digit[temp/10%10];
	DisplayData[5] = digit[temp % 10];
}

/*正确显示函数*/
void display_right()   
{
	unsigned char i;
	LCD12864_Init();  

	LCD12864_SetWindow(0x80+0x00,0);
	i=0;
	while(D1[i]!='\0')
	{
		LCD12864_WriteData(D1[i]);
		i++;	
	}
}

void display_temp()
{
	LCD12864_WriteData(DisplayData[1]);
	LCD12864_WriteData(DisplayData[2]);
	LCD12864_WriteData(DisplayData[3]);
	LCD12864_WriteData('.');
	LCD12864_WriteData(DisplayData[4]);
	LCD12864_WriteData(DisplayData[5]);
	LCD12864_WriteData(' ');
	LCD12864_WriteData(0xa1);
	LCD12864_WriteData(0xe6);
}	

void main()
{
	display_right();	
	while(1)
	{
		datapros(Ds18b20ReadTemp());	 //数据处理函数
		display_temp();
		delay_us(1000);	
	}		
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/216838.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三种定时器的实现方式

一、Scheduled Schedule是Spring框架提供的一种简单的定时任务调度方法&#xff0c;通过注解的方式即可实现定时任务的调度。它适用于简单的定时任务需求&#xff0c;例如每隔一段时间执行一次任务或者在特定时间执行任务。Scheduled可以轻松地集成到Spring应用中&#xff0c;…

Huawei FusionSphere FusionCompte FusionManager

什么是FusionSphere FusionSphere 解决方案不独立发布软件&#xff0c;由各配套部件发布&#xff0c;请参 《FusionSphere_V100R005C10U1_版本配套表_01》。 目前我们主要讨论FusionManager和FusionCompute两个组件。 什么是FusionCompte FusionCompute是华为提供的虚拟化软…

什么是中间人攻击

中间人攻击 1. 定义2. 中间人攻击如何工作3. 常见中间人攻击类型4. 如何防止中间人攻击 1. 定义 中间人攻击&#xff08;Man-in-the-Middle Attack&#xff0c;简称MITM&#xff09;&#xff0c;是一种会话劫持攻击。攻击者作为中间人&#xff0c;劫持通信双方会话并操纵通信过…

python程序将部分文件复制到指定目录

geotools-28.2中的lib一共有264个jar包&#xff0c;但我只想将部分100个左右jar包引导我的环境中&#xff0c;那个就需要从目录中找出想要的那100个jar&#xff0c;手动挑选太费时间&#xff0c;我简单的写了个小脚本来实现。 我将想要的jar文件名和路径存放到txt中&#xff0…

如何在 Chrome 上调试文件打断点

1. 控制台进入 Source 2. CtrlP 输入文件名称 3. 在需要的位置手动打断点 4. 重新触发代码运行&#xff0c;触发断点

Python中的类(Class)和对象(Object)

目录 一、引言 二、类&#xff08;Class&#xff09; 1、类的定义 2、类的实例化 三、对象&#xff08;Object&#xff09; 1、对象的属性 2、对象的方法 四、类和对象的继承和多态性 1、继承 2、多态性 五、类与对象的封装性 1、封装的概念 2、Python中的封装实现…

Java参数验证@Validated

就以登录接口为例&#xff0c;如果用户传参的时候没有传递帐号或者密码&#xff0c;会报错&#xff0c;但是报错的信息不够全面&#xff0c;前端人员不好判断是什么问题&#xff0c;这个时候就需要对参数进行一个校验 引入依赖 <dependency><groupId>org.hibernat…

一键式紧急报警柱系统

随着科技的不断发展&#xff0c;一键式紧急报警柱在我们的生活和工作中扮演着越来越重要的角色。在这篇文章中&#xff0c;我们将一起探究与一键式紧急报警柱有关的知识。 一键式紧急报警柱是一种常见的安全防护设备&#xff0c;能够在紧急情况下快速发出警报&#xff0c;保护…

LabVIEW开发工业设备远程在线状态监测

LabVIEW开发工业设备远程在线状态监测 项目需要减少意外停机和维护费用、提供更完整的机器操作和状态图、改进设备使用情况跟踪。 该解决方案是一个多节点&#xff08;即多站点&#xff09;远程监控系统&#xff0c;它利用了基于NI cRIO的控制器和定制的LabVIEW监测软件。 方…

基于YOLOv8深度学习的安全帽目标检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

外包干了2个月,技术明显退步了...

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近5年的功能测试&#xff0c;今年11月份&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…

C语言入门基础知识(一)

#C语言基础知识入门 说明C语言代码块结构 #include <stdio.h> //这个语句的功能是进行有关的预处理操作。include称为文件包命令&#xff0c;后面尖括号中内容称为头部文件或收文件。 #include "demo.h" //导入的是工程内部的头文件 int main() { //main 函…

JVM==>图解字节码指令

一&#xff0c;原始代码 我们来看一下执行这段代码的具体流程 那执行这段代码中 JVM就会把已经编译好的.class文件加载到内存中&#xff0c;交给CPU运行 1&#xff09;常量池载入运行时常量池 我们发现 10 并没有被存入常量池中&#xff0c; 这是因为short范围以内的数字不会…

马斯克极简5步工作法 —— 筑梦之路

马斯克的五步流程法则&#xff1a; 第一步&#xff1a;确定需求 第二步&#xff1a;极力删除零件或过程 第三步&#xff1a;简化和优化 第四步&#xff1a;加快周期时间 第五步&#xff1a;自动化特别注意&#xff1a;完成前三步之前&#xff0c;千万不要考虑加速和自动化&…

关于 Windows 11 显示更多选项

更新 Windows 11 后&#xff0c;右键鼠标出现 显示更多选项&#xff0c;本文解决如何默认显示所有选项 默认显示更多选项 winR打开运行框输入cmd回车输入下面的命令并回车&#xff0c;重启系统 reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c9…

GeoServer本地部署与远程访问Web管理页面——“cpolar内网穿透”

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址 前言 GeoServer是OGC Web服务器规范的J2EE实现&#xff0c;利用GeoServer可以方便地发布地图数据&#xff0c;允许用户对要素数据进行更新、删除、插入…

docker配置redis主从、哨兵集群

搭建redis主从 准备工作 在/usr/local/software/redis/文件夹下建立如下的文件夹、文件 rootlocalhost redis]# mkdir -p 6379/conf 6379/data 6379/log [rootlocalhost redis]# mkdir -p 6380/conf 6380/data 6380/log [rootlocalhost redis]# mkdir -p 6381/conf 6381/…

craco + webpack 4 升 5

craco webpack 4 升 5 更新包版本尝试build升级其他依赖库使用process插件打印进度信息到底需要多少内存分析构建产出添加 splitChunk总结记录一些好文章&#xff1a; 我的项目使用 craco react 开发 我的 package.json {// ......"dependencies": {"ant-desi…

无需服务器,无需魔法,拥有一个微信机器人就是这么简单

前情提要 还没看过的朋友可以看一下上一篇文章《拥有一个微信机器人总共需要几步&#xff1f;》在这篇文章里&#xff0c;我们提到&#xff0c;创建微信机器人需要一个大前提--你得有一台服务器。现在&#xff0c;不再需要了&#xff01;没错&#xff0c;上一篇提到的Serverles…

UVM验证环境 加入env

&#xff08;1&#xff09; 如何在UVM验证环境中例化reference model、scoreboard 如何在在验证平台中加入reference model、scoreboard&#xff0c;这个问题的解决方案是引入一个容器类&#xff0c;在这个容器类中实例化driver、monitor、reference model和scoreboard等。在…