在本文中,将探讨如何在PIC24微控制器上实现实时时钟日历(RTCC)模块的功能。请注意,虽然这个示例使用的是PIC24FJ64GA002型号,但大部分代码也可以通过少量修改应用于其他类似的PIC微控制器。在开始之前,需要指出的是,与DS1307等外部RTC模块不同,RTCC模块没有专用的时间保持电池,它与PIC共享电源。因此,为了在不使用时保持RTCC模块运行,可能需要将PIC置于待机状态以节省电力。
首先,需要启用RTCC模块的次级振荡器。以下是C++代码示例:
__builtin_write_OSCCONL(OSCCON | 0x02);
接下来,将定义一个函数,用于将指定的日期和时间值写入RTCC模块。
void setRTCTime(unsigned char year, unsigned char month, unsigned char day, unsigned char weekday, unsigned char hour, unsigned char minute, unsigned char second) {
// 启用RTCC计时器访问
NVMKEY = 0x55;
NVMKEY = 0xAA;
RCFGCALbits.RTCWREN = 1;
// 禁用RTCC模块
RCFGCALbits.RTCEN = 0;
// 写入RTCC计时器
RCFGCALbits.RTCPTR = 3;
// RTCC值寄存器窗口指针位
RTCVAL = bin2bcd(year); // 设置年份 (#0x00YY)
RTCVAL = (bin2bcd(month) << 8) + bin2bcd(day); // 设置月份和日期 (#0xMMDD)
RTCVAL = (bin2bcd(weekday) << 8) + bin2bcd(hour); // 设置星期和小时 (#0x0WHH)
RTCVAL = (bin2bcd(minute) << 8) + bin2bcd(second); // 设置分钟和秒 (#0xMMSS)
// 启用RTCC模块
RCFGCALbits.RTCEN = 1;
// 禁用RTCC计时器访问
RCFGCALbits.RTCWREN = 0;
}
为了获取当前的RTCC时间,需要编写一段代码来读取RTCC时间保持寄存器。以下是C++代码示例:
// 等待RTCSYNC位变为‘0’
while(RCFGCALbits.RTCSYNC == 1);
// 读取RTCC时间保持寄存器
RCFGCALbits.RTCPTR = 3;
unsigned int year = bcd2bin(RTCVAL);
unsigned int month_date = RTCVAL;
unsigned char month = bcd2bin(month_date >> 8);
unsigned char day = bcd2bin(month_date & 0xFF);
unsigned int wday_hour = RTCVAL;
unsigned char weekday = bcd2bin(wday_hour >> 8);
unsigned char hour = bcd2bin(wday_hour & 0xFF);
unsigned int min_sec = RTCVAL;
unsigned char minute = bcd2bin(min_sec >> 8);
unsigned char second = bcd2bin(min_sec & 0xFF);
日期和时间值在内部以二进制编码的十进制(BCD)形式存储。为了方便值的转换,编写了bcd2bin和bin2bcd两个函数。完整的源代码,包括BCD转换函数,可以在这里下载。
在编程过程中,需要注意几个关键点。首先,NVMKEY是一个只写寄存器,用于防止意外写入或擦除Flash或EEPROM内存。要开始编程或擦除序列,必须按照以下顺序执行以下步骤:
其次,需要在写入RTCC模块之前禁用它,并且在写入完成后重新启用。此外,还需要注意在写入过程中使用正确的指针位来选择正确的RTCC值寄存器。