找回密码
 立即注册
查看: 91|回复: 3

关于掉电状态下,RTC唤醒的功耗问题。

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:682
  • 最近打卡:2026-04-02 05:45:52

54

主题

259

回帖

1430

积分

金牌会员

积分
1430
发表于 2026-3-11 10:54:10 | 显示全部楼层 |阅读模式
大家好,我正在做一个东西,MCU是32G12K128,遇到到外部电源掉电后,电路板跑时钟的问题,期望电路板的外电没有后,电路板进入掉电状态,MCU由纽扣电池供电,功耗尽可能的小,仅维持MCU的RTC运行,RTC每隔1秒唤醒MCU,通过比较器检测外电,检测到外电后,MCU退出掉电状态,没有则继续进入掉电状态,RTC的纽扣供电及比较器部分参考手册的电路图,如下:

程序主要部分在“例程81-内部RTC时钟低功耗休眠唤醒-比较器检测电压程序”上修改而成:
相关的函数如下:


void        Port_Mode(void)                //外部电源正常时的端口设置 空闲口置为高阻
{ P0M0 = 0xe0; P0M1 = 0x1f;                                                                                 
  P1M0 = 0x00; P1M1 = 0xfc;                                                                                 
  P2M0 = 0xb9; P2M1 = 0x46;
  P3M0 = 0x20; P3M1 = 0xd4;
  P4M0 = 0x1e; P4M1 = 0x61;
  P5M0 = 0x02; P5M1 = 0xe0;
  P6M0 = 0x27; P6M1 = 0xc0;
  P7M0 = 0x0e; P7M1 = 0x81;
        P0=0xE0;                                                                        //11100000;                                
        P1=0x03;                                                                        //00000011;                        
        P2=0x01;                                                                        //00000001;                                
        P3=0x0b;                                                                        //00001011;
        P4=0x80;                                                                        //10000000;
        P5=0x1F;                                                                        //00011111;
        P6=0x39;                                                                        //00111001;
        P7=0x70;                                                                        //01110000;
}

void        PD_Port_Mode(void)                        //掉电状态后端口设置 除P1.6、P1.7均设为开漏
{                                    
  P0M0 = 0xff; P0M1 = 0xff;   
  P1M0 = 0x3f; P1M1 = 0xff;   
  P2M0 = 0xff; P2M1 = 0xff;   
  P3M0 = 0xff; P3M1 = 0xff;   
  P4M0 = 0xff; P4M1 = 0xff;   
  P5M0 = 0xff; P5M1 = 0xff;   
  P6M0 = 0xff; P6M1 = 0xff;   
  P7M0 = 0xff; P7M1 = 0xff;   
                                                                                                //所有端口关闭数字输入
        P0IE = 0x00;         P1IE = 0x00;                       
        P2IE = 0x00;        P3IE = 0x00;                        
        P4IE = 0x00;        P5IE = 0x00;                        
        P6IE = 0x00;        P7IE = 0x00;               
                                                                                                //所有端口初值赋为1      
        P0=0xff;        P1=0xff;                                       
        P2=0xff;        P3=0xff;                                          
        P4=0xff;        P5=0xff;                                       
        P6=0xff;        P7=0xff;                                                         
}

//========================================================================
// 函数: void RTC_config(void)
// 描述: RTC初始化函数。
// 参数: 无.
// 返回: 无.
// 版本: V1.0, 2020-6-10
//========================================================================
void RTC_config(void)                //RTC初始化
{        INIYEAR         = 26;             //Y:2026
        INIMONTH = 01;            //M:01
        INIDAY         = 01;              //D:63
        INIHOUR         = 00;             //H:15
        INIMIN         = 00;              //M:46
        INISEC         = 00;              //S:50
        INISSEC         = 00;              //S/128:0
        
        X32KCR = 0x80 + 0x40;   //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
        while (!(X32KCR & 1));    //等待时钟稳定
        RTCCFG = 0x01;                 //选择外部32K时钟源,触发RTC寄存器初始化

        RTCIF = 0x00;                             //清中断标志
        RTCIEN = 0x08;                            //中断使能, 0x08:秒中断,
        RTCCR = 0x01;                             //RTC使能
        while(RTCCFG & 0x01);        //等待初始化完成,需要在 "RTC使能" 之后判断.
        //设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
        //如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
}

/******************** RTC中断函数 *********************/
void RTC_Isr() interrupt 36
{        if(RTCIF & 0x08)                                            //秒中断
        {        RTCIF &= ~0x08;                                //清秒中断
                B_1s = 1;
                //P3M0 = 0x5f; P3M1 = 0xdf;              //P3.5准双向
               P3M0 = 0x7f; P3M1 = 0xdf;               //P3.5推挽
                _nop_();_nop_();_nop_();
                _nop_();_nop_();_nop_();
                _nop_();_nop_();_nop_();
                CMPEN = 1;                                     //使能比较器模块        
        }
}

//========================================================================
// 函数: void CMP_config(void)
// 描述: 比较器初始化函数。
// 参数: 无.
// 返回: 无.
// 版本: V1.0, 2020-6-10
//========================================================================

void CMP_config(void)                //比较器初始化函数
{ CMPEXCFG = 0x00;
  CMPEXCFG |=0xc0;              //比较器DC迟滞输入选择,0xc0:30mV
  CMPEXCFG |= 0x04;        //内部1.19V参考电压为CMP-输入脚
  CMPEXCFG &= ~0x03;    //P3.7为CMP+输入脚
  CMPCR2 = 0x00;            
  INVCMPO = 0;          //比较器正向输出
  DISFLT = 0;             //使能0.1us滤波
  CMPCR2 |= 0x10;      //比较器结果经过16个去抖时钟后输出
  CMPCR1 = 0x00;        
  CMPIF = 0;            //清中断标志
                                                                                                
  PIE = 1;                //开比较器上升沿中断
  NIE = 1;               //开比较器下降沿中断
  CMPOE = 0;            //禁止比较器输出
  CMPO_S = 0;           //选择P3.4作为比较器输出脚
  CMPEN = 1;            //使能比较器模块
}                                 

/******************* 比较器中断函数 ********************/
void CMP_Isr() interrupt 21
{   CMPIF = 0;                  //清中断标志
    if(CMPRES)                      //有外部电源供电
    {        Port_Mode();              //退出掉电状态端口设置
    }                           
    else                              //无外部电源供电        
    {        CMPEN = 0;             //关比较器模块                        
        PD_Port_Mode();                                //掉电状态端口设置
        PD=1;                                                //进掉电状态
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
    }
}
程序运行时,在主循环之前,执行Port_Mode();RTC_config()        ;CMP_config()。               
现在的情况是在电路板插着纽扣电池的状态下,外部电源掉电后,电路板可以进入掉电状态,掉电状态下,用万用表测纽扣的工作电流在2uA左右,符合要求,现在有2个疑问:
1、在电路板没有外部电源的情况下,插上纽扣电池,这种情况下,MCU应该马上进入掉电状态,但是貌似没有,此时测的纽扣电池的工作电流在7mA左右,只有加上外部电源,再断掉外部电源,MCU才进入掉电状态,纽扣的工作电流才降下来。
2、RTC秒中断中,唤醒MCU后,P3.5必须设置为强推挽,才可以,如果设为开漏或准双向,掉电状态下,测纽扣的工作电流在7mA左右,MCU貌似也没有进入掉电状态。
请大家看看问题出在哪里?尤其第一个问题,生产线上,调试人员有可能会在调试完电路板,断电后,统一插纽扣电池,造成MCU进不了掉电状态,放空电池,谢谢。

无标题.png
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:90
  • 最近打卡:2026-04-02 10:16:19
已绑定手机

4

主题

245

回帖

885

积分

高级会员

积分
885
发表于 2026-3-11 15:35:46 | 显示全部楼层
由于在开启比较器中断前清除了标志,如果比较器输出不变,它就不再产生中断,所以如果一开始就是电池供电它也不中断,
建议初始化完成后令CMPIF =1;看能不能触发中断。
如果不想用中断,也可以在初始化之后采用查询方式,查询比较器输出再作处理。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:682
  • 最近打卡:2026-04-02 05:45:52

54

主题

259

回帖

1430

积分

金牌会员

积分
1430
发表于 2026-3-11 15:38:48 | 显示全部楼层
lcws*** 发表于 2026-3-11 15:35
由于在开启比较器中断前清除了标志,如果比较器输出不变,它就不再产生中断,所以如果一开始就是电池供电它 ...

好的,谢谢您,我试下。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:682
  • 最近打卡:2026-04-02 05:45:52

54

主题

259

回帖

1430

积分

金牌会员

积分
1430
发表于 2026-3-11 16:06:56 | 显示全部楼层
lcws*** 发表于 2026-3-11 15:35
由于在开启比较器中断前清除了标志,如果比较器输出不变,它就不再产生中断,所以如果一开始就是电池供电它 ...

我刚去试了一下,确实是这样,问题解决,非常感谢
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-3 05:05 , Processed in 0.103227 second(s), 56 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表