stm32 RTC_WaitForSynchro()死循环

1.RTC_WaitForSynchro()死循环,发现是没有执行RTC_Configuration(),增加函数,但不知道对之后的时钟准确性有什么影响


/*******************************************************************************
* Function Name  : RTC_Configuration
* Description    : Configures the RTC.
* Input          : None
* Output         : None
* Return         : 0 reday,-1 error.
*******************************************************************************/
int RTC_Configuration(void)
{
    u32 countmax = 0x20000;
    u32 count = countmax;
    /* 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) && (--count));
 
    if(count == 0)
    {
        count = countmax;
        //关闭外部低速晶振(LSE)
        RCC_LSEConfig(RCC_LSE_OFF);
        //如果失败,使用内部晶振
        //使能或者失能内部低速晶振(LSI)
        RCC_LSICmd(ENABLE);
        //设置RTC时钟(RTCCLK)
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
 
        /* Wait till LSI is ready */
        while((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) && (--count));
 
        if(count == 0)
            return 1;
    }
    else
    {
        /* Select LSE as RTC Clock Source */
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//设置RTC时钟(RTCCLK)
    }
 
    /* 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();
    /* 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();
    return 0;
}


void rt_hw_rtc_init(void)
{
    rtc.type    = RT_Device_Class_RTC;
 
    if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
    {
        rt_kprintf("rtc is not configured\n");
        rt_kprintf("please configure with set_date and set_time\n");
 
        if(RTC_Configuration() != 0)
        {
            rt_kprintf("rtc configure fail...\r\n");
            return ;
        }
    }
    else
    {
        if(RTC_Configuration() != 0)
        {
            rt_kprintf("rtc configure fail...\r\n");
            return ;
        }
 
        /* Wait for RTC registers synchronization */
        RTC_WaitForSynchro();
    }
 
    /* register rtc device */
    rtc.init    = RT_NULL;
    rtc.open    = rt_rtc_open;
    rtc.close   = RT_NULL;
    rtc.read    = rt_rtc_read;
    rtc.write   = RT_NULL;
    rtc.control = rt_rtc_control;
    /* no private */
    rtc.user_data = RT_NULL;
    rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
    return;
}









void RTC_Config(void) { uint8_t timeout = 0; RTC_InitTypeDef RTC_InitStructure; //Enable the PWR clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //Allow access to RTC PWR_BackupAccessCmd(ENABLE); if(RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2) { //Reset RTC Domain RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE); /**** firstly use LSE OSC for RTC ****/ //Enable the LSE OSC RCC_LSEConfig(RCC_LSE_ON); //Wait till LSE is ready while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) { timeout++; Delay_MS(20); if(timeout > 200) { break; } } if(timeout < 200) { //Select the RTC Clock Source RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); //Configure the RTC data register and RTC prescaler RTC_InitStructure.RTC_AsynchPrediv = 0x7F; RTC_InitStructure.RTC_SynchPrediv = 0xFF; //32.768KHz RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); } else //after 4 seconds LSE not stable use LSI 4秒后LSE没准备好才使用LSI { //Enable the LSI OSC RCC_LSICmd(ENABLE); //Wait till LSI is ready while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == 0) {} //Select the RTC Clock Source RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); //Configure the RTC data register and RTC prescaler RTC_InitStructure.RTC_AsynchPrediv = 0x7F; RTC_InitStructure.RTC_SynchPrediv = 0xFA; //LSI 32KHz RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_Init(&RTC_InitStructure); } RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2); } } void RTC_AlarmInterrupt_Init(void) //--wangbin 2025.3.20 { NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; // 配置EXTI Line17(连接到RTC Alarm) 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); // 配置RTC Alarm中断优先级 NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void RTC_AlarmSet(uint8_t x,uint8_t WeekDay,uint8_t Hours,uint8_t Minutes) //--wangbin 2025.3.20 { RTC_AlarmTypeDef RTC_AlarmStructure; // 参数合法性检查(根据实际需求添加) assert_param(IS_RTC_HOURS(Hours)); assert_param(IS_RTC_MINUTES(Minutes)); assert_param(IS_RTC_WEEKDAY(WeekDay)); /* 禁用闹钟 */ RTC_AlarmCmd(RTC_Alarm_A, DISABLE); /* 设置闹钟时间参数 */ // 使用星期模式(非日期模式) RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay; if (x == 3){ RTC_AlarmStructure.RTC_AlarmDateWeekDay = WeekDay; } // 设置时间(忽略秒) else if(x == 4){ RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = Hours; } else{ RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = Minutes; } RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0; // 秒被忽略 // 设置掩码:仅匹配星期、小时、分钟(忽略秒) RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;//RTC_AlarmMask_Seconds; /* 写入闹钟配置 */ RTC_SetAlarm(RTC_Format_BINorBCD, RTC_Alarm_A, &RTC_AlarmStructure); /* 使能闹钟中断及闹钟 */ RTC_ITConfig(RTC_IT_ALRA, ENABLE); // 根据AlarmX选择对应中断 RTC_AlarmCmd(RTC_Alarm_A, ENABLE); /* 清除中断标志 */ RTC_ClearFlag(RTC_FLAG_ALRAF); // 根据AlarmX选择对应标志 EXTI_ClearITPendingBit(EXTI_Line17); }这三个函数是我对RTC的操作,看着有什么问题吗
03-22
逐句分析以下代码/** ****************************************************************************** * @file stm32f10x_rtc.c * @author MCD Application Team * @version V3.5.0 * @date 11-March-2011 * @brief This file provides all the RTC firmware functions. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_rtc.h" /** @addtogroup STM32F10x_StdPeriph_Driver * @{ */ /** @defgroup RTC * @brief RTC driver modules * @{ */ /** @defgroup RTC_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup RTC_Private_Defines * @{ */ #define RTC_LSB_MASK ((uint32_t)0x0000FFFF) /*!< RTC LSB Mask */ #define PRLH_MSB_MASK ((uint32_t)0x000F0000) /*!< RTC Prescaler MSB Mask */ /** * @} */ /** @defgroup RTC_Private_Macros * @{ */ /** * @} */ /** @defgroup RTC_Private_Variables * @{ */ /** * @} */ /** @defgroup RTC_Private_FunctionPrototypes * @{ */ /** * @} */ /** @defgroup RTC_Private_Functions * @{ */ /** * @brief Enables or disables the specified RTC interrupts. * @param RTC_IT: specifies the RTC interrupts sources to be enabled or disabled. * This parameter can be any combination of the following values: * @arg RTC_
03-12
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值