51_DS18B20

news/2024/10/18 0:22:50/

基于51单片机的知识总结,使用protues和keil共同学习。
我使用的是protues7.8 和 keil4,需要软件的联系我。
源码及protues仿真:https://download.csdn.net/download/sinat_33734313/11857025

DS18B20温度测量

protues电路仿真

仿真元器件

DS18B20
LM016L

仿真电路以及使用软件截图

在这里插入图片描述
在这里插入图片描述

硬件说明

1. LCD
参照:https://blog.csdn.net/sinat_33734313/article/details/102461590
2. DS18B20
在这里插入图片描述
在这里插入图片描述
2.1 初始化时序
在这里插入图片描述
2.2 读时序
在这里插入图片描述
2.3 写时序
在这里插入图片描述

程序

/*-------------------------------------------
FileName:main.c
Function: 使用DS18B20测量温度
Description:测量温度;
LCD1602实时显示温度
---------------------------------------------
Author: Ethan Chen
Date: 2019-10-12
-------------------------------------------*/#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#include "temp.h"
#include "lcd.h"typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;char num=0;
u8 DisplayData[8];/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{while(i--);	
}/*******************************************************************************
* 函 数 名         : datapros()
* 函数功能		   : 温度读取处理转换函数
* 输    入         : temp
* 输    出         : 无
*******************************************************************************/void datapros(int temp) 	 
{static int LastTemp = 0;float tp; u8 index;index = 0;if(temp < 0)				//当温度值为负数{DisplayData[index++] = '-'; 	  //   -//因为读取的温度是实际温度的补码,所以减1,再取反求出原码temp=temp-1;temp=~temp;tp=temp;temp=tp*0.0625*100+0.5;	//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算加上0.5,还是在小数点后面。}else{tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量//如果温度是正的那么,那么正数的原码就是补码它本身temp=tp*0.0625*100+0.5;	//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算加上0.5,还是在小数点后面。}if( LastTemp == temp )	return;LastTemp = temp;DisplayData[index++] = temp / 10000 + '0';DisplayData[index++] = temp % 10000 / 1000 + '0';DisplayData[index++] = temp % 1000 / 100 + '0';DisplayData[index++] = '.';DisplayData[index++] = temp % 100 / 10 + '0';DisplayData[index++] = temp % 10 + '0';display(DisplayData, index);
}/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	LcdInit();displayInit();while(1){delay(1000);datapros(Ds18b20ReadTemp());	 //数据处理函数}		
}
/*-----------------------------
FileName:temp.c
Function: DS18B20
Author: Ethan Chen
Date: 2019-10-12
------------------------------*/#include"temp.h"
/*******************************************************************************
* 函 数 名         : Delay1ms
* 函数功能		   : 延时函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void Delay1ms(uint y)
{uint x;for( ; y>0; y--){for(x=110; x>0; x--);}
}
/*******************************************************************************
* 函 数 名         : Ds18b20Init
* 函数功能		   : 初始化
* 输    入         : 无
* 输    出         : 初始化成功返回1,失败返回0
*******************************************************************************/uchar Ds18b20Init()
{uchar i;DSPORT = 0;			 //将总线拉低480us~960usi = 100;	while(i--);//延时642usDSPORT = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低i = 0;while(DSPORT)	//等待DS18B20拉低总线{//Delay1ms(1);i++;if(i>100)//等待>5MS{return 0;//初始化失败}}return 1;//初始化成功
}/*******************************************************************************
* 函 数 名         : Ds18b20WriteByte
* 函数功能		   : 向18B20写入一个字节
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void Ds18b20WriteByte(uchar dat)
{uint i, j;for(j=0; j<8; j++){DSPORT = 0;	     	  //每写入一位数据之前先把总线拉低1usi++;DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始i=7;while(i--); //延时68us,持续时间最少60usDSPORT = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat >>= 1;}
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadByte
* 函数功能		   : 读取一个字节
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/uchar Ds18b20ReadByte()
{uchar byte, bi;uint i, j;	for(j=8; j>0; j--){DSPORT = 0;//先将总线拉低1usi++;DSPORT = 1;//然后释放总线i++;i++;//延时6us等待数据稳定bi = DSPORT;	 //读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/byte = (byte >> 1) | (bi << 7);						  i = 4;		//读取完之后等待48us再接着读取下一个数while(i--);}				return byte;
}
/*******************************************************************************
* 函 数 名         : Ds18b20ChangTemp
* 函数功能		   : 让18b20开始转换温度
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void  Ds18b20ChangTemp()
{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 Ds18b20WriteByte(0x44);	    //温度转换命令//Delay1ms(100);	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadTempCom
* 函数功能		   : 发送读取温度命令
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void  Ds18b20ReadTempCom()
{	Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令Ds18b20WriteByte(0xbe);	 //发送读取温度命令
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadTemp
* 函数功能		   : 读取温度
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/int Ds18b20ReadTemp()
{static int LastTemp=0;static unsigned char TempTime = 0;int temp = 0;uchar tmh, tml;Ds18b20ChangTemp();Ds18b20ReadTempCom();tml = Ds18b20ReadByte();tmh = Ds18b20ReadByte();temp = tmh;temp <<= 8;temp |= tml;if( LastTemp == temp ){TempTime++;if( TempTime >= 20 ){TempTime = 0;return temp;}}else{LastTemp = temp;TempTime = 0;}return temp;
}

注:
程序运行过程中,仿真提示RAM COMMAND UNSUPPORTED,这是由于读数据太快,以至于DS18B20还没准备好。


http://www.ppmy.cn/news/150163.html

相关文章

P1308

这个代码的关键思路是&#xff0c;在字符串的最后面加上一个空格&#xff0c;使所有的单词都满足后面有一个空格的性质&#xff0c;通过后面的空格来定位一个单词的结束。 #include <stdio.h> #include <string.h> int main() {char a[11], b[1000001];gets(a);ge…

208 - Junit

Junit 单元测试 1、引入 【1】软件测试的目的 软件测试的目的是在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。 【2】测试分类 &#xff08;1&#xff09;黑盒测试 软件的黑盒测试意味着测试要在软件的接口处进行。…

公司百兆局域网千兆升级方案之硬件设备升级(一)

百兆局域网千兆升级方案 随着主机的升级公司已有90%以上的主机带有千兆网卡,以及网络的应用增多,对交换机之间、以及交换机到服务器之间带宽的要求越来越高,原有带宽已经成为制约网络传输的瓶颈。将主干网络提升至千兆以太网,是目前公司网络改造实现速度提升的总要保证。 分…

window用户程序数据文件夹AppData

window用户程序数据文件夹AppData 在 Windows 操作系统中&#xff0c;C 盘的用户的 AppData 文件夹包含了当前用户与计算机上的许多应用程序相关的数据。具体来说&#xff0c;AppData 文件夹包含三个子文件夹&#xff0c;分别为&#xff1a; Local(本地)&#xff1a;这个文件夹…

spoj1812

此题困扰了我一天。。。今天才得以解决啊。。问了两位大神才得解。 一直没搞懂为什么要对长度进行统计然后就是dag有序了 首先sam就是一个dag的图&#xff0c;为什么是dag呢&#xff0c;由于自动机从根出来的每一路径都是一条子串&#xff0c;那么必定无环&#xff0c;则一定…

22.1.18

一.AcWing算法学习 1.区间和并 ①pair<int,int>的排序优先排序左边&#xff0c;再排序右边&#xff1b; ②for(auto a:b)中b为一个容器&#xff0c;效果是利用a遍历并获得b容器中的每一个值&#xff0c;但是a无法影响到b容器中的元素。 for(auto &a:b)中加了引用…

CH1801

括号画家 Candela是一名漫画家&#xff0c;她有一个奇特的爱好&#xff0c;就是在纸上画括号。这一天&#xff0c;刚刚起床的Candela画了一排括号序列&#xff0c;其中包含小括号()、中括号[]和大括号{}&#xff0c;总长度为N。这排随意绘制的括号序列显得杂乱无章&#xff0c;…

T1008

分支结构&#xff08;switch语句 &#xff09;&#xff1a;四兄弟 要求&#xff1a; 1.输入运算法对a&#xff0c;b进行运算 方案 1.对于Q1: 为了避免过多的if else语句造成的代码冗余 使用switch语句 switch语句算法模版&#xff1a; 用处&#xff1a;充当算法的分支结…