sbit unit = P1^0; //P1.0为外部中断口(接菜单键)。我想实现:开机时按此键为菜单切换键,长按时休眠,休眠后再短按一下开机。 目前可以实现开机时菜单切换,自动休眠后再短按一下开机,但长按给Low_Power =101;按理论上应该可以进入休眠,但是休眠瞬间又复位开机了。如果把这句 Power_Down_F = 0; 放在掉电模式STOP2后,可以实现菜单切换,长按时休眠,但休眠后短按开机又出现了以下几个问题:1.自动休眠后需按两次才能开机,(休眠后电流为:15uA,按下第一次电流升到1到2mA但不开机,按下第二次才能开机)2.长按按键休眠后待机电流为1-2mA(休眠电流应该为:15uA,没有完全休眠),这时只需按下一次会开机。
目前我的思路是借鉴论坛里 “家用厨房电子秤” 的休眠程序 :原程序中没有长按关机功能,只是自动休眠前把外部中断打开,按下接外部中断的开关触发中断退出休眠。和之前WULIN老师说的方法类似,“利用单片机休眠功能即可解决。初次上电自动开机,P1.0作为普通按键使用,短按切换菜单,长按执行菜单下不同任务。只要再加一项菜单,长按打开外部中断,执行睡眠即可关机。在睡眠状态由外部触发唤醒,关闭外部中断,恢复P1.0作为普通按键使用。”
以下是按照上面的思路我写的。
//休眠 ---------------------------------------------------------------------------------------------
if(XmCnt==1) //XmCnt为定时器500mS到标志,即500mS检测一下是否进来休眠
{
if(md1==0&&press<50) //如果md1==0&&press<50休眠
{
Low_Power ++;
}
else
{
Low_Power = 0;
}
}
if(Low_Power > 100) //50S休眠
{
IT1=1; //使能INT1下降沿中断
EX1=1; //使能INT1中断
ET0=0; //关闭定时器0
ET1=0; //关闭定时器1
WD_DIS // 看门狗关闭
//--配置IO模式 (确保不漏电)
P0M0 = 0x00; P0M1 = 0xff;
P1M0 = 0x00; P1M1 = 0xfe; //P1.0为外部中断口
P2M0 = 0x00; P2M1 = 0xff;
P3M0 = 0x00; P3M1 = 0xff;
P4M0 = 0x00; P4M1 = 0xff;
P0 = 0x00;
P1 = 0x01; //P1.0为外部中断口
P2 = 0x2E; //p2.1 p2.2 p2.3 p2.5低电平驱动四个数码管的COM口
P3 = 0x00;
P4 = 0x00;
Power_Down_F = 0;
_nop_();
PCON |= 0x10; //进入掉电模式STOP2
_nop_();
//-- 关机 : 等待外部中断唤醒 ---
while(1)
{
if(Power_Down_F)
PCON = 0x0C; //唤醒
}
}
}
}
void EX_Int1 (void) interrupt 2 //INT1
{
Power_Down_F = 1 ;
}
按键为低层和应该用层扫描识别
void key_Service() //应用层
{
switch(Key_Scan()) //key_Scan() 为底层 返回键值
{
case 2: if(Setflag == 1){ KeyNum=0; E2prom_Read_user();T1Cnt=0; SSCnt=0; keyflag=0; Setflag=0;} else {KeyNum=0; wnd++; if(wnd>2) wnd=0; E2prom_write_user();} break; //短按P1.0 键值为2 菜单窗口wnd切换
-
-
-
case 22: KeyNum=0; Low_Power = 101; E2prom_write_user(); Setflag = 1; break; //长按P1.0 键值为22 这里给 Low_Power = 101; 进入上面的休眠部分,即 if(Low_Power > 100) 。
}
}
|