PCB图
SCH图
北方由于冬季较长,太阳能几乎处于废弃状态,于是自己用MCU作了这款简易自动加热热控制器,本款加热器还可以做其他方面如水温,室内测温,各种家电设备测温,测温范围0-100。很实用。
源程序更新:
太阳能热水器智能控制,它以89C52单片机为核心,配合电阻型4档水位传感器、负温度系数NTC热敏电阻温度传感器、8255A扩展键盘和显示器件、驱动电路(电磁阀、电加热、报警)等外围器件, 完成对太阳能热水器容器内的水位、水温测量、显示等
全部源码下载:
太阳能热水器智能控制系统程序.rar
(2.84 KB, 下载次数: 208)
以下是部分程序预览:
- //太阳能热水器智能控制系统程序:
- //定义头文件和各个输入管脚以及变量声明
- #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;
- }
复制代码
|