RTC实时时钟预约开机自动煲粥电饭煲.docx
《RTC实时时钟预约开机自动煲粥电饭煲.docx》由会员分享,可在线阅读,更多相关《RTC实时时钟预约开机自动煲粥电饭煲.docx(17页珍藏版)》请在冰豆网上搜索。
![RTC实时时钟预约开机自动煲粥电饭煲.docx](https://file1.bdocx.com/fileroot1/2023-1/24/42edf9ad-3844-4863-8fcd-0555d58d7c52/42edf9ad-3844-4863-8fcd-0555d58d7c521.gif)
RTC实时时钟预约开机自动煲粥电饭煲
/***********************
文件名:
RTC实时时钟预约开机自动煲粥电饭煲
作者;枫落
版本:
V11.11.1
说明:
通过RTC实时时钟断电走时,预约开机时只需要调试CLOCK时间开机,
然后全功率加热水开后半功率熬闷,熬完之后自动间歇加热(保温}
不改变普通电饭煲内部工作电路使电饭煲变智能。
1602液晶显示当前时间和开机预约时间默认预约时间为05:
30
RTC时钟DS1302芯片保证时间延续性
四按键控制简单明了
傻瓜式操作界面
修改记录:
2012年4月17日基本完成功能,加装无限延时程序可以使用
备份时间2012年4月18日
**/
/***************头文件********************/
#include
#include
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
/******************1302地址定义**************/
#defineWRITE_SECOND0x80
#defineWRITE_MINUTE0x82
#defineWRITE_HOUR0x84
#defineREAD_SECOND0x81
#defineREAD_MINUTE0x83
#defineREAD_HOUR0x85
#defineWRITE_PROTECT0x8E
/******************位地址********8********/
sbitACC_7=ACC^7;
//管脚定义
//*********************LCD1602设置START************************/
#defineLCD_DBP0
sbitLCD_RS=P2^6;
sbitLCD_RW=P2^5;
sbitLCD_E=P2^7;
sbitKZ=P1^0;//键盘控制键
sbitSJ=P1^1;//小时加
sbitFJ=P1^2;//分钟加
sbitNKZ=P1^3;//闹钟控制
//sbitKT=P1^3;
sbitSCLK=P3^6;//DS1302时钟信号7脚
sbitDIO=P3^4;//DS1302数据信号6脚
sbitCE=P3^5;//DS1302片选5脚
sbitZK=P1^4;//高压总开关
sbitMK=P3^0;//模式控制
/*****************变量***************/
//ucharduan,wei;//当前显示的段数据,位数据
//sbitDQ=P3^7;
//uinttempl,temph;
//uintshuju=0x0000;
ucharBZW=0;
ucharZKB=1,MKB=1;
ucharNfen=30,Nshi=5;//闹钟变量
ucharNfen_1,Nshi_1;//加热开水延时量
ucharhc[6];//数据拆分缓冲变量
ucharMiao,Fen,Shi;//时分秒变量
ucharcodeduanma[]={"0123456789"};//LED显示字段码
//ucharcodeweima[]={0x05,0x04,0x03,0x02,0x01,0x00};//动态显示数据位码
/**************延时函数***************/
voidDelay(uinti)
{
uintx,y;
for(x=i;x>0;x--)
{
for(y=120;y>0;y--)
{
;
}
}
}
/****************短延时*****
voidTempDelay(unsignedcharidataus)
{
while(us--);
}***/
/**************地址、数据发送子程序**********************/
voidWrite1302(unsignedcharaddr,dat)
{
unsignedchari,temp;
CE=0;//CE引脚为低,数据传送中止
SCLK=0;//清零时钟总线
CE=1;//CE引脚为高,逻辑控制有效
//发送地址
for(i=8;i>0;i--)//循环8次移位
{
SCLK=0;
temp=addr;
DIO=(bit)(temp&0x01);//每次传输低字节
addr>>=1;//右移一位
SCLK=1;
}
//发送数据
for(i=8;i>0;i--)
{
SCLK=0;
temp=dat;
DIO=(bit)(temp&0x01);
dat>>=1;
SCLK=1;
}
CE=0;
}
/******************数据读取子程序*******************/
unsignedcharRead1302(unsignedcharaddr)
{
unsignedchari,temp,dat1,dat2;
CE=0;
SCLK=0;
CE=1;
//发送地址
for(i=8;i>0;i--)//循环8次移位
{
SCLK=0;
temp=addr;
DIO=(bit)(temp&0x01);//每次传输低字节
addr>>=1;//右移一位
SCLK=1;
}
//读取数据
for(i=8;i>0;i--)
{
ACC_7=DIO;
SCLK=0;
ACC>>=1;
SCLK=1;
}
CE=0;
dat1=ACC;
dat2=dat1/16;//数据进制转换
dat1=dat1%16;//十六进制转十进制
dat1=dat1+dat2*10;
return(dat1);
}
/*************数据处理*********/
voidsjcl(uchardat,det)//dat为待拆分数据,det为即将存入缓冲数组位置
{
hc[det]=dat%10;
hc[det+1]=dat/10;
}
/*************BCD码转换函数***************/
ucharTo_BCD(uchardat)//十进制转BCD码
{
uchartemp,temp1;
temp=dat/10;
temp1=dat%10;
dat=temp*16+temp1;
return(dat);
}
/*--------------------------------------
;模块名称:
delay_n10us();
;功能:
延时函数,延时约n个10us
;占用资源:
--
;参数说明:
--
;-------------------------------------*/
voiddelay_n10us(uintn)//延时n个10us@12M晶振
{
uinti;
for(i=n;i>0;i--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
/*--------------------------------------
;模块名称:
LCD_write_command();
;功能:
LCD1602写指令函数
;占用资源:
P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E).
;参数说明:
dat为写命令参数
;-------------------------------------*/
voidLCD_write_command(uchardat)
{
delay_n10us(10);
LCD_RS=0;//指令
LCD_RW=0;//写入
LCD_E=1;//允许
LCD_DB=dat;
delay_n10us(10);//
LCD_E=0;
delay_n10us(10);//
}
/*--------------------------------------
;模块名称:
LCD_write_data();
;功能:
LCD1602写数据函数
;占用资源:
P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E).
;参数说明:
dat为写数据参数
;-------------------------------------*/
voidLCD_write_data(uchardat)
{
delay_n10us(10);
LCD_RS=1;//数据
LCD_RW=0;//写入
LCD_E=1;//允许
LCD_DB=dat;
delay_n10us(10);
LCD_E=0;
delay_n10us(10);
}
/*--------------------------------------
;模块名称:
;功能:
显示一个字符
;占用资源:
--
;参数说明:
;-------------------------------------*/
voidLCD_disp_char(ucharx,uchary,uchardat)
{
ucharaddress;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
/*--------------------------------------
;模块名称:
;功能:
显示一个字符串。
;占用资源:
--
;参数说明:
;-------------------------------------*/
voidLCD_disp_str(ucharx,uchary,uchar*str)
{
ucharaddress;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
while(*str!
='\0')
{
LCD_write_data(*str);
str++;
}
}
/*--------------------------------------
;模块名称:
LCD_init();
;功能:
初始化LCD1602
;占用资源:
--
;参数说明:
--
;-------------------------------------*/
voidLCD_init(void)
{
delay_n10us(10);
LCD_write_command(0x38);//设置8位格式,2行,5x7
delay_n10us(10);
LCD_write_command(0x0c);//整体显示,关光标,不闪烁
delay_n10us(10);
LCD_write_command(0x06);//设定输入方式,增量不移位
delay_n10us(10);
LCD_write_command(0x01);//清除屏幕显示
delay_n10us(100);//延时清屏,延时函数,延时约n个10us
}
voidxianshi_1(ucharxx,wei)
{
LCD_disp_char(xx,1,0x3a);
LCD_disp_char(xx+2,1,duanma[hc[wei]]);
LCD_disp_char(xx+1,1,duanma[hc[wei+1]]);
}
voidxianshi_2(ucharxx,wei)
{
LCD_disp_char(xx,2,0x3a);
LCD_disp_char(xx+2,2,duanma[hc[wei]]);
LCD_disp_char(xx+1,2,duanma[hc[wei+1]]);
}
/************键盘扫描************/
voidKeybod()
{
ucharfen,shi;//调试RTC时钟缓冲变量
fen=Fen;
shi=Shi;
sjcl(fen,2);
sjcl(shi,4);
LCD_write_command(0x01);
Delay
(1);
LCD_disp_str(0,1,"Time");
xianshi_1(4,4);
xianshi_1(7,2);
LCD_disp_str(14,1,"T");//显示调试界面
Delay(500);
while
(1)//进入调试模式,进行键盘扫描
{
if(SJ==0)//小时调试
{
shi++;
if(shi>=24)
shi=0;
sjcl(shi,4);
xianshi_1(4,4);
Delay(250);
SJ=1;
}
if(FJ==0)//分钟调试
{
fen++;
if(fen>=60)
fen=0;
sjcl(fen,2);
xianshi_1(7,2);
Delay(250);
FJ=1;
}
if(KZ==0)//调试完毕返回待机界面
{
Fen=fen;
Shi=shi;
shi=To_BCD(shi);
fen=To_BCD(fen);
Miao=0x00;
Write1302(WRITE_PROTECT,0X00);//禁止写保护
Write1302(WRITE_SECOND,Miao);
Write1302(WRITE_MINUTE,fen);
Write1302(WRITE_HOUR,shi);
Write1302(WRITE_PROTECT,0x80);//允许写保护
LCD_write_command(0x01);
Delay
(1);
LCD_disp_str(0,1,"Time");
LCD_disp_str(0,2,"clock");//第二行显示字符串
sjcl(Nshi,4);//清平之后的闹钟显示
sjcl(Nfen,2);
xianshi_2(5,4);
xianshi_2(8,2);
sjcl(Miao,0);
sjcl(Fen,2);
sjcl(Shi,4);
xianshi_1(4,4);
xianshi_1(7,2);
xianshi_1(10,0);
Delay(250);
KZ=1;
break;
}
}
}
/***************调闹钟键盘扫描函数*********/
voidKeybod_N()
{
LCD_write_command(0x01);
Delay
(1);
LCD_disp_str(0,2,"clock");//显示闹钟调试界面
sjcl(Nshi,4);
sjcl(Nfen,2);
xianshi_2(5,4);
xianshi_2(8,2);
Delay(500);
while
(1)//进入调试模式按键扫描
{
if(SJ==0)//小时调试
{
Nshi++;
if(Nshi>=24)
Nshi=0;
sjcl(Nshi,4);
xianshi_2(5,4);
Delay(250);
SJ=1;
}
if(FJ==0)//分钟调试
{
Nfen++;
if(Nfen>=60)
Nfen=0;
sjcl(Nfen,2);
xianshi_2(8,2);
Delay(250);
FJ=1;
}
if(NKZ==0)//调试完毕返回主界面
{
LCD_write_command(0x01);
Delay
(1);
LCD_disp_str(0,1,"Time");
LCD_disp_str(0,2,"clock");//第二行显示字符串
sjcl(Nshi,4);//清平之后的闹钟显示
sjcl(Nfen,2);
xianshi_2(5,4);
xianshi_2(8,2);
sjcl(Miao,0);
sjcl(Fen,2);
sjcl(Shi,4);
xianshi_1(4,4);
xianshi_1(7,2);
xianshi_1(10,0);
Delay(250);
Nfen_1=Nfen;
Nshi_1=Nshi;
NKZ=1;
break;
}
}
}
/******************RTC延时加热,停机函数*************************/
voidY_shi(ucharshijian)//改变延时闹钟变量
{
Nfen_1=Nfen_1+shijian;//定义闹钟变量
if(Nfen_1>=60)
{
Nfen_1=Nfen_1-60;//如果超过60进位
Nshi_1=Nshi_1+1;
if(Nshi_1>=24)
Nshi_1=0;
}
}
/*************主函数************/
voidmain()
{
ucharbiaozhi;
LCD_init();
LCD_disp_str(0,1,"Time");//显示字符串
LCD_disp_str(0,2,"clock");//第二行显示字符串
sjcl(Nshi,4);
sjcl(Nfen,2);
xianshi_2(5,4);
xianshi_2(8,2);
Nfen_1=Nfen;
Nshi_1=Nshi;
ZK=1;
MK=1;
while
(1)
{
if(KZ==0)
Keybod();
if(NKZ==0)
Keybod_N();
Miao=Read1302(0x81);//读时分秒
Fen=Read1302(0x83);
Shi=Read1302(0x85);
if(Fen==Nfen&&Shi==Nshi&&ZKB==1)//全功率加热
{
if(ZK==1)
Y_shi(10);//全功率加热10分钟
ZK=0;//总开关开
ZKB=0;
MK=1;//模式控制为1
MKB=1;
}
if(ZKB==0&&Fen==Nfen_1&&Shi==Nshi_1&&MKB==1&&BZW==0)//半功率熬粥
{
MK=0;
MKB=0;
Y_shi(10);//半功率熬粥10分钟
BZW=1;
}
if(ZKB==0&&Fen==Nfen_1&&Shi==Nshi_1&&BZW==1)//全功率间歇停机(保温)
{
MK=1;
MKB=1;
Y_shi(5);//停机时间
ZK=1;//总开关关
ZKB=1;
}
if(ZKB==1&&Fen==Nfen_1&&Shi==Nshi_1&&BZW==1)//全功率间歇加热(保温)
{
MK=1;
MKB=1;
Y_shi
(2);//加热时间(保温)
ZK=0;//总开关开
ZKB=0;
}
if(biaozhi!
=Miao)//判断是否走时
{
sjcl(Miao,0);
sjcl(Fen,2);
sjcl(Shi,4);
biaozhi=Miao;
xianshi_1(4,4);
xianshi_1(7,2);
xianshi_1(10,0);
}
}
}