查看: 3507|回复: 0

SAM4N RTC的驱动

[复制链接]
  • TA的每日心情
    奋斗
    2015-1-22 18:04
  • 签到天数: 189 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-12-3 18:55:47 | 显示全部楼层 |阅读模式
    分享到:
    SAM4N的RTC使用非常简单,可惜板子上并没有带电池,所以断掉不能保持RTC数据。
    驱动代码如下:
    1. #include "drv_rtc.h"
    2. RTC_Time_TypeDef default_time={0x20,0x13,0x10,0x22,0x15,0x22,0x11,0x02,0x00};

    3. void rtc_init(Hour_Mode_Typedef mode)
    4. {
    5.                 /*禁止外设管理控制寄存器(PMC)写保护*/
    6.   PMC->PMC_WPMR = 0x504D4300;
    7.     /*使能RTC时钟*/       
    8.   PMC->PMC_PCER0 = (1UL << ID_RTC);  
    9.         /*使能外设管理控制寄存器(PMC)写保护*/
    10.   PMC->PMC_WPMR = 0x504D4301;  
    11.   rtc_set_mode(mode);
    12.     rtc_set_time(&default_time,BCD);
    13. }

    14. void rtc_set_mode(Hour_Mode_Typedef mode)
    15. {
    16. RTC->RTC_MR=mode;
    17. }
    18. Hour_Mode_Typedef rtc_get_mode(void)
    19. {
    20.         Hour_Mode_Typedef mode;
    21.   mode=(Hour_Mode_Typedef)(RTC->RTC_MR&0x01);
    22.         return mode;
    23. }
    24. void rtc_set_time(RTC_Time_TypeDef *time,RTC_Time_Format format)
    25. {
    26.         RTC->RTC_CR|=(RTC_CR_UPDCAL|RTC_CR_UPDTIM);        //停止时间和日期更新
    27.         while((RTC->RTC_SR&RTC_SR_ACKUPD)!=RTC_SR_ACKUPD); //等待允许更新时间和日期
    28.         RTC->RTC_SCCR=RTC_SCCR_ACKCLR;                     //必须先清除状态寄存器ACK位
    29.   if (BCD==format)
    30.   {
    31.          RTC->RTC_CALR=RTC_CALR_CENT(time->cent)|
    32.                            RTC_CALR_YEAR(time->year)|
    33.                      RTC_CALR_MONTH(time->month)|
    34.                      RTC_CALR_DATE(time->date)|
    35.                      RTC_CALR_DAY(time->day);
    36.          RTC->RTC_TIMR=RTC_TIMR_HOUR(time->hour)|
    37.                              RTC_TIMR_MIN(time->minnute)|
    38.                              RTC_TIMR_SEC(time->second) |
    39.                              (time->am_pm<<22);

    40.   }
    41.   else if (BIN==format)
    42.   {              
    43.          RTC->RTC_CALR=RTC_CALR_CENT(BIN2BCD(time->cent))|
    44.                              RTC_CALR_YEAR(BIN2BCD(time->year))|
    45.                        RTC_CALR_MONTH(BIN2BCD(time->month))|
    46.                        RTC_CALR_DATE(BIN2BCD(time->date))|
    47.                        RTC_CALR_DAY(BIN2BCD(time->day));
    48.          RTC->RTC_TIMR=RTC_TIMR_HOUR(BIN2BCD(time->hour))|
    49.                        RTC_TIMR_MIN(BIN2BCD(time->minnute))|
    50.                        RTC_TIMR_SEC(BIN2BCD(time->second))|
    51.                               (time->am_pm<<22);
    52.   }
    53.         RTC->RTC_CR&=~(RTC_CR_UPDCAL|RTC_CR_UPDTIM);    //重新允许更新时间和日期
    54.   RTC->RTC_SCCR|=RTC_SCCR_SECCLR;                        //清除秒事件状态
    55. }

    56. void rtc_get_time(RTC_Time_TypeDef *time,RTC_Time_Format format)
    57. {
    58.         if (BCD==format)
    59.   {
    60.          time->cent=((RTC->RTC_CALR&RTC_CALR_CENT_Msk)>>RTC_CALR_CENT_Pos);
    61.          time->year=((RTC->RTC_CALR&RTC_CALR_YEAR_Msk)>>RTC_CALR_YEAR_Pos);
    62.          time->month=((RTC->RTC_CALR&RTC_CALR_MONTH_Msk)>>RTC_CALR_MONTH_Pos);
    63.          time->date=((RTC->RTC_CALR&RTC_CALR_DATE_Msk)>>RTC_CALR_DATE_Pos);
    64.          time->day=((RTC->RTC_CALR&RTC_CALR_DAY_Msk)>>RTC_CALR_DAY_Pos);
    65.          time->hour=((RTC->RTC_TIMR&RTC_TIMR_HOUR_Msk)>>RTC_TIMR_HOUR_Pos);
    66.          time->minnute=((RTC->RTC_TIMR&RTC_TIMR_MIN_Msk)>>RTC_TIMR_MIN_Pos);
    67.          time->second=((RTC->RTC_TIMR&RTC_TIMR_SEC_Msk)>>RTC_TIMR_SEC_Pos);
    68.          time ->am_pm=((RTC->RTC_TIMR>>22)&0x01UL);
    69.   }
    70.   else if (BIN==format)
    71.   {
    72.          time->cent=BCD2BIN((RTC->RTC_CALR&RTC_CALR_CENT_Msk)>>RTC_CALR_CENT_Pos);
    73.          time->year=BCD2BIN((RTC->RTC_CALR&RTC_CALR_YEAR_Msk)>>RTC_CALR_YEAR_Pos);
    74.          time->month=BCD2BIN((RTC->RTC_CALR&RTC_CALR_MONTH_Msk)>>RTC_CALR_MONTH_Pos);
    75.          time->date=BCD2BIN((RTC->RTC_CALR&RTC_CALR_DATE_Msk)>>RTC_CALR_DATE_Pos);
    76.          time->day=BCD2BIN((RTC->RTC_CALR&RTC_CALR_DAY_Msk)>>RTC_CALR_DAY_Pos);
    77.          time->hour=BCD2BIN((RTC->RTC_TIMR&RTC_TIMR_HOUR_Msk)>>RTC_TIMR_HOUR_Pos);
    78.          time->minnute=BCD2BIN((RTC->RTC_TIMR&RTC_TIMR_MIN_Msk)>>RTC_TIMR_MIN_Pos);
    79.          time->second=BCD2BIN((RTC->RTC_TIMR&RTC_TIMR_SEC_Msk)>>RTC_TIMR_SEC_Pos);
    80.          time ->am_pm=((RTC->RTC_TIMR>>22)&0x01UL);
    81.   }
    82. }
    复制代码
    时间和日期寄存器里面保存的值是BCD编码的,这里用两个宏定义实现二进制和BCD码的互换:
    1. #define BCD2BIN(x) ((x>>4)*10+(x&0x0f))
    2. #define BIN2BCD(x) (((x/10)<<4)|(x%10))
    复制代码
    下面是相关的结构体定义:
    1. typedef enum
    2. {
    3. Hour_Mode_24,
    4. Hour_Mode_12
    5. }Hour_Mode_Typedef;
    6. struct RTC_Time
    7. {
    8. uint8_t cent;
    9. uint8_t year;
    10. uint8_t month;
    11. uint8_t date;
    12. uint8_t hour;
    13. uint8_t minnute;
    14. uint8_t second;
    15. uint8_t day;
    16. uint8_t am_pm;
    17. } ;
    18. typedef struct RTC_Time RTC_Time_TypeDef;
    19. typedef enum
    20. {
    21.         BCD,
    22.         BIN,
    23. } RTC_Time_Format;
    复制代码
    这里需要注意的是RTC里面支持12小时模式和24小时模式,对于12小时模式,在时间寄存器中会有个AM/PM位分辨是上午还是下午,在24小时模式下,这个位是无效的。
    在同时日期寄存器中还有个cent位,是多少世纪的意思,这个部分时钟芯片可能没有。
    还要注意的是每次重新设置时间时,必须要去停止时间和日期的更新,然后等待ACKUPD清零才能进行重新设置时间日期操作。
    1. int main(void)
    2. {
    3. RTC_Time_TypeDef time;
    4. systick_hw_init();
    5. led_hw_init();
    6. UART0_Init(115200);
    7. glcd_init();

    8. printf("this is a rtc demo!\r\n");
    9. rtc_init(Hour_Mode_24);
    10. while(1){
    11. rtc_get_time(&time,BIN);
    12. printf("%d-%d-%d %d:%d:%d\r\n",time.year,time.month,time.date,time.hour,time.minnute,time.second);
    13. PIOB->PIO_CODR=(0x01<<LED0_PIN);
    14. delay_ms(500);
    15. PIOB->PIO_SODR=(0x01<<LED0_PIN);
    16. delay_ms(500);
    17. }

    18. }
    复制代码
    这里是一个简单的时间读取程序,会定时的打印当前时间到串口,如下图:
    QQ图片20131028164206.jpg
    10.rtc.rar (1.07 MB, 下载次数: 3)
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-11-20 01:36 , Processed in 0.114851 second(s), 16 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.