AT89C52项目:DS18B20温度报警器

2024-03-26 04:36

本文主要是介绍AT89C52项目:DS18B20温度报警器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

源码在这里,需要自取:

13.2 DS18B20温度报警器 · 钦某/51project - 码云 - 开源中国 (gitee.com)

先看演示视频:

51温度报警演示视频

我们先来了解DS18B20

我们看到总共有三个接口,gnd是接地,vcc接5v。在DS18B20手册上Vcc标的是Vdd。

中间的接口是传输数据的线。单总线,异步,半双工,单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电(由通信线提供电压,主机配一个强上拉电路)时还可以省去VDD线路,此时,供电加通信只需要两根线。(51单片机不采取这种做法)

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

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

接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1,整个时间片应大于60us

 之后就将上面两个步骤走8次,就可以封装出两个函数:发送一个字节和接受一个字节。

#include <REGX52.H>//引脚定义
sbit OneWire_DQ=P3^7;/*** @brief  单总线初始化* @param  无* @retval 从机响应位,0为响应,1为未响应*/
unsigned char OneWire_Init(void)
{unsigned char i;unsigned char AckBit;EA=0;OneWire_DQ=1;OneWire_DQ=0;i = 247;while (--i);		//Delay 500usOneWire_DQ=1;i = 32;while (--i);			//Delay 70usAckBit=OneWire_DQ;i = 247;while (--i);		//Delay 500usEA=1;return AckBit;
}/*** @brief  单总线发送一位* @param  Bit 要发送的位* @retval 无*/
void OneWire_SendBit(unsigned char Bit)
{unsigned char i;EA=0;OneWire_DQ=0;i = 4;while (--i);			//Delay 10usOneWire_DQ=Bit;i = 24;while (--i);			//Delay 50usOneWire_DQ=1;EA=1;
}/*** @brief  单总线接收一位* @param  无* @retval 读取的位*/
unsigned char OneWire_ReceiveBit(void)
{unsigned char i;unsigned char Bit;EA=0;OneWire_DQ=0;i = 2;while (--i);			//Delay 5usOneWire_DQ=1;i = 2;while (--i);			//Delay 5usBit=OneWire_DQ;i = 24;while (--i);			//Delay 50usEA=1;return Bit;
}/*** @brief  单总线发送一个字节* @param  Byte 要发送的字节* @retval 无*/
void OneWire_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){OneWire_SendBit(Byte&(0x01<<i));}
}/*** @brief  单总线接收一个字节* @param  无* @retval 接收的一个字节*/
unsigned char OneWire_ReceiveByte(void)
{unsigned char i;unsigned char Byte=0x00;for(i=0;i<8;i++){if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}}return Byte;
}

之后就是在main函数里面调用这俩,然后将其显示在LCD1602上。

之后的任务就是设定温度报警阈值。

定义两个变量THigh,TLow,分别初始化为0°和30°。然后调用独立按键函数,按下Key1,THigh++;按下Key2,THigh--;Key3,4同理控制TLow。

#include <REGX52.H>
#include "Key.h"
#include "Delay.h"
/*** @brief	获取独立按键键码* @param	无* @retval 按下按键的键码,范围 0~4,无按键按下,返回0*/
unsigned char Key()
{unsigned char KeyNumber = 0;if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}return KeyNumber;
}

这里将逻辑写好后会发现一个问题:

在你将按键按下后,它就不会再读取数据了。这是因为程序卡在了while循环,在你没松开之前是不会出来的。我们需要重新封装Key.c这时我们就需要定时器每隔20ms调用一次它。这样既不会干扰主程序的执行,可以实现按键调节温度阈值的功能。

#include <REGX52.H>
#include "Delay.h"unsigned char Key_KeyNumber;/*** @brief  获取按键键码* @param  无* @retval 按下按键的键码,范围:0,1~4,0表示无按键按下*/
unsigned char Key(void)
{unsigned char Temp=0;Temp=Key_KeyNumber;Key_KeyNumber=0;return Temp;
}/*** @brief  获取当前按键的状态,无消抖及松手检测* @param  无* @retval 按下按键的键码,范围:0,1~4,0表示无按键按下*/
unsigned char Key_GetState()
{unsigned char KeyNumber=0;if(P3_1==0){KeyNumber=1;}if(P3_0==0){KeyNumber=2;}if(P3_2==0){KeyNumber=3;}if(P3_3==0){KeyNumber=4;}return KeyNumber;
}/*** @brief  按键驱动函数,在中断中调用* @param  无* @retval 无*/
void Key_Loop(void)
{static unsigned char NowState,LastState;LastState=NowState;				//按键状态更新NowState=Key_GetState();		//获取当前按键状态//如果上个时间点按键按下,这个时间点未按下,则是松手瞬间,以此避免消抖和松手检测if(LastState==1 && NowState==0){Key_KeyNumber=1;}if(LastState==2 && NowState==0){Key_KeyNumber=2;}if(LastState==3 && NowState==0){Key_KeyNumber=3;}if(LastState==4 && NowState==0){Key_KeyNumber=4;}
}

 然后加上蜂鸣器的报警功能,这个很简单,当T<TLow调用Buzzer,当T>THigh调用Buzzer。

到这里我们的main是这样的:

#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Key.h"
#include "Timer0.h"
#include "Buzzer.h"float T,TShow;
char TLow,THigh;
unsigned char KeyNum;void main()
{DS18B20_ConvertT();		//上电先转换一次温度,防止第一次读数据错误Delay(1000);			//等待转换完成THigh=AT24C02_ReadByte(0);	//读取温度阈值数据TLow=AT24C02_ReadByte(1);if(THigh>125 || TLow<-55 || THigh<=TLow){THigh=20;			//如果阈值非法,则设为默认值TLow=15;}LCD_Init();LCD_ShowString(1,1,"T:");LCD_ShowString(2,1,"TH:");LCD_ShowString(2,9,"TL:");LCD_ShowSignedNum(2,4,THigh,3);LCD_ShowSignedNum(2,12,TLow,3);Timer0_Init();while(1){KeyNum=Key();/*温度读取及显示*/DS18B20_ConvertT();	//转换温度T=DS18B20_ReadT();	//读取温度if(T<0)				//如果温度小于0{LCD_ShowChar(1,3,'-');	//显示负号TShow=-T;		//将温度变为正数}else				//如果温度大于等于0{LCD_ShowChar(1,3,'+');	//显示正号TShow=T;}LCD_ShowNum(1,4,TShow,3);		//显示温度整数部分LCD_ShowChar(1,7,'.');		//显示小数点LCD_ShowNum(1,8,(unsigned long)(TShow*100)%100,2);//显示温度小数部分/*阈值判断及显示*/if(KeyNum){if(KeyNum==1)	//K1按键,THigh自增{THigh++;if(THigh>125){THigh=125;}}if(KeyNum==2)	//K2按键,THigh自减{THigh--;if(THigh<=TLow){THigh++;}}if(KeyNum==3)	//K3按键,TLow自增{TLow++;if(TLow>=THigh){TLow--;}}if(KeyNum==4)	//K4按键,TLow自减{TLow--;if(TLow<-55){TLow=-55;}}LCD_ShowSignedNum(2,4,THigh,3);	//显示阈值数据LCD_ShowSignedNum(2,12,TLow,3);AT24C02_WriteByte(0,THigh);		//写入到At24C02中保存Delay(5);AT24C02_WriteByte(1,TLow);Delay(5);}if(T>THigh)			//越界判断{LCD_ShowString(1,13,"OV:H");Buzzer_Time(50);}else if(T<TLow){LCD_ShowString(1,13,"OV:L");Buzzer_Time(50);}else{LCD_ShowString(1,13,"    ");}}
}void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值T0Count++;if(T0Count>=20){T0Count=0;Key_Loop();	//每20ms调用一次按键驱动函数}
}

这样我们就实现了开头视频的全部功能了。

本期博客到这里就结束了,如果有什么错误,欢迎指出,如果对你有帮助,请点个赞,谢谢!

这篇关于AT89C52项目:DS18B20温度报警器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/847294

相关文章

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

使用vscode搭建pywebview集成vue项目实践

《使用vscode搭建pywebview集成vue项目实践》:本文主要介绍使用vscode搭建pywebview集成vue项目实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录环境准备项目源码下载项目说明调试与生成可执行文件核心代码说明总结本节我们使用pythonpywebv