OpenEdv-开源电子网

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

STM32 RTC闹钟问题

[复制链接]

4

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2014-8-8
在线时间
1 小时
发表于 2014-8-20 15:30:01 | 显示全部楼层 |阅读模式
5金钱
 大家帮我看看我的STM32F107VCT6一直触发不了闹钟中断,目前只能触发秒中断。网上的很多例子都是利用RTC唤醒低功耗模式,我的这个项目不需要闹钟来唤醒低功耗。
我把我的RTC部分代码全贴下面。

/*******************************************************************************
* Function Name  : RTC_Configuration
* Description    : Configures the RTC.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTC_Configuration(void)
{
  /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);

  /* Reset Backup Domain */
  BKP_DeInit();

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

  /* Wait for RTC registers synchronization */
  RTC_WaitForSynchro();

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

    /* Enable the RTC ALARM */
     RTC_ITConfig(RTC_IT_ALR, ENABLE);

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

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


void RTC_Init(void)
{
  if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
  {
    /* Backup data register value is not correct or not yet programmed (when
       the first time the program is executed) */

    printf("\r\n RTC not yet configured....");

      RTC_Configuration();

    printf("\r\n RTC configured....");

    /* Adjust time by values entred by the user on the hyperterminal */
     Time_SetCalendarTime(time_now);
    BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  }
  else
  {
    /* Check if the Power On Reset flag is set */
    if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
    {
      printf("\r\n\n Power On Reset occurred....");
    }
    /* Check if the Pin Reset flag is set */
    else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
    {
      printf("\r\n\n External Reset occurred....");
    }
    printf("\r\n No need to configure RTC....");
    /* Wait for RTC registers synchronization */
    RTC_WaitForSynchro();

          /* Enable the RTC ALARM */
     RTC_ITConfig(RTC_IT_ALR, ENABLE);

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

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

  /* Clear reset flags */
  RCC_ClearFlag();
}

void Alarm_PreAdjust(void)
{
 // uint32_t alarm_value = 0;
  uint32_t tmp = 0;

  /* Read the alarm value stored in the Backup register */
  tmp = BKP_ReadBackupRegister(BKP_DR6);
  tmp |= BKP_ReadBackupRegister(BKP_DR7) << 16;

     tmp = (time_alarm.tm_year + time_alarm.tm_mon + time_alarm.tm_mday + time_alarm.tm_hour
        + time_alarm.tm_min + time_alarm.tm_sec);

  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  /* Set RTC Alarm register with the new value */
  RTC_SetAlarm(tmp);
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();  

          /* Enable PWR and BKP clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);

  /* Save the Alarm value in the Backup register */
  BKP_WriteBackupRegister(BKP_DR6, (tmp & 0x0000FFFF));
  BKP_WriteBackupRegister(BKP_DR7, (tmp >> 16));
  PWR_BackupAccessCmd(DISABLE);
}

void Set_RTCAlarm(void)
{  
  uint32_t tmp = 0;

  tmp = RTC_GetCounter();

  /* Save the Alarm value in the Backup register */
  BKP_WriteBackupRegister(BKP_DR6, (tmp & 0x0000FFFF));
  BKP_WriteBackupRegister(BKP_DR7, (tmp >> 16));
      
  Alarm_PreAdjust();
 
  /* Request to enter STOP mode with regulator in low power */
//  PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

}

上面是RTC初始化和设置闹钟函数。

//系统中断管理
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
      /* Configure the NVIC Preemption Priority Bits */  
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;    //更新事件
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //抢占优先级1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          //响应优先级1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //允许中断
    NVIC_Init(&NVIC_InitStructure);
        /* 使能 RTC 中断 */
        
    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

      /* Enable the RTC Alarm Interrupt */
      NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    
      /* Enable the EXTI Line17 Interrupt */
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
      EXTI_InitStructure.EXTI_Line = EXTI_Line17;
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);

}
//配置系统时钟,使能各外设时钟
void RCC_Configuration(void)
{
    SystemInit();    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA
                           | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB | RCC_APB2Periph_ADC1
                           | RCC_APB2Periph_AFIO, ENABLE );
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 | RCC_APB1Periph_PWR | RCC_APB1Periph_BKP
                           |RCC_APB1Periph_USART2|RCC_APB1Periph_TIM2                               
                           , ENABLE );
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
}


下面是RTC闹钟中断函数,一直进不了这里。

/*******************************************************************************
* Function Name  : RTCAlarm_IRQHandler
* Description    : This function handles RTC Alarm interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTCAlarm_IRQHandler(void)
{
     /* Clear the Alarm Pending Bit */
  RTC_ClearITPendingBit(RTC_IT_ALR);
 
      AlarmStatus = 1;
      alarm_flag = 1;
//  Set_STOPModeStatus();
        LED1 = 1;
  /* Clear the EXTI Line 17/ */  
  EXTI_ClearITPendingBit(EXTI_Line17);
     
}

进不了RTCAlarm_IRQHandler(void)的时候我又在下面函数中也同样插入了闹钟处理函数。

/*******************************************************************************
* Function Name  : RTC_IRQHandler
* Description    : This function handles RTC global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTC_IRQHandler(void)
{
    if(RTC_GetITStatus(RTC_IT_SEC) != RESET)
      {
            Time_Show();
        /* 清除 RTC 秒中断 */
        RTC_ClearITPendingBit(RTC_IT_SEC);
        /* 更新时间显示标志位 */
    //    TimeDisplay = 1;
    }
    if (RTC_GetITStatus(RTC_IT_ALR) != RESET){
        
      AlarmStatus = 1;
      alarm_flag = 1;
//  Set_STOPModeStatus();
        LED1 = 1;
         /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
 /* Clear the Alarm Pending Bit */
          RTC_ClearITPendingBit(RTC_IT_ALR);
  /* Wait until last write operation on RTC registers has finished */
  RTC_WaitForLastTask();
  /* Clear the EXTI Line 17/ */  
  EXTI_ClearITPendingBit(EXTI_Line17);
    
    }
}

上面那个函数只能秒中断处理能进入。另外我的RTC闹钟值是能设置成功的,包括BKP->DR6,DR7都能写入成功,目前就是不能触发闹钟中断标志位。
先在这里谢谢了。

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-8-20 21:38:54 | 显示全部楼层
楼主可以参考下我们的库函数版本例程.
综合实验.才有闹钟设置部分.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2014-8-8
在线时间
1 小时
 楼主| 发表于 2014-8-20 23:30:07 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我在线仿真时发现RTC->ALRH,ALARL的值都是65535。不掉电的话能写进去,重新上电用仿真器查看时就是65535。
说明没有写进去,但是我不掉电的话,我的值写进去了啊,怎么也不触发闹钟呢。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-2 14:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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