基于单片机的温度湿度采集系统

    科技2022-07-12  116

    基于单片机的温度湿度采集系统

    程序

    /**************************************************************** ***************************************************************/ #include <reg52.h> #define uint unsigned int #define uchar unsigned char #include <intrins.h> typedef bit BOOL ; sbit io = P1^1 ;//(口线定义) sbit bee=P1^0; sbit rs = P2^5 ; sbit rw = P2^6 ; sbit ep = P2^7 ; bit flag_300ms ; sbit K1=P1^2; sbit K2=P1^3; sbit K3=P1^4; uchar yemian=0;//(定义变量) uchar flat=1; uchar data_byte; uchar RH,RL,TH,TL; uchar WenDu,ShiDu;//报警的温度和湿度 #include "eeprom52.h" /****************************延时程序****************************/ void delay(uchar ms) { // 延时子程序 uchar i ; while(ms--) { for(i = 0 ; i<250;i++) ; } } void delay1()//延时10us { uchar i; i--; i--; i--; i--; i--; i--; } void longdelay(uchar s) //长延时 { while(s--) { delay(20) ; } } /******************把数据保存到单片机内部eeprom中******************/ void write_eeprom() { SectorErase(0x2000); byte_write(0x2000, WenDu); byte_write(0x2001, ShiDu); byte_write(0x2060, a_a); } /******************把数据从单片机内部eeprom中读出来*****************/ void read_eeprom() { WenDu = byte_read(0x2000); ShiDu = byte_read(0x2001); a_a = byte_read(0x2060); } /**************开机自检eeprom初始化*****************/ void init_eeprom() { read_eeprom(); //先读 if(a_a != 2) //新的单片机初始单片机内问eeprom { WenDu = 30; ShiDu = 80; a_a = 2; write_eeprom(); } } /********************报警程序部分*******************/ void warn() //报警函数 { if(TH>=WenDu) //检测的温度高于设定温度报警值 { bee=0; //报警 } if(RH>=ShiDu) //检测的湿度高于设定的湿度值 { bee=0; //报警 } if( TH<WenDu && RH<ShiDu ) { bee=1; //停止报警 } } /************************LCD模块******************************************/ BOOL lcd_bz()//测试LCD忙碌状态 { BOOL result ; rs = 0 ; rw = 1 ; ep = 1 ; result = (BOOL)(P0 & 0x80) ; ep = 0 ; return result ; } void write_cmd(uchar cmd)// 写指令 { while(lcd_bz()) ; rs = 0 ; rw = 0 ; ep = 0 ; P0 = cmd ; ep = 1 ; ep = 0 ; } void write_addr(uchar addr)//写地址 { write_cmd(addr|0x80) ; } void write_byte(uchar dat)//写字节 { while(lcd_bz()) ; rs = 1 ; rw = 0 ; ep = 0 ; P0 = dat ; ep = 1 ; ep = 0 ; } void lcd_init()// 初始化 { write_cmd(0x38) ; delay(1); write_cmd(0x08) ; delay(1); write_cmd(0x01) ; delay(1); write_cmd(0x06) ; delay(1); write_cmd(0x0c) ; delay(1); } void display(uchar addr, uchar q)//在某一地址上显示一字节 { delay(1) ; write_addr(addr) ; write_byte(q) ; delay(1) ; } /*********************** DHT11测试模块***************************************/ void start()//开始信号 { io=1; delay1(); io=0; delay(20);//>18ms io=1; delay1();//20-40us delay1(); delay1(); delay1(); delay1(); } uchar receive_byte()//接收一个字节 { uchar i,temp,count; for(i=0;i<8;i++) { temp=0; delay1();delay1();delay1();delay1(); if(io==1)temp=1; count=2; while((io)&&count++); if(count==1)break; data_byte<<=1; data_byte|=temp; } return data_byte; } void receive()//接收数据 { uchar T_H,T_L,R_H,R_L,check,num_check; uchar count; start();//开始信号 io=1; if(!io)//读取DHT11响应信号 { while((io)&&count++); R_H=receive_byte(); R_L=receive_byte(); T_H=receive_byte(); T_L=receive_byte(); check=receive_byte(); io=0;//拉低延时50us delay1();delay1();delay1();delay1();delay1(); io=1; num_check=R_H+R_L+T_H+T_L; if(num_check=check) { RH=R_H; RL=R_L; TH=T_H; TL=T_L; check=num_check; } } } void showw() // 问候语函数 { lcd_init(); //初始化 delay(10); display(0x05,'W'); display(0x06,'e'); display(0x07,'l'); display(0x08,'c'); display(0x09,'o'); display(0x0a,'m'); display(0x0b,'e'); delay(250); //短暂延时 delay(250); delay(250); /*********************************/ /* display(0x40,' ') ; display(0x41,'h'); display(0x42,'e'); */ } /*************定时器0初始化程序***************/ void time_init() { EA = 1; //开总中断 TMOD = 0X01; //定时器0、定时器1工作方式1 ET0 = 1; //开定时器0中断 TR0 = 1; //允许定时器0定时 } void key() //按键程序 选择菜单模式 { if(!K1) { delay(20); if(!K1) { while(!K1) ; yemian++; flat++; if(yemian>=3) { yemian=0; } } } } shezhi() //对里面的数值进行修改 { if(!K2) { delay(50); if(!K2) { ; if(yemian==1) { WenDu+=1; if(WenDu>99) { WenDu=99; } //湿度上限加 } if(yemian==2) { ShiDu+=1; if(ShiDu>99) { ShiDu=99; } //湿度下限加 } write_eeprom(); //保存数据 } } if(!K3) { delay(50); if(!K3) { ; if(yemian==1) { WenDu-=1; //湿度下限减 if(WenDu<1) {WenDu=1; } } if(yemian==2) { ShiDu-=1; //湿度下限减 if(ShiDu<1) { ShiDu=1; } } write_eeprom(); //保存数据 } } } /***************************主程序*********************************/ void main() { init_eeprom(); //读eeprom数据 time_init(); //初始化定时器 showw(); //显示问候语 和名字 while(1) { key(); //====================yemian==0时 进入工作状态================================= if(yemian==0) { if(flat==1) { flat=0; lcd_init(); //初始化 display(0x00,'T') ; //Temp display(0x01,'e'); display(0x02,'m'); display(0x03,'p'); display(0x04,':'); display(0x08,0xdf); // 度 display(0x09,'C'); display(0x40,'H') ; //Humi display(0x41,'u'); display(0x42,'m'); display(0x43,'i'); display(0x44,':'); display(0x47,'%'); display(0x48,'R'); display(0x49,'H'); display(0x0c,'T'); display(0x0d,':'); display(0x0e,WenDu/10+0x30); //报警温度 display(0x0f,WenDu%10+0x30); display(0x4c,'H'); display(0x4d,':'); display(0x4e,ShiDu/10+0x30); //报警湿度 display(0x4f,ShiDu%10+0x30); } if(flag_300ms == 1) { flag_300ms = 0; receive(); display(0x05,TH/10+0x30); //温度显示 display(0x06,TH%10+0x30); display(0x45,RH/10+0x30); //湿度显示 display(0x46,RH%10+0x30); warn(); } } //====================yemian==1 温度设置=========================== if(yemian==1) //温度 { if(flat==1) { flat=0; bee=1; lcd_init(); //初始化 display(0x06,'T'); display(0x07,'e'); display(0x08,'m'); display(0x09,'p'); } shezhi(); display(0x47,WenDu/10+0x30); //温度 display(0x48,WenDu%10+0x30); } //====================yemian==1湿度设置========================== if(yemian==2) //湿度设置 { if(flat==1) { flat=0; bee=1; lcd_init(); //初始化 display(0x06,'H'); display(0x07,'u'); display(0x08,'m'); display(0x09,'i'); } shezhi(); display(0x47,ShiDu/10+0x30); //湿度 display(0x48,ShiDu%10+0x30); } } } /*************定时器0中断服务程序***************/ void time0_int() interrupt 1 { static uchar value; TH0 = 0x3c; TL0 = 0xb0; // 50ms if(value % 6 == 0) { flag_300ms = 1; //300ms value = 0; } }

    头文件

    #ifndef _EEPROM52_H_ #define _EEPROM52_H_ uchar a_a; /********STC89C51扇区分布******* 第一扇区:1000H--11FF 第二扇区:1200H--13FF 第三扇区:1400H--15FF 第四扇区:1600H--17FF 第五扇区:1800H--19FF 第六扇区:1A00H--1BFF 第七扇区:1C00H--1DFF 第八扇区:1E00H--1FFF *****************/ /********STC89C52扇区分布******* 第一扇区:2000H--21FF 第二扇区:2200H--23FF 第三扇区:2400H--25FF 第四扇区:2600H--27FF 第五扇区:2800H--29FF 第六扇区:2A00H--2BFF 第七扇区:2C00H--2DFF 第八扇区:2E00H--2FFF *****************/ #define RdCommand 0x01 //定义ISP的操作命令 #define PrgCommand 0x02 #define EraseCommand 0x03 #define Error 1 #define Ok 0 #define WaitTime 0x01 //定义CPU的等待时间 sfr ISP_DATA=0xe2; //寄存器申明 sfr ISP_ADDRH=0xe3; sfr ISP_ADDRL=0xe4; sfr ISP_CMD=0xe5; sfr ISP_TRIG=0xe6; sfr ISP_CONTR=0xe7; /* ================ 打开 ISP,IAP 功能 ================= */ void ISP_IAP_enable(void) { EA = 0; /* 关中断 */ ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */ ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */ } /* =============== 关闭 ISP,IAP 功能 ================== */ void ISP_IAP_disable(void) { ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */ ISP_TRIG = 0x00; EA = 1; /* 开中断 */ } /* ================ 公用的触发代码 ==================== */ void ISPgoon(void) { ISP_IAP_enable(); /* 打开 ISP,IAP 功能 */ ISP_TRIG = 0x46; /* 触发ISP_IAP命令字节1 */ ISP_TRIG = 0xb9; /* 触发ISP_IAP命令字节2 */ _nop_(); } /* ==================== 字节读 ======================== */ unsigned char byte_read(unsigned int byte_addr) { EA = 0; ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */ ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff); ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */ ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令 */ ISPgoon(); /* 触发执行 */ ISP_IAP_disable(); /* 关闭ISP,IAP功能 */ EA = 1; return (ISP_DATA); /* 返回读到的数据 */ } /* ================== 扇区擦除 ======================== */ void SectorErase(unsigned int sector_addr) { unsigned int iSectorAddr; iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */ ISP_ADDRH = (unsigned char)(iSectorAddr >> 8); ISP_ADDRL = 0x00; ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */ ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */ ISPgoon(); /* 触发执行 */ ISP_IAP_disable(); /* 关闭ISP,IAP功能 */ } /* ==================== 字节写 ======================== */ void byte_write(unsigned int byte_addr, unsigned char original_data) { EA = 0; // SectorErase(byte_addr); ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */ ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff); ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */ ISP_CMD = ISP_CMD | PrgCommand; /* 写命令2 */ ISP_DATA = original_data; /* 写入数据准备 */ ISPgoon(); /* 触发执行 */ ISP_IAP_disable(); /* 关闭IAP功能 */ EA =1; } #endif

    原理图

    Processed: 0.015, SQL: 8