- 打卡等级:以坛为家III
- 打卡总天数:682
- 最近打卡:2026-04-02 05:45:52
金牌会员
- 积分
- 1430
|
大家好,我正在做一个东西,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进不了掉电状态,放空电池,谢谢。
|
-
|