搜索
bottom↓
回复: 2

DS1302调时后写不进去呀,12864的屏,列出代码,高的来帮帮忙啊

[复制链接]

出0入0汤圆

发表于 2011-4-24 03:23:46 | 显示全部楼层 |阅读模式
/************************************************************************************************
屏是12864的;DS1302的时钟。时钟能正常走,关键在于我修改了时间了,重写的时钟数据,读不进去啊!
如果不用KEY,或者在KEY里面将重写数据那全改成变量竟能读进去,所以读应该没有问题吧。。。。
昨天晚上通宵思考,今天晚上又思考,好打击信心啊,在此请求各路高手帮帮小生。的确没有办法了,才在此求救!!
程序有点乱,麻烦各位耐心看看。希望指出问题!!!!我暂时删了调日期的代码,勉得更乱

************************************************************************************************/

程序能正常运行,按键能显示加减后的数,但退出修改时间后,却不能显示补修改后的数,也就是说当你在进入KEY的时候,时钟内部跟本没有停,依然在走,当退出KEY时,显示DS1302一直在走的数!!!我试着把主函数中的if全部注释后,下进去,依然在走!!!这也就是说我跟本无法控制时间。怎么的?难不成要中断,可是我不知道这个中断如果加在这个程序里面。。。。。我好困啊,二个晚上没有睡了。高手们,帮帮我吧!!!!!网上的程序看了很多,可是我的问题依然无法解决!!!


#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define lcd P0   

sbit rs=P2^0;
sbit rw=P2^1;
sbit e=P2^2;

sbit sck=P1^0;
sbit io=P1^1;
sbit rst=P1^2;

sbit key1=P3^1;
sbit key2=P3^2;
sbit key3=P3^3;

uchar code table[]={
"2010年04月19日MO"
"  00时00分00秒  "
};

char sec,min,hour,date,mon,day,year;
uchar s1num,s2num;
uchar flag1,flag2;

void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

/*******************************************************
        1 2 8 6 4
*******************************************************/

void write_com(uchar com)//写指令
{
        rs=0;
        rw=0;
        e=1;
        lcd=com;
        delay(5);
        e=0;
}

void write_date(uchar dat)//写数据
{
        rs=1;
        rw=0;
        e=1;
        lcd=dat;
        delay(5);
        e=0;
}

void init_lcd1(uchar code *chn)//首屏显示
{
        uchar i,j;
        write_com(0x30);
        write_com(0x30);
        for(i=0;i<2;i++)
        {
                for(j=0;j<16;j++)
                {
                        write_date(chn[i*16+j]);
                }
        }
}

void write_xq(uchar day1)//星期-将数字转换成字母
{
        write_com(0x80+7);
        if(day1==1)
        {
                write_date(0x4d);
                write_date(0x4f);
        }
        if(day1==2)
        {
                write_date(0x54);
                write_date(0x55);
        }
        if(day1==3)
        {
                write_date(0x57);
                write_date(0x45);
        }
        if(day1==4)
        {
                write_date(0x54);
                write_date(0x48);
        }
        if(day1==5)
        {
                write_date(0x46);
                write_date(0x52);
        }
        if(day1==6)
        {
                write_date(0x53);
                write_date(0x41);
        }
        if(day1==7)
        {
                write_date(0x53);               
                write_date(0x55);                               
        }       
}

void clrram()//清屏
{
        write_com(0x30);
        write_com(0x01);
}

void init_lcd()//初始化LCD并显首屏
{
        e=0;
        write_com(0x30);
        write_com(0x30);
        write_com(0x0c);
        write_com(0x01);
        write_com(0x06);
        init_lcd1(table);
}


/*******************************************************
                DS 1302
*******************************************************/

void write_byte(uchar dat)//写一个字节
{
        uchar i;
        for(i=0;i<8;i++)
        {
                io=dat&0x01;
                sck=0;
                sck=1;
                dat>>=1;
        }
}
uchar read_byte()//读一个字节
{
        uchar i;
        uchar temp=0x00;
        for(i=0;i<8;i++)
        {
                if(io)
                temp=temp|0x80;
                sck=1;
                sck=0;
                temp>>=1;
        }
        return(temp);
}

void write_ds1302(uchar add,uchar dat)//写
{
        rst=0;
        sck=0;
        rst=1;
        write_byte(add);
        write_byte(dat);
        sck=1;
        rst=0;
}

uchar read_ds1302(uchar add)//读
{
        uchar inf;
        rst=0;
        sck=0;
        rst=1;
        write_byte(add);
        inf=read_byte();
        sck=1;
        rst=0;

        return(inf);
}
void protect_ds1302(bit flags)//写保护  1为关,0为开
{
        if(flags)
                write_ds1302(0x8e,0x00);
        else
                write_ds1302(0x8e,0x80);
}

void init_ds1302(uchar sec,uchar min,uchar hour,uchar date,uchar mon,uchar day,uchar year)//初始化及十进制转BCD
{
        protect_ds1302(1);
        write_ds1302(0x80,((sec/10)<<4|(sec%10)));
        write_ds1302(0x82,((min/10)<<4|(min%10)));
        write_ds1302(0x84,((hour/10)<<4|(hour%10)));
        write_ds1302(0x86,((date/10)<<4|(date%10)));
        write_ds1302(0x88,((mon/10)<<4|(mon%10)));
        write_ds1302(0x8a,((day/10)<<4|(day%10)));
        write_ds1302(0x8c,((year/10)<<4|(year%10)));
        protect_ds1302(0);       
}

uchar bcd_shi(uchar dat)//BCD转十进制
{
        uchar temp;
        temp=((dat>>4)&0x0f)*10+(dat&0x0f);
        return(temp);
}

void ds1302_read()//读出DS1302数据
{
        sec=bcd_shi(read_ds1302(0x81));
        min=bcd_shi(read_ds1302(0x83));
        hour=bcd_shi(read_ds1302(0x85));
        date=bcd_shi(read_ds1302(0x87));
        mon=bcd_shi(read_ds1302(0x89));
        day=bcd_shi(read_ds1302(0x8b));
        year=bcd_shi(read_ds1302(0x8d));
}

void write_sfm(uchar add,uchar dat)//将时分秒写入LCD
{
        uchar shi,ge;
        shi=dat/10;
        ge=dat%10;
        write_com(0x88+add);
        write_date(0x30+shi);
        write_date(0x30+ge);
}

void write_disp()//给地址,显示在LCD上
{
        write_sfm(5,sec);
        write_sfm(3,min);
        write_sfm(1,hour);
        write_nyr(5,date);
        write_nyr(3,mon);
        write_xq(day);
        write_nyr(1,year);
}


////////////////////////////////////////////////////////////
/*****************************************************************************************************************************************
按键调时,当key1按下时,s1num++, 1为秒地址,2为分,3为时,4为退出并令flag1=0允许退出后进行主函数中的if语句!问题就出在这儿,往下看!
****************************************************************************************************************************************/
void key_time1()   
{
        if(key1==0)
        {

                delay(5);
                if(key1==0)
                {
                        s1num++;
                        flag1=1;
//进行调时前,先把LCD现显的数读出来,不然按下时会乱跳数字,这个问题我想了好久才解决了
                        sec=bcd_shi(read_ds1302(0x81));
                        min=bcd_shi(read_ds1302(0x83));
                        hour=bcd_shi(read_ds1302(0x85));
                        date=bcd_shi(read_ds1302(0x87));
                        mon=bcd_shi(read_ds1302(0x89));
                        day=bcd_shi(read_ds1302(0x8b));
                        year=bcd_shi(read_ds1302(0x8d));
                        while(!key1);
                        if(s1num==1)
                        {
                                write_com(0x88+5);
                                write_com(0x0f);
                        }
                        if(s1num==2)
                        {
                                write_com(0x88+3);
                        }
                        if(s1num==3)
                        {
                                write_com(0x88+1);
                        }
                       
                        if(s1num==4)
                        {
                                s1num=0;
                                write_com(0x0c);
                                flag1=0;        //s1num为4时退出keyscan,下次循环将进入主函数if语句,
                                sck=0;
                                rst=0;
                                rst=1;

/*********************************问题就在这儿,下面这五行代码!!!当按键退出时,我要把我修改后的数重新读给DS1302,可是为什么不成功呢??
当我把括号中的变量名换成数字的时候,却能成功显示,怎么的?是不认别sec..吗?还是不允许读,或者是这样读不进去???
                                write_ds1302(0x8e,0x00);
                                write_ds1302(0x80,((sec/10)<<4|(sec%10)));
                                write_ds1302(0x82,((min/10)<<4|(min%10)));
                                write_ds1302(0x84,((hour/10)<<4|(hour%10)));       
                                write_ds1302(0x8e,0x80);
                        }

                }
        }
}

void key_time2()//加
{
        if(key2==0)
        {
                delay(5);
                if(key2==0)
                {
                        while(!key2);
                        if(s1num==1)
                        {
                                sec++;
                                if(sec==60)
                                {
                                        sec=0;
                                }
                                write_sfm(5,sec);
                                write_com(0x88+5);//光标置位
                        //        write_sfm(5,miao);

                        }
                        if(s1num==2)
                        {
                                min++;
                                if(min==60)
                                {
                                        min=0;
                                }
                                write_sfm(3,min);
                                write_com(0x88+3);
                        }
                        if(s1num==3)
                        {
                                hour++;
                                if(hour==24)
                                {
                                        hour=0;
                                }
                                write_sfm(1,hour);
                                write_com(0x88+1);
                        }
                }
        }
}

void key_time3()//减
{
        if(key3==0)
        {
                delay(5);
                if(key3==0)
                {
                        while(!key3);
                        if(s1num==1)
                        {
                                        sec--;
                                        if(sec==-1)
                                        {
                                                sec=59;
                                        }
                                        write_sfm(5,sec);
                                        write_com(0x88+5);                                               
                        }

                        if(s1num==2)
                        {
                                min--;
                                if(min==-1)
                                {
                                        min=59;
                                }
                                write_sfm(3,min);
                                write_com(0x88+3);
                        }

                        if(s1num==3)
                        {
                                hour--;
                                if(hour==-1)
                                {
                                        hour=23;
                                }
                                write_sfm(1,hour);
                                write_com(0x88+1);
                        }
                }
        }                       
}

void keyscan()
{
        key_time1();       
       
        if(s1num!=0)
        {
                key_time2();
                key_time3();       
        }
}
////////////////////////////////////////////////////////////////////////////


void main()
{
        clrram();
        init_lcd();
        delay(5);
//        init_ds1302(27,7,7,23,4,6,11);//复位后重显初始化,所以注释了这行
//        delay(5);
        while(1)
        {
                keyscan();
                if(flag1==0)
                {
                        ds1302_read();
                        write_disp();                       
                }
        }
}

程序能正常运行,按键能显示加减后的数,但退出修改时间后,却不能显示补修改后的数,也就是说当你在进入KEY的时候,时钟内部跟本没有停,依然在走,当退出KEY时,显示DS1302一直在走的数!!!我试着把主函数中的if全部注释后,下进去,依然在走!!!这也就是说我跟本无法控制时间。怎么的?难不成要中断,可是我不知道这个中断如果加在这个程序里面。。。。。我好困啊,二个晚上没有睡了。高手们,帮帮我吧!!!!!

出0入0汤圆

 楼主| 发表于 2011-4-24 03:28:05 | 显示全部楼层
程序我没有整理,用的是最笨的方法。昨晚半夜的时候好像成功解决了问题,可是我在整理的时候又成了这样了,今天重写的,把程序发出来,希望大家指出问题的所在!!!!

程序是否不稳定??在按键的时候,有时按一下跑秒那儿,有时按一下跑时那儿!或者调整时间时,按几下才动,是程序的问题还是按键的问题啊???按键防抖我真不明白是个什么意思,好像跟本没有用。当手在按下时,稍微的一动数字一样在变,感觉防抖没有用啊。

我在线等,等到天亮,等到天黑,不解决此问题,誓不就寝!!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 19:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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