Chinaunix首页 | 论坛 | 博客
  • 博客访问: 163147
  • 博文数量: 73
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 09:43
个人简介

为兴趣挑灯夜战

文章分类
文章存档

2018年(4)

2017年(7)

2016年(9)

2015年(4)

2014年(49)

分类: 嵌入式

2018-03-13 22:57:30

在按照GD32F350官方demo板提供的历程做RTC时,发现外部低速时钟不能用,用内部低速时钟不设置时间时,大多数时间都不正常,现象表现为时、分、秒走得很快,几秒种日期能加一天。如果设置了时间,RTC马上就死掉,直接停了。找FAE,也没找出问题,最后FAE发来一个能用的例程,经过对比,原来是开发板提供的例程有误,我估计做资料的人也没亲自测试,只是简单的复制粘贴。
下面来看库代码:

点击(此处)折叠或打开

  1. oid rtc_pre_config(void)
  2. {
  3.     /* enable access to RTC registers in backup domain */
  4.     rcu_periph_clock_enable(RCU_PMU);
  5.     pmu_backup_write_enable();

  6.     #if defined (RTC_CLOCK_SOURCE_IRC40K)
  7.           /* enable the IRC40K oscillator */
  8.           rcu_osci_on(RCU_IRC40K);
  9.           /* wait till IRC40K is ready */
  10.           rcu_osci_stab_wait(RCU_IRC40K);
  11.           /* select the RTC clock source */
  12.           rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
  13.   
  14.           prescaler_s = 0x18F;
  15.           prescaler_a = 0x63;
  16.     #elif defined (RTC_CLOCK_SOURCE_LXTAL)
  17.            /* enable the IRC40K oscillator */
  18.           rcu_osci_on(RCU_LXTAL);
  19.           /* wait till IRC40K is ready */
  20.           rcu_osci_stab_wait(RCU_LXTAL);
  21.           /* select the RTC clock source */
  22.           rcu_rtc_clock_config(RCU_LXTAL);
  23.           
  24.           prescaler_s = 0xFF;
  25.           prescaler_a = 0x7F;
  26.     #else
  27.     #error RTC clock source should be defined.
  28.     #endif /* RTC_CLOCK_SOURCE_IRC40K */

  29.     rcu_periph_clock_enable(RCU_RTC);
  30.     rtc_register_sync_wait();
  31. }
例程是通过RTC_CLOCK_SOURCE_IRC40KRTC_CLOCK_SOURCE_LXTAL这两个宏来切换时钟的,另外初始化了     prescaler_s = 0x18F;prescaler_a = 0x63; 这两个变量,我一开始就发现这两个变量没在任何地方应用,觉得很奇怪。例程默认使用内部低速时钟,第23行 rcu_rtc_clock_config(RCU_LXTAL);中的RCU_LXTAL这个参数是错的,应该使用RCU_RTCSRC_LXTAL。最重要的一点是prescaler_s和prescaler_a应该是设置时间时配置预分频寄存器 (RTC_PSC)的。设置时间时先填充一个rtc_parameter_struct型的结构体,然后调用ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)函数,填入初始化后的结构体就可以了。下面是一个时间设置函数:

  1. void set_time(u8 year,u8 month,u8 day,u8 week,u8 hour,u8 minute,u8 second)
  2. {
  3.     rtc_parameter_struct time;

  4.    
  5.   time.rtc_factor_asyn = prescaler_a;
  6.   time.rtc_factor_syn = prescaler_s;
  7.     
  8.   //将十进制转化为BCD码?
  9.   time.rtc_year=((year/10)<<4)+(year%10); //: 0x0 - 0x99(BCD format)
  10.   time.rtc_month=((month/10)<<4)+(month%10);//: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  11.   time.rtc_date=((day/10)<<4)+(day%10); //: 0x1 - 0x31(BCD format)
  12.   time.rtc_day_of_week=week; //: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
  13.   time.rtc_hour=((hour/10)<<4)+(hour%10);//: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
  14.   time.rtc_minute=((minute/10)<<4)+(minute%10); //: 0x0 - 0x59(BCD format)
  15.   time.rtc_second=((second/10)<<4)+(second%10); //: 0x0 - 0x59(BCD format)
  16.   time.rtc_display_format=RTC_24HOUR;//: RTC_24HOUR, RTC_12HOUR    
  17.   time.rtc_am_pm=RTC_PM;
  18.     if(ERROR==rtc_init(&time))
  19.     {
  20.      PrintStr("rtc set fail!\r\n");
  21.     
  22.     }
  23.                 
  24. }




阅读(3927) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~