chaqing的笔记 https://passport2.21ic.com/?92411 [收藏] [复制] [RSS]

日志

调试时钟芯片DS1302有感

已有 833 次阅读2006-5-18 17:00 |个人分类:程序集

经过几天的劳累终于可以把时间显示出来啦!真是好兴奋总结一下吧!

       由于本人手中和网上的源程序实在是太多“看上去”也挺完美,就是因为这个“看上去完美”让我花费了好长时间。来读别人的代码,程序怎么条就是不通,后来看了一位网友的文章写的是关于DS1302调试过程中应注意的事项,指出了ds1302的datasheet中的一些错误,这才使我恍然大悟,原来读数据的时间要求是非常严格的。要求在命令字之后的第一个下降沿就要读数据,否则读出的数据就是错误的,也不能说完全错误,那就必须作必要的调整。本来读数据手册时已经注意到这个问题,但就是再看别人的程序时没引起注意。害得我浪费了几天的时间。


    下次一定要注意:别人程序很可能有缺陷,能参考,但不能够完全照抄,数据手册一定要细读。时间是浪费了,但也值,这几天告诉我,自己的c语言功夫还不够,具体地说差得好远。提醒自己要努力。一定要学会应用汇编,汇编与c的相互调用。


  下面是我的原程序,写得不好,如果有哪位高手看见了一定要指教,小弟不胜感激。其中最想改的就是write()和read()函数,每个函数大概编译后都是63字节,肯定能再少,就是不用ACC而用变量移位来完成。试了几次调不通呀!


/******************************************************************/
/* 文件名:DS1302.c
/* 库  名:DS1302.h
/* 功  能:此文件中的函数可用于对DS1302的时间进行设置和读取DS1302内部的时间
/* 缺  点:此文件中的函数没有用到DS1302的所有功能,如:连续的读写操作、RAM的应用,充电部分的应用,写保护、抗干扰等
/*         但是可以根据DS1302的datasheet和此文件中的部分函数组合可以实现上述功能
/******************************************************************/


#i nclude <at89x51.h>
#define uchar unsigned char
/******************************************************************/


uchar code time_set[7]={0x15,0x30,0x13,0x04,0x12,0x07,0x05};  file://设置时间初始值数组
                     //  秒   分   时   号  月份 星期  年


uchar data timercur[7];  file://用于存放从DS1302读回的时间数据  
uchar data timerint[14]; file://用于存放将BCD码型数据转换成INT型后的数据
uchar data *pTimerInt;   file://指向存放转换后时间数据的指针
/******************************************************************/
sbit CLK=P1^0;         file://与硬件相关的连线  clk为DS1302的时钟信号线
sbit DAT=P1^1;         file://DAT为DS1302的I/O数据线
sbit RST=P1^2;         file://RST为DS1302的RST信号线


sbit ACC0=ACC^0;
sbit ACC1=ACC^1;
sbit ACC2=ACC^2;
sbit ACC3=ACC^3;
sbit ACC4=ACC^4;
sbit ACC5=ACC^5;
sbit ACC6=ACC^6;
sbit ACC7=ACC^7;
/****************************函数定义**************************************/


/******************************************************************/
/* 函数名:write(address);
/* 参  数:地址/数据字节
/* 功  能:用于向DS1302输入地址或数据信息
/******************************************************************/
void write(uchar address)
{
   ACC=address;
   CLK=0;
   DAT=ACC0;
   CLK=1;CLK=0;
   DAT=ACC1;
   CLK=1;CLK=0;
   DAT=ACC2;
   CLK=1;CLK=0;
   DAT=ACC3;
   CLK=1;CLK=0;
   DAT=ACC4;
   CLK=1;CLK=0;
   DAT=ACC5;
   CLK=1;CLK=0;
   DAT=ACC6;
   CLK=1;CLK=0;
   DAT=ACC7;
   CLK=1;
}


/******************************************************************/
/* 函数名:read();
/* 参  数:无
/* 功  能:用于从DS1302读出时间数据信息
/******************************************************************/
void read()
{
 // DAT=1;            /*注意在进行读操作之前DAT应置1*/
  CLK=0;
  ACC0=DAT;
  CLK=1;CLK=0;
  ACC1=DAT;
  CLK=1;CLK=0;
  ACC2=DAT;
  CLK=1;CLK=0;
  ACC3=DAT;
  CLK=1;CLK=0;
  ACC4=DAT;
  CLK=1;CLK=0;
  ACC5=DAT;
  CLK=1;CLK=0;
  ACC6=DAT;
  CLK=1;CLK=0;
  ACC7=DAT;
  CLK=1


  return(ACC);
}


/******************************************************************/
/* 函数名:W_Byte(address, byte);
/* 参  数:地址,数据
/* 功  能:用于向DS1302指定的地址address输入数据byte
/******************************************************************/
void W_Byte(uchar address,uchar byte)
{
  RST=0;
  CLK=0;
  RST=1;
  write(address);
  write(byte);
  RST=0;         
}
/******************************************************************/
/* 函数名:R_Byte(address);
/* 参  数:地址
/* 功  能:用于从DS1302指定地址address处读出数据,并将数据存放到ACC中
/******************************************************************/
uchar R_Byte(uchar address)
{
  RST=0;
  CLK=0;
  RST=1;
  write(address);
  DAT=1;
  read();
  RST=0;
  return(ACC);
}


/******************************************************************/
/* 函数名:timeset() ;
/* 参  数:无
/* 功  能:用于设置DS1302的时间,具体时间值存放在time_set[7]数组中
/******************************************************************/
void timeset()  
{ uchar i;
  W_Byte(0x8e,0x00);
  for(i=0;i<7;i++)
  W_Byte(0x80+i+i,time_set);
}
/******************************************************************/
/* 函数名:readtime() ;
/* 参  数:无
/* 功  能:用于读取DS1302的当前时间,具体时间值存放在timecur[7]数组中
/******************************************************************/
void readtime()
{ uchar i;
  for(i=0;i<7;i++)
  timercur=R_Byte(0x81+i+i);
}
/******************************************************************/
/* 函数名:unsigned char * bcd_int(unsigned char i)
/* 参  数:BCD型数据
/* 功  能:因为从DS1302读回的数据是BCD码,所以要将其转换为十进制整形数据
/******************************************************************/
unsigned char * bcd_int(unsigned char i)
{
   uchar j;
  
   *(pTimerInt++)=(i&0x0f);
  
  j=i>>4;
   *(pTimerInt++)= j&0x0f;
 
   return(*pTimerInt);
}


/******************************************************************/
/* 函数名:BCD_to_INT();
/* 参  数:无
/* 功  能:用于将时间BCD码转换为十进制码
/******************************************************************/
void BCD_to_INT()
{ uchar i;
  for(i=0;i<7;i++)
 bcd_int(timercur);
}


路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (1 个评论)

回复 GUILIN 2008-8-6 16:44
不错,但是我还是不明白怎么设置的时间