2 xuliumeng xuliumeng 于 2014.11.14 20:18 提问

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();
}                                

}

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!