51单片机实时时钟 PCF8563时钟芯片

实现实时时钟,电源拔插时间不重置(内置电池供电维持时间变化)。功能有查看日期,查看星期,查看闹钟和分别的调整时间,调整日期,调整闹钟,调整星期。且默认情况下不可以调整,当按下可调控键之后才可以调整、再次按可调控键关闭变为不可调整状态。还有整点报时功能(有个小瑕疵就是闹钟正好是整点的时候和这个整点报时同时间的时候不会报时和闹钟,这个很容易改好,因为下午3点要答辩了,懒得改了机子老是写不进去,学校穷便宜机子没办法)。然后这个闹钟可以设置星期几几点闹也可以设置为普通的每天的这个时间点闹铃,这些都是可以调控的。时钟所有的功能都有,只差一个秒表,,这个很简单,,,外部中断来一个或者定时器T1中断来一个都可以,我没弄,因为我这个已经代码很长了,头疼、加中断还得加显示函数和秒表变化函数if分大于60 时++啥的,但因为这个采用的显示是低四位高四位控制的,我强行加一个也比较麻烦所有就没加了。欢迎下载干货,难看懂的都有备注,写了断断续续一周+时间左右(恕在下才疏学浅,因为书上上课的时候没学过I2C总线和pcf8563所以写的比较久。)部分代码如下:

#define MAIN_Fosc             22118400L     //定义主时钟  频率也是计数计时周期一秒的计数值

 

#include "STC15Fxxxx.H" 

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

#define DIS_DOT         0x20

#define DIS_BLACK      0x10

#define DIS_         0x11

/****************************** 用户定义宏***********************************/

#define   Timer0_Reload      (65536UL -(MAIN_Fosc / 1000))         //Timer 0 中断频率,1000次/秒 频率倍数计数即周期 周期为1秒 除以一千就是1000次每秒

 

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

/************* 本地常量声明       **************/

u8 code t_display[]={                                       //标准字库

       //     0   1    2    3   4    5    6   7    8    9   A    B    C   D    E    F //共阴

       0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,

              //black    -    H    J     K     L     N      o   P     U     t   G    Q    r  M    y

              0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,

              0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

      

       u8code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};             //位码 取反就是书上213面   0从低位到高位

      

      

       /************* IO口定义      **************/

       sbit  P_HC595_SER  = P4^0;     //pin 14  SER         datainput

       sbit  P_HC595_RCLK = P5^4;    //pin 12  RCLk      store(latch) clock

       sbit  P_HC595_SRCLK = P4^3;     //pin 11  SRCLK    Shift data clock

       sbit    led=P1^7;

       sbit    led1=P4^7;

       sbit    key=P3^2;

      

       /************* 本地变量声明       **************/

      

       u8  LED8[8];         //显示缓冲

       u8   display_index; //显示位索引

       bit   B_1ms;                  //1ms标志

      

       u8IO_KeyState, IO_KeyState1, IO_KeyHoldCnt; //行列键盘变量

       u8   KeyHoldCnt;  //键按下计时

       u8   KeyCode;       //给用户使用的键码, 1~16有效

       u8   cnt50ms;

       u8hello;

       u8nao;

       u8minute2;

       u8KeyCode0;

      

       u8   hour,hour1,minute,minute1,second,day,week,week1,month,year;  //RTC变量

       u16  msecond;

       u16msecond1;

       u8hello;

       u8naofu;

       u8zhuangtai;

       u8xunhuan;

       u8tuinao; //闹钟控制开启退出

       u8xinqinao;//星期·闹钟

      

      

       /************* 本地函数声明       **************/

       void CalculateAdcKey(u16 adc);

       void IO_KeyScan(void); //50ms call

       void WriteNbyte(u8 addr, u8 *p, u8 number);

       void ReadNbyte( u8 addr, u8 *p, u8 number);

       void DisplayRTC(void);

       void DisplayRTC1(void);

       void DisplayRTC2(void);

       void ReadRTC(void);//读取时钟

       void ReadRTC1(void);

       void ReadRTC2(void);

       void ReadRTC3(void);

       void WriteRTC(void);

       void WriteRTC1(void);

       void WriteRTC2(void);

       void WriteRTC3(void);

       void      DisplayRTC3(void);

       void      DisplayRTC4(void);

       void    DisplayRTC5(void);

      

       /****************  外部函数声明和外部变量声明*****************/

      

      

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

      

       voidmain(void)

       {

              u8   i;

             

              P0M1= 0;      P0M0 = 0;      //设置为准双向口

              P1M1= 0;      P1M0 = 0;      //设置为准双向口

              P2M1= 0;      P2M0 = 0;      //设置为准双向口

              P3M1= 0;      P3M0 = 0;      //设置为准双向口

              P4M1= 0;      P4M0 = 0;      //设置为准双向口

              P5M1= 0;      P5M0 = 0;      //设置为准双向口

              P6M1= 0;      P6M0 = 0;      //设置为准双向口

              P7M1= 0;      P7M0 = 0;      //设置为准双向口

             

              display_index= 0;              

              AUXR= 0x80;//T0时钟无分频

              TMOD=0x00; //Timer0 set as 1T, 16 bits timer auto-reload,T0时钟无分频,16位自动重装

              TH0= (u8)(Timer0_Reload / 256);      //定时器取其高低8位为状态值

              TL0= (u8)(Timer0_Reload % 256);

              ET0= 1;  //Timer0 interrupt enable  T0中断允许

              TR0= 1;  //Tiner0 run   T0启动

              EA= 1;          //打开总中断 ,总中断允许

              hello=0;

              if(nao==1){}//断电重置

              elseif(nao==2){}

              else

              {

              nao=0;

              }

              for(i=0;i<8; i++)   LED8[i] = 0x10;      //上电消隐     dp高位 防止极短时间内出现两个数字的重叠

             

             

              ReadRTC();//读取时钟

              ReadRTC1();

              F0= 0;

              if(second>= 60)   F0 = 1;    //错误

              if(minute>= 60)    F0 = 1;    //错误

              if(hour   >= 24)   F0= 1;    //错误

              if(F0==1) //有错误, 默认12:00:00

              {

                     second= 0;

                     minute= 0;

                     hour  = 12;

                     WriteRTC();

              }

              if(day>=32)    F0=2;

              if(week>=8)   F0=2;

              if(month>=13)F0=2;

              if(year>=100)F0=2;

              if(F0==2) //有错误, 默认12:00:00

              {

                     day=6;

                     week=3;

                     month=6;

                     year=18;

                     WriteRTC1();

              }

              if(minute1>= 60)  F0 = 3;    //错误

              if(hour1   >= 24) F0= 3;    //错误

              if(F0==3)

              {

                     minute1=30;

                     hour1=7;

                     WriteRTC2();

              }

              if(week1>=8)

              {

                     WriteRTC3();

              }

              DisplayRTC();

              KeyHoldCnt= 0;    //键按下计时

              KeyCode= 0; //给用户使用的键码,1~16有效

             

              IO_KeyState= 0;

              IO_KeyState1= 0;

              IO_KeyHoldCnt= 0;

              cnt50ms= 0;

              zhuangtai=0;

              KeyCode0=0;

              tuinao=0;

              minute2=61;

              naofu=0;//控制闹钟加1加5与分钟同步

              xunhuan=0;//控制循环闹钟

              xinqinao=0;//星期闹钟控制

              if(msecond1==0){}

              else

              {

              msecond1=0;

              }

              while(1)

              {

                            if(B_1ms) //1ms到

                            {

                                   B_1ms= 0;

                                   if(++msecond>= 500) //1秒到 刷新时钟

                                   {

                                          if(hello==0)

                                          {

                                                 ReadRTC();

                                                 DisplayRTC();

                                                 if(minute==0)  //整点报时

                                                        {

                                                               if(hour==hour1)

                                                               {

                                                               if(minute==minute1)

                                                               {}else{

                                                               led1=0;

                                                               }

                                                               }else

                                                               {

                                                                      led1=0;

                                                               }

                                                        }

                                                        else{

                                                               led1=1;

                                                 }

                                                 if(hour==hour1)    //闹钟实现块

                                                 {                   

                                                        if(second==0)//保证和时钟分钟同步++乘其下一分钟前进行+5 +1操作

                                                        {

      

                                                               msecond1=0;

                                                               naofu=1;

                                                        }

                                                        else

                                                        {

                                                        if(naofu==1)

                                                        {

                                                               if(++msecond1>=60)

                                                               {msecond1=0;

                                                               naofu=0;

                                                               }

                                                        }

                                                        }

                                                       

                                                              

                                                        if(minute==minute1-1)//取出闹钟分钟值

                                                        {      ReadRTC2();

                                                               minute2=minute1;

                                                        }

       


你可能感兴趣的:(发烧友单片机)