📄 main.c
字号:
#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 + -