| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4162 人关注过本帖
标题:单片机电子时钟问题,求高手解答。
只看楼主 加入收藏
gtrmao
Rank: 2
等 级:论坛游民
帖 子:38
专家分:32
注 册:2011-10-24
结帖率:75%
收藏
 问题点数:0 回复次数:2 
单片机电子时钟问题,求高手解答。
小弟手上有一个单片机ds1302+lcd1602的程序。运行后发现,只要关闭电源,再打开。时钟就会自己初始化。程序如下:
#include<reg52.h>
#include<intrins.h>


#define uint unsigned int
#define uchar unsigned char

/*****************************
1602液晶显示位定义
*****************************/
#define lcd_data P0
sbit rs=P2^6;
sbit rw=P2^5;
sbit en=P2^7;


void write_1602_cmd(uint);
void write_1602_dat(uint);
void delay1ms(uint);
void lcd1602_init();

uchar nyx[16]=" 2000-00-00 000 ";
uchar sfm[13]  ="    00:00:00 ";

/******************************
ds1302的位定义
******************************/
sbit rst=P3^5;
sbit sclk=P3^6;
sbit io=P3^4;

void write_ds1302_byte(uint);
void lcd_busy_wait();
void write_ds1302(uint,uint);
uint read_ds1302(uint);
void init_time();
void read_time();

void xieshijian2(uint add,uint shu);
void xieshijian1(uint add,uint shu);
void xiexingqi(uint add,uint shu);
void time_bcd(uint x);


uint time_wadd[]={0x8c,0x88,0x86,0x8a,0x84,0x82,0x80};
uint time_radd[]={0x8d,0x89,0x87,0x8b,0x85,0x83,0x81};
uint time_init[7]={12,5,13,7,21,8,0};
uint time_shuzhi[7]={0,0,0,0,0,0,0};

uchar xingqi[7][3]={{"MON"},{"TUS"},{"WEN"},{"THU"},{"FRI"},{"STA"},{"SUN"}};

//按键定义

sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;

//标志位定义
void keyscan();
 uint gn_flag;



//程序开始

void main()
{
    uint num;
    lcd1602_init();   
    init_time();   
    write_1602_cmd(0x80);
    for(num=0;num<16;num++)
    {
        write_1602_dat(nyx[num]);
        
    }
    write_1602_cmd(0x80+0x40);
   
    for(num=0;num<13;num++)
    {
        write_1602_dat(sfm[num]);
        
    }  
    while(1)
    {
         
        keyscan();
        if(gn_flag==0)
        {        
        read_time();
        
        xieshijian2(10,time_shuzhi[6]);
        
        xieshijian2(7,time_shuzhi[5]);
        
        xieshijian2(4,time_shuzhi[4]);
        
        xiexingqi(12,time_shuzhi[3]);
        
        xieshijian1(9,time_shuzhi[2]);
   
        xieshijian1(6,time_shuzhi[1]);
   
        xieshijian1(3,time_shuzhi[0]);
        
        }
            
    }            
}


/************************
1602读写时序操作
************************/


void write_1602_cmd(uint cmd)
{
    lcd_busy_wait();
    en=0;
    rs=0;
    rw=0;
    lcd_data=cmd;
    _nop_();
    en=1;
    _nop_();
    en=0;        
}

void write_1602_dat(uint dat)
{
    lcd_busy_wait();
    en=0;
    rs=1;
    rw=0;
    lcd_data=dat;
    _nop_();
    en=1;
    _nop_();
    en=0;   
}

void lcd1602_init()
{
    write_1602_cmd(0x38);
    delay1ms(4);
    write_1602_cmd(0x0c);
    write_1602_cmd(0x06);
    write_1602_cmd(0x01);
    lcd_data=0xff;
    delay1ms(4);

}

void lcd_busy_wait()
{
    rs=0;
    rw=1;
    en=1;
    lcd_data= 0xff;
    while(lcd_data&0x80);
    en=0;
}

void delay1ms(uint x)
{
    uint i,j;
    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}


/*****************************
ds1302的时序操作
*****************************/


void write_ds1302_byte(uint date)
{
    uint i;
    for(i=0;i<8;i++)
    {
        sclk=0;
        io=date&0x01;
        date>>=1;
        sclk=1;
    }        
}


void write_ds1302(uint cmd,uint date)
{   
    rst=0;
    _nop_();
    sclk=0;
    _nop_();
    rst=1;
    _nop_();
    write_ds1302_byte(cmd);
    write_ds1302_byte(date);
    rst=0;
    _nop_();
   
    io=1;
    sclk=1;   
}

uint read_ds1302(uint add)
{
    uint shu,i;
    rst=0;
    _nop_();
    sclk=0;
    _nop_();
    rst=1;
    _nop_();
    write_ds1302_byte(add);
    for(i=0;i<8;i++)
    {
        shu>>=1;
        sclk=0;
        if(io) shu|=0x80;
        sclk=1;   
    }
    rst=0;
    _nop_();

    io=1;
    sclk=1;
    return shu;
}

void init_time()
{
    uint i,a,b;
    uchar second=read_ds1302(0x81);
    if(second&0x80)
    {
        for(i=0;i<7;i++)
        {
            a=time_init[i]/10;
            b=time_init[i]%10;
            time_init[i]=a*16+b;
        }
        write_ds1302(0x8e,0x00);
        for(i=0;i<7;i++)
        {
            write_ds1302(time_wadd[i],time_init[i]);
        
        }
        write_ds1302(0x8e,0x80);
     }            
}

void read_time()
{
    uint i;
    for(i=0;i<7;i++)
    {
        time_shuzhi[i]=read_ds1302(time_radd[i]);
    }        
}

void xieshijian2(uint add,uint shu)
{
    uint a,b;
    a=shu/16;
    b=shu%16;
    write_1602_cmd(0x80+0x40+add);
    write_1602_dat(0x30+a);
    write_1602_dat(0x30+b);
        
}

void xieshijian1(uint add,uint shu)
{
    uint a,b;
    a=shu/16;
    b=shu%16;
    write_1602_cmd(0x80+add);
    write_1602_dat(0x30+a);
    write_1602_dat(0x30+b);
}

void xiexingqi(uint add,uint shu)
{
    uint i;
    write_1602_cmd(0x80+add);
    for(i=0;i<3;i++)
    {
        write_1602_dat(xingqi[shu-1][i]);   
    }   
}



void time_bcd(uint x)
{
    uint a,b;
    a=time_shuzhi[x]/16;
    b=time_shuzhi[x]%16;
    if(b==0x0a)
    {
        a++;
        b=0;
    }
    time_shuzhi[x]=a*16+b;   
}                                












/********************************
按键设置时间
********************************/


void keyscan()
{
    uint i;
    if(key1==0)
    {
        delay1ms(5);
        if(key1==0)
        {   
            while(!key1);
            
            gn_flag++;
            if(gn_flag==8)
            {
                gn_flag=0;
                write_1602_cmd(0x0c);
                write_ds1302(0x8e,0x00);
                for(i=0;i<7;i++)
                {
                    write_ds1302(time_wadd[i],time_shuzhi[i]);

                }
                write_ds1302(0x8e,0x10);
               
            }
                 
            switch(gn_flag)
            {
                case 1 :    write_1602_cmd(0x80+0x40+11);
                            write_1602_cmd(0x0f);break;
                case 2 :    write_1602_cmd(0x80+0x40+8);break;
                case 3 :    write_1602_cmd(0x80+0x40+5);break;
                case 4 :    write_1602_cmd(0x80+14);break;
                case 5 :    write_1602_cmd(0x80+10);break;
                case 6 :    write_1602_cmd(0x80+7);break;
                case 7 :    write_1602_cmd(0x80+4);break;               
                default:    break;        
            }

        }
    }
   
   
    if(key2==0)
    {
        delay1ms(5);
        if(key2==0)
        {
            while(!key2);
            switch(gn_flag)
            {
            case 1    :    time_shuzhi[6]++;
                        time_bcd(6);
                        if(time_shuzhi[6]==0x59) time_shuzhi[6]=0    ;
                        xieshijian2(10,time_shuzhi[6]);
                        write_1602_cmd(0x80+0x40+11);
                        break;
            case 2    :    time_shuzhi[5]++;
                        time_bcd(5);
                        if(time_shuzhi[5]==0x59) time_shuzhi[5]=0    ;
                        xieshijian2(7,time_shuzhi[5]);
                        write_1602_cmd(0x80+0x40+8);
                        break;
            case 3    :    time_shuzhi[4]++;
                        time_bcd(4);
                        if(time_shuzhi[4]==0x12) time_shuzhi[4]=0    ;
                        xieshijian2(4,time_shuzhi[4]);
                        write_1602_cmd(0x80+0x40+5);
                        break;
            case 4    :    time_shuzhi[3]++;
                        time_bcd(3);
                        if(time_shuzhi[3]==0x8) time_shuzhi[3]=1    ;
                        xiexingqi(12,time_shuzhi[3]);
                        write_1602_cmd(0x80+14);
                        break;
            case 5    :    time_shuzhi[2]++;
                        time_bcd(2);
                        if(time_shuzhi[2]==0x30) time_shuzhi[2]=0    ;
                        xieshijian1(9,time_shuzhi[2]);
                        write_1602_cmd(0x80+10);
                        break;
            case 6    :    time_shuzhi[1]++;
                        time_bcd(1);
                        if(time_shuzhi[1]==0x13) time_shuzhi[1]=1    ;
                        xieshijian1(6,time_shuzhi[1]);
                        write_1602_cmd(0x80+7);
                        break;
            case 7    :    time_shuzhi[0]++;
                        time_bcd(0);
                        if(time_shuzhi[6]==0x50) time_shuzhi[6]=0    ;
                        xieshijian1(3,time_shuzhi[0]);
                        write_1602_cmd(0x80+4);
                        break;
            default :   break;
            }
        }

    }
}   

小弟不才参照这下面的程序(经运行,下面程序关闭后,时钟还在走,开机继续)进行检查,但却找不到问题所在望高手解答。最好能小弟上面的程序改下,以实现功能。万分感谢~                             
#include<reg52.h>
#include<intrins.h>
#define  uchar  unsigned char
#define uint unsigned int
#define ADDATA P0
sbit RS=P2^6;
sbit RW= P2^5;
sbit E=P2^7;
sbit Acc0=ACC^0;
sbit Acc7=ACC^7;
sbit Ds1302_clk=P3^6;
sbit Ds1302_rst=P3^5;
sbit Ds1302_DQ=P3^4;

   
   
//uchar  code time1[]={"time:"};
//uchar code data1[]={"date:"};
//uchar code week1[]={"week:"};
uchar  data timestr[8];
uchar data datestr[8];
//uchar data  weekstr[3];

void delayms(uint tt )
 {
     uint i;
     while( tt-- )
      for(i=113;i>0;i--);
  }
  //*************check busy**************//
void lcd_busy()
{
     RS= 0;
     RW = 1;
     E = 1;
     _nop_();
     _nop_();
     _nop_();
     _nop_();
     while(P0&0x80);
}
void write_date( uchar dat)//写数据
{
    lcd_busy() ;
    RS=1;
    RW=0;
    E=1;
     P0=dat;
     delayms(1);
     E=0;
     delayms(2);
}
 
  
void  write_com(uchar dat)//写指令
{
    lcd_busy();
      RS=0;
       RW=0;
       E=1;
       P0=dat;
       delayms(1);
       E=0;
       delayms(2);
}
 
void write_string(uchar *p)// 写数组,
{
       uchar i=0;
     while(*(p+i)!='\0')
     {
        write_date(*(p+i));
         i++;
     }
}


void Init_LCD()//初始化
{

    write_com(0x38); //设置几行几 6
      write_com(0x0f);//光标        4        
      write_com(0x06); //光标自动移动
      write_com(0x01);//清黑框
}


//****************** 1302 PIN defined***********//



//#define AM(X) X
//#define PM(X) (X+12)
#define Ds1302_SEC 0x81
#define Ds1302_MIN 0x82
#define Ds1302_HOUR 0x84
#define Ds1302_WEEK 0x8a
#define Ds1302_DAY 0x86
#define Ds1302_MON 0x88
#define Ds1302_YEAR 0x8c


void Ds1302InputByte(uchar d)  //* input a byte to ds1302******//
{

    uchar i;
    ACC=d;
     for (i=8;i>0;i--)
     {
        Ds1302_DQ=Acc0;
        Ds1302_clk=1;
          Ds1302_clk=0;
          ACC=ACC>>1;
     }
}

uchar Ds1302OutputByte(void)  //* output a byte to ds1302******//
    {
        uchar i;
         for(i=8;i>0;i--)
           {
        
        ACC=ACC>>1;
        Acc7=Ds1302_DQ;
        Ds1302_clk=1;
        Ds1302_clk=0;
        
        }
          return (ACC);
      }
uchar Ds1302_RD(uchar ucAddr)
{
    uchar Data;
    Ds1302_rst=0;
     Ds1302_clk=0;
     Ds1302_rst=1;
     Ds1302InputByte(ucAddr|0x01);
     Data=Ds1302OutputByte();
     Ds1302_clk=1;
     Ds1302_rst=0;
    return(Data);
 }
void Ds_1302WR(uchar ucAddr, uchar ucData)
{
    Ds1302_rst=0;
    Ds1302_clk=0;
     Ds1302_rst=1;
    Ds1302InputByte(ucAddr);
     Ds1302InputByte(ucData);
     Ds1302_clk=1;
     Ds1302_rst=0;
 }


void Init_DS1302()
{
    uchar second=Ds1302_RD(Ds1302_SEC);
      if(second&0x80)
      {   
   
        Ds_1302WR(0x8e,0x00);
           Ds_1302WR(0x8c,0x12);
           Ds_1302WR(0x88,0x05);
           Ds_1302WR(0x86,0x13);
           Ds_1302WR(0x8a,0x28);
           Ds_1302WR(0x84,0x20);
           Ds_1302WR(0x82,0x12);
           Ds_1302WR(0x80,0x10);
        Ds_1302WR(0x8e,0x80);
       }
}
  
uchar bcd_to_bin(uchar bcd)
 {  
     uchar a;
     a=bcd;
     a>>=4;
     a*=10;
     bcd&=0x0f;
     a+=bcd;
     return a;
 }



  void gettime1()   
{   
    uchar x; uchar y;
    x= Ds1302_RD(Ds1302_HOUR);
    y= bcd_to_bin(x);
   
    timestr[0]=y/10+'0';
    timestr[1]=y%10+'0';
   
    timestr[2]=':';
    x=Ds1302_RD(Ds1302_MIN);
    y=bcd_to_bin(x);
  
    timestr[3]=y/10+'0';
    timestr[4]=y%10+'0';
  
 
    timestr[5]=':';
    x=Ds1302_RD(Ds1302_SEC);
       y= bcd_to_bin(x);
  
    timestr[6]=y/10+'0';
    timestr[7]=y%10+'0';
   
 
      
    timestr[8]='\0';
}
  
   void gettime2()     
{   
    uchar x; uchar y;
    x=Ds1302_RD(Ds1302_YEAR);
    y=bcd_to_bin(x);
   
    datestr[0]=y/10+'0';
    datestr[1]=y%10+'0';
  
  
      
    datestr[2]='-';
    x=Ds1302_RD(Ds1302_MON);
    y=bcd_to_bin(x);
   
    datestr[3]=y/10+'0';
    datestr[4]=y%10+'0';
   
  

    datestr[5]='-';
    x=Ds1302_RD(Ds1302_DAY);
    y=bcd_to_bin(x);
  
    datestr[6]=y/10+'0';
    datestr[7]=y%10+'0';
   
   
    datestr[8]='\0';


   
 }
   



  

  
void Show_Time()   //我用的是12864,用1602 修改DDRAM地址即可
 {
   gettime1();
 write_com(0xc4);
 write_string( timestr);
   gettime2();
 write_com(0x84);
 write_string(datestr);
  }

 

 

void  main()
 {
    Init_LCD();
     Init_DS1302();
   //Ds_1302WR(0xbf);
   
while(1)

 {
 
         
         
             Show_Time();
         
            //Ds_1302WR(0x91,0x15);
  
  
    }
  
  
}

搜索更多相关主题的帖子: 电子 include 单片机 void 
2012-05-15 18:51
a935245228
Rank: 2
来 自:湖北武汉
等 级:论坛游民
帖 子:45
专家分:56
注 册:2012-3-12
收藏
得分:0 
太长了

2012-05-15 18:59
电子手指
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2012-5-29
收藏
得分:0 
需要下载两次的,第一次正常下载,第二次把Init_LCD();屏蔽了,就可以了
2012-05-29 20:51
快速回复:单片机电子时钟问题,求高手解答。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.049961 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved