51单片机 - DS18B20实验1-读取温度

news2024/11/19 9:26:23

上来一张图,明确思路,程序整体裤架如下,通过单总线,单独封装一个.c文件用于单总线的操作,其实,我们可以把点c文件看成一个类操作,其属性就是我们面向对象的函数,也叫方法,操作起来方便,通过DS18B20调用封装好的单总线,实现温度的读取(用LCD1602显示出读取的温度  ),总后通过主函数调用这些模块,这就是模块化的编程,两个模块,主函数直接调用,也方便移植。

作者:Whappy

时间:2024.9.14

DS18B20实验-温度测试

第一步:模块化单总线 :OneWire.c

一共五个函数

看时序写代码

unsigned char OneWire_Init(void)
{
	unsigned char AckBit;
	
	OneWire_DQ = 1; //保证拉低之前是高电平
	OneWire_DQ = 0; //拉低
	Delay1ms();//延时1ms ,至少480us
	OneWire_DQ = 1;  //释放
	Delay70us();
	AckBit = OneWire_DQ; //应答位:存在的从机会拉低总线60~240us以响应主机
	Delay1ms();//延时1ms ,至少480us
	
	
	return AckBit;
	
}

void OneWire_SendBit(unsigned char Bit)
{
	OneWire_DQ = 0; //拉低
	Delay10us();
	OneWire_DQ = Bit; //10us 将数据放到总线上
	Delay50us();
	OneWire_DQ = 1;  //释放
}

//接收一位:即主机51读取一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),
//读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us
unsigned char OneWire_ReadBit(void)
{
	unsigned char Bit;
	OneWire_DQ = 0; //拉低
	Delay5us();
	OneWire_DQ = 1;  //释放
	Delay5us();
	Bit = OneWire_DQ;  //数据放到总线上,主机读
	Delay50us();
	
	return Bit;
		
}

//发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0; i<8; i++)
	{
		OneWire_SendBit(Byte & (0X01 << i));
	}
}

//接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)

unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i, Byte = 0X00;
	
	for(i=0; i<8; i++)
	{
		if(OneWire_ReadBit())
		{
			Byte |= (0x01);
		}
	}
	
	
	return Byte;
}

第二步:模块化 DS18B20.c:DS18B20.c  :两个函数


//温度转换函数 :初始化→跳过ROM →开始温度变换

void DS18B20_ConvertTemperature(void)
{
	OneWire_Init();
	OneWire_SendByte(SKIP_ROM); //跳过ROM,写入一个字节数据,说我要读取温度
	OneWire_SendByte(CONVERT_T); //发送一个字节,让DS18B20开始温度转化
	
}


//温度读取:初始化→跳过ROM →读暂存器→连续的读操作
float DS18B20_ReadTemperature(void)
{
	unsigned char TLSB, TMSB;
	int Temp;
	float T;
	OneWire_Init();//初始化
	OneWire_SendByte(READ_SCRATCHPAD); //跳过ROM,写入一个字节数据,说我要读取温度
	TLSB = OneWire_ReceiveByte();
	TMSB = OneWire_ReceiveByte();
	
	Temp = (TMSB<<8)| TLSB;
	
	T = Temp/16.0;
	return T;


}

第三步:主函数调用 :main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"


float T;

void main(void)
{
	DS18B20_ConvertTemperature();	//上电先转换一次温度,防止第一次读数据错误
	Delay_Any(1000);			//等待转换完成
	//初始化
	LCD_Init();

	
	
	LCD_ShowString(1,1,"Temperature:");
	
	
	while(1)
	{	
		DS18B20_ConvertTemperature();
		T = DS18B20_ReadTemperature();
		if(T < 0)
		{
			LCD_ShowChar(2,1,'-');
			T = -T;
		}
		else
			LCD_ShowChar(2,1,'+');
		
		LCD_ShowNum(2,2,T,3);
		LCD_ShowChar(2,5,'.');
		LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
	}
}






//#include <REGX52.H>
//#include "LCD1602.h"
//#include "DS18B20.h"
//#include "Delay.h"

//float T;

//void main()
//{
//	DS18B20_ConvertT();		//上电先转换一次温度,防止第一次读数据错误
//	Delay(1000);			//等待转换完成
//	LCD_Init();
//	LCD_ShowString(1,1,"Temperature:");
//	while(1)
//	{
//		DS18B20_ConvertT();	//转换温度
//		T=DS18B20_ReadT();	//读取温度
//		if(T<0)				//如果温度小于0
//		{
//			LCD_ShowChar(2,1,'-');	//显示负号
//			T=-T;			//将温度变为正数
//		}
//		else				//如果温度大于等于0
//		{
//			LCD_ShowChar(2,1,'+');	//显示正号
//		}
//		LCD_ShowNum(2,2,T,3);		//显示温度整数部分
//		LCD_ShowChar(2,5,'.');		//显示小数点
//		LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);//显示温度小数部分
//	}
//}






总代码:

OneWire.c

#include <REGX52.H>
#include "Delay.h"


sbit OneWire_DQ = P3^7; //单总线的管脚定义

//编写5个函数 初始化、写一位、读一位、写一个字节、读一个字节



//初始化:主机将总线拉低至少480us,然后释放总线,等待15~60us后,存在的从机会拉低总线60~240us以响应主机,之后从机将释放总线

unsigned char OneWire_Init(void)
{
	unsigned char AckBit;
	
	OneWire_DQ = 1; //保证拉低之前是高电平
	OneWire_DQ = 0; //拉低
	Delay1ms();//延时1ms ,至少480us
	OneWire_DQ = 1;  //释放
	Delay70us();
	AckBit = OneWire_DQ; //应答位:存在的从机会拉低总线60~240us以响应主机
	Delay1ms();//延时1ms ,至少480us
	
	
	return AckBit;
	
}


//写一位数据,即主机51发送一位:主机将总线拉低60~120us,然后释放总线,表示发送0;主机将总线拉低1~15us,
//然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us

void OneWire_SendBit(unsigned char Bit)
{
	OneWire_DQ = 0; //拉低
	Delay10us();
	OneWire_DQ = Bit; //10us 将数据放到总线上,主机写,
	Delay50us();
	OneWire_DQ = 1;  //释放
}


//接收一位:即主机51读取一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),
//读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us
unsigned char OneWire_ReadBit(void)
{
	unsigned char Bit;
	OneWire_DQ = 0; //拉低
	Delay5us();
	OneWire_DQ = 1;  //释放
	Delay5us();
	Bit = OneWire_DQ;  //数据放到总线上,主机读
	Delay50us();
	
	return Bit;
		
}

//发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0; i<8; i++)
	{
		OneWire_SendBit(Byte & (0X01 << i));
	}
}

//接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)

unsigned char OneWire_ReceiveByte(void)
{
	unsigned char i, Byte = 0X00;
	
	for(i=0; i<8; i++)
	{
		if(OneWire_ReadBit())
		{
			Byte |= (0x01);
		}
	}
	
	
	return Byte;
}

















DS18B20.c

#include <REGX52.H>
#include "OneWire.h"

//DS18B20 程序使用的寄存器进行红宏定义
#define SKIP_ROM			0XCC	//ROM指令 跳过ROM ,相当于直接访问DS18B20
#define CONVERT_T			0X44   //功能指令 温度转换
#define READ_SCRATCHPAD		0XBE  //功能指令  暂存器


//温度转换函数 :初始化→跳过ROM →开始温度变换

void DS18B20_ConvertTemperature(void)
{
	OneWire_Init();
	OneWire_SendByte(SKIP_ROM); //跳过ROM,写入一个字节数据,说我要读取温度
	OneWire_SendByte(CONVERT_T); //发送一个字节,让DS18B20开始温度转化
	
}


//温度读取:初始化→跳过ROM →读暂存器→连续的读操作
float DS18B20_ReadTemperature(void)
{
	unsigned char TLSB, TMSB;
	int Temp;
	float T;
	OneWire_Init();//初始化
	OneWire_SendByte(SKIP_ROM);
	OneWire_SendByte(READ_SCRATCHPAD); //跳过ROM,写入一个字节数据,说我要读取温度
	TLSB = OneWire_ReceiveByte();
	TMSB = OneWire_ReceiveByte();
	
	Temp = (TMSB<<8) | TLSB;
	
	T = Temp/16.0;
	return T;


}

Delay.c

#include <REGX52.H>
#include "intrins.h"



void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}





void Delay70us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 29;
	while (--i);
}


void Delay_Any(unsigned int xms)		//@11.0592MHz
{
	unsigned char i, j;
	
	while(xms--)
	{
		_nop_();
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}


void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}


void Delay50us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 20;
	while (--i);
}


void Delay5us()		//@11.0592MHz
{
}








其余代码可参考(主页51单片机内容)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux echo,printf 命令

参考资料 【Linux】ハイフンをいっぱい出したかっただけなのに【printfコマンド】 目录 一. echo命令1.1 -n 选项1.2 -e 选项1.3 配合扩展实现批量换行输出1.3.1 xargs -n 11.3.2 tr \n1.3.3 xargs printf "%s\n"1.4 ANSI转义序列1.5 彩色文本输出 二. printf 命令…

Centos7安装gitlab-ce(rpm安装方式)

本章教程&#xff0c;主要介绍如何在Centos7安装gitlab-ce。 一、安装基础环境 安装gitlab-ce之前&#xff0c;我们需要安装一下jdk版本。 sudo yum install java-11-openjdk-devel二、下载安装包 这里我们下载的是rpm包。更多gitlab-ce版本可以在这里查看&#xff1a;https://…

果蔬识别系统架构+流程图

相关文章和代码 果蔬识别系统 果蔬识别系统优化&#xff08;1~5&#xff09; 架构图 流程图 初始化 识别流程 学习流程 同步流程 与初始化类似&#xff0c;只是同步只同步一个storeCode数据 删除数据流程 导入数据

无人机几种常见的避障系统!!!

1. 视觉避障系统 工作原理&#xff1a; 视觉避障系统通过安装在无人机上的摄像头捕捉周围环境的图像&#xff0c;利用计算机视觉技术对图像进行处理和分析&#xff0c;提取出障碍物的信息。 通过对障碍物的识别和分类&#xff0c;无人机可以判断出障碍物的性质和危险程度&am…

AI 时代程序员的挑战与机遇

你好&#xff0c;我是看山。 在当今数字化快速发展的时代&#xff0c;AIGC&#xff08;如 ChatGPT、Midjourney、Claude 等&#xff09;大语言模型如雨后春笋般接二连三的涌现&#xff0c;与此同时&#xff0c;AI 辅助编程工具也日益普及。 这一系列的变化使得程序员的工作方…

pdf文件怎么转换成ppt?介绍几种pdf转ppt的方法

pdf文件怎么转换成ppt&#xff1f;将pdf文件转换成ppt格式是一种常见且实用的需求&#xff0c;特别是在制作演示文稿和准备报告时。pdf格式因其文件内容的固定排版和高兼容性而广泛应用于文档的保存和分享。然而&#xff0c;在某些情况下&#xff0c;将pdf文件转换为ppt格式可以…

拒绝千篇一律,AI帮你定制独一无二的个人写真

每个女人都渴望展现最美的自己&#xff0c;你是否厌倦了拍出千篇一律的照片&#xff1f;今天&#xff0c;我要告诉你一个秘密&#xff0c;用简单三步&#xff0c;即可打造属于你的独一无二个人写真&#xff01;文生图、蒙版换脸、图生图&#xff0c;三步化身超级模特&#xff0…

Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计

文章目录 Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计0. 前言1. XXE代码审计【有1处】1.1. 搜索JRXmlLoader1.1.1. JRAntApiWriteTask1.1.2. JRAntUpdateTask1.1.3. TableReportContextXmlRule1.1.4. JasperCompileManager【存在漏洞】 1.2. 搜索XMLReader1.2…

C++初阶:类和对象(上)

&#x1f680;前言&#xff1a; 本文主要讲述了&#xff0c;面向过程和面向对象&#xff0c;并引入类&#xff0c;然后就以类为基础并讲解。 目录 &#x1f349;1.面向过程和面向对象的初步认识&#xff1a; &#x1f952;2.类的引入&#xff1a; &#x1f351;3.类的定义…

dd 命令:复制和转换文件

一、dd 命令简介 ​dd​ 命令是一个在 Unix 和类 Unix 系统中用于复制文件和转换文件的命令行工具。它的功能非常强大&#xff0c;可以用于各种目的&#xff0c;例如创建镜像文件、备份和恢复数据、复制数据等。 ​dd​ 是一个用于读取、转换和写入数据的工具&#xff0c;通常…

Metasploit 渗透测试之Metasploit快速入门

简介 Metasploit 是目前世界上领先的渗透测试工具&#xff0c;也是信息安全与渗透测试领域最大的开源项目之一。它彻底改变了我们执行安全测试的方式。Metasploit之所以流行&#xff0c;是因为它可以执行广泛的安全测试任务&#xff0c;从而简化渗透测试的工作。Metasploit 适…

海外云手机怎么实现TikTok多账号防关联?

TikTok多账号运营&#xff0c;作为众多用户选择的引流策略&#xff0c;旨在通过多账号的协同作用&#xff0c;更快速、高效地推动主账号的流量增长。然而&#xff0c;这一策略面临着一个关键难题——TikTok账号防关联。本文将简要介绍海外云手机如何解决这一问题。 在TikTok多账…

解题 - 模拟实现 atoi

文章目录 前言 一、atoi 函数是什么&#xff1f; 二、模拟实现 atoi 总结 前言 路漫漫其修远兮&#xff0c;吾将上下而求索&#xff1b; 一、atoi 函数是什么&#xff1f; atoiint atoi(const char* str);所要引用的头文件: <stdlib.h>原理&#xff1a;将字符串转换…

计算几何学习

凸包 凸组合&#xff0c; λ < λ 1 , λ 1 , . . . , λ n > T \lambda <\lambda_1,\lambda_1,...,\lambda_n>^T λ<λ1​,λ1​,...,λn​>T 其中 λ 1 λ 2 . . . λ n 1 \lambda_1\lambda_2...\lambda_n 1 λ1​λ2​...λn​1,且 λ i ≥ 0 \l…

深度解析 MintRich 独特的价格曲线机制玩法

随着 Meme 币赛道的迅速崛起&#xff0c;NFT 市场也迎来了新的变革。作为一个创新的 NFT 发行平台&#xff0c;Mint.Rich 正掀起一场全民参与的 NFT 热潮。其简易的操作界面和独特的价格曲线设计&#xff0c;让任何人都能以极低的门槛发行和交易自己的 NFT&#xff0c;从而参与…

多线程实现数据处理与打印分离

注意&#xff0c;结构体传入数据 一开始int* 不能变成void 传入int ** 也会失效&#xff0c; 只能一开始在message 结构体里有 int* 类型才能运行 这是通过打印表格得到的 使用raylib 开发 #include <raylib.h> #include <stdio.h> #include <math.h> #…

【零成本】七日杀 服务器搭建 异地联机 无需公网IP、服务器

主要内容 什么是七日杀 搭建前需要准备什么 详细步骤 1.Steam中下载七日杀服务器工具 2.修改七日杀服务配置文件 3.启动七日杀服务器应用 4.运行 MoleSDN 进行异地联机 5.小伙伴打开游戏加入 鼠鼠的服务器 什么是七日杀 《七日杀》是一款沙盒生存恐怖游戏&#xff0c;…

Linux shell编程学习笔记80:gzip命令——让文件瘦身

0 引言 在 Linux shell编程学习笔记76&#xff1a;tar命令——快照 & 备份&#xff08;上&#xff09;-CSDN博客 Linux shell编程学习笔记77&#xff1a;tar命令——快照 & 备份&#xff08;下&#xff09;_linux 系统快照-CSDN博客 Linux shell编程学习笔记78&am…

ai绘画文生图怎么制作?2024教你快速进行ai绘画

ai绘画文生图怎么制作&#xff1f;2024教你快速进行ai绘画 AI绘画技术的迅速发展&#xff0c;使得用户只需输入文本描述&#xff0c;就能生成符合要求的图像&#xff0c;这种“文生图”&#xff08;Text-to-Image&#xff09;功能使得绘画和创作变得简单、高效。以下是5款帮助…

Git提交有乱码

服务器提交记录如图 可知application.properties中文注释拉黄线 &#xff0c;提示Unsupported characters for the charset ISO-8859-1 打开settings - Editor - File Encodings 因为我们项目的其他文件都是UTF-8&#xff0c;所以&#xff0c;我们将默认值都改成UTF-8 然后…