你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32L152芯片使用RTC制作万年历

[复制链接]
Imody 提问时间:2017-7-5 19:49 /
大家好,小弟在这里有个疑问,看了正点原子FI的RTC实时时钟试验后,想自己写一个STM32L152的实时时钟(万年历),但不知道如何配置,网上的资源大都是用Cube来写的,但小弟我想不用Cube来写。求大神们指点一下。
收藏 1 评论25 发布时间:2017-7-5 19:49

举报

25个回答
废鱼 回答时间:2017-7-6 13:46:21
都差不多,L152系列的例程里面都有了。如下代码:
  1. RTC_InitTypeDef RTC_InitStructure;
  2.   RTC_TimeTypeDef RTC_TimeStruct;
  3.         RTC_DateTypeDef RTC_DateStruct;
  4.         uint32_t t;
  5.         bool scc = FALSE;
  6.   
  7.   /* Enable the PWR clock */
  8.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  9.   /* Allow access to RTC */
  10.   PWR_RTCAccessCmd(ENABLE);

  11.   /* Reset RTC Domain */
  12.   RCC_RTCResetCmd(ENABLE);
  13.   RCC_RTCResetCmd(DISABLE);

  14.         /* Enable the LSE OSC */
  15.   RCC_LSEConfig(RCC_LSE_ON);
  16.         t = Fun_GetTicks();
  17.   /* Wait till LSE is ready */  
  18.   while(Fun_GetTicks()-t<2000)
  19.   {
  20.                 if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == SET)
  21.                 {
  22.                         /* Select the RTC Clock Source */
  23.                         RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  24.                         scc = TRUE;
  25.                         printf("LSE OK\n");
  26.                         break;
  27.                 }
  28.   }
  29.         if(scc == FALSE)
  30.         {
  31.                 /* Enable the LSI OSC */
  32.                 RCC_LSICmd(ENABLE);
  33.                 t = Fun_GetTicks();
  34.                 /* Wait till LSI is ready */  
  35.                 while(Fun_GetTicks()-t<2000)
  36.                 {
  37.                         if(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == SET)
  38.                         {                       
  39.                                 /* Select the RTC Clock Source */
  40.                                 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  41.                                 scc = TRUE;
  42.                                 printf("LSI OK\n");
  43.                                 break;
  44.                         }
  45.                 }
  46.         }
  47.        
  48.   /* Enable the RTC Clock */
  49.   RCC_RTCCLKCmd(ENABLE);
  50.        
  51.   /* Configure the RTC data register and RTC prescaler */
  52.   RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
  53.   RTC_InitStructure.RTC_SynchPrediv  = 0xFF;
  54.   RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
  55.   RTC_Init(&RTC_InitStructure);
  56.        
  57.   /* Set the time to 00h 00mn 00s AM */
  58.   RTC_TimeStruct.RTC_H12     = RTC_H12_AM;
  59.   RTC_TimeStruct.RTC_Hours   = hh;
  60.   RTC_TimeStruct.RTC_Minutes = mm;
  61.   RTC_TimeStruct.RTC_Seconds = ss;
  62.   RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);       
  63.        
  64.   /* Set the date */
  65.   RTC_DateStruct.RTC_WeekDay = RTC_Weekday_Monday;
  66.         RTC_DateStruct.RTC_Year    = year;
  67.         RTC_DateStruct.RTC_Month   = m;
  68.         RTC_DateStruct.RTC_Date    = day;
  69.   RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);

  70.        
  71.   /* Wait for RTC APB registers synchronisation */
  72.   RTC_WaitForSynchro();
复制代码


Imody 回答时间:2017-7-6 17:18:44
安 发表于 2017-7-6 16:46
楼主,你看的是103的例程吧。L152是不一样的。

恩恩。版主。我是想按照F103的例程写一个L152的万年历。现在就是在配置上还有写中断服务函数上卡壳了,不知道用什么来代替F103的秒中断和RTC-Setcounter()函数。因为在L152里面没找到秒中断标志位和溢出中断的标志位。代码如下:

void RTC_IRQHandler(void)
{                 
        if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
        {                                                       
                RTC_Get();//¸üÐÂʱ¼ä   
        }
        if(RTC_GetITStatus(RTC_IT_ALRA)!= RESET)
        {
                RTC_ClearITPendingBit(RTC_IT_ALRA);                                    
          }                                                                                                    
        RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);               
}

然后看了资料有人这么写的。

   //配置自动定时功能
    /* 中断配置 *******************************************************/
    EXTI_ClearITPendingBit(EXTI_Line20);
    EXTI_InitStructure.EXTI_Line = EXTI_Line20;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /*使能 RTC Wakeup Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* RTC 唤醒中端配置: Clock Source: RTCDiv_16, Wakeup Time Base: 4s */
    RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
    RTC_SetWakeUpCounter(0x1FFF);//0x1FFF = 8191; 4s = (8191+1)*(1/(32768/16))

    /* 使能 the Wakeup Interrupt */
    RTC_ITConfig(RTC_IT_WUT, ENABLE);  
}



使能了RTC的定时中断,那么就要编写中断服务子程序,如下:
void RTC_WKUP_IRQHandler(void)
{
  if(RTC_GetITStatus(RTC_IT_WUT) != RESET)
  {
    RTC_ClearITPendingBit(RTC_IT_WUT);
    EXTI_ClearITPendingBit(EXTI_Line20);
  }
}

但我不懂下面的那种写法中为什么还要给唤醒时钟进行分频,这样用能不能实现跟F103一样的效果。
版主  你写的代码是用cube写的吗?
Imody 回答时间:2017-7-6 14:23:42
安 发表于 2017-7-6 13:46
都差不多,L152系列的例程里面都有了。如下代码:

版主,我想问下时钟分频那里为什么是0X7F  0XFF。查了一下是同步的跟异步的,到时候用的是32.768K的外部晶振吧,原子是直接用的这个函数RTC_SetPrescaler()。那为什么要设置同步跟异步的那两个数呢。 L系列开发板没有秒中断函数,我查了一下用时间戳中断函数好像也行的,那我该怎么配置呢
Imody 回答时间:2017-7-5 19:52:23
希望能得到大神的指点,我QQ是1253414972
zhao.zhao 回答时间:2017-7-6 08:56:30
直接读出RTC内的秒数,然后就一样了
废鱼 回答时间:2017-7-6 09:31:26
stm32L152可以直接设置日期、时间、星期。设置以后会自动进行更新。
Imody 回答时间:2017-7-6 12:49:45
zhao.zhao 发表于 2017-7-6 08:56
直接读出RTC内的秒数,然后就一样了

在STM32L152中 好像没有秒中断函数的吧,看了好久都没找到,只有图片里面的这些函数。还有清除中断位函数中的秒中断和溢出中断函数也没找到
微信截图_20170706124554.png
TIM截图20170706124817.png
Imody 回答时间:2017-7-6 12:52:34
安 发表于 2017-7-6 09:31
stm32L152可以直接设置日期、时间、星期。设置以后会自动进行更新。

版主。在L152板子上配置的时候时钟分频的配置函数跟F1的板子好像不一样,但没找到具体是什么函数
zhao.zhao 回答时间:2017-7-6 13:25:34
使用HAL库,也不用动什么脑筋,很好使
Imody 回答时间:2017-7-6 14:05:34
zhao.zhao 发表于 2017-7-6 13:25
使用HAL库,也不用动什么脑筋,很好使

恩恩。是的。直接用stm32cube来配置的话很容易就弄好了。但主要是想不用cube然后自己弄一个写一个万年历的。谢谢提醒啦
废鱼 回答时间:2017-7-6 14:35:48
手册中写了,The maximum resolution allowed (30.52 μs with a 32768 Hz clock) is obtained with PREDIV_S set to 0x7FFF.
用秒中断做什么?要根据实际情况来进行设置。
Imody 回答时间:2017-7-6 15:00:14
安 发表于 2017-7-6 14:35
手册中写了,The maximum resolution allowed (30.52 μs with a 32768 Hz clock) is obtained with PREDIV ...

就像图中的打×和感叹号的语句一样,编译的时候是不通过的。我是直接把原子的代码复制过来,然后改一些地方。但现在这些地方找不到对应的函数
TIM截图20170706145529.png
TIM截图20170706145630.png
Imody 回答时间:2017-7-6 15:07:55
安 发表于 2017-7-6 13:46
都差不多,L152系列的例程里面都有了。如下代码:

好像懂了,里面的这个两个数是跟这句话有关的吧。RTC_PRER register: Write first the synchronous value and
then write the asynchronous。 然后LSE = 32.768 kHz,PREDIV_A[6:0] 127=0x7F。 PREDIV_S[12:0】 255=0xFF.这么设置的话正好外部晶振的频率是32768HZ。
废鱼 回答时间:2017-7-6 16:46:14
楼主,你看的是103的例程吧。L152是不一样的。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版