📄 太阳能热水器智能控制系统程序.c
字号:
//太阳能热水器智能控制系统程序:
//定义头文件和各个输入管脚以及变量声明
#include <reg52.h>
#include <absacc.h>
#include <stdio.h>
#include <intrins.h>
#define uint unsigned int//定义变量类型名
#define uchar unsigned char
/*定义8255a字符型字位口*/
#define DIGPORT XBYTE[0x1FFF]//PA口地址,位选码地址
#define WORDPORT XBYTE[0X3FFF]//PB口地址,断选码地址
#define CCOM XBYTE[0X7FFFF]//控制字寄存器地址
#define KPORT XBYTE[0X5FFF]//PC口,键盘扫描地址
//DS1302_RST=1//定义DS1302时钟芯片引脚操作
#define Set_DS1302_RST DS1302_RST=1
//DS1302_RST=0
#define Clr_DS1302_RST DS1302_RST=0
//DS1302_SDA=1
#define Set_DS1302_SDA DS1302_SDA=1
//DS1302_SDA=0
#define Clr_DS1302_SDA DS1302_SDA=0
//DS1302_SCLK=1
#define Set_DS1302_SCLK DS1302_SCLK=1
//DS1302_SCLK=0
#define Clr_DS1302_SCLK DS1302_SCLK=0
//定义读时间控制字
#define DS1302_SEC_Reg 0x80
#define DS1302_MIN_Reg 0x82
#define DS1302_HR_Reg 0x84
#define DS1302_DATE_Reg 0x86
#define DS1302_MONTH_Reg 0x88
#define DS1302_DAY_Reg 0x8a
#define DS1302_YEAR_Reg 0x8c
#define DS1302_CONTROL_Reg 0x8e
#define DS1302_CHARGER_Reg 0x90
#define DS1302_CLKBURST_Reg 0xbe
//全局变量
//为了方便,我把个位和十位分开了
uchar year1=0x88;
uchar year0=0x88;
uchar month=0x88;
uchar date=0x88;
uchar day=0x88;
uchar hour=0x88;
uchar minute=0x88;
uchar second=0x88;
/*定义P1口各管脚*/
sbit L0=P2^0;
sbit L1=P2^1;
sbit L2=P2^2;
sbit L3=P2^3;
sbit K0=P2^4;
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit Hig=P1^4;
sbit DS1302_SDA=P1^5;//定义DS1302时钟引脚与单片机引脚的连接
sbit DS1302_SCLK=P1^6;
sbit DS1302_RST=P1^7;
/*声明调用函数*/
void inital(void);
void timer1_svr(void);
void display(void);
void delay(uchar j);
void DS1302_Write(uchar reg,uchar dat);
uchar DS1302_Read(uchar reg);
void DS1302_Init(void);
void ReadTime(void);
void WtTmCr();
void LvRead();
void TmRead();
void key(void);
uchar kbscan(void);
void DS1302(void);
void int0_int(void);
void int1_int(void);
/*定义调用存储单元*/
/*显示缓冲区(依次为高位低位)*/
uchar BUFFER[3]={0,0,0};
uchar WTLV;//水位值
uchar TMP;//水温值
uchar WTLVSET;//水位设定值
uchar TMPSET;//水温设定值
uchar buf[4]={0,0,0,0};
/*数码管显示编码"0"-"9","A","-"*/
uchar code TABLE[]={0x7B,0x30,0xEA,0xF8,0xB1,0xD9,0xDB,0x70,0xFB,0xF9,0xF3,0x80};
main()
{
inital();//初始化中断、定时器、I/O口
kbscan();//键盘扫描
key();//键盘处理
TmRead();//读取温度
LvRead();//读取水位
DS1302();//读取时间
display();//显示
}
void inital()
{
P1_0= P1_1= P1_2=K0=0;//初始化外部驱动口
DS1302_Init();
EA=1;//开外部中断
IT0=1;//外部中断下降沿触发
EX0=1;//允许外部中断0
Hig=1;P1.3输出高电平
TMOD=0x11;定时器工作于方式1
TH1=0X8A;//定时器1赋初值
TL1=0XD0;
ET1=1;定时器1开定时中断
TR1=1;//开启定时器1
CCOM=0X80;//初始化8255A,送控制字,工作方式0
}
uchar kbscan(void)
{
uchar recode;
if((KPORT&0X0F)!=0X0F) //若有键按下
{
delay(2); //延时抖动
if((KPORT&0X0F)!=0X0F)
{
recode=KPORT;
return(recode);
}
}
else
return(0);
}
void key(void)
{
uchar key;
key=kbscan();
delay(2);
if(key==0x01)
{
P1_1=1;//上水
}
if(key==0x02) //设置水位
{
if(WTLVSET==4)
WTLVSET=0;
else
WTLVSET+=WTLVSET;
BUFFER[0]=WTLVSET;//显示设置水位
display();
}
if(key==0x04)//电加热
{
P1_0=1;
}
if(key==0x08)//设置温度
{
if(TMPSET>=80)
TMPSET=30;
else
TMPSET=TMPSET+10;//增加十度
BUFFER[0]=TMPSET; 显示设置水温
display();
}
}
void timer1_svr() interrupt 1
{
TH1=0X8A;//重新给定时器1赋值
TL1=0XD0;
Hig=!Hig;//充放电变换
if(Hig)//充电开始时启动定时器0
{
TL0=TH0=0X00;//定时器0赋初值0
TR0=1;//启动定时器0
}
}
void int0_int(void) interrupt 0//外部中断0,测水位
{
EX0=0;
EX1=1;
TR0=0;
buf[0]=TL0;
buf[1]=TH0;
}
void int1_int(void) interrupt 2//外部中断1,测水温
{
EX1=0;
EX0=1;
TR0=0;
buf[2]=TL0;
buf[3]=TH0;
}
void TmRead()//水温值处理
{
uint val;
val=buf[3]*256+buf[2];
if(val<7549)
TMP=97-int(val*8/1000);
else
if(val<20000)
TMP=50-int(val/1000);
else
TMP=30-int(val*5/10000);
}
void LvRead()//水位值处理
{
if(buf[1]>60)
{
WTLV=1;//
L3=0;L2=1;L1=1;L0=1;
}
else if(buf[1]>45)
{
WTLV=2;
L3=1;L2=0;L1=1;L0=1;
}
else if(buf[1]>36)
{
WTLV=3;
L3=1;L2=1;L1=0;L0=1;
}
else
{
WTLV=4;
L3=1;L2=1;L1=1;L0=0;
}
}
void WtTmCr()//水位、水温控制
{
if(WTLV==4)
P1_1=0;
if(WTLV==1)
P1_1=1;
if(TMP>=TMPSET)
P1_0=0;
if(TMP<TMPSET&&hour==0x19)
P1_0=1;
}
void display(void)
{
uchar i; //显示缓冲区首址
uchar delay; //显示延时
uchar disp; //显示内容
uchar digit; //定义数码管显示位
digit=0x0200;
for(i=2;i>=0;i--)
{
if(BUFFER[i]>100) disp=BUFFER[i]%10+10;//显示高位
else disp=BUFFER[i]%10;
DIGPORT=digit;
WORDPORT=TABLE[disp];
for(delay=0;delay<=200;delay++);
digit=digit>>1;//显示低位
disp=BUFFER[i]/10;
DIGPORT=digit;
WORDPORT=TABLE[disp];
for(delay=0;delay<=200;delay++);
digit=digit>>1;
}
}
void delay(uchar j)//延时程序
{
uchar a,b;
for(a=0;a<j;a++)
for(b=0;b<200;b++)
;
}
void DS1302()//时间程序
{
ReadTime();
BUFFER[1]=second;
BUFFER[2]=hour;
}
void DS1302_Write(uchar reg,uchar dat)//写入时间
{
uchar i;
Clr_DS1302_RST;
_nop_();
_nop_();
Clr_DS1302_SCLK;
_nop_();
_nop_();
Set_DS1302_RST;
_nop_();
_nop_();
for(i=8;i>0;i--)
{
if(reg&0x01) Set_DS1302_SDA;
else Clr_DS1302_SDA;
_nop_();
_nop_();
Set_DS1302_SCLK;
_nop_();
_nop_();
Clr_DS1302_SCLK;
_nop_();
_nop_();
reg>>=1;
}
for(i=8;i>0;i--)
{
if(dat&0x01) Set_DS1302_SDA;
else Clr_DS1302_SDA;
_nop_();
_nop_();
Set_DS1302_SCLK;
_nop_();
_nop_();
Clr_DS1302_SCLK;
_nop_();
_nop_();
dat>>=1;
}
Clr_DS1302_RST;
_nop_();
_nop_();
}
uchar DS1302_Read(uchar reg)//读取时间
{
uchar dat=0,i;
Clr_DS1302_RST;
_nop_();
_nop_();
Clr_DS1302_SCLK;
_nop_();
_nop_();
Set_DS1302_RST;
_nop_();
_nop_();
for(i=8;i>0;i--)
{
if(reg&0x01) Set_DS1302_SDA;
else Clr_DS1302_SDA;
_nop_();
_nop_();
Set_DS1302_SCLK;
_nop_();
_nop_();
Clr_DS1302_SCLK;
_nop_();
_nop_();
reg>>=1;
}
for(i=8;i>0;i--)
{
dat>>=1;
if(DS1302_SDA) dat|=0x80;
Set_DS1302_SCLK;
_nop_();
_nop_();
Clr_DS1302_SCLK;
_nop_();
_nop_();
}
Clr_DS1302_RST;
_nop_();
_nop_();
return(dat);
}
void DS1302_Init(void)//初始化DS1302
{
DS1302_Write(DS1302_CONTROL_Reg,0x00);//关闭写保护
DS1302_Write(DS1302_SEC_Reg,0x80);//暂停
DS1302_Write(DS1302_CHARGER_Reg,0xa9);//涓流充电
DS1302_Write(DS1302_YEAR_Reg,0x04); //年
DS1302_Write(DS1302_MONTH_Reg,0x12); //月
DS1302_Write(DS1302_DATE_Reg,0x09); //日
DS1302_Write(DS1302_DAY_Reg,0x04); //周
DS1302_Write(DS1302_HR_Reg,0x10); //时
DS1302_Write(DS1302_MIN_Reg,0x25); //分
DS1302_Write(DS1302_SEC_Reg,0x00); //秒
DS1302_Write(DS1302_CONTROL_Reg,0x80);//打开写保护
}
void ReadTime(void)//读取时间
{
uchar dat;
dat=DS1302_Read(DS1302_YEAR_Reg);//年
year0=dat&0x0f;
year1=dat>>4;
dat=DS1302_Read(DS1302_MONTH_Reg);//月
month=dat;
dat=DS1302_Read(DS1302_DATE_Reg);//日
date=dat;
dat=DS1302_Read(DS1302_DAY_Reg);//周
day=dat;
dat=DS1302_Read(DS1302_HR_Reg);//时
hour=dat;
dat=DS1302_Read(DS1302_MIN_Reg);//分
minute=dat;
dat=DS1302_Read(DS1302_SEC_Reg);//秒
second=dat;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -