ds1302

原文地址:ds1302 作者:面包会有的

DS1302是 DALLAS 公司推出的涓流充电时钟芯片,内含一个实时时钟/日历和31字节静态 RAM,可以通过串行接口与单片机进行通信,仅需三根 I/O线:复位(RST)、I/O数据线、串行时钟(SCLK),(补充一点小知识:一般来讲,无论是哪种同步通讯类型的串行接口,都是对时钟信号敏感的,而且一般数据写入有效是在上升沿,读出有效是在下降沿)。要想与ds1302通讯,就必须先了解它的控制字,[转载]ds1302如图所示,控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到 DS1302中;位6:如果为0,则表示存取日历时钟数据,为1表示存取 RAM 数据;位5至位1(A4~A0):指示操作单元的地址;位0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK 时钟的上升沿时,数据被写入 DS1302,数据输入从最低位(0位)开始。同样,在紧跟8位的控制字指令后的下一个 SCLK 脉冲的下降沿,读出 DS1302的数据,读出的数据也是从最低位到最高位。

程序还有些地方看不懂,就是关于写操作时CLK应该是上升沿,但此程序是下降沿,而且运行良好,改成上升沿反而不对了,很不理解,etc.

现在介绍下主要的几块程序:

void v_RTInputByte(uchar ucDa)        //输入-写操作
{
  uchar i;
  ACC=ucDa;//待写数据送给ACC
  for(i=8;i>0;i--)
 {
   if((ACC&0x01)==1)  //ACC最后1位为1
   T_IO=1;
   else T_IO=0;//if((ACC&0x01)==0)
   T_CLK=1;
   T_CLK=0;//不是上升沿写吗?
   ACC=ACC>>1;
 }
}

uchar uc_RTOutputByte(void)          //输出-读操作
{
  uchar i,ACC;
  ACC=0;//ACC清0
  for(i=0;i<8;i++)
 {
   ACC=ACC>>1;  

   if(T_IO==1)
   ACC=ACC|0x80;//ACC第1位置1
   T_CLK=1;
   T_CLK=0;  //下降沿
 }
 return(ACC);//返回ACC
}

 

void v_W1302(uchar ucAddr,uchar ucDa)     //指定地址写数据
{
 T_RST=0;
 T_CLK=0;
 T_RST=1;
 v_RTInputByte(ucAddr);  //写地址

 v_RTInputByte(ucDa);    //写数据
 T_CLK=1;
 T_RST=0;
}

 

uchar uc_R1302(uchar ucAddr)     //指定地址读数据
{
 unsigned char ucDa,k;  //BCD转换成16进制
 k=0x00;
 T_RST=0;
 T_CLK=0;
 T_RST=1;
 v_RTInputByte(ucAddr); 
 ucDa=uc_RTOutputByte();
 T_CLK=1;
 T_RST=0;

 k=ucDa/16;
 ucDa=ucDa;
 ucDa=ucDa+k*10;//16进制转化为10进制

 return(ucDa);
}

以上就是对ds1302的给定地址读写操作了,下面是显示初始值的设定和记录时间子程序

void v_Set1302()//uchar *pSecDa)    设置初始时间值
{
  uchar i,j;
  uchar ucAddr=0x80;     // 秒写地址
  v_W1302(0x8e,0x00);    // 控制命令,WP=0,写操作
  for(i=0;i<7;i++)       // 连续写入7个时间
 {
   j=ucCurtime[i];    // 代入初始时间
   v_W1302(ucAddr,j); // 秒 分 时  
   ucAddr +=2;        // 地址+2,因为都是两位数
 }
  v_W1302(0x8e,0x80);    // 控制命令,WP=1,写保护
}

 

void v_Get1302()           // 记录时间
{
  uchar i;
  uchar ucAddr=0x81;     // 秒读地址
  for (i=0;i<7;i++)      // 连续读数据
 {
   ucCurtime[i]=uc_R1302(ucAddr);//格式为: 秒 分 时 

   ucAddr +=2;
 }
}

然后是数码管显示内容和显示设置

void  t2_10()         //数码管段数字显示内容
{
 unint k;
 a[5]=temp1/10;
 a[4]=temp1;
 a[3]=temp/1000;
 k=temp00;
 a[2]=k/100;
 k=k0;
 a[1]=k/10;
 a[0]=k;
}

void display2()         //显示设置
{
 t2_10();

 wei_1(0x7f);    //秒(两位)
 duan_1(a[0]);
 wei_1(0xbf);
 duan_1(a[1]);

 

 wei_1(0xdf);   
 duan_1(10);

 

 wei_1(0xef);  
 duan_1(a[2]);
 wei_1(0xf7);
 duan_1(a[3]);

 

 wei_1(0xfb);   
 duan_1(10);

 

 wei_1(0xfd);  
 duan_1(a[4]);
 wei_1(0xfe);
 duan_1(a[5]);

 

 wei_1(0xff);  
}

然后是主程序

void main()
{
 unint i,k;
 for(i=0;i<7;i++)       //将10进制转换成16进制
 {
  k=ucCurtime[i]/10;
  ucCurtime[i]=ucCurtime[i];
  ucCurtime[i]=ucCurtime[i]+16*k;
 }
 v_Set1302();           //时间初值
 while(1)

 {

   v_Get1302();                              //记录时间
   temp1=ucCurtime[2];                       //时
   temp=ucCurtime[1]*100+ucCurtime[0];       //分+秒
   display2();                               //显示

 }
}

这个程序是比较综合的除了中断没用到,其他的基本都用到了,其实若加进去整点报时或闹铃设置就更全面了,想着以后用1602做个时钟加进去这两个功能,试试吧。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值