找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2391|回复: 4
收起左侧

PIC单片机自带RTCC制作误差mS级时钟 附源程序

[复制链接]
ID:474417 发表于 2021-5-23 21:49 | 显示全部楼层 |阅读模式
在网上淘了一个PIC18F85K90自带RTCC功能的单片机,写了一段测试一下RTCC的精度,运作了5天,还好_精度达到了误差毫秒级.
随手加了一个AHT15温湿度,上传赚点黑币
注:32.768(5ppm)晶振需要加两个30pF电容稳定震荡频率, 每30分钟与60分钟进位时秒显示。

制作出来的实物图如下:
IMG_20210523_213954.jpg IMG_20210523_213908.jpg IMG_20210523_213901.jpg

单片机源程序如下:
  1. #include <htc.h>
  2. #include "Delay.h"
  3. #include "Driver.h"
  4. #include "TA6932.H"  
  5. #include "RTCC.H"
  6. #include "Selection.h"
  7. #include "AHT15.H"

  8. void main()
  9.   {
  10.                 initialization();                        //单片机寄存器初始化
  11.             Delay_mS(500);
  12.                 AHT15_iic_Init();          //AHT15_初始化        
  13.                   RTCC_WD_Init();
  14.                 while (1)
  15.            {
  16.         READ_RTCC();                    //读时间寄存器操作
  17.         check_Data();                       //时间校准【此函数一定要放在READ_RTCC()后面_因为判断每分钟调整一次的判断值是十进制】
  18.               Function_Selection();    //功能选择
  19.                 SMG_DisPlay_TIME(0x44, 0x06, LED);//数码管显示
  20.        }   
  21.     }

  22. void  interrupt TIMER0()     //TIMER0中断函数【定时 50mS】
  23.   {
  24.         TMR0IF      =  0 ;                   //中断标志位清零
  25.         TMR0H      =  0x3C;                                // TMR0H只是缓冲寄存器,在写 TMR0L寄存器同时,使用TMR0H的内容更新Timer0的高字节内容
  26.         TMR0L      =   0xB7  ;           //初值 15536_分频器倍数少于16,所有不用需要校正值【15536+(14/(2_分频值))】
  27.         if(  Key_Flag   ==  400)      Key_Flag  =  0;
  28.         if( Sec_Flag    ==  20)         Sec_Flag   =  0;
  29.         Key_Flag ++;
  30.         Sec_Flag++ ;
  31.     }
复制代码
  1. #include "Delay.h"
  2. #include "RTCC.H"
  3. #include "Selection.h"

  4. RTC   _RTCVALH; //定义_共同体变量1
  5. RTC   _RTCVALL; //定义_共同体变量2

  6. void check_Data()  //校准_【每秒钟调整一次将其加到 RTCC 定时器中】
  7.         {
  8.                 //如2小时快1秒的话则为 1/(2小时*3600秒)= 1s / 7200 = 0.1389ms
  9.                 //也就是说明每秒快了0.139MS,由此可推算出真正的【XI】晶振频率为:1.3472=XI/32768
  10.                 //XI=1.0001389*32768 =  32772.55HZ     32772.55-32768 = 4.55即晶振频率为每秒钟多了约5个脉冲
  11.                 //4.55*60= 每秒分钟多了 273个脉冲   273 / 4 =  68.25 取 69 【可以认为每秒分钟减去69个脉冲】即69*4 = 276
  12.                 //- 69 = 0XBB;

  13.                 if (_RTCVALL.SECOND == 0 )//每秒钟调整一次 !HALFSEC
  14.                              RTCCAL         =  RTCCAL_Temp ;   //时钟校准寄存器;    //RTCC 校准寄存器   0x88【-120】; -120X4=-480 即在 RTCCAL“每分钟减少480”个时钟脉冲
  15. }               
  16.          


  17. void RTCC_WD_Init()  //*** RTCC预设初值* ****/    RTCC数据允许写入
  18.    {
  19.                 uchar temp  ;
  20.                  /*********启动数据初始化**************/
  21.                 _RTCVALH.YEAR            =    0x21; //11     年            YEAR  【自动返回RTCC 值寄存器_初始地址】
  22.                 _RTCVALH.MONTH       =    0x05;  //10    月             MONTH
  23.                 _RTCVALH.DAY              =    0x07;         //10   日             DAY
  24.                 _RTCVALH.WEEKDAY   =    0x05;         //01   星期         WEEKDAY
  25.                 _RTCVALH.HOUR          =     0x12;          //01  小时数     HOUR        
  26.                 _RTCVALH.MINUTE       =     0x01;  //00   分钟数     MINUTE
  27.                 _RTCVALH.SECOND      =     0x58;          //00  秒数         SECOND
  28.         
  29.             EECON2    = 0X55;
  30.                 EECON2   = 0XAA;
  31.                 nop();   //在 55h/AA 解码序列和 RTCWREN置 1 之间只允许一个指令周期的时间窗口
  32.                 RTCCFGbits.RTCWREN = 1;       // 允许RTCCFG寄存器进行写操作
  33.                 RTCCFG            |=  0x03;             //  RTCC 值寄存器窗口指针位_指向地址【1 1】
  34.         
  35.                   GIE  = 0;                                              //关闭全局中断
  36. /***********************RTCVALL   ****************************/
  37.         /*通过读 / 写    RTCVALH 寄存器, RTCC 指针值(RTCPTR<1:0>)*/      
  38.         /*递减 1,直到其达到 00。一旦达到00; MINUTES 和 SECONDS 值就可 */
  39.         /*通过 RTCVALH 和  RTCVALL 进行访问,直到手动更改指针值为止。
  40.                                                                         RTCVALH:
  41.                                                                         00 = 分钟数
  42.                                                                         01 = 星期
  43.                                                                         10 = 月
  44.                                                                         11 = 保留
  45.                                                                         RTCVALL:
  46.                                                                         00 = 秒数
  47.                                                                         01 = 小时数
  48.                                                                         10 = 日
  49.                                                                         11 = 年
  50.         **************************************************************/   
  51.                 RTCCFGbits. RTCPTR = 3;
  52.            
  53.                 RTCVALL  =   _RTCVALH.YEAR  ;
  54.                 temp         =    RTCVALH;  //11 保留        
  55.                 RTCVALL  =   _RTCVALH.DAY;
  56.                 RTCVALH  =  _RTCVALH.MONTH ;
  57.                 RTCVALL  =  _RTCVALH.HOUR;
  58.                 RTCVALH =   _RTCVALH.WEEKDAY ;
  59.                 RTCVALL  =   _RTCVALH.SECOND  ;
  60.                 RTCVALH =  _RTCVALH.MINUTE;

  61.                 RTCEN = 1;   //  RTCC使能
  62.         RTCCFGbits. RTCWREN = 0;          //关闭RTCCFG寄存器写操作
  63.                 /*******************************************************/
  64.        GIE  = 1;// 恢复全局中断

  65. }

  66. void READ_RTCC()  //读时间寄存器操作
  67.    {  
  68.                 uchar temp  ;
  69.                 RTCCFGbits. RTCPTR = 3;
  70.                 temp           =    RTCVALH;  //11 保留        
  71.                 Delay_uS(1); //延时10指令周期, 等待RTCC 值寄存器指针跳到【0 0】
  72.                
  73.                 /*        指针一旦达到【0 0】        【MINUTES 和 SECONDS 值就可通过 RTCVALH 和        RTCVALL 进行访问】*/
  74.                 while(RTCPTR1 &&  RTCPTR0);

  75.                         RTCCFGbits. RTCPTR = 3;
  76.                         temp           =    RTCVALH;  //11 保留-->【开始调用指针        】
  77.                         
  78.                         RTCCFGbits. RTCPTR = 2;
  79.                         _RTCVALH.MONTH        =   RTCVALH;  //10   月
  80.                         
  81.                         RTCCFGbits. RTCPTR = 1;  
  82.                         _RTCVALH.WEEKDAY          =   RTCVALH;  //01 星期   
  83.                         
  84.                         RTCCFGbits. RTCPTR = 0;
  85.                         _RTCVALH.MINUTE        =   RTCVALH;  //00 分钟数
  86.                         
  87.                         RTCCFGbits. RTCPTR = 3;  
  88.                         _RTCVALL.YEAR                   =   RTCVALL;   //11   年         
  89.                         
  90.                         RTCCFGbits. RTCPTR = 2;                        
  91.                         _RTCVALL.DAY                     =   RTCVALL;   //10    日
  92.                         
  93.                         RTCCFGbits. RTCPTR = 1;        
  94.                         _RTCVALL.HOUR           =   RTCVALL;    //01   小时数
  95.                         
  96.                         RTCCFGbits. RTCPTR = 0;
  97.                         _RTCVALL.SECOND      =   RTCVALL;    //00   秒数


  98.                 _RTCVALL.YEAR                     =    Read_RTCC_Bin( _RTCVALL.YEAR);        // 年
  99.                 _RTCVALH.MONTH         =    Read_RTCC_Bin(  _RTCVALH.MONTH); // 月
  100.                 _RTCVALL.DAY                          =    Read_RTCC_Bin( _RTCVALL.DAY);          // 日
  101.                 _RTCVALH.WEEKDAY     =    _RTCVALH.WEEKDAY         & 0x07;                      // 星期
  102.                 _RTCVALL.HOUR                    =    Read_RTCC_Bin( _RTCVALL.HOUR);      // 小时
  103.                 _RTCVALH.MINUTE         =    Read_RTCC_Bin( _RTCVALH.MINUTE );  //分钟数
  104.                 _RTCVALL.SECOND         =    Read_RTCC_Bin( _RTCVALL.SECOND); //  秒  
  105.   }
复制代码

51hei.png

所有代码51hei提供下载:
PIC18F85K90.rar (623.24 KB, 下载次数: 20)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:454811 发表于 2021-5-24 19:52 | 显示全部楼层
aht15精度怎么样,做水合了吗?
回复

使用道具 举报

ID:474417 发表于 2021-5-24 23:38 | 显示全部楼层
温湿度的精度还很不错,反应也很快
回复

使用道具 举报

ID:107522 发表于 2021-8-9 17:17 | 显示全部楼层
请教一下,只有一个时钟源,怎么做到频率校准的啊
回复

使用道具 举报

ID:474417 发表于 2021-9-29 23:37 | 显示全部楼层
cjs2004 发表于 2021-8-9 17:17
请教一下,只有一个时钟源,怎么做到频率校准的啊

单片机时钟与RTCC时钟是各自独立的晶振运行,经过几个月的运行,RTCC的精度还可以,误差小于1秒。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表