RTC休眠后,闹钟唤醒掉电模式,偶发性唤醒失败
单片机型号: STC8H4K64TL
固件版本号: 7.4.3U
碰到比较奇怪的现象,使用外部32.768晶振驱动RTC,设备每次休眠前都会设置下一次唤醒的闹钟,经过烧机测试发现会出现偶发性的唤醒失败的情况。
休眠前打印的闹钟时间比当前时间往后、闹钟标志也都是清零的,在PCON的6个nop后打印当前时间用于判断是否唤醒成功,
不能理解的是,当偶发性出现唤不醒的时候,PCON后面的时间打印也没输出,有没有大佬遇到过这种情况?
初步判定跟IRCDB有关,还在持续烧机测试中 miaoyahan 发表于 2024-3-29 11:37
初步判定跟IRCDB有关,还在持续烧机测试中
如果跟IRCDB有关的话,你的IRC主频是不是设置很高? 乘风飞扬 发表于 2024-3-29 11:47
如果跟IRCDB有关的话,你的IRC主频是不是设置很高?
主频只有24M,奇怪的是IRCDB设置的越大越稳定,反之越小则RTC唤不醒的概率越大,有点搞不懂了。。。 miaoyahan 发表于 2024-3-29 13:10
主频只有24M,奇怪的是IRCDB设置的越大越稳定,反之越小则RTC唤不醒的概率越大,有点搞不懂了。。。 ...
主频24M正常是不需要修改IRCDB寄存器的。
方便的话把你相关的代码发出来大家一起分析一下。 /*
//////////////////IE
bit7*bit6bit5*bit4*bit3 bit2 bit1* bit0
EA ELVDEADC 串口1time1外部中断1time0 外部中断0
总开 adc 调试 串口1 滴答
//////////////////IE2
bit7* bit6 bit5* bit4 bit3 bit2 bit1bit0*
触摸 time4 time3串口4串口3 time2SPI 串口2
按键 pwm
//////////////////P0INTE P06-BAT P07-DC
//////////////////P0WKUE P06-BAT P07-DC
//////////////////RTCIEN rtc中断
//////////////////P5INTE P51,电机对射
*/
#define ENTER_SLEEP_CFG_PIN()do{\
WIFI_SLEEP_IO();\
LED_SLEEP_IO();\
ADC_SLEEP_IO();\
PWM_SLEEP_IO();\
MOTOR_SLEEP_IO();\
REMAIN_SLEEP_IO();\
}while(0)
#define ENTER_SLEEP_DOING()do{\
IE &= ~((1<<5)|(1<<4)|(1<<1));\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
PCON = 0x02;\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
IE |= ((1<<5)|(1<<4)|(1<<1));\
}while(0)
#define BREAK_SLEEP_CFG_PIN()do{\
WIFI_CFG_PIN();\
RTC_CFG_PIN();\
TOUCH_CFG_PIN();\
LED_CFG_PIN();\
ADC_CFG_PIN();\
PWM_CFG_PIN();\
MOTOR_CFG_PIN();\
REMAIN_CFG_PIN();\
}while(0)
//休眠处理
void gui_sleep_while(SLEEP_TYPE type)
{
unsigned char rtcbuf;//默认深度休眠
rtcbuf = 0xff;
rtcbuf = 0xff;
rtcbuf = 0xff;
/////////////////////////////////// 进入休眠
// 正常休眠--按键、闹钟唤醒
if(type == SLEEP_NORMAL){
// 休眠前准备,检索喂食计划设置闹钟
if(feed_sleep_before(rtcbuf)==0){
return;//休眠时间和喂食时间太近,直接不休眠
}
// 触摸休眠--触摸唤醒
touch_sleep_set(KEY_SLEEP_ENTER);
// 打开闹钟唤醒
RTC_IEN_ALARM();
}
// 深度休眠--仅RTC工作
else{
// 触摸休眠--触摸失能
touch_sleep_set(KEY_SLEEP_DISABLE);
// 深度休眠--RTC不唤醒
RTC_IEN_OFF();
}
// 关闭5V电源
POWER_ALL5V_SET(0);
POWER_MCU3V3_SET(0);
// 关闭屏幕
gui_display_full_set(0);
bsp_sys_delay_n10ms(5);
// 打印闹钟唤醒时间
gui_queue_rtc_alarm(rtcbuf);
gui_queue_push2uart();
// 立即刷新时间和主显
gui_time_ref();
// 发送主显内容,立即显示
gui_main_info.cmd = QUEUE_CMD_MAIN_SLEEP;
gui_queue_main_display();
gui_queue_push2uart();
// 外设IO配置为低功耗
ENTER_SLEEP_CFG_PIN();
bsp_sys_delay_n10ms(5);//稳定IO
// 正式进入休眠
gui_queue_debug_value_api(0x24);
gui_queue_debug_value_api(IE);
gui_queue_debug_value_api(IE2);
gui_queue_debug_value_api(RTCIEN);
gui_queue_debug_value_api(RTCIF);
gui_queue_debug_value_api(DAY);
ENTER_SLEEP_DOING();
gui_queue_debug_value_api(0x24);
gui_queue_debug_value_api(IE);
gui_queue_debug_value_api(IE2);
gui_queue_debug_value_api(RTCIEN);
gui_queue_debug_value_api(RTCIF);
/////////////////////////////////// 退出休眠
// 退出休眠后,设置锁屏状态
gui_main_info.cmd = QUEUE_CMD_MAIN_LOCK;
// 立即刷新时间和主显
gui_time_ref();
gui_queue_main_display();
gui_queue_push2uart();
// 立刻检查喂食计划是否有出粮
feed_check_now();
// 外设IO配置恢复正常模式
BREAK_SLEEP_CFG_PIN();
// 开启秒中断
RTC_IEN_SEC();
// 触摸恢复
touch_sleep_set((type==SLEEP_DEPTH)?KEY_SLEEP_ENABLE:KEY_SLEEP_BREAK);
// 有接DC或电池才打开MCU3.3V
if((POWER_DC_PIN)||(POWER_BAT_PIN)){
POWER_MCU3V3_SET(1);
}
}
其中gui_queue_debug_value_api函数内部用的是串口发送等待while (!TI),
疑问点在于PCON = 0x02;后会有概率性唤不醒,尝试打印各种标志也都是正常的。
加个信号输出判断当前MCU的工作状态
例如休眠指令前将一个IO口拉低,唤醒NOP之后拉高,通过IO口电平判断MCU是处于休眠状态,还是已经被唤醒了,只是卡在其它地方。
此外可以逐步屏蔽无关程序,看看是不是其它程序影响了正常流程的执行。
当然也可以烧录附件的例子到芯片里试试看RTC唤醒休眠状态是否会复现唤不醒的情况。 P26 = 1;\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
PCON = 0x02;\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
_nop_();\
P26 = 0;\
休眠前后加入了IO状态变化,目前测试来看是死在了PCON = 0x02;也就是MCU还是处于休眠状态。 本帖最后由 miaoyahan 于 2024-3-30 09:55 编辑
只有RTC闹钟会低概率唤醒失败,其他的IO中断唤醒、触摸按键唤醒都没有问题,休眠前百分百确认:闹钟时间>当前时间,闹钟标志位也请零了,还有什么原因会造成RTC闹钟唤不醒呢? 记录下,把IRCDB设置为0xff,连续烧机3天暂无问题,但具体原因仍不明朗
页:
[1]
2