×
单片机 > 单片机程序设计 > 详情

DS1302驱动程序(平年和闰年天数自动调整)

发布时间:2020-06-04 发布时间:
|

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

1.本程序能够显示年,月,日,时,分,
  秒,星期七个参数.
  2.时间和日期可调。可分别完成年,月,日,时,分,
  秒六个参数的调整。支持平年和闰年天数的自动调整。
实验名称:时钟芯片DS12C887演示程序
    
          晶振:内部  8M
 接线方法:
     1.PA0-PA2分别接DS1302的CS,TADA,SLK.

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

#include
#include
#define uchar unsigned char
#define uint unsigned int
#define ds1302_PIN             PINA&BIT(PA1) 
#define ds1302_DDR             DDRA
#define ds1302_DDR_OUT         ds1302_DDR|=BIT(PA0)|BIT(PA1)|BIT(PA2)
#define ds1302_DDR_IN          ds1302_DDR&=~(BIT(PA1)|BIT(PA2))
#define ds1302_PORT            PORTA 
#define ds1302_RST_H        ds1302_PORT|= BIT(PA0)  //片选               
#define ds1302_RST_L        ds1302_PORT&= ~BIT(PA0)                                           
#define ds1302_DAT_H        ds1302_PORT|= BIT(PA1)  //数据                            
#define ds1302_DAT_L        ds1302_PORT&= ~BIT(PA1)  
#define ds1302_CLK_H        ds1302_PORT|= BIT(PA2)  //时钟                          
#define ds1302_CLK_L        ds1302_PORT&= ~BIT(PA2) 
const char start_time[]={0x00,0x00,0x00,0x01,0x01,0x07,0x06};   //初始值;
char month_p[13]={0,31,28,31,30,31,30,31,31,30,31,30,31,};//平年
char month_y[13]={0,31,29,31,30,31,30,31,31,30,31,30,31,};//闰年
uchar second=0;
uchar minute=0;
uchar hour=0;
uchar day=1;
uchar month=1;
uchar year=6;
uchar week=7;
uchar month_max=0;//每月最大天数
/****************DS1302子程序***********************/
void ds1302_inputbyte(uchar CD)  //写入一字节数据
{
   uchar i,mid=0;
  for (i=8;i>0;i--)
  {
     mid=CD&0x01;
   if (mid==0)
   ds1302_DAT_L; 
   else
   ds1302_DAT_H ;
   ds1302_CLK_H ;
   ds1302_CLK_L ;
   CD=CD>>1;
 }
}
uchar ds1302_outputbyte(void)  //读取一字节数据
{
    uchar i,mid=0;
   for (i=8;i>0;i--)
   {
       ds1302_DDR_IN;
    mid=mid>>1;
    if ((ds1302_PIN)==0)
    mid&=~BIT(PB7);
    else
    mid|=BIT(PB7);
    ds1302_DDR_OUT;
    ds1302_CLK_H ;
    ds1302_CLK_L ;
   }
   return(mid);
}
void w1302(uchar ucAddr,uchar ucDa)   //写入数据
{
   ds1302_DDR_OUT ;
  ds1302_RST_L;
  ds1302_CLK_L;
  ds1302_RST_H;
  ds1302_inputbyte(ucAddr);
  ds1302_inputbyte(ucDa);
  ds1302_CLK_H ;
  ds1302_RST_L;
}
uchar r1302(uchar ucAddr)        //读取数据
{
    uchar ucDa;
   ds1302_DDR_OUT ;
   ds1302_RST_L;
   ds1302_CLK_L ;
   ds1302_RST_H ;
   ds1302_inputbyte(ucAddr);
   ucDa=ds1302_outputbyte();
   ds1302_CLK_H ;
   ds1302_RST_L;
   return(ucDa);
}
//设置初始时间
//格式:秒,分,时,日,月,星期,年
void set1302()
{
   uchar i;
  uchar ucaddr=0x80;
  w1302(0x8e,0x00);//写允许
  w1302(0x90,0xa6);//打开充电功能
  for (i=0;i<7;i++)
  {
     w1302(ucaddr,start_time[i]);
   ucaddr+=2;
  }
 w1302(0x8e,0x80);//写禁止
}
//读取当前时间
void get1302()
{
   uchar i=0,ucaddr=0x81;
  uchar uctimer[6];
  char sec1,day1,mon1,year1,min1,hour1;
  for (i=0;i<7;i++)
  {
     uctimer[i]=r1302(ucaddr);
   ucaddr+=2;
   }
   sec1=uctimer[0];//十进制到二进制的调整
   second=((sec1&0x70)>>4)*10+(sec1&0x0f);
   min1=uctimer[1];
   minute=((min1&0x70)>>4)*10+(min1&0x0f);
   hour1=uctimer[2];
   hour=((hour1&0x30)>>4)*10+(hour1&0x0f);
   day1=uctimer[3];
   day=((day1&0x30)>>4)*10+(day1&0x0f);
   mon1=uctimer[4];
   month=((mon1&0x10)>>4)*10+(mon1&0x0f);
   week=uctimer[5];
   year1=uctimer[6];
   year=((year1&0x70)>>4)*10+(year1&0x0f);
}
void second_set()   //调秒
{
   w1302(0x8e,0x00);
  w1302(0x80,((second/10)<<4)+(second%10));
  w1302(0x8e,0x80);
}

void minute_set()  //调分
{
   w1302(0x8e,0x00);
  w1302(0x82,((minute/10)<<4)+(minute%10));
  w1302(0x8e,0x80);
}

void hour_set()  //调时
{
   w1302(0x8e,0x00);
  w1302(0x84,((hour/10)<<4)+(hour%10));
  w1302(0x8e,0x80);
}

void year_set()  //调年
{
   year++;
  if (year>69)
  year=6;
  if (year%4==0)
  month_max=month_y[month];
  else
  month_max=month_p[month];
  if (day>month_max)
  day=month_max;
  day_set();
  w1302(0x8e,0x00);
  w1302(0x8c,((year/10)<<4)+(year%10));
  w1302(0x8e,0x80);
}

void month_set()  //调月
{
   month++;
  if (month>12)
  month=1;
  if (year%4==0)
  month_max=month_y[month];
  else
  month_max=month_p[month];
  if (day>month_max)
  day=month_max;
  day_set();
  w1302(0x8e,0x00);
  w1302(0x88,((month/10)<<4)+(month%10));
  w1302(0x8e,0x80);
}

void day_set()  //调日
{
   uchar i=0;
  uchar j=0;
  uchar month_m=0;
  uint day_n=0;
  day_n=0;
  for (i=6;i  {
     if (i   {
     if (i%4==0)
   day_n=day_n+366;
   else
   day_n=day_n+365;
    }
    if (i==year)
    {
       if (month>1)
       {
         for (j=1;j      {
          if (year%4==0)
          month_m=month_y[j];
        else
        month_m=month_p[j];
        day_n=day_n+month_m;
     }
         }
            }
      }
   if (year%4==0)
   month_max=month_y[month];
   else
   month_max=month_p[month];
   if (day>month_max)
   day=1;
   week=(day_n+day-1)%7;
   if (week==0)
   week=7;
   w1302(0x8e,0x00);
   w1302(0x86,((day/10)<<4)+(day%10));
   w1302(0x8a,week);
   w1302(0x8e,0x80);
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
TQ210天嵌开发板S5PV210 LED闪烁程序C语言代码记录