在网上淘了一个PIC18F85K90自带RTCC功能的单片机,写了一段测试一下RTCC的精度,运作了5天,还好_精度达到了误差毫秒级.
随手加了一个AHT15温湿度
注:32.768(5ppm)晶振需要加两个30pF电容稳定震荡频率, 每30分钟与60分钟进位时秒显示。

制作出来的实物图如下:
1.jpg

2.jpg

3.jpg

单片机源程序如下:
#include "Delay.h"
  • #include "RTCC.H"
  • #include "Selection.h"
  • RTC   _RTCVALH; //定义_共同体变量1
  • RTC   _RTCVALL; //定义_共同体变量2
  • void check_Data()  //校准_【每秒钟调整一次将其加到 RTCC 定时器中】
  •         {
  •                 //如2小时快1秒的话则为 1/(2小时*3600秒)= 1s / 7200 = 0.1389ms
  •                 //也就是说明每秒快了0.139MS,由此可推算出真正的【XI】晶振频率为:1.3472=XI/32768
  •                 //XI=1.0001389*32768 =  32772.55HZ     32772.55-32768 = 4.55即晶振频率为每秒钟多了约5个脉冲
  •                 //4.55*60= 每秒分钟多了 273个脉冲   273 / 4 =  68.25 取 69 【可以认为每秒分钟减去69个脉冲】即69*4 = 276
  •                 //- 69 = 0XBB;
  •                 if (_RTCVALL.SECOND == 0 )//每秒钟调整一次 !HALFSEC
  •                              RTCCAL         =  RTCCAL_Temp ;   //时钟校准寄存器;    //RTCC 校准寄存器   0x88【-120】; -120X4=-480 即在 RTCCAL“每分钟减少480”个时钟脉冲
  • }               
  •          
  • void RTCC_WD_Init()  //*** RTCC预设初值* ****/    RTCC数据允许写入
  •    {
  •                 uchar temp  ;
  •                  /*********启动数据初始化**************/
  •                 _RTCVALH.YEAR            =    0x21; //11     年            YEAR  【自动返回RTCC 值寄存器_初始地址】
  •                 _RTCVALH.MONTH       =    0x05;  //10    月             MONTH
  •                 _RTCVALH.DAY              =    0x07;         //10   日             DAY
  •                 _RTCVALH.WEEKDAY   =    0x05;         //01   星期         WEEKDAY
  •                 _RTCVALH.HOUR          =     0x12;          //01  小时数     HOUR        
  •                 _RTCVALH.MINUTE       =     0x01;  //00   分钟数     MINUTE
  •                 _RTCVALH.SECOND      =     0x58;          //00  秒数         SECOND
  •         
  •             EECON2    = 0X55;
  •                 EECON2   = 0XAA;
  •                 nop();   //在 55h/AA 解码序列和 RTCWREN置 1 之间只允许一个指令周期的时间窗口
  •                 RTCCFGbits.RTCWREN = 1;       // 允许RTCCFG寄存器进行写操作
  •                 RTCCFG            |=  0x03;             //  RTCC 值寄存器窗口指针位_指向地址【1 1】
  •         
  •                   GIE  = 0;                                              //关闭全局中断
  • /***********************RTCVALL   ****************************/
  •         /*通过读 / 写    RTCVALH 寄存器, RTCC 指针值(RTCPTR<1:0>)*/      
  •         /*递减 1,直到其达到 00。一旦达到00; MINUTES 和 SECONDS 值就可 */
  •         /*通过 RTCVALH 和  RTCVALL 进行访问,直到手动更改指针值为止。
  •                                                                         RTCVALH:
  •                                                                         00 = 分钟数
  •                                                                         01 = 星期
  •                                                                         10 = 月
  •                                                                         11 = 保留
  •                                                                         RTCVALL:
  •                                                                         00 = 秒数
  •                                                                         01 = 小时数
  •                                                                         10 = 日
  •                                                                         11 = 年
  •         **************************************************************/   
  •                 RTCCFGbits. RTCPTR = 3;
  •            
  •                 RTCVALL  =   _RTCVALH.YEAR  ;
  •                 temp         =    RTCVALH;  //11 保留        
  •                 RTCVALL  =   _RTCVALH.DAY;
  •                 RTCVALH  =  _RTCVALH.MONTH ;
  •                 RTCVALL  =  _RTCVALH.HOUR;
  •                 RTCVALH =   _RTCVALH.WEEKDAY ;
  •                 RTCVALL  =   _RTCVALH.SECOND  ;
  •                 RTCVALH =  _RTCVALH.MINUTE;
  •                 RTCEN = 1;   //  RTCC使能
  •         RTCCFGbits. RTCWREN = 0;          //关闭RTCCFG寄存器写操作
  •                 /*******************************************************/
  •        GIE  = 1;// 恢复全局中断
  • }
  • void READ_RTCC()  //读时间寄存器操作
  •    {  
  •                 uchar temp  ;
  •                 RTCCFGbits. RTCPTR = 3;
  •                 temp           =    RTCVALH;  //11 保留        
  •                 Delay_uS(1); //延时10指令周期, 等待RTCC 值寄存器指针跳到【0 0】
  •                
  •                 /*        指针一旦达到【0 0】        【MINUTES 和 SECONDS 值就可通过 RTCVALH 和        RTCVALL 进行访问】*/
  •                 while(RTCPTR1 &&  RTCPTR0);
  •                         RTCCFGbits. RTCPTR = 3;
  •                         temp           =    RTCVALH;  //11 保留-->【开始调用指针        】
  •                         
  •                         RTCCFGbits. RTCPTR = 2;
  •                         _RTCVALH.MONTH        =   RTCVALH;  //10   月
  •                         
  •                         RTCCFGbits. RTCPTR = 1;  
  •                         _RTCVALH.WEEKDAY          =   RTCVALH;  //01 星期   
  •                         
  •                         RTCCFGbits. RTCPTR = 0;
  •                         _RTCVALH.MINUTE        =   RTCVALH;  //00 分钟数
  •                         
  •                         RTCCFGbits. RTCPTR = 3;  
  •                         _RTCVALL.YEAR                   =   RTCVALL;   //11   年         
  •                         
  •                         RTCCFGbits. RTCPTR = 2;                        
  •                         _RTCVALL.DAY                     =   RTCVALL;   //10    日
  •                         
  •                         RTCCFGbits. RTCPTR = 1;        
  •                         _RTCVALL.HOUR           =   RTCVALL;    //01   小时数
  •                         
  •                         RTCCFGbits. RTCPTR = 0;
  •                         _RTCVALL.SECOND      =   RTCVALL;    //00   秒数
  •                 _RTCVALL.YEAR                     =    Read_RTCC_Bin( _RTCVALL.YEAR);        // 年
  •                 _RTCVALH.MONTH         =    Read_RTCC_Bin(  _RTCVALH.MONTH); // 月
  •                 _RTCVALL.DAY                          =    Read_RTCC_Bin( _RTCVALL.DAY);          // 日
  •                 _RTCVALH.WEEKDAY     =    _RTCVALH.WEEKDAY         & 0x07;                      // 星期
  •                 _RTCVALL.HOUR                    =    Read_RTCC_Bin( _RTCVALL.HOUR);      // 小时
  •                 _RTCVALH.MINUTE         =    Read_RTCC_Bin( _RTCVALH.MINUTE );  //分钟数
  •                 _RTCVALL.SECOND         =    Read_RTCC_Bin( _RTCVALL.SECOND); //  秒  
  •   }
  • 复制代码