OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2370|回复: 6

F0 RTC闹钟中断作为秒中断时间不准

[复制链接]

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2018-4-15
在线时间
34 小时
发表于 2019-10-18 16:20:42 | 显示全部楼层 |阅读模式
10金钱
求助大侠们,使用STM32F030的RTC Alarm 中断实现 1s中断计数一次 功能,但是设置10s,实际用示波器抓时间只有7.9s,f0的LSI是40kHZ,已设置频率1HZ,Alarm也设置了一秒中断1次
/* Set AlarmA subseconds and enable SubSec Alarm : generate 1 interripts per Second */
    RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0XFF, RTC_AlarmSubSecondMask_SS14_8);
  

百度多方信息对于F0的信息少,跪求大佬们指教,源代码如下

void USR_RTC_Init(void)
{
   RTC_InitTypeDef  RTC_InitStructure;
  RTC_TimeTypeDef  RTC_TimeStruct;
  
    EXTI_InitTypeDef EXTI_InitStructure;
  RTC_AlarmTypeDef RTC_AlarmStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the PWR clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  /* Allow access to RTC */
  PWR_BackupAccessCmd(ENABLE);

  /* Reset RTC Domain */
  RCC_BackupResetCmd(ENABLE);
  RCC_BackupResetCmd(DISABLE);

  /* Enable the LSE OSC */
  RCC_LSICmd(ENABLE);                    /*使能LSI时钟*/

  /* Wait till LSE is ready */  
  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /*等待LSI就绪*/

  /* Select the RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  

  /* Configure the RTC data register and RTC prescaler */
  /* ck_spre(1Hz) = RTCCLK(LSI) /(AsynchPrediv + 1)*(SynchPrediv + 1)*/
  RTC_InitStructure.RTC_AsynchPrediv = 99;
  RTC_InitStructure.RTC_SynchPrediv  = 399;
  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
  RTC_Init(&RTC_InitStructure); //1HZ
  
  /* Set the time to 00h 00mn 00s AM */
  RTC_TimeStruct.RTC_H12     = RTC_H12_AM;
  RTC_TimeStruct.RTC_Hours   = 0x00;
  RTC_TimeStruct.RTC_Minutes = 0x00;
  RTC_TimeStruct.RTC_Seconds = 0x00;  
  RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);


  RTC_AlarmStructInit(&RTC_AlarmStructure);
   
  /* EXTI configuration */
  EXTI_ClearITPendingBit(EXTI_Line17);
  EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  
  /* Enable the RTC Alarm Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Set the alarmA Masks */
  RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
  RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0x01;
  RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_Seconds;
  RTC_SetAlarm(RTC_Format_BCD, RTC_Alarm_A, &RTC_AlarmStructure);
  
  /* Set AlarmA subseconds and enable SubSec Alarm : generate 1 interripts per Second */
    RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0XFF, RTC_AlarmSubSecondMask_SS14_8);
  
   /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);
   
    /* Wait for RTC APB registers synchronisation */
    RTC_WaitForSynchro();
   
    /* Enable the alarmA */
    RTC_AlarmCmd(RTC_Alarm_A, ENABLE);

  /* Enable AlarmA interrupt */
  RTC_ITConfig(RTC_IT_ALRA, ENABLE);
}

void RTC_IRQHandler(void)
{
  /* Check on the AlarmA flag and on the number of interrupts per Second (60*8) */
  if(RTC_GetITStatus(RTC_IT_ALRA) != RESET)
  {
    /* ALARM is enabled */
   if((Start_RTC == 1)&&(SetValue.RemainingTime>0))
   {
      SetValue.RemainingTime--;
   }
    /* Clear RTC AlarmA Flags */
    RTC_ClearITPendingBit(RTC_IT_ALRA);
  }
  /* Clear the EXTIL line 17 */
  EXTI_ClearITPendingBit(EXTI_Line17);
  
}





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2018-4-15
在线时间
34 小时
 楼主| 发表于 2019-10-18 16:22:54 | 显示全部楼层
void USR_RTC_Init(void)
{
   RTC_InitTypeDef  RTC_InitStructure;
  RTC_TimeTypeDef  RTC_TimeStruct;
  
    EXTI_InitTypeDef EXTI_InitStructure;
  RTC_AlarmTypeDef RTC_AlarmStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the PWR clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  /* Allow access to RTC */
  PWR_BackupAccessCmd(ENABLE);

  /* Reset RTC Domain */
  RCC_BackupResetCmd(ENABLE);
  RCC_BackupResetCmd(DISABLE);

  /* Enable the LSE OSC */
  RCC_LSICmd(ENABLE);                    /*使能LSI时钟*/

  /* Wait till LSE is ready */  
  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /*等待LSI就绪*/

  /* Select the RTC Clock Source */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  

  /* Configure the RTC data register and RTC prescaler */
  /* ck_spre(1Hz) = RTCCLK(LSI) /(AsynchPrediv + 1)*(SynchPrediv + 1)*/
  RTC_InitStructure.RTC_AsynchPrediv = 99;
  RTC_InitStructure.RTC_SynchPrediv  = 399;
  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
  RTC_Init(&RTC_InitStructure); //1HZ
  
  /* Set the time to 00h 00mn 00s AM */
  RTC_TimeStruct.RTC_H12     = RTC_H12_AM;
  RTC_TimeStruct.RTC_Hours   = 0x00;
  RTC_TimeStruct.RTC_Minutes = 0x00;
  RTC_TimeStruct.RTC_Seconds = 0x00;  
  RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);


  RTC_AlarmStructInit(&RTC_AlarmStructure);
   
  /* EXTI configuration */
  EXTI_ClearITPendingBit(EXTI_Line17);
  EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  
  /* Enable the RTC Alarm Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Set the alarmA Masks */
  RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
  RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0x01;
  RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_Seconds;
  RTC_SetAlarm(RTC_Format_BCD, RTC_Alarm_A, &RTC_AlarmStructure);
  
  /* Set AlarmA subseconds and enable SubSec Alarm : generate 1 interripts per Second */
    RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0XFF, RTC_AlarmSubSecondMask_SS14_8);
  
   /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);
   
    /* Wait for RTC APB registers synchronisation */
    RTC_WaitForSynchro();
   
    /* Enable the alarmA */
    RTC_AlarmCmd(RTC_Alarm_A, ENABLE);

  /* Enable AlarmA interrupt */
  RTC_ITConfig(RTC_IT_ALRA, ENABLE);
}

void RTC_IRQHandler(void)
{
  /* Check on the AlarmA flag and on the number of interrupts per Second (60*8) */
  if(RTC_GetITStatus(RTC_IT_ALRA) != RESET)
  {
    /* ALARM is enabled */
   if((Start_RTC == 1)&&(SetValue.RemainingTime>0))
   {
      SetValue.RemainingTime--;
   }
    /* Clear RTC AlarmA Flags */
    RTC_ClearITPendingBit(RTC_IT_ALRA);
  }
  /* Clear the EXTIL line 17 */
  EXTI_ClearITPendingBit(EXTI_Line17);
  
}
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10570
金钱
10570
注册时间
2017-2-18
在线时间
1913 小时
发表于 2019-10-18 17:28:53 | 显示全部楼层
帮顶~~
回复

使用道具 举报

0

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
416
金钱
416
注册时间
2019-8-7
在线时间
182 小时
发表于 2019-10-21 17:36:25 | 显示全部楼层
我用F030,测试RTC一秒还是挺准确的啊。可能你的内部晶振不稳定吧
回复

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2018-4-15
在线时间
34 小时
 楼主| 发表于 2019-10-23 11:41:44 | 显示全部楼层
振翅高飞2019 发表于 2019-10-21 17:36
我用F030,测试RTC一秒还是挺准确的啊。可能你的内部晶振不稳定吧

我后面修改了程序 用示波器抓时间
10s  示波器抓时间10.224s
30s                       29.735s
40s                      39.5600s
60s                      59.295s
120                      117.770s

感觉误差还是挺大的
回复

使用道具 举报

0

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
416
金钱
416
注册时间
2019-8-7
在线时间
182 小时
发表于 2019-10-23 13:48:49 | 显示全部楼层
黄LX 发表于 2019-10-23 11:41
我后面修改了程序 用示波器抓时间
10s  示波器抓时间10.224s
30s                       29.735s

我测试的时候只是用示波器大概量了一下1秒的时间,没仔细测量啊。要精确的可以硬件加32.768k晶振,或用时钟芯片啊
回复

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2018-4-15
在线时间
34 小时
 楼主| 发表于 2019-10-23 16:57:40 | 显示全部楼层
振翅高飞2019 发表于 2019-10-23 13:48
我测试的时候只是用示波器大概量了一下1秒的时间,没仔细测量啊。要精确的可以硬件加32.768k晶振,或用时 ...

加东西就加成本 嘿嘿嘿
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-2 20:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表