miaoyahan 发表于 2024-3-28 21:16:38

RTC休眠后,闹钟唤醒掉电模式,偶发性唤醒失败



单片机型号: STC8H4K64TL
固件版本号: 7.4.3U


碰到比较奇怪的现象,使用外部32.768晶振驱动RTC,设备每次休眠前都会设置下一次唤醒的闹钟,经过烧机测试发现会出现偶发性的唤醒失败的情况。


休眠前打印的闹钟时间比当前时间往后、闹钟标志也都是清零的,在PCON的6个nop后打印当前时间用于判断是否唤醒成功,

不能理解的是,当偶发性出现唤不醒的时候,PCON后面的时间打印也没输出,有没有大佬遇到过这种情况?

miaoyahan 发表于 2024-3-29 11:37:53

初步判定跟IRCDB有关,还在持续烧机测试中

乘风飞扬 发表于 2024-3-29 11:47:00

miaoyahan 发表于 2024-3-29 11:37
初步判定跟IRCDB有关,还在持续烧机测试中

如果跟IRCDB有关的话,你的IRC主频是不是设置很高?

miaoyahan 发表于 2024-3-29 13:10:53

乘风飞扬 发表于 2024-3-29 11:47
如果跟IRCDB有关的话,你的IRC主频是不是设置很高?

主频只有24M,奇怪的是IRCDB设置的越大越稳定,反之越小则RTC唤不醒的概率越大,有点搞不懂了。。。

乘风飞扬 发表于 2024-3-29 13:17:25

miaoyahan 发表于 2024-3-29 13:10
主频只有24M,奇怪的是IRCDB设置的越大越稳定,反之越小则RTC唤不醒的概率越大,有点搞不懂了。。。 ...

主频24M正常是不需要修改IRCDB寄存器的。
方便的话把你相关的代码发出来大家一起分析一下。

miaoyahan 发表于 2024-3-29 13:43:30

/*
//////////////////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;后会有概率性唤不醒,尝试打印各种标志也都是正常的。

乘风飞扬 发表于 2024-3-29 22:51:38

加个信号输出判断当前MCU的工作状态
例如休眠指令前将一个IO口拉低,唤醒NOP之后拉高,通过IO口电平判断MCU是处于休眠状态,还是已经被唤醒了,只是卡在其它地方。
此外可以逐步屏蔽无关程序,看看是不是其它程序影响了正常流程的执行。
当然也可以烧录附件的例子到芯片里试试看RTC唤醒休眠状态是否会复现唤不醒的情况。

miaoyahan 发表于 2024-3-30 09:00:00

                              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:53:30

本帖最后由 miaoyahan 于 2024-3-30 09:55 编辑

只有RTC闹钟会低概率唤醒失败,其他的IO中断唤醒、触摸按键唤醒都没有问题,休眠前百分百确认:闹钟时间>当前时间,闹钟标志位也请零了,还有什么原因会造成RTC闹钟唤不醒呢?

miaoyahan 发表于 2024-4-2 12:01:48

记录下,把IRCDB设置为0xff,连续烧机3天暂无问题,但具体原因仍不明朗
页: [1] 2
查看完整版本: RTC休眠后,闹钟唤醒掉电模式,偶发性唤醒失败