找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4854|回复: 5
打印 上一主题 下一主题
收起左侧

DS1302与1602显示时间正常,但用按键无法调整时间

[复制链接]
跳转到指定楼层
楼主
DS1302与1602显示时间正常,但用按键无法调整时间,好像是数据没有存入,找不到问题请教大家了下面代码是DS1302的驱动代码;

#include"sys_config.h"

u8 getTimebuf[7];//存放时间数据
u8 time[]={"  :  :  "};                                        //时间格式字符串
u8 date[]={"20  -  -  "};                                //日期格式字符串
u8 week[]={"   "};                                                //星期格式字符串
u8 weeklist[]={"SunMonTueWedThuFriSat"};        //星期字符列表


int count=0;//设定秒分时日月星期年的时候count的值分别为1235647
int alarm=0;//是否进入闹钟设置界面 123分别代表开关 分 小时的设置
int isOpen;//闹钟是否开启  默认不开启
int fen,shi;//闹钟的分钟小时
int isRing;//闹钟是否在响
u8 isInit_1302;//是否初始化时钟完毕

//sbit scl=P1^3;//时钟线
//sbit rst=P1^5;//复位线
//sbit io=P1^4;//数据口
/**********************ds1302初始化*****************************/
void init_ds1302(){
        //ds1302初始化
       
        isInit_1302=read_ds1302(0x81);        //读出时钟状态
        if(isInit_1302&0x80){                        //说明没有初始化
                write_ds1302(0x8e,0x00);        //关闭写保护  以后一直开着
                write_ds1302(0x90,0xa5);         //辅助电源充电命令 一个二极管  一个2K电阻
                write_ds1302(0x80,0x00);        //秒 CH置0 开启时钟
                write_ds1302(0x82,0x00);        //分
                write_ds1302(0x84,0x00);        //时
                write_ds1302(0x86,0x00);        //日
                write_ds1302(0x88,0x01);        //月
                write_ds1302(0x8a,0x01);        //星期
                write_ds1302(0x8c,0x17);        //年
                write_ds1302(0x8e,0x80);
        }
}
/**********************ds1302写一个字节数据*****************************/
void write_ds1302_byte(u8 temp){
        //ds1302写一个字节数据
        u8 i;
        for(i=0;i<8;i++){
                io=temp&0x01;//将数据放到IO口上
                scl=0;//scl为低时准备数据
                scl=1;//上升沿写入
                temp>>=1;
        }
}
/**********************向地址add写入数据datds1302*****************************/
void write_ds1302(u8 add,u8 dat){
        //向地址add写入数据dat
        rst=0;
        scl=0;
        rst=1;
        write_ds1302_byte(add);
        write_ds1302_byte(dat);
        scl=1;
        rst=0;
}
/**********************ds1302读数据*****************************/
u8 read_ds1302(u8 add)
        {
        //ds1302读数据
        u8 i,dat;
        rst=0;
        scl=0;
        rst=1;
        write_ds1302_byte(add);//首先写入要读的数据处的地址
        for(i=0;i<8;i++){
                if(io==1){
                        dat|=0x80;
                }
                scl=1;
                scl=0;//下降沿读取数据
                dat>>=1;
        }
        scl=1;
        rst=0;
        return dat;
}

/**********************ds1302读时间*****************************/
void read_time(u8 *s){
          u8 i;
          u8 ucAddr = 0x81;
          for (i=0;i<7;i++){
                s[i] = read_ds1302(ucAddr);//格式为: 秒 分 时 日 月 星期 年
                ucAddr += 2;
          }
}

/**********************ds1302设定时间*****************************/
void set_time(u8 *pSecDa){
        //设定时间
        u8 i;
        u8 ucAddr = 0x80;
        write_ds1302(0x8e,0x00);       
        for(i =7;i>0;i--){
                write_ds1302(ucAddr,*pSecDa); //秒 分 时 日 月 星期 年
                pSecDa++;
                ucAddr+=2;
        }
        write_ds1302(0x8e,0x80);
}
下面是按钮赋值代码,代码运行时,光标移动的按键更改值都正常,就是更新不了时间
void key_scan()
       
{
        int i;
        u8 code tips1[]="SET SUCCESS";//闹钟设置成功的提示
        u8 code tips2[]="CANCEL SUCCESS";//取消闹钟的提示
        if(key_dat==4){//检测是否按下
                delay(10);//消抖
                if(LCD_cnt)
                {//再次检测是否按下
                LCD_cnt=0;
                        while(!key_set_time);//检测是否松开
                        delay(10);//延时消抖
                        while(!key_set_time);//再次检测是否松开
                        if(alarm==0)
                        {//当没有显示闹钟界面时才显示时间设定
                                count++;       
                               
                                write_ds1302(0x80,0x80);//让时钟停止
                                if(count==8){//继续走时,说明时间已经设定好了
                                        Lcd1602_WriteCom(0x0c);//让光标消失
                                        LED1=1;
                                        set_time(getTimebuf);//写入新的时间
                                        write_ds1302(0x80,0x00);//让时钟继续
                                        count=0;BE_cnt=500;        //蜂鸣器
                                        return;
                                }
                                LED1=0;
                                switch(count){
                                        case 1:
                                                Lcd1602_WriteCom(0x80+0x40+7);//在秒的位置
                                                break;
                                        case 2:
                                                Lcd1602_WriteCom(0x80+0x40+4);//在分的位置
                                                break;
                                        case 3:
                                                Lcd1602_WriteCom(0x80+0x40+1);//在时的位置
                                                break;
                                        case 4:
                                                Lcd1602_WriteCom(0x80+14);//在星期的位置
                                                break;
                                        case 5:
                                                Lcd1602_WriteCom(0x80+10);//在日的位置
                                                break;
                                        case 6:
                                                Lcd1602_WriteCom(0x80+7);//在月的位置
                                                break;
                                        case 7:
                                                Lcd1602_WriteCom(0x80+4);//在年的位置
                                                break;
                                }
                                Lcd1602_WriteCom(0x0f);//让光标闪烁
                        }
                }
        }
        if(key_add==0){//检测是否按下
                delay(10);//消抖
  if(add_LCD)
        {//再次检测是否按下
                        add_LCD=0;
                        while(!key_add);//检测是否松开
                        delay(10);//延时消抖
                        while(!key_add);//再次检测是否松开
                        if(count!=0)
                                {
                                switch(count){
                                case 1:
                                        //在秒的位置
                                        getTimebuf[0]++;
                                        if(getTimebuf[0]==0x5a){
                                                getTimebuf[0]=0;
                                        }
                                        if(getTimebuf[0]==0x4a){
                                                getTimebuf[0]=0x50;
                                        }
                                        if(getTimebuf[0]==0x3a){
                                                getTimebuf[0]=0x40;
                                        }
                                        if(getTimebuf[0]==0x2a){
                                                getTimebuf[0]=0x30;
                                        }
                                        if(getTimebuf[0]==0x1a){
                                                getTimebuf[0]=0x20;
                                        }
                                        if(getTimebuf[0]==0x0a){
                                                getTimebuf[0]=0x10;
                                        }
                                        time[6]=(getTimebuf[0])/16+48;//格式化时间秒
                                        time[7]=(getTimebuf[0])%16+48;
                                        Lcd1602_WriteCom(0x80+0x40+6);//在秒的位置
                                        Lcd1602_Writedata(time[6]);
                                        Lcd1602_WriteCom(0x80+0x40+7);//在秒的位置
                                        Lcd1602_Writedata(time[7]);
                                        Lcd1602_WriteCom(0x80+0x40+7);//让光标在秒的位置闪烁
                                        break;
                                case 2:
                                        //在分的位置
                                        getTimebuf[1]++;
                                        if(getTimebuf[1]==0x5a){
                                                getTimebuf[1]=0;
                                        }
                                        if(getTimebuf[1]==0x4a){
                                                getTimebuf[1]=0x50;
                                        }
                                        if(getTimebuf[1]==0x3a){
                                                getTimebuf[1]=0x40;
                                        }
                                        if(getTimebuf[1]==0x2a){
                                                getTimebuf[1]=0x30;
                                        }
                                        if(getTimebuf[1]==0x1a){
                                                getTimebuf[1]=0x20;
                                        }
                                        if(getTimebuf[1]==0x0a){
                                                getTimebuf[1]=0x10;
                                        }
                                        time[3]=(getTimebuf[1])/16+48;//格式化时间分
                                        time[4]=(getTimebuf[1])%16+48;
                                        Lcd1602_WriteCom(0x80+0x40+3);//在分的位置
                                        Lcd1602_Writedata(time[3]);
                                        Lcd1602_WriteCom(0x80+0x40+4);//在分的位置
                                        Lcd1602_Writedata(time[4]);
                                        Lcd1602_WriteCom(0x80+0x40+4);//让光标在分的位置闪烁
                                        break;
                                case 3:
                                        //在时的位置
                                        getTimebuf[2]++;
                                        if(getTimebuf[2]==0x24){
                                                getTimebuf[2]=0;
                                        }
                                        if(getTimebuf[2]==0x1a){
                                                getTimebuf[2]=0x20;
                                        }
                                        if(getTimebuf[2]==0x0a){
                                                getTimebuf[2]=0x10;
                                        }
                                        time[0]=(getTimebuf[2])/16+48;//格式化时间小时
                                        time[1]=(getTimebuf[2])%16+48;
                                        Lcd1602_WriteCom(0x80+0x40+0);//在小时的位置
                                        Lcd1602_Writedata(time[0]);
                                        Lcd1602_WriteCom(0x80+0x40+1);
                                        Lcd1602_Writedata(time[1]);
                                        Lcd1602_WriteCom(0x80+0x40+1);
                                        break;
                                case 4:
                                        //在星期的位置
                                        getTimebuf[5]++;
                                        if(getTimebuf[5]==0x08){
                                                getTimebuf[5]=0x01;
                                        }
                                        if((getTimebuf[5]%10)*3==21){//轮完了  重新开始
                                                week[0]=weeklist[0];
                                                week[1]=weeklist[1];
                                                week[2]=weeklist[2];
                                        }else{
                                                week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期
                                                week[1]=weeklist[(getTimebuf[5]%10)*3+1];
                                                week[2]=weeklist[(getTimebuf[5]%10)*3+2];
                                        }
                                        Lcd1602_WriteCom(0x80+12);
                                        Lcd1602_Writedata(week[0]);
                                        Lcd1602_WriteCom(0x80+13);
                                        Lcd1602_Writedata(week[1]);
                                        Lcd1602_WriteCom(0x80+14);
                                        Lcd1602_Writedata(week[2]);
                                        Lcd1602_WriteCom(0x80+14);
                                        break;
                                case 5:
                                        //在日的位置
                                        getTimebuf[3]++;
                                        if(getTimebuf[3]==0x32){
                                                getTimebuf[3]=0x01;
                                        }
                                        if(getTimebuf[3]==0x2a){
                                                getTimebuf[3]=0x30;
                                        }
                                        if(getTimebuf[3]==0x1a){
                                                getTimebuf[3]=0x20;
                                        }
                                        if(getTimebuf[3]==0x0a){
                                                getTimebuf[3]=0x10;
                                        }
                                        date[8]=(getTimebuf[3])/16+48;
                                        date[9]=(getTimebuf[3])%16+48;
                                        Lcd1602_WriteCom(0x80+9);
                                        Lcd1602_Writedata(date[8]);
                                        Lcd1602_WriteCom(0x80+10);
                                        Lcd1602_Writedata(date[9]);
                                        Lcd1602_WriteCom(0x80+10);
                                        break;
                                case 6:
                                        //在月的位置
                                        getTimebuf[4]++;
                                        if(getTimebuf[4]==0x13){
                                                getTimebuf[4]=0x01;
                                        }
                                        if(getTimebuf[4]==0x0a){
                                                getTimebuf[4]=0x10;
                                        }
                                        date[5]=(getTimebuf[4])/16+48;
                                        date[6]=(getTimebuf[4])%16+48;
                                        Lcd1602_WriteCom(0x80+6);
                                        Lcd1602_Writedata(date[5]);
                                        Lcd1602_WriteCom(0x80+7);
                                        Lcd1602_Writedata(date[6]);
                                        Lcd1602_WriteCom(0x80+7);
                                        break;
                                case 7:
                                        //在年的位置
                                        getTimebuf[6]++;
                                        if(getTimebuf[6]==0x9a){
                                                getTimebuf[6]=0x00;
                                        }
                                        if(getTimebuf[6]==0x8a){
                                                getTimebuf[6]=0x90;
                                        }
                                        if(getTimebuf[6]==0x7a){
                                                getTimebuf[6]=0x80;
                                        }
                                        if(getTimebuf[6]==0x6a){
                                                getTimebuf[6]=0x70;
                                        }
                                        if(getTimebuf[6]==0x5a){
                                                getTimebuf[6]=0x60;
                                        }
                                        if(getTimebuf[6]==0x4a){
                                                getTimebuf[6]=0x50;
                                        }
                                        if(getTimebuf[6]==0x3a){
                                                getTimebuf[6]=0x40;
                                        }
                                        if(getTimebuf[6]==0x2a){
                                                getTimebuf[6]=0x30;
                                        }
                                        if(getTimebuf[6]==0x1a){
                                                getTimebuf[6]=0x20;
                                        }
                                        if(getTimebuf[6]==0x0a){
                                                getTimebuf[6]=0x10;
                                        }
                                        date[2]=(getTimebuf[6])/16+48;
                                        date[3]=(getTimebuf[6])%16+48;
                                        Lcd1602_WriteCom(0x80+3);
                                        Lcd1602_Writedata(date[2]);
                                        Lcd1602_WriteCom(0x80+4);
                                        Lcd1602_Writedata(date[3]);
                                        Lcd1602_WriteCom(0x80+4);
                                        break;
                                }
                        }
                       
                }
        }
        if(key_minus==0){//检测是否按下
                delay(10);//消抖
                if(minus_LCD){//再次检测是否按下
                        while(!key_minus);//检测是否松开
                        delay(10);//延时消抖
                        while(!key_minus);//再次检测是否松开
                        minus_LCD =0;
                        if(count!=0){
                                switch(count){
                                case 1:
                                        //在秒的位置
                                        getTimebuf[0]--;
                                        if(getTimebuf[0]==0xff){
                                                getTimebuf[0]=0x59;
                                        }
                                        if(getTimebuf[0]==0x4f){
                                                getTimebuf[0]=0x49;
                                        }
                                        if(getTimebuf[0]==0x3f){
                                                getTimebuf[0]=0x39;
                                        }
                                        if(getTimebuf[0]==0x2f){
                                                getTimebuf[0]=0x29;
                                        }
                                        if(getTimebuf[0]==0x1f){
                                                getTimebuf[0]=0x19;
                                        }
                                        if(getTimebuf[0]==0x0f){
                                                getTimebuf[0]=0x09;
                                        }
                                        time[6]=(getTimebuf[0])/16+48;//格式化时间秒
                                        time[7]=(getTimebuf[0])%16+48;
                                        Lcd1602_WriteCom(0x80+0x40+6);//在秒的位置
                                        Lcd1602_Writedata(time[6]);
                                        Lcd1602_WriteCom(0x80+0x40+7);//在秒的位置
                                        Lcd1602_Writedata(time[7]);
                                        Lcd1602_WriteCom(0x80+0x40+7);//让光标在秒的位置闪烁
                                        break;
                                case 2:
                                        //在分的位置
                                        getTimebuf[1]--;
                                        if(getTimebuf[1]==0xff){
                                                getTimebuf[1]=0x59;
                                        }
                                        if(getTimebuf[1]==0x4f){
                                                getTimebuf[1]=0x49;
                                        }
                                        if(getTimebuf[1]==0x3f){
                                                getTimebuf[1]=0x39;
                                        }
                                        if(getTimebuf[1]==0x2f){
                                                getTimebuf[1]=0x29;
                                        }
                                        if(getTimebuf[1]==0x1f){
                                                getTimebuf[1]=0x19;
                                        }
                                        if(getTimebuf[1]==0x0f){
                                                getTimebuf[1]=0x09;
                                        }
                                        time[3]=(getTimebuf[1])/16+48;//格式化时间分
                                        time[4]=(getTimebuf[1])%16+48;
                                        Lcd1602_WriteCom(0x80+0x40+3);//在分的位置
                                        Lcd1602_Writedata(time[3]);
                                        Lcd1602_WriteCom(0x80+0x40+4);//在分的位置
                                        Lcd1602_Writedata(time[4]);
                                        Lcd1602_WriteCom(0x80+0x40+4);//让光标在分的位置闪烁
                                        break;
                                case 3:
                                        //在时的位置
                                        getTimebuf[2]--;
                                        if(getTimebuf[2]==0xff){
                                                getTimebuf[2]=0x23;
                                        }
                                        if(getTimebuf[2]==0x1f){
                                                getTimebuf[2]=0x19;
                                        }
                                        if(getTimebuf[2]==0x0f){
                                                getTimebuf[2]=0x09;
                                        }
                                        time[0]=(getTimebuf[2])/16+48;//格式化时间小时
                                        time[1]=(getTimebuf[2])%16+48;
                                        Lcd1602_WriteCom(0x80+0x40+0);//在小时的位置
                                        Lcd1602_Writedata(time[0]);
                                        Lcd1602_WriteCom(0x80+0x40+1);
                                        Lcd1602_Writedata(time[1]);
                                        Lcd1602_WriteCom(0x80+0x40+1);
                                        break;
                                case 4:
                                        //在星期的位置
                                        getTimebuf[5]--;
                                        if(getTimebuf[5]==0){
                                                getTimebuf[5]=0x07;
                                        }
                                        if((getTimebuf[5]%10)*3==21){//轮完了  重新开始
                                                week[0]=weeklist[0];
                                                week[1]=weeklist[1];
                                                week[2]=weeklist[2];
                                        }else{
                                                week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期
                                                week[1]=weeklist[(getTimebuf[5]%10)*3+1];
                                                week[2]=weeklist[(getTimebuf[5]%10)*3+2];
                                        }
                                        Lcd1602_WriteCom(0x80+12);
                                        Lcd1602_Writedata(week[0]);
                                        Lcd1602_WriteCom(0x80+13);
                                        Lcd1602_Writedata(week[1]);
                                        Lcd1602_WriteCom(0x80+14);
                                        Lcd1602_Writedata(week[2]);
                                        Lcd1602_WriteCom(0x80+14);
                                        break;
                                case 5:
                                        //在日的位置
                                        getTimebuf[3]--;
                                        if(getTimebuf[3]==0){
                                                getTimebuf[3]=0x31;
                                        }
                                        if(getTimebuf[3]==0x2f){
                                                getTimebuf[3]=0x29;
                                        }
                                        if(getTimebuf[3]==0x1f){
                                                getTimebuf[3]=0x19;
                                        }
                                        if(getTimebuf[3]==0x0f){
                                                getTimebuf[3]=0x09;
                                        }
                                        date[8]=(getTimebuf[3])/16+48;
                                        date[9]=(getTimebuf[3])%16+48;
                                        Lcd1602_WriteCom(0x80+9);
                                        Lcd1602_Writedata(date[8]);
                                        Lcd1602_WriteCom(0x80+10);
                                        Lcd1602_Writedata(date[9]);
                                        Lcd1602_WriteCom(0x80+10);
                                        break;
                                case 6:
                                        //在月的位置
                                        getTimebuf[4]--;
                                        if(getTimebuf[4]==0){
                                                getTimebuf[4]=0x12;
                                        }
                                        if(getTimebuf[4]==0x0f){
                                                getTimebuf[4]=0x09;
                                        }
                                        date[5]=(getTimebuf[4])/16+48;
                                        date[6]=(getTimebuf[4])%16+48;
                                        Lcd1602_WriteCom(0x80+6);
                                        Lcd1602_Writedata(date[5]);
                                        Lcd1602_WriteCom(0x80+7);
                                        Lcd1602_Writedata(date[6]);
                                        Lcd1602_WriteCom(0x80+7);
                                        break;
                                case 7:
                                        //在年的位置
                                        getTimebuf[6]--;
                                        if(getTimebuf[6]==0xff){
                                                getTimebuf[6]=0x99;
                                        }
                                        if(getTimebuf[6]==0x8f){
                                                getTimebuf[6]=0x89;
                                        }
                                        if(getTimebuf[6]==0x7f){
                                                getTimebuf[6]=0x79;
                                        }
                                        if(getTimebuf[6]==0x6f){
                                                getTimebuf[6]=0x69;
                                        }
                                        if(getTimebuf[6]==0x5f){
                                                getTimebuf[6]=0x59;
                                        }
                                        if(getTimebuf[6]==0x4f){
                                                getTimebuf[6]=0x49;
                                        }
                                        if(getTimebuf[6]==0x3f){
                                                getTimebuf[6]=0x39;
                                        }
                                        if(getTimebuf[6]==0x2f){
                                                getTimebuf[6]=0x29;
                                        }
                                        if(getTimebuf[6]==0x1f){
                                                getTimebuf[6]=0x19;
                                        }
                                        if(getTimebuf[6]==0x0f){
                                                getTimebuf[6]=0x09;
                                        }
                                        date[2]=(getTimebuf[6])/16+48;
                                        date[3]=(getTimebuf[6])%16+48;
                                        Lcd1602_WriteCom(0x80+3);
                                        Lcd1602_Writedata(date[2]);
                                        Lcd1602_WriteCom(0x80+4);
                                        Lcd1602_Writedata(date[3]);
                                        Lcd1602_WriteCom(0x80+4);
                                        break;
                                }
                        }
                       
                }
        }
       
}





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:82765 发表于 2017-6-22 21:46 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

板凳
ID:164602 发表于 2017-6-23 08:24 | 只看该作者
我有这样的程序,是例程。你可以借鉴一下。
不过,这个例程也是有问题的:设置的时间、日期十分的不完善,如:可以设置0月0日,2月可以有30、31日,6月可以有31日等等,不过这些是可以自己修改的。它只是个例程,抛砖引玉而已。
你说的按键没反应,是绝对可以借鉴一下的。你的程序太长,没时间看啊。

DS1302显示时钟(可以按键设置时钟).rar

50.65 KB, 下载次数: 87

回复

使用道具 举报

地板
ID:111634 发表于 2017-6-23 17:26 | 只看该作者
本帖最后由 zl2168 于 2017-6-23 20:51 编辑

实例91  具有校正功能的时钟1302(LCD1602显示)
Proteus仿真,确认有效。
实例91 带校正时钟1302(LCD1602显示).rar (52.68 KB, 下载次数: 72)

以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1书中电路和程序设计有详细说明,程序语句条条有注解。仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。
回复

使用道具 举报

5#
ID:33544 发表于 2017-6-24 15:37 | 只看该作者
补充说明一下,单片机用的是stc12c5a60s2,程序用仿真软件运行都很正常,硬件部分DS1302的三个脚上都加上了1K的上拉电阻,程序上电第一次初始化能写进数据,上电后无法重复修改,程度逻辑在仿真软件上运行都正常,仿真时重复写入数据也正常
回复

使用道具 举报

6#
ID:292218 发表于 2018-3-15 11:39 | 只看该作者
wis98 发表于 2017-6-24 15:37
补充说明一下,单片机用的是stc12c5a60s2,程序用仿真软件运行都很正常,硬件部分DS1302的三个脚上都加上了 ...

我也属上电初始化可以更改,可是在循环里检测串口通过串口就不能更改
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表