⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 51单片机实现的温湿度采集监控
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg52.h>
#include "LCD12864.h"
#include "SHT10.h"
#include "DS1302.h"
#include <delay.h>
#include<stdio.h>

#define	ADDR_YEAR 0x8d
#define ADDR_MON  0x89
#define ADDR_DATE 0x87
#define ADDR_HOUR 0x85
#define ADDR_MIN  0x83
#define ADDR_SEC  0x81
#define ADDR_DAY  0x8B

#define POS_YEAR ADDR_LINE1+2
#define POS_MON  ADDR_LINE1+4
#define POS_DATE ADDR_LINE1+6
#define POS_HOUR ADDR_LINE2
#define POS_MIN  ADDR_LINE2+1
#define POS_SEC  ADDR_LINE2+3
#define POS_DAY  ADDR_LINE2+7 
#define POS_TEMP ADDR_LINE3+5
#define POS_HUMI ADDR_LINE4+5

#define SEC  0
#define MIN  1
#define HOUR 2
#define DATE 3
#define MON  4
#define DAY  5
#define YEAR 6	

float idata	humiLimit = 80;		//温湿度上限
float idata	tempLimit = 28;

sbit buzzer=P2^5;
uchar idata sysData[7]={0x00,0x00,0x00,0x31,0x10,0x05,0x08};//DS1302数据(BCD码)
float tempf,humif;
uchar idata temps[5],humis[5];
uchar code MonSheet[2][19]={0,0x31,0x28,0x31,0x30,0x31,0x30,0x31,0x31,0x30,0,0,0,0,0,0,0x31,0x30,0x31,
				  0,0x31,0x29,0x31,0x30,0x31,0x30,0x31,0x31,0x30,0,0,0,0,0,0,0x31,0x30,0x31};


bit flagSettings,pFlagSettings,flagInc,flagDec,flagInc10,flagDec10; //依次为系统设置标志位,前次系统设置标志位,加标志位,减标志位(长按加标志位,长按减标志位,实现长按加减10的功能,尚未实现)
bit n;
uchar m;
uchar flagOpt;									//选项的标志位,0-8,对应9项数据

sbit key1=P2^2;
sbit key2=P2^3;
sbit key3=P2^4;

uint SHTcount,blinkCount;
/********************************************************************
函数名称:keyscan 
功	能:按键监测,分长按短按(用定时器实现),长按时间为1秒,按键1短按返回11,长按返
		回12,按键2短按返回21,长按返回22,以此类推,同时改变按键对应
		的标志位
入口参数:无
返回参数:a
********************************************************************/
int keyscan()
{
	unsigned char a;
	if(key1==0)
	{
		delay(5);
		if(key1==0)
		{
			TR0=1;
				
		}
		while(!key1);
		delay(5);
		while(!key1);
		if(n==0)
		{
			if(flagSettings==1)
			{
				flagOpt++;
				if(flagOpt==9)
				flagOpt=0;
			}
				a=11;
				m=0;
				TR0=0;

		}
		else if(n==1)
		{	
			flagSettings=~flagSettings;		//系统设置的标志位,1进入系统设置,0退出
			flagOpt=0;
			LcdClear();
			a=12;
			n=0;
			m=0;
			TR0=0;
		}
	}
	if(key2==0)
	{
		delay(5);
		if(key2==0)
		{
			TR0=1;
	
		}
		while(!key2);
		delay(5);
		while(!key2);
		if(n==0)
		{
			if(flagSettings==1)
				flagInc=1;
			a=21;
			m=0;
			TR0=0;

		}
		else if(n==1)
		{	
			flagInc10=1;
			a=22;
			n=0;
			m=0;
			TR0=0;
		}
	}
	if(key3==0)
	{
		delay(5);
		if(key3==0)
		{
			TR0=1;
				
		}
		while(!key3);
		delay(5);
		while(!key3);
		if(n==0)
		{
			if(flagSettings==1)
				flagDec=1;
			a=31;
			m=0;
			TR0=0;

		}
		else if(n==1)
		{	
			flagDec10=1;
			a=32; 
			n=0;
			m=0;
			TR0=0;
		}
	}
	return a;
}

void timer0() interrupt 1 using 3
{
	TH0=(65536-10000)/256;
	TL0=(65536-10000)%256;
	m++;
	if(m==100)
	{
		m=0;
		n=1;
	}
}
/********************************************************************
函数名称:Display***()
功	能:显示年月日星期时分秒
入口参数:无
返回参数:无
********************************************************************/


void DisplayYear()
{
	WriteCmd12864(POS_YEAR);
	WriteData12864(sysData[YEAR]/16+0x30);
	WriteData12864(sysData[YEAR]%16+0x30);
}
void DisplayMon()
{
	WriteCmd12864(POS_MON);
	WriteData12864(sysData[MON]/16+0x30);
	WriteData12864(sysData[MON]%16+0x30);
}
void DisplayDate()
{
	WriteCmd12864(POS_DATE);
	WriteData12864(sysData[DATE]/16+0x30);
	WriteData12864(sysData[DATE]%16+0x30);
}
void DisplayHour()
{
	WriteCmd12864(POS_HOUR);
	WriteData12864(sysData[HOUR]/16+0x30);
	WriteData12864(sysData[HOUR]%16+0x30);
}
void DisplayMin()
{
	WriteCmd12864(POS_MIN);
	WriteData12864(0x3A);
	WriteData12864(sysData[MIN]/16+0x30);
	WriteData12864(sysData[MIN]%16+0x30);
	WriteData12864(0x3A);
}
void DisplaySec()
{
	WriteCmd12864(POS_SEC);
	WriteData12864(sysData[SEC]/16+0x30);
	WriteData12864(sysData[SEC]%16+0x30);
}      

void DisplayDay()
{
	switch (sysData[DAY])	
	{
		case 1:	Display12864(POS_DAY,"一"); break;
		case 2:	Display12864(POS_DAY,"二"); break;
		case 3:	Display12864(POS_DAY,"三"); break;
		case 4: Display12864(POS_DAY,"四"); break;
		case 5: Display12864(POS_DAY,"五"); break;
		case 6: Display12864(POS_DAY,"六"); break;
		case 7: Display12864(POS_DAY,"日"); break;
		default: break;
	}
}
/********************************************************************
函数名称:DisplayFrame() 
功	能:初试显示,仅在flagsettings发生变化的时候调用
入口参数:无
返回参数:无
********************************************************************/



void DisplayFrame()
{
	Display12864(ADDR_LINE1+3,"年");
 	Display12864(ADDR_LINE1+5,"月");
	Display12864(ADDR_LINE1+7,"日");
	Display12864(ADDR_LINE2+5,"星期");
	
	DisplayYear();
	DisplayMon();
	DisplayDate();
	DisplayHour();
	DisplayMin();
	DisplaySec();
	DisplayDay();


	if(flagSettings==0)				 //监视状态显示当前温湿度的字样,设置状态显示要设置的报警温湿度的字样
	{
		Display12864(ADDR_LINE3,"当前温度:");
		Display12864(ADDR_LINE4,"当前湿度:");
	}
	else if(flagSettings==1)
	{
		Display12864(ADDR_LINE3,"报警温度:");
		Display12864(ADDR_LINE4,"报警湿度:");
	}
	WriteCmd12864(ADDR_LINE3+7);
	WriteData12864(0xA1);		   //摄氏度符号
	WriteData12864(0xE6);
	WriteCmd12864(ADDR_LINE4+7);
	WriteData12864(0xA3);		  //表示湿度的百分号
	WriteData12864(0xA5);
} 

/********************************************************************
函数名称: CheckLimit()			 
功能:监测温湿度是否超标,超标报警
入口参数:无
返回参数:无
********************************************************************/

void CheckLimit(float *tempc,float *humic)
{
	if(*tempc>tempLimit||*humic>humiLimit)
			buzzer=0;
	else
			buzzer=1;
}

/********************************************************************
函数名称:CheckLeapyear
功	能:uchar cYear
入口参数:(sysData)
返回参数:1、0 
********************************************************************/
bit CheckLeapyear(uchar cYear)
{
   if( (!(cYear%4) && (cYear%100)) || !(cYear%400) ) return 1; else return 0;
}

/********************************************************************
函数名称:GetDay()
功	能:计算星期
入口参数:uchar cYear,uchar cMon,uchar cDay
返回参数:uchar  1-7
********************************************************************/
//蔡勒(Zeller)公式(只适合于1582年10月15日之后的情形):
//     w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
//公式中的符号含义如下:
//c:世纪(年的高两位数);
//y:年(年的低两位数);
//m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月
//        来计算,比如2005年1月1日要看作2004年的13月1日来计算);
//d:日;
//[]代表取整,即只要整数部分。
uchar GetDay(uchar cYear,uchar cMon,uchar cDate)
{
	uchar tempYear,tempMon,tempDate,day;
	tempYear=cYear/16*10+cYear%16;	//BCD转十进制
	tempMon=cMon/16*10+cMon%16;
	tempDate=cDate/16*10+cDate%16;
	if(tempMon<3)
	{
		tempMon=cMon+12;
		if(tempYear==0)
		tempYear=99;
		else
		tempYear=tempYear-1;
	}
	day=(tempYear+(tempYear/4)+(26*(tempMon+1)/10)+tempDate-36)%7;
	if(day==0)
		day=7;
	return day;

}



/********************************************************************
函数名称:BCDpp(uchar bcd)
功	能:BCD自加运算
入口参数:bcd
返回参数:无
********************************************************************/
void BCDpp(uchar *bcd)
{
	*bcd=*bcd+1;
	if(*bcd%16==10)
	*bcd=*bcd+6;
}
/********************************************************************
函数名称:BCDmm(uchar bcd)
功	能:BCD自减运算
入口参数:bcd
返回参数:无
********************************************************************/
void BCDmm(uchar *bcd)
{
 	*bcd=*bcd-1;
	if(*bcd%16==15)
	*bcd=*bcd-6;	
} 
/********************************************************************
函数名称:SystemSetting() 
功	能:系统设置函数,由标志位来识别设置的选项
入口参数:无
返回参数:无
********************************************************************/
void SystemSettings()
{  
	if(flagInc)
	{
		flagInc=0;
		blinkCount=0;	 //闪烁计数清零,按键间隔比较短的时候不闪
		switch(flagOpt)
		{
			case 0:BCDpp(&sysData[YEAR]);
				if(sysData[YEAR]>0x99)
					sysData[YEAR]=0;
				break;
			case 1:BCDpp(&sysData[MON]);
				if(sysData[MON]>0x12)
					sysData[MON]=1;
				break;
			case 2:BCDpp(&sysData[DATE]);
				if(sysData[DATE]>MonSheet[CheckLeapyear(sysData[YEAR])][sysData[MON]])
					sysData[DATE]=1;
				break;
			case 3:BCDpp(&sysData[HOUR]);
				if(sysData[HOUR]>0x23)
					sysData[HOUR]=0;
				break;
			case 4:BCDpp(&sysData[MIN]);
				if(sysData[MIN]>0x59)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -