求助:STM32F407的RTC没有秒钟中断的问题

2019-07-21 03:54发布

之前的STM32F1系列都有秒钟中断,我现在这STM32F407发现没有秒中断,在参考手册里面有看到配置异步分频设置为:0x7F 同步分频:0xFF,就是产生1HZ。可是配置完后,发现,秒跳的非常快,不是一秒跳一次。而且设置了24小时格式的,根本上不了13之后的,如果是设置13之后的小时格式,就会超出24,移植到四十几小时,再跳回1小时。以下下是我RTC的配置 和读取:
void RTCTime_Test(void)
{
                RTC_InitTypeDef RTC_InitStructure;
    /* Output a message on Hyperterminal using printf function */
    printf("   *********************** RTC Time Stamp Example *********************** ");   
    if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x5566)
    {
        /* RTC configuration  */
        RTC_Config();
        /* Check on RTC init */
        if (RTC_Init(&RTC_InitStructure) == ERROR)
        {
            printf("         /!\***** RTC Prescaler Config failed ********/!\ ");
        }       
        /* Configure the time register */
        RTC_TimeRegulate(); 
//                                RTC_WriteProtectionCmd(DISABLE);
//                                RCC_RTCCLKCmd(ENABLE); 
    }
    else
    {
        /* Check if the Power On Reset flag is set */
        if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
        {
          printf(" Power On Reset occurred.... ");
        }
        /* Check if the Pin Reset flag is set */
        else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
        {
          printf(" External Reset occurred.... ");
        }       
        printf(" No need to configure RTC.... ");        
        /* Enable the PWR clock */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);       
        /* Allow access to RTC */
        WR_BackupAccessCmd(ENABLE);      
        /* Wait for RTC APB registers synchronisation */
        RTC_WaitForSynchro();        
        /* Clear the RTC Alarm Flag */
//        RTC_ClearFlag(RTC_FLAG_ALRAF);        
        /* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */
//        EXTI_ClearITPendingBit(EXTI_Line17);       
        /* Display the RTC Time/Date and TimeStamp Time/Date */
        RTC_TimeShow();
        RTC_DateShow();
        RTC_TimeStampShow();
    }
}


void RTC_Config(void)
{
        RTC_InitTypeDef RTC_InitStructure;
  //使能电源时钟//
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
        //使能后备区域时钟//
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
        RTC_DeInit();
  //允许RTC后备后备寄存器读写权限//
  WR_BackupAccessCmd(ENABLE);
  //复位后备域//
//  RCC_BackupResetCmd(ENABLE);
//  RCC_BackupResetCmd(DISABLE);
  // 使能外部低速时钟/
  RCC_LSEConfig(RCC_LSE_ON);
  //等待低速时钟准备就绪/  
  while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {
  }
  //选择外部低速时钟(LSE)作为RTC时钟源//
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); 
        //使能RTC//
        RCC_RTCCLKCmd(ENABLE); 
        //等待RTC APB 寄存器同步//
  RTC_WaitForSynchro();
        //Enable The TimeStamp
        RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, ENABLE);
        RTC_WriteProtectionCmd(ENABLE);
        //配置RTC分频值        设置1Hz//
//        RTC->CR |= 0x0010;                                                                                                                                                                                                //基准时钟
  RTC_InitStructure.RTC_AsynchPrediv = 0x7F;                          //设置异步分频值
  RTC_InitStructure.RTC_SynchPrediv  = 0xFF;                         //设置同步分频值
  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;             //设置时间格式为24小时制
  RTC_Init(&RTC_InitStructure);                                        //初始化RTC
        // 使能低电压时使用后备电池//
  WR_BackupRegulatorCmd(ENABLE);
//        RCC_BackupResetCmd(ENABLE);
        RCC_RTCCLKCmd(ENABLE);
  // 等待后备域低电压稳定器就绪 //
  while(PWR_GetFlagStatus(PWR_FLAG_BRR) == RESET)
  {
  }
   //向后备寄存器0写入0x5566用于标记已经配置过RTC//
//   RTC_WriteBackupRegister(RTC_BKP_DR0, 0X5566);                
}


void RTC_TimeStampRead(void)
{
//                RTC_Time RTC_Read;
        
                RTC_TimeTypeDef RTC_TimeStructure;
                RTC_DateTypeDef RTC_DateStructure;
        
                RTC_GetTime(RTC_Format_BIN,&RTC_TimeStructure);                                                //获取时间BCD码
                RTC_GetDate(RTC_Format_BIN,&RTC_DateStructure);                                                //获取日期BCD码
                BACK_COLOR = WHITE;
                POINT_COLOR = RED;

                LCD_ShowNum(56,100,RTC_DateStructure.RTC_Year,2,RED);
                LCD_ShowNum(104,100,RTC_DateStructure.RTC_Month,2,RED);
                LCD_ShowNum(160,100,RTC_DateStructure.RTC_Date,2,RED);
                LCD_ShowNum(72,120,RTC_DateStructure.RTC_WeekDay,2,RED);
                LCD_ShowNum(40,140,RTC_TimeStructure.RTC_Hours,2,RED);
                LCD_ShowNum(96,140,RTC_TimeStructure.RTC_Minutes,2,RED);
                LCD_ShowNum(136,140,RTC_TimeStructure.RTC_Seconds,2,RED);
}
int main(void)
{                 
        Clock_Config();                        //系统时钟设置 168M 此后可以设置超频输出到432MHz
        Delay_Init();
        LCD_Init();
        LED_Init();                                  //初始化与LED连接的硬件接口
        COM1Init(115200);
        DMA_Conf(USART_REC_LEN);
        DMA_NVIC_Init();
        USART_NVIC_Init();
        
//        RTC_AlarmConfig();
        Address_set(0,0,800,480);
        LCD_Clear(WHITE);
        LCD_ShowString(40,100,"20  year  month  data",1,BLUE);
        LCD_ShowString(40,120,"week  ",1,BLUE);
        LCD_ShowString(40,140,"  hours  min  sec",1,BLUE);
        if (SysTick_Config(SystemCoreClock / 1000))  //延时1毫秒
        { 
         /* Capture error */ 
                while (1);
        }
        while(1)
        {
                RTCTime_Test();
                RTC_TimeStampRead();
                Delay_ms(500);
//                LCD_Clear(WHITE);
        }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
注册个号来学习
1楼-- · 2019-07-22 13:24
回复【13楼】正点原子:
---------------------------------
错了,一个控制LED1,一个控制LED0,用RTC_WAKE_UP中断控制LED1,用定时器中断控制LED0,都设置的是1秒钟发生一次中断,为什么板子测试时两个灯亮的有先后顺序,并且中间有时还不准。
我好像漏了一点东西:TIM_GetITStatus这个函数的值为SET和RESET什么意思?我看开发指南上没怎么讲这块。
谢谢了。原子哥
注册个号来学习
2楼-- · 2019-07-22 17:20
回复【13楼】正点原子:
---------------------------------
在固件库函数里面,用来读取中断状态寄存器的值判断中断类型的函数是:
ITStatusTIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)
该函数的作用是,判断定时器TIMx的中断类型TIM_IT是否发生中断。比如,我们要判断定时器3是否发生更新(溢出)中断,方法为:
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){}
固件库中清除中断标志位的函数是:
 
voidTIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
该函数的作用是,清除定时器TIMx的中断TIM_IT标志位。使用起来非常简单,比如我们在TIM3的溢出中断发生后,我们要清除中断标志位,方法是:
TIM_ClearITPendingBit(TIM3,TIM_IT_Update  );
这里需要说明一下,固件库还提供了两个函数用来判断定时器状态以及清除定时器状态标志位的函数TIM_GetFlagStatus和TIM_ClearFlag,他们的作用和前面两个函数的作用类似。只是在TIM_GetITStatus函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而TIM_GetFlagStatus直接用来判断状态标志位。

我找到这些资料,有点理解了。

一周热门 更多>