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

相关文章

用Microsoft.Extensions.Hosting 管理WPF项目.

首先引入必要的包: <ItemGroup><PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" /><PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /><PackageReference Include="Serilog

eclipse运行springboot项目,找不到主类

解决办法尝试了很多种,下载sts压缩包行不通。最后解决办法如图: help--->Eclipse Marketplace--->Popular--->找到Spring Tools 3---->Installed。

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT

vscode-创建vue3项目-修改暗黑主题-常见错误-element插件标签-用法涉及问题

文章目录 1.vscode创建运行编译vue3项目2.添加项目资源3.添加element-plus元素4.修改为暗黑主题4.1.在main.js主文件中引入暗黑样式4.2.添加自定义样式文件4.3.html页面html标签添加样式 5.常见错误5.1.未使用变量5.2.关闭typescript检查5.3.调试器支持5.4.允许未到达代码和未定义代码 6.element常用标签6.1.下拉列表

局域网内vue2 配置本地IP地址访问项目

在日常开发中同事可能需要访问你的前端项目,可以通过配置实现通过ip访问 一.首先找到config文件夹目录下的 index.js文件             将此处的host的值修改为0.0.0.0(即 host: 0.0.0.0) // Various Dev Server settings//host: 'localhost' //将localhost进行替换成 0.0.0.0host:

把Tiled中做出的地图弄到项目中~~就是懒,为了以后直接复制写过来

1.现在.h中声明private: cocos2d::CCSprite* ninja; cocos2d::CCTMXTiledMap*  tileMap; 然后.cpp中加入tileMap = CCTMXTiledMap::create("MyTileMap.tmx"); CCTMXLayer* backLayer = tileMap->layerNamed("Tile L

CocoStudio中的UI弄到项目中

1、   与alpah版相比,beta版中更改了创建的脚本,可以自定义项目的目录,接下来我们看看。先上图: 2、项目创建     找到 cocos2dx根目录/tools/project-creator/create_project.py文件,双击运行即可。如果未安装python环境,则需要下载安装。脚本运行起来,会显示一个图形界面,用以设置相应的项目

计算机Java项目|基于SpringBoot的网上摄影工作室

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路  关注作者有好处 文末获取源码  项目编号:L-BS-QBBSSPRINGBOOT