返回该小组首页 回复主题
chuzhujun1985

chuzhujun1985

小组等级:     E币:227  (E币换礼)

#1楼主:【原创】RTC专栏 [精华]

文章发表于:2008-09-07 06:34

昨天调试RTC模块,弄了好几个小时,虽然资料上讲的也不少,但是懒懒散散的,不是集中在一块,涉计到RTC  RRC 还有BKP,我下面就如何成功的使用RTC和大家分享一下:有什么问题一起讨论哈!

首先需要开启这么一些模块:#define _BKP      #define _NVIC        #define _PWR     #define _RCC      #define _RTC,BKP开启并不是必须的,如果要想复位BKP中的寄存器到初始状态,或者说是进行RTC校准之类的,就必须开启,如果不需要校准的话就可以不用开启,校准的问题我们放在下次讲吧!

其次复位时候RTC的寄存器是被保护的(因为处在BKP区域),所以首要问题就是解除保护,而保护的地方就是在电源的PWR—CR寄存器中的DBP位,所以需要将这一位置位后解除RTC和BKP寄存器的保护,这样就可以进行RTC寄存器的访问了。对应库中的函数调用:PWR_BackupAccessCmd(ENABLE);

第三:由于BKP和PWR都是在APB总线上的,所以需要使能APB的这两个外设的时钟,语句:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);需要注意的是我这个虽然是写在第三的位置上,但是如果这两个外设时钟不开启,那么刚才第二条语句其实就不能执行的,所以这条语句应该放在上面一条语句之前的,我这么写是按照逻辑的顺序描述的,这里其实需要注意一点的是为什么RTC的一些寄存器也是通过APB1总线同cm3核进行通信的,但是为什么没有APB1的RTC时钟使能呢?这个问题我开始也很纳闷,后来才理解了,这是因为RTC有自己的时钟的,如果它仰仗APB1的时钟驱动,那么在休眠时候,APB1总线凝结,那么RTC也就不能工作了,所以他需要自己的时钟节拍,但是cm3终究是要访问RTC的寄存器的,所以在访问的时候就可能出现两套总线不同步的现象,于是麻烦的事情就出来了,cm3访问RTC寄存器的时候需要判断两条总线有没有同步,写一次数据也需要判断有没有写完成,可以说这是ST设计这个模块要考虑两全的一个迫不得已的方法,并不是一个好的方法,因为需要指令等待,而这是不希望看见的事情。

第四:由于RTC是用的外部低速晶体的,所以需要开启外部低速晶体,而且选择其为RTC的时钟,在开启外部晶体时候不要忘了需要等待外部晶体稳定,这是所有微控制都需要注意的问题,具体语句为:

RCC_LSEConfig(RCC_LSE_ON);
  /* Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}

  /* Select LSE as RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  /* Enable RTC Clock */
  RCC_RTCCLKCmd(ENABLE);

第五:开始想RTC寄存器中写数据了,首先必须等待同APB1总线同步:/* Wait for RTC registers synchronization */
       RTC_WaitForSynchro();

第六:同步完成之后在写数据到RTC寄存器时候,需要判断上一条语句有没有完成从APB1总线到RTC寄存器的转移,所以:

/* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

第七:使能秒中断。

/* Enable the RTC Second */
  RTC_ITConfig(RTC_IT_SEC, ENABLE);

第八:设置预分频器,保证是一秒产生一次事件,注意:这里可能会不准,下一次讲校准问题。

/* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();

  /* Set RTC prescaler: set RTC period to 1sec */
  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

第九:以上设置完成了之后,就可以了吗?就能够在每一秒中进入RTC中断函数里面一次吗?其实还有最重要也是最后一点:使能NVIC的RTC中断,将RTC的中断请求链接到NVIC的中断线上,并且设置相应的抢占优先级和副优先级:

/* Enable the RTC Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

哈哈,这样的话,如果在stm32f10x_it.c文件的RTC中断函数入口设置一个断点,然后运行程序,就能够每一秒进去一次了!希望给还没有使用过RTC的朋友一个启发,关于时钟校准在下次讲解了,手都写酸了…………

 

chuzhujun1985

   小组等级:    E币:227  (E币换礼)

#2

文章发表于:2008-09-09 21:58

哎,怎么加了精华之后连一个顶的人都没有啊?好歹顶一下嘛!呵呵,

zhu_dongpo

   小组等级:    E币:356  (E币换礼)

#3

文章发表于:2008-10-07 09:19

期待时钟校准

sunke9

   小组等级:    E币:2245  (E币换礼)

#4

文章发表于:2008-10-07 14:11

好像还应该有下文

fengcj

   小组等级:    E币:59  (E币换礼)

#5

文章发表于:2008-10-26 01:49

RTC的校验快点发啊  我很期待啊 ~~~~~~

bobi2005

   小组等级:    E币:1535  (E币换礼)

#6

文章发表于:2008-10-26 09:17

就是,都过来

thetaedn

   小组等级:    E币:62  (E币换礼)

#7

文章发表于:2008-10-28 18:19

谢谢分享, 省了我不少时间.

APOOU

   小组等级:    E币:68  (E币换礼)

#8

文章发表于:2008-11-03 20:28

好东西啊,就是/* Enable the RTC Interrupt */还不太明白的,自己还要努力啊

总共 , 当前 /

快速回复主题--如果想加入编辑器功能,建议使用 [高级回复]

您目前还不是小组成员,请先加入

回复贴子区

用户名:    您没有注册?

密码:    忘记了密码?

内容:

  • DesignDesign
  • HTMLHTML

浏览该小组的用户还看过...

设计资源与分销

所有小组精华文章