|
最近论坛有网友测试了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 |
|