请教关于RTC时钟的问题

hhhhwangba   2009-5-6 15:12 楼主
                                 万利的EK-STM32F板子,预分频值设置为32763,打开秒中断,在秒中断程序里LED翻转一次,看了一下,LED翻转一次的时间大概是15秒,不解?

回复评论 (14)

肯定是哪里设置不正确咯

                                  
点赞  2009-5-6 15:22

相关的设置程序

void RCC_Configuration(void)
{
    ErrorStatus HSEStartUpStatus;

    //使能外部晶振
    RCC_HSEConfig(RCC_HSE_ON);
    //等待外部晶振稳定
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    //如果外部晶振启动成功,则进行下一步操作
    if(HSEStartUpStatus==SUCCESS)
    {
        //开启FLASH预取指功能
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

        //FLASH时序控制
        //推荐值:SYSCLK = 0~24MHz   Latency=0
        //        SYSCLK = 24~48MHz  Latency=1
        //        SYSCLK = 48~72MHz  Latency=2
        FLASH_SetLatency(FLASH_Latency_2);

        //设置HCLK(AHB时钟)=SYSCLK
       RCC_HCLKConfig(RCC_SYSCLK_Div1);

        //PCLK2(APB2) = HCLK
        RCC_PCLK2Config(RCC_HCLK_Div1);

        //PCLK1(APB1) = HCLK/2
        RCC_PCLK1Config(RCC_HCLK_Div2);

        //PLL设置 SYSCLK/1 * 9 = 8*1*9 = 72MHz
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

        //启动PLL
        RCC_PLLCmd(ENABLE);

        //等待PLL稳定
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

        //系统时钟SYSCLK来自PLL输出
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

        //切换时钟后等待系统时钟稳定
        while(RCC_GetSYSCLKSource()!=0x08)
        {
        }
    }
    else
    { 
        /* If HSE fails to start-up, the application will have wrong clock configuration.
           User can add here some code to deal with this error */    
        /* Go to infinite loop */
        while (1)
       {
       }
    }

    //下面是给各模块开启时钟
    //启动GPIO
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |
                           RCC_APB2Periph_GPIOD,
                           ENABLE);
    //启动AFIO
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}

void RTC_Configuration(void)
{
    //启用PWR和BKP的时钟(from APB1)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);

    //后备域解锁
    PWR_BackupAccessCmd(ENABLE);

    //备份寄存器模块复位
    BKP_DeInit();

    //外部32.768K
    RCC_LSEConfig(RCC_LSE_ON);

    //等待稳定
    while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);

    //RTC时钟源配置成LSE(外部32.768K)
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

    //RTC开启
    RCC_RTCCLKCmd(ENABLE);

    //开启后需要等待APB1时钟与RTC时钟同步,才能读写寄存器
    RTC_WaitForSynchro();

    //读写寄存器前,要确定上一个操作已经结束
    RTC_WaitForLastTask();

    //设置RTC分频器,使RTC时钟为1Hz
    //RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
    RTC_SetPrescaler(32763); 
    //加快一点,设置为32767一天慢20秒  设置为32764一天慢1秒

    //等待寄存器写入完成
    RTC_WaitForLastTask();

    //使能秒中断
    RTC_ITConfig(RTC_IT_SEC,ENABLE);

    //等待写入完成
    RTC_WaitForLastTask();
}


实在查不出问题在哪儿,看到很多关于STM的RTC不准的问题,是不是也是这个原因。
点赞  2009-5-6 15:45

RTC再不准,也不会1秒变成15秒吧

                                 瓦卡卡
点赞  2009-5-6 15:47

对了,你的NVIC不会没有配置RTC秒中断吧

                                  
点赞  2009-5-6 15:50

配置了,要不LED怎么能翻转呢

这是NVIC部分。

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM
    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x00);
#else  /* VECT_TAB_FLASH  */
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
#endif

    /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* 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);

    /* Enable and configure RCC global IRQ channel */
    NVIC_InitStructure.NVIC_IRQChannel = RCC_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

点赞  2009-5-6 15:54

请先使用内部的RC振荡器作为RTC的时钟

内部的RC振荡器大概在40kHz左右。

看看你能得到什么结果,这样对照一下如果与使用LSE差的不多,应该是RTC之后的问题;如果差的比较多,则可能是晶振的振荡有问题,可以用示波器检查看看。
点赞  2009-5-6 15:59

内部RC一样的问题

主程序只是一个一秒钟点LED工作,如下

   while(1)
   {      
      if(TimeDisplay==1)
      {
          TimeDisplay = 0; 
          GPIOC->ODR ^= (1<<5);//PC5
      }
   }


这是RTC中断程序

void RTC_IRQHandler(void)
{
   if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
   {
      /* Clear the RTC Second interrupt */
      RTC_ClearITPendingBit(RTC_IT_SEC);

      GPIOC->ODR ^= (1<<4);

      TimeDisplay = 1;
   }
}

不知道其他哪儿会有影响,请指点一下。
点赞  2009-5-6 16:35

不要使用RTC的中断,

                                 就算你这次调试好了,下次修改程序时又会出现这样奇怪的问题,而且非常奇怪,不信你可以仿真并且在里面都使用几个条件语句,你看看这些条件语句是否会出现,至少我没有解决这个问题,最后放弃使用RTC的中断
点赞  2009-5-6 17:14

那你项目里还有作其他事情呢

之前的贴子里有一个使用了RTC秒中断的例子,LZ可以参照看看。


相关链接:https://bbs.eeworld.com.cn/upfiles/img/20092/2009223152041840.zip
点赞  2009-5-6 18:00

怀疑是分频器设置有问题

试试修改这句中的参数:RTC_SetPrescaler(32763); 

把参数大幅改小看看什么结果。

再有就是直接看看RTC预分频装载寄存器(RTC_PRLH/RTC_PRLL)的内容,确认是否正确。
点赞  2009-5-6 18:16

RTC预分频装载寄存器是正确的

                                 我查看了,RTC预分频装载寄存器值是0x7ffb=32763,正确的
点赞  2009-5-7 08:38

RTC预分频装载寄存器是20位的,分别在2个16位的寄存器中

RTC_PRLH/RTC_PRLL

你肯定RTC_PRLH=0?

如果果真如此,只能把振荡器的信号输出到I/O脚上,用示波器检查它的振荡频率。这是我能想到的最后一招了~~~~
点赞  2009-5-7 08:43

谢谢香主

RTC_PRLH=0的,所以没有写出来。
不过还是感谢,自己再慢慢查吧。
点赞  2009-5-8 08:27

你可以看看应用笔记AN2604,可以更清楚地了解RTC的工作

该笔记第6页的图2显示了把振荡器的信号输出到I/O脚上的配置,方便用示波器检查它的振荡频率。
相关链接:http://www.st.com/stonline/products/literature/an/13789.pdf
点赞  2009-5-8 08:47
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复