完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我通过设置RTC时钟定时每一分钟唤醒MCU一次进行一些查询检测工作。但会偶尔发现无法唤醒MCU,感觉RTC无法产生中断,应该是RTC的问题,现在就是不知道是硬件引起的还是软件引起的。因为有的机子从来没有问题,有的偶尔会有,但不是每次都出现,有的用了很久也没有出现过。很困扰。以下是RTC的处理代码,有哪位大侠搞过RTC闹钟唤醒睡眠的,帮看看有没有问题。
/****************************************************************************** **函数名: Init_RTC **入 口: **返 回: **功 能: RTC配置初始化 *******************************************************************************/ void Init_RTC(void) { RTC_Config(); GetRTCtime(); Set_RTC_Alarm_Minute(); //设置闹钟时间 } /****************************************************************************** **函数名:RTC_Config **入 口: **返 回: **功 能: RTC配置,24小时的时间格式 *******************************************************************************/ void RTC_Config(void) { RTC_InitTypeDef RTC_InitStructure; RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE ); /* Enable the PWR clock */ PWR_BackupAccessCmd( ENABLE ); /* Allow access to RTC */ if( RTC_ReadBackupRegister( RTC_BKP_DR0 ) != RTC_BKP_VALUE )//如果掉电了,则重新初始化时间 { RCC_LSEConfig( RCC_LSE_ON); /* Enable the LSE OSC */ while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET ); /* Wait till LSE is ready */ RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE ); /* Select the RTC Clock Source */ RCC_RTCCLKCmd( ENABLE ); /* Enable the RTC Clock */ RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */ //设置RTC时钟分频,1秒 RTC_InitStructure.RTC_AsynchPrediv = 127; RTC_InitStructure.RTC_SynchPrediv = 255;//255 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; //24小时的时间格式 if( RTC_Init( &RTC_InitStructure ) == ERROR ) { /* 此处作设置失败处理 */ } //设置默认的时间:2017-1-1- 12:30:00 SetCalendarTime( DEFAULT_HOUR, DEFAULT_MIN, DEFAULT_SEC); //时间 SetCalendarDate(3,DEFAULT_YEAR,DEFAULT_MON,DEFAULT_DAY); //日期 bPowerDown = TRUE;//系统掉电,又重新上电 bSynchronizeTime = TRUE; } else { RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */ RTC_ClearFlag( RTC_FLAG_ALRAF ); /* Clear the RTC Alarm Flag */ } } /****************************************************************************** **函数名:Set_RTC_Alarm_Minute **入 口: **返 回: **功 能: 设置RTC报警时间,单位为分钟 *******************************************************************************/ void Set_RTC_Alarm_Minute(void) { RTC_AlarmTypeDef RTC_AlarmStructure; unsigned char hour = 0; unsigned char min = 0; // unsigned char sec = 0; //GetRTCTime(); //获取系统时间 hour = RTC_Time[3]; min = RTC_Time[4]; min += 1; if(min >= 60) { min = 0; hour += 1; if(hour >= 24) hour = 0; } RTC_ITConfig( RTC_IT_ALRA, DISABLE ); /* Enable the RTC Alarm A Interrupt */ RTC_AlarmCmd( RTC_Alarm_A, DISABLE ); /* Disable the Alarm A */ RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM; RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = hour; RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = min; RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0; /* Set the Alarm A */ RTC_AlarmStructure.RTC_AlarmDateWeekDay = 31; RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay; RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure ); /* Configure the RTC Alarm A register */ RTC_ITConfig( RTC_IT_ALRA, ENABLE ); /* Enable the RTC Alarm A Interrupt */ RTC_AlarmCmd( RTC_Alarm_A, ENABLE ); /* Enable the alarm A */ } /****************************************************************************** **函数名:GetRTCTime **入 口: **返 回: **功 能: 读取RTC时间 *******************************************************************************/ void GetRTCTime(void) { unsigned char Getweek = 0; GetCalendarTime(&RTC_Time[3],&RTC_Time[4],&RTC_Time[5]); GetCalendarDate(&Getweek,&RTC_Time[0],&RTC_Time[1],&RTC_Time[2]); } /****************************************************************************** **函数名:RTC_IRQHandler **入 口: **返 回: **功 能: 日历报警中断 *******************************************************************************/ void RTC_IRQHandler( void ) { if( RTC_GetITStatus( RTC_IT_ALRA ) != RESET ) { if((gStatus != G_POWER_OFF)&&(gStatus != G_MODE_CHARGE)) { GprsConnectInTime++; } else { GprsConnectInTime = 0; } bOneMinuteFlg = TRUE;//一分钟时间到 bBatTest1Min = TRUE; //一分钟测量一次电量 RTC_ClearITPendingBit( RTC_IT_ALRA ); } EXTI_ClearITPendingBit(EXTI_Line17); } } } } /****************************************************************************** **函 数 名: **入 口: **返 回: **功 能: *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; //RTC时钟中断 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); NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RTC_ClearITPendingBit( RTC_IT_ALRA ); EXTI_ClearITPendingBit(EXTI_Line17); } /****************************************************************************** **函数名:main **入 口: **返 回: **功 能: 系统主程序 *******************************************************************************/ int main(void) { ............. Init_RTC(); //日历时间初始化 ................ NVIC_Configuration(); //系统中断配置初始化 while(1) { //每分钟检测一次 if(bOneMinuteFlg == TRUE) { bOneMinuteFlg = FALSE; GetRTCTime(); //获取系统时间 Set_RTC_Alarm_Minute(); //设置闹钟中断时间 } .......................... SleepMode(); ............................ } |
|
相关推荐
12个回答
|
|
哇,这种少量事件很难处理。。。有的行,有的不行。。。不能唤醒只的是,会漏掉一分钟?还是说一睡不醒?
|
|
|
|
睡不醒了一样,通过按键中断唤醒后,又正常了
|
|
|
|
你的RTC时钟是外部还是内部?外部的话,Crystal的质量是否可靠,负载电容是否合适?
|
|
|
|
使用的外部晶振32.768K。我要先确认如果软件没有问题再去排查硬件问题
|
|
|
|
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;这个把秒也加上
另外,如果是一分钟唤醒一次,不如使用RTC WakeUp,这个简单方便。 |
|
|
|
1分钟唤醒一次,这样只开分就可以了。把日、小时、秒都关了。
|
|
|
|
如果不关会有问题吗
|
|
|
|
如果不关,他是要等到时分秒都匹配了才会唤醒。下面是我使用时分唤醒的配置:
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_Seconds | RTC_AlarmMask_DateWeekDay; |
|
|
|
TOPCB 发表于 2018-12-10 11:58 hour = RTC_Time[3]; min = RTC_Time[4]; min += 1; if(min >= 60) { min = 0; hour += 1; if(hour >= 24) hour = 0; } RTC_ITConfig( RTC_IT_ALRA, DISABLE ); /* Enable the RTC Alarm A Interrupt */ RTC_AlarmCmd( RTC_Alarm_A, DISABLE ); /* Disable the Alarm A */ RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM; RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = hour; RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = min; RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = 0; 你说的这个我也会试试。不过以上我是根据每次当前时间设置下一次闹钟时间的,就是下一次分钟闹钟,我觉得这个也没有什么问题。 |
|
|
|
换个硬件再测试下是否为软件问题
|
|
|
|
不过还有一个现象,我设定的是每分钟闹钟中断一次并更新时间,但是偶尔发现中间有一次一分钟时间过来也不产生中断,然后时间就慢了一分钟,过了大概过10分钟这样然后时间又对应上了,感觉是连续产生两次中断,时间刷了两次。每次中断都是读取RTC时间,不是人为加一累计。
|
|
|
|
这个问题有可能是GetRTCTime这个函数调用中处理有问题,读取时间存储是数组,则是通过指针传递,然后这个数据没有得到及时更新,造成时间延后。但本身时间已经是走了,而读取的时间没有更新,则设定的闹钟就永远的错过了
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1085 浏览 0 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1041 浏览 2 评论
2145 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1240 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1660 浏览 1 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 01:10 , Processed in 0.916543 second(s), Total 96, Slave 79 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号