DHT11传感器测量温湿度,按键调节上下限阈值,蜂鸣器报警。

您所在的位置:网站首页 si5002传感器设置 DHT11传感器测量温湿度,按键调节上下限阈值,蜂鸣器报警。

DHT11传感器测量温湿度,按键调节上下限阈值,蜂鸣器报警。

2024-01-25 15:44| 来源: 网络整理| 查看: 265

DHT11传感器测量温湿度,按键调节上下限阈值,蜂鸣器报警。 前言课设要求代码呈现感悟

前言

这个课设可以说写了四天,因为我接触单片机的时间也不是很长,基础也不是太扎实。写的代码bug真的是太多,绝大多数的时间都画在了找bug上了。但是幸运的是我有一个能够为我传道,授业,解惑的好老师,没有老师的帮忙,这个代码估计到现在也写不好。在实习的过程中也看到了很多厉害的同学,写代码思路很清晰,对于模块的理解也很透彻,写的也很快。我也是比较嫉妒的,希望有一天我的单片机也能学的很透彻。以后我一定要加强对于单片机方面的学习,我还想靠着单片机在一些比赛上拿一些奖项呢。

课设要求

在这里插入图片描述

代码呈现

main函数

#include "1602.h" #include "DHT11.h" #include "juzhen.h" void Selay(unsigned char k); unsigned char TTop=30; unsigned char TLow=10; unsigned char RHTop=80; unsigned char RHLow=30; extern T_Data_H; volatile unsigned char KeyValue=0; unsigned char Temp=0; extern unsigned char DHT11_Data[17]; unsigned char *DHT11_Dis; unsigned char SegData[4]={0}; unsigned char SegSata[4]={0}; void Init(); unsigned char k=0; sbit led1=P2^4; sbit led2=P2^5; sbit led3=P2^6; sbit led4=P2^7; sbit buzzer=P1^0; void main() { unsigned char T; unsigned char RH; Init(); LCD_Init(); //液晶初始化 LCD_Cls(); //液晶清屏 LCD_DisplayString(0,0,"S:",2); LCD_DisplayString(9,0,"X:",2); LCD_DisplayChar(2,0,TTop/10+0X30); LCD_DisplayChar(3,0,TTop%10+0X30); LCD_DisplayChar(11,0,TLow/10+0X30); LCD_DisplayChar(12,0,TLow%10+0X30); LCD_DisplayChar(5,0,RHTop/10+0X30); LCD_DisplayChar(6,0,RHTop%10+0X30); LCD_DisplayChar(14,0,RHLow/10+0X30); LCD_DisplayChar(15,0,RHLow%10+0X30); LCD_DisplayString(4,0,":",1); LCD_DisplayString(13,0,":",1); DHT11_Dis = Read_DHT11(); //获取温湿度 LCD_DisplayString(0,1,DHT11_Dis,16); //显示温湿度 while(1) { KeyValue=keyscan(); if(KeyValue) { Temp = KeyValue; KeyValue=0; switch(Temp) { case 1:TTop++;if(TTop>99)TTop=10; LCD_DisplayChar(2,0,TTop/10+0X30); LCD_DisplayChar(3,0,TTop%10+0X30); break; case 2:TTop--;if(TTop99)TLow=10; LCD_DisplayChar(11,0,TLow/10+0X30); LCD_DisplayChar(12,0,TLow%10+0X30); break; case 4:TLow--;if(TLow99)RHTop=30; LCD_DisplayChar(5,0,RHTop/10+0X30); LCD_DisplayChar(6,0,RHTop%10+0X30); break; case 6:RHTop--;if(RHTop50)RHLow=49; LCD_DisplayChar(14,0,RHLow/10+0X30); LCD_DisplayChar(15,0,RHLow%10+0X30); break; case 8:RHLow--;if(RHLow=40) { k = 0; DHT11_Dis = Read_DHT11(); //获取温湿度 LCD_DisplayString(0,1,DHT11_Dis,16); //显示温湿度 } T=(DHT11_Dis[11]-0x30)*10+DHT11_Dis[12]-0x30; RH=(DHT11_Dis[3]-0x30)*10+DHT11_Dis[4]-0x30; if(TTopT || RHTopRH) { buzzer=0; } if(TTopled2=1;buzzer=1;} if(RHTopled4=1;buzzer=1;} } } //定时器初始化 void Init() { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; ET0=1; TR0=1; EA=1; } void Timer0() interrupt 1 { //led1=0; TH0=(65536-50000)/256; TL0=(65536-50000)%256; k++;//led1=0; }

DHT11.C

//----以下变量均为全局变量-------- //----温度高8位== T_Data_H------ //----温度低8位== T_Data_L------ //----湿度高8位== RH_Data_H----- //----湿度低8位== RH_Data_L----- //----校验 8位 == CRC_Data----- #include "DHT11.h" //----------------IO口定义区--------------------// sbit DHT11_IO = P1^1 ; //----------------定义区--------------------// unsigned char CRC_Error = 0,flag = 0; void Delay(unsigned int j) { unsigned char i; for(;j>0;j--) { for(i=0;i unsigned char i = 0; unsigned char ReceiveData = 0; bit temp; for(i=0;i unsigned char T_Data_H,T_Data_L,RH_Data_H,RH_Data_L,CRC_Data; static unsigned char DHT11_Data[17] = {0}; DHT11_IO=0; Delay(20); //主机拉低 18ms,由于上电的不稳定性,延长时间适当拉长。 DHT11_IO=1; //总线由上拉电阻拉高 主机延时40us Delay_10us(); Delay_10us(); Delay_10us(); Delay_10us(); DHT11_IO=1; //主机设为输入 判断从机响应信号 if(!DHT11_IO) //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 { flag=2; while((!DHT11_IO)&&flag++); //判断从机是否发出 80us 的低电平响应信号是否结束 flag=2; while((DHT11_IO)&&flag++); //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 RH_Data_H = Receive_Byte(); //数据接收 RH_Data_L = Receive_Byte(); T_Data_H = Receive_Byte(); T_Data_L = Receive_Byte(); CRC_Data = Receive_Byte(); DHT11_IO = 1; if( CRC_Data != RH_Data_H + RH_Data_L + T_Data_H + T_Data_L) { RH_Data_H = 0; RH_Data_L = 0; T_Data_H = 0; T_Data_L = 0; } else { DHT11_Data[0] = 'R'; DHT11_Data[1] = 'H'; DHT11_Data[2] = ':'; DHT11_Data[3] = RH_Data_H / 10 + 0x30; DHT11_Data[4] = RH_Data_H % 10 + 0x30; DHT11_Data[5] = '.'; DHT11_Data[6] = RH_Data_L / 10 + 0x30; DHT11_Data[7] = '%'; DHT11_Data[8] = ' '; DHT11_Data[9] = 'T'; DHT11_Data[10] = ':'; DHT11_Data[11] = T_Data_H / 10 + 0x30; DHT11_Data[12] = T_Data_H % 10 + 0x30; DHT11_Data[13] = '.'; DHT11_Data[14] = T_Data_L / 10 + 0x30; DHT11_Data[15] = 0xdf; //1602液晶度的字符码 } return DHT11_Data; } return 0; }

DHT11.h

#ifndef __DHT11_H_ #define __DHT11_H_ #include #include void Delay(unsigned int j); void Delay_10us(void); unsigned char Receive_Byte(void); unsigned char * Read_DHT11(void); #endif

LCD1602.C

/******** (C) Copyright 2012 All rights reserved ******** * 文件名 : 160.2.c * 版本 : V1.0 * 完成日期 : 2011-05-17 * 功能描述 : 1602液晶驱动程序 ********************************************************************/ #include "1602.H" sbit RS = P3^5; sbit RW = P3^6; sbit E = P3^7; #define RS_High() RS = 1;_nop_();_nop_() //数据 #define RS_Low() RS = 0;_nop_();_nop_() //指令 #define RW_High() RW = 1;_nop_();_nop_() //读操作 #define RW_Low() RW = 0;_nop_();_nop_() //写操作 #define E_High() E = 1;_nop_();_nop_() //使能 #define E_Low() E = 0;_nop_();_nop_() //禁止 #define DataPort P0 #define DataInput() DataPort = 0xff #define FirstLineAdd 0x80 #define SecondLineAdd 0xC0 #define DisplayData 1 #define Command 0 #define DisplayMode 0x38 #define DisplayOFF 0x08 #define LcdCls 0x01 #define DisplayCursor 0x06 #define DisplayOn 0x0C /************************************************** *函数名:Delay_Ms *功能 :毫秒延时函数 *参数 :DelayTime - 延时时间 DelayTime 毫秒 晶振:12Mhz **************************************************/ void Delay_Ms(unsigned char DelayTime) { unsigned int j; while(DelayTime) { for(j = 0;j LCD_CheckBusy(); } } /************************************************** * 函数名称:LCD_Cls() * 功能 :清屏 **************************************************/ void LCD_Cls() { LCD_WriteByte(Command,LcdCls); Delay_Ms(10); } /************************************************** * 函数名称:LCD_WriteByte(bit DataOrCommand,unsigned char Data) * 功能 :向液晶写入数据或者命令 * 参数 :DataOrCommand:数据或者命令判断 Data **************************************************/ void LCD_WriteByte(bit DataOrCommand,unsigned char Data) { if(DataOrCommand == Command) //判断指令或者数据 { RS_Low();} else { RS_High();} RW_Low(); //写入 E_High(); DataPort = Data; Delay_Ms(5); E_Low(); } /************************************************** * 函数名称:LCD_DisplayChar * 功能 :在指定位置显示字符 * 参数 :Local_X X坐标, Local_Y Y坐标, Data 待显示字符 **************************************************/ void LCD_DisplayChar(unsigned char Local_X,unsigned char Local_Y,unsigned char Data) { LCD_CheckBusy(); if (Local_Y == FirstLine) LCD_WriteByte(Command,FirstLineAdd + Local_X); //第一行X位置 else LCD_WriteByte(Command,SecondLineAdd + Local_X); //第二行X位置 LCD_WriteByte(DisplayData,Data); } /************************************************** * 函数名称:LCD_DisplayString * 功能 :在指定位置显示字符 * 参数 :Local_X X坐标(0-15), Local_Y Y坐标(0-1), Str 待显示字符串 **************************************************/ void LCD_DisplayString(unsigned char Local_X,unsigned char Local_Y,unsigned char *Str,unsigned char Num) { LCD_CheckBusy(); if (Local_Y == FirstLine) LCD_WriteByte(Command,FirstLineAdd + Local_X); //第一行X位置 else LCD_WriteByte(Command,SecondLineAdd + Local_X); //第二行X位置 while(Num--) { LCD_WriteByte(DisplayData,*Str); Str ++; } } /************************************************** * 函数名称:LCD_Init * 功能 :液晶屏初始化 **************************************************/ void LCD_Init() { LCD_WriteByte(Command,DisplayMode); //显示模式: 16*2行显示,5*7点阵,8位数据接口 Delay_Ms(10); LCD_WriteByte(Command,DisplayMode); //显示模式: 16*2行显示,5*7点阵,8位数据接口 Delay_Ms(10); LCD_WriteByte(Command,DisplayMode); //显示模式: 16*2行显示,5*7点阵,8位数据接口 Delay_Ms(10); LCD_WriteByte(Command,DisplayMode); //显示模式: 16*2行显示,5*7点阵,8位数据接口 LCD_WriteByte(Command,DisplayOFF); //显示关闭 LCD_WriteByte(Command,LcdCls); //显示清屏 LCD_WriteByte(Command,DisplayCursor); //显示光标 地址加1,光标加1 Delay_Ms(10); LCD_WriteByte(Command,DisplayOn); //显示开 }

LCD1602.h

#ifndef __1602_H_ #define __1602_H_ #include #include #define FirstLine 0 #define SecondLine 1 void Delay_Ms(unsigned char DelayTime); void LCD_CheckBusy(); void LCD_Cls(); void LCD_WriteByte(bit DataOrCommand,unsigned char Data); void LCD_DisplayChar(unsigned char Local_X,unsigned char Local_Y,unsigned char Data); void LCD_DisplayString(unsigned char Local_X,unsigned char Local_Y,unsigned char *Str,unsigned char Num); void LCD_Init(); #endif

JuZhen.C

#include #include #include "juzhen.h" #define u8 unsigned char //矩阵键盘的扫描 unsigned char keyscan() { unsigned char value = 0;//定义按键值 u8 row,column; P2=0xf0; if(P2!=0xf0) { Selay(20); if(P2!=0xf0) { row=P2; P2=0x0f; column=P2; switch(row|column) { case 0x77:Selay(50);value=1;if(value==1);Selay(50);break;//温度上限阈值+1 case 0xb7:Selay(50);value=2;if(value==2);Selay(50);break;//温度上限阈值-1 case 0xd7:Selay(50);value=3;if(value==3);Selay(50);break;//温度下限阈值+1 case 0xe7:Selay(50);value=4;if(value==4);Selay(50);break;//温度下限阈值-1 case 0x7b:Selay(50);value=5;if(value==5);Selay(50);break; case 0xbb:Selay(50);value=6;if(value==6);Selay(50);break; case 0xdb:Selay(50);value=7;if(value==7);Selay(50);break; case 0xeb:Selay(50);value=8;if(value==8);Selay(50);break; default:value=0;break; } } } return value;//返回最终的键值 } void Selay(unsigned char k) //@11.0592MHz { unsigned char o, u; while(k--) { _nop_(); o = 2; u = 199; do { while (--u); } while (--o); } }

JuZhen.h

#ifndef __JUZHEN_H_ #define __JUZHEN_H_ unsigned char keyscan(); void Selay(unsigned char k); #endif 感悟

通过这次课设我也学习到了很多,通过写博客的方式来分享我的学习成果: 1.要学会使用switch case语句,要不一直用if语句会很麻烦。 2.定时器延时与Delay延时的区别: 定时器的做法是在你的程序里还有其他事要做的情况下去设置的。也就是说设置了定时器后就可以去做其他事情了,delay就是不做事光用消耗的,消耗一定的时间后再去做其他事。 3.extern后面要加全局变量,不能加局部变量。 4.使用指针定义的时候,要将指针指向一个区域。例如:unsigned char *p; p=&a; 5.指针与数组是可以相互转换的。 6.要让lcd上面显示相应的字符,要写入这个字符对应的Ascll码值,写入的整数字符要+0x30。要想变回原来的整数也要减去相应的0x30。 例: T=(DHT11_Dis[11]-0x30)*10+DHT11_Dis[12]-0x30; 7.要多看数据手册,多看一些比较成体系的视频,学习不要碎片化。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3