问题描述
- DS1302主电源断开再打开时间初始化了
-
/*时钟显示1602
独立键盘(P1口)设置时钟(K1设置时分秒星期年月日,K2加一,K3减一) */#include
#include
#define uchar unsigned char
#define uint unsigned int//DS1302控制端口定义
sbit CE=P1^6;
sbit SDA=P1^5;
sbit SCLK=P1^4;//LCD1602控制端口定义
sbit LCD_RS = P3^5;sbit LCD_RW = P3^6;
sbit LCD_EN = P3^4;
//独立按键定义
sbit K1=P1^0; //功能键
sbit K2=P1^1; //增大键
sbit K3=P1^2; //减小键
sbit K4=P1^3;bit k=0;
//屏幕初始化图标
uchar code table1[]={" 20 - - "};
uchar code table2[]={" : : "};//星期LOGO
uchar code table3[]={"MON TUE WED THU FRI SAT SUN"};//初始化 年 月 日 星期 时 分 秒
char year_h,year_l,month_h,month_l,day_h,day_l,hour_h,hour_l,min_h,min_l,sec_h,sec_l,date=1;
uchar year=1,month=1,day=1,hour=1,min=1,sec=1;uchar K1num=0;
//声明延时函数毫秒级
void delay1ms(uint ms);/*******************************************************************************************
- 以下为DS1302驱动程序 *
*******************************************************************************************/
/***********************************/
/* 延时程序 /
/**********************************/void delayus()
{
;;
;
}uchar DS1302_Read(uchar address)
{uchar i,temp=0x00; CE=0; SDA=1; SCLK=0; CE=1; for (i=0;i<8;i++) //循环8次 写入地址数据 { SCLK=0; SDA=address&0x01; //每次传输低字节 address>>=1; //右移一位 SCLK=1; } delay1ms(1); if(SDA) temp|=0x80; //每次传输低字节 SCLK=0; temp>>=1; for (i=0;i<7;i++) //循环8次 读取数据 { SCLK=0; if(SDA) temp|=0x80; //每次传输低字节 SCLK=1; temp>>=1; //右移一位 } SCLK=1; CE=0; SDA=0; return temp; //返回
}
void DS1302_Write(uchar address,uchar dat)
{uchar i; CE=0; SCLK=0; CE=1; for (i=0;i<8;i++) //循环8次 写入地址数据 { SCLK=0; _nop_(); SDA=address&0x01; //每次传输低字节 address>>=1; //右移一位 SCLK=1; _nop_(); } for (i=0;i<8;i++) //循环8次 写入数据 { SCLK=0; _nop_(); SDA=dat&0x01; //每次传输低字节 dat>>=1; //右移一位 DSCLK=1 SCLK=1; _nop_(); } CE=0; _nop_();
}
void DS1302_initW() //初始化时间设置(写)
{
DS1302_Write(0x8e,0x00); //写保护关
DS1302_Write(0x80,sec); //秒
DS1302_Write(0x82,min); //分
DS1302_Write(0x84,hour); //时
DS1302_Write(0x86,day); //日
DS1302_Write(0x88,month); //月
DS1302_Write(0x8a,date); //周
DS1302_Write(0x8c,year); //年
DS1302_Write(0x8e,0x80); //写保护开
}void DS1302_initR()
{
sec=DS1302_Read(0x81); //读秒数据
min=DS1302_Read(0x83); //读分钟数据
hour=DS1302_Read(0x85); //读小时数据
date=DS1302_Read(0x8b); //读星期数据
day=DS1302_Read(0x87); //读日数据
month=DS1302_Read(0x89); //读月数据
year=DS1302_Read(0x8d); //读年数据
}/*******************************************************************************************
- 以上为DS1302驱动程序 *
*******************************************************************************************/
/*******************************************************************************************
- 以下为LCD1602驱动显示程序 *
*******************************************************************************************/
void delay1ms(uint ms) //延时程序1ms
{
uint i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void LCD_writecom(uchar com) //写命令
{
LCD_RS=0;
LCD_RW=0;
LCD_EN=1;
delay1ms(2);
P0=com;
LCD_EN=0;
delay1ms(2);}
void LCD_writedat(uchar dat) //写数据
{
LCD_RS=1;
LCD_RW=0;
LCD_EN=1;
delay1ms(2);
P0=dat;
LCD_EN=0;
delay1ms(2);}
void init()
{
LCD_EN=0;
LCD_writecom(0x38); //工作方式设置(8位数据接口;两行显示;5*7点阵字符)
LCD_writecom(0x06); //输入方式设置(数据读写操作后AC自动加1;数据读写操作后画面不移动)
LCD_writecom(0x0C); //显示开关控制(开显示,关光标,关闪烁)
LCD_writecom(0x01); //清屏
}void display1() //初始化屏幕 格式: 20 - -
{ // : :
uchar num;
init();
LCD_writecom(0x80);
for(num=0;num<12;num++)
{
LCD_writedat(table1[num]);
delay1ms(2);}
LCD_writecom(0x80+0x40);
for(num=0;num<15;num++)
{
LCD_writedat(table2[num]);
delay1ms(2);}
}void display2(uchar date)
{
uchar num;
LCD_writecom(0x80+12);
if(date==1) //星期一
{
for(num=0;num<3;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
}
if(date==2) //星期二
{
for(num=4;num<7;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
}
if(date==3) //星期三
{
for(num=8;num<11;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
}
if(date==4) //星期四
{
for(num=12;num<15;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
} //星期五
if(date==5)
{
for(num=16;num<19;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
}
if(date==6) //星期六
{
for(num=20;num<23;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
} //星期日
if(date==7)
{
for(num=24;num<27;num++)
{
LCD_writedat(table3[num]);
delay1ms(2);}
}
}void write_sfm(uchar add,char date) //时分秒写入显示
{
char shi,ge;
shi=date/16;
ge=date%16;
LCD_writecom(0x80+0x40+add);
LCD_writedat(0x30+shi);
LCD_writedat(0x30+ge);
}void write_nyrx(uchar add,char date) //年月日星期写入显示
{
char shi,ge;
shi=date/16;
ge=date%16;
LCD_writecom(0x80+add);
LCD_writedat(0x30+shi);
LCD_writedat(0x30+ge);
}/*******************************************************************************************
- 以上为LCD1602驱动显示程序 *
*******************************************************************************************/
void display3() //时间显示程序
{
if(k==0) //时间显示停止控制标志{
DS1302_initR();
write_sfm(10,sec);
write_sfm(7,min);
write_sfm(4,hour);
write_nyrx(3,year);
write_nyrx(6,month);
write_nyrx(9,day);
display2(date);
}
}void keyscan() //键盘扫描
{
display3();
if(K1==0)
{
delay1ms(5);
if(K1==0)
{
K1num++; //K1按键计数
while(!K1);
k=1;
DS1302_Write(0x8e,0x00); //写保护关switch(K1num) { case 1:LCD_writecom(0x80+0x40+11); LCD_writecom(0x0f); k=1; //时间暂停显示 break; case 2:LCD_writecom(0x80+0x40+8); break; case 3:LCD_writecom(0x80+0x40+5); break; case 4:LCD_writecom(0x80+14); break; case 5:LCD_writecom(0x80+10); break; case 6:LCD_writecom(0x80+7); break; case 7:LCD_writecom(0x80+4); break; case 8:LCD_writecom(0x0c); K1num=0; //K1按键计数清零 k=0; //时间继续走 write_sfm(10,sec); write_sfm(7,min); write_sfm(4,hour); write_nyrx(3,year); write_nyrx(6,month); write_nyrx(9,day); display2(date); DS1302_initW(); //将设置的时间日期等写入DS1302中 DS1302_Write(0x8e,0x80); //写保护开 break; } } } if(K1num!=0) //如果K1按下进行以下操作 { if(K2==0) //K1按下进行K2按键检测 { delay1ms(5); if(K2==0) { while(!K2); switch(K1num) { //秒++ case 1: DS1302_initW(); sec_h=sec/16; sec_l=sec%16; sec_l++; if(sec_l==10) { sec_l=0; sec_h++; } if(sec_h==6) sec_h=0; sec=sec_h*16+sec_l; write_sfm(10,sec); LCD_writecom(0x80+0x40+11); break; case 2: min_h=min/16; //分++ min_l=min%16; min_l++; if(min_l==10) { min_l=0; min_h++; } if(min_h==6) min_h=0; min=min_h*16+min_l; write_sfm(7,min); LCD_writecom(0x80+0x40+8); break; case 3: hour_h=hour/16; hour_l=hour%16; //时++ if(hour_h==2) { if(hour_l>3) { hour_h=0; hour_l=0; } } hour_l++; if(hour_l==10) { hour_l=0; hour_h++; } if((hour_h==2)&&(hour_l>3)) { hour_h=0; hour_l=0; } hour=hour_h*16+hour_l; write_sfm(4,hour); LCD_writecom(0x80+0x40+5); break; case 4: date++; if(date==8) date=1; display2(date); LCD_writecom(0x80+14); break; case 5: day_h=day/16; day_l=day%16; if(day_h==3) { if(day_l>1) { day_h=0; day_l=1; } } day_l++; if(day_l==10) { day_l=0; day_h++; } if((day_h==3)&&(day_l>1)) { day_h=0; day_l=1; } day=day_h*16+day_l; write_nyrx(9,day); LCD_writecom(0x80+10); break; case 6: month_h=month/16; //月++ month_l=month%16; if(month_h==1) { if(month_l>2) { month_h=0; month_l=1; } } month_l++; if(month_l==10) { month_l=0; month_h++; } if((month_h==1)&&(month_l>2)) { month_h=0; month_l=1; } month=month_h*16+month_l; write_nyrx(6,month); LCD_writecom(0x80+7); break; case 7: year_h=year/16; year_l=year%16; year_l++; if(year_l==10) { year_l=0; year_h++; } if(year_h==6) year_h=0; year=year_h*16+year_l; write_nyrx(3,year); LCD_writecom(0x80+4); break; case 8: LCD_writecom(0x0c); K1num=0; k=0; display2(date); display3(); DS1302_Write(0x8e,0x80); //写保护开 break; } } } if(K3==0) //K1按下进行K3按键检测 { delay1ms(5); if(K3==0) { while(!K3); switch(K1num) { case 1: sec_h=sec/16; sec_l=sec%16; sec_l--; if(sec_l==-1) { sec_l=9; sec_h--; } if(sec_h==-1) sec_h=5; sec=sec_h*16+sec_l; write_sfm(10,sec); LCD_writecom(0x80+0x40+11); break; case 2: min_h=min/16; min_l=min%16; min_l--; if(min_l==-1) { min_l=9; min_h--; } if(min_h==-1) min_h=5; min=min_h*16+min_l; write_sfm(7,min); LCD_writecom(0x80+0x40+8); break; case 3: hour_h=hour/16; hour_l=hour%16; hour_l--; if(hour_l==-1) { hour_l=9; hour_h--; } if(hour_h==-1) { hour_h=2; hour_l=3; } hour=hour_h*16+hour_l; write_sfm(4,hour); LCD_writecom(0x80+0x40+5); break; case 4: date--; if(date==0) date=7; display2(date); LCD_writecom(0x80+14); break; case 5: day_l--; if(day_l==-1) { day_l=9; day_h--; } if(day_h==-1) { day_h=3; day_l=1; } if((day_h==0)&&(day_l==0)) { day_h=3; day_l=1; } day=day_h*16+day_l; write_nyrx(9,day); LCD_writecom(0x80+10); break; case 6: month_l--; if(month_l==-1) { month_l=9; month_h--; } if(month_h==-1) { month_h=1; month_l=2; } if((month_h==0)&&(month_l==0)) { month_h=1; month_l=2; } month=month_h*16+month_l; write_nyrx(6,month); LCD_writecom(0x80+7); break; case 7: year_h=year/16; year_l=year%16; year_l--; if(year_l==-1) { year_l=9; year_h--; } if(year_h==-1) year_h=5; year=year_h*16+year_l; write_nyrx(3,year); LCD_writecom(0x80+4); break; case 8: LCD_writecom(0x0c); K1num=0; k=0; DS1302_initW(); display2(date); display3(); DS1302_Write(0x8e,0x80); //写保护开 break; } } } }
}
void main()
{
display1(); //初始化屏幕显示
DS1302_initW(); //初始化时间日期
DS1302_initR(); //读取时间日期
while(1)
{keyscan(); }
}
- 以下为DS1302驱动程序 *