查看: 1054|回复: 0

【XMEGA深思录】5、片内精准实时时钟

[复制链接]

该用户从未签到

发表于 2015-12-8 09:19:22 | 显示全部楼层 |阅读模式
分享到:
最近论坛有网友测试了SAMV71的片内RTC,反应计时误差大。

周末得空可以用XMEGA开发板外接OLED扩展板做了一个实时时钟,
经过一天的测试,误差在几秒钟,折算到一个月,约一分多钟左右,
比实时时钟芯片DS1302一点也不差。完全能满足一般应用。






选择开发板未使用的SPIC与OLED1306SPI接口连接,其余复位脚、
命令数据选择脚选择任意空闲的IO口即可。





void disp_date_time_sub_fast(void) // 显示年月日时分秒(快速显示)
{
         char s[11];
         //显示日期
         s[0] = date.year / 1000 + 0x30;
         s[1] = date.year % 1000 / 100 + 0x30;
         s[2] = date.year % 100 / 10 + 0x30;
         s[3] = date.year % 10 + 0x30;
         s[4] = '-';
         s[5] = (date.month + 1) / 10 + 0x30;
         s[6] = (date.month + 1) % 10 + 0x30;
         s[7] = '-';
         s[8] = (date.date + 1) / 10 + 0x30;
         s[9] = (date.date + 1) % 10 + 0x30;
         s[10] = '\0';
         disp_str_fast(s, DATE_X, DATE_Y);
         //显示时间
         s[0] = date.hour / 10 + 0x30;
         s[1] = date.hour % 10 + 0x30;
         s[2] = ':';
         s[3] = date.minute / 10 + 0x30;
         s[4] = date.minute % 10 + 0x30;
         s[5] = ':';
         s[6] = date.second / 10 + 0x30;
         s[7] = date.second % 10 + 0x30;
         s[8] = '\0';
         disp_str_fast(s, TIME_X, TIME_Y);
}
void fresh_date_time(void)
{
          static uint32_t t;
          uint32_t counter = rtc_get_time();
        
          if(counter - t){
                 t = counter;
                 rtc32_cnt2date(counter);
                 clr_all();
                  disp_date_time_sub_fast();
          }
}
#include "main.h"
#include "clock.h"
int main (void)
{
         /* Insert system clock initialization code here (sysclk_init()). */

         board_init();
         sysclk_init();



//         tcc0_initial();
//         irq_initialize_vectors();
         
         
         
//         /* USB */
//         irq_initialize_vectors();
//         cpu_irq_enable();
//         stdio_usb_init();
//         stdio_usb_enable();


         
         ioport_configure_pin(LED1_EXT3,IOPORT_DIR_OUTPUT|IOPORT_INIT_LOW);
         
         
         ioport_configure_pin(SSD1306_CS_PIN,IOPORT_DIR_OUTPUT|IOPORT_PULL_UP);
         ioport_configure_pin(SSD1306_RES_PIN,IOPORT_DIR_OUTPUT|IOPORT_PULL_UP);
         ioport_configure_pin(SSD1306_DC_PIN,IOPORT_DIR_OUTPUT|IOPORT_PULL_UP);
         ioport_configure_pin(IOPORT_CREATE_PIN(PORTC,5),IOPORT_DIR_OUTPUT|IOPORT_PULL_UP);
         ioport_configure_pin(IOPORT_CREATE_PIN(PORTC,7),IOPORT_DIR_OUTPUT|IOPORT_PULL_UP);
         // Initialize SPI and SSD1306 controller
         ssd1306_init();



         /* RTC32,RTC32初次启动标志存储在EEPROM的0x001E */
         uint8_t rtc32FirstBootFlag; // RTC32初次启动标志
         sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); // 使能RTC32
         while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) { // 等待时钟稳定
         }
         rtc32FirstBootFlag = nvm_eeprom_read_byte(0x001E); // 0x001E为初次启动标志在EEPROM中的存储地址
         if(rtc32FirstBootFlag != 0x5C) { // 初次启动
                 nvm_eeprom_write_byte(0x001E,0x5C);
                 rtc_vbat_system_check(false);
                 rtc_init();
                 rtc32_set_init_DT(); // 设置初始时间2015-2-9 08:58:00
                 rtc_set_time(rtc32_date2cnt(date)); // 初始时间对应的32位数值写入RTC32 CNT寄存器
                 } else { // 非初次启动
                 if(rtc_vbat_system_check(true) != VBAT_STATUS_OK) {
                         rtc_init();
                         rtc32_set_init_DT(); // 设置初始时间2015-2-9 08:58:00
                         rtc_set_time(rtc32_date2cnt(date)); // 初始时间对应的32位数值写入RTC32 CNT寄存器
                 }
         }
         rtc32_cnt2date(rtc_get_time()); // 读取RTC32计数器并转化为年月日时分秒

         
         clr_all();
         while(1) {
                 fresh_date_time();
         }


End
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

手机版|小黑屋|与非网

GMT+8, 2024-12-18 23:41 , Processed in 0.116965 second(s), 18 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.