今天突然翻百度长按按键唤醒掉电模式,没有发现有资料介绍,于是自己用STC15W408AS做了个实验,用于长按按键唤醒。
构思如下,查数据手册表示,掉电模式无系统时钟,外部设备除掉电前开启唤醒的外设一律停止工作,故想用系统执行任务判断按下时间是不可能了,但注意到数据手册中写到,唤醒后执行下一条语句后转向中断服务程序,于是想在中断服务程序中判断按键按下时长,并作出处理,短按则再次进入掉电状态,长按则唤醒。实验代码如下,基本实现了长按唤醒led发光,再次长按掉电led熄灭,正常状态短按则改变led状态。代码如下:
单片机源程序如下:
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^2;
sbit k1 =P3^2;//STC15W408AS此脚为外部中断0,在非掉电模式下做按键用,按一次led改变一次状态。
uint num=0,kn=0;
uchar km;
void delay (uint yc)//仅在唤醒掉电时用
{
uint i,j;
for (i=yc;i>0;i--)
for (j=100;j>0;j--);
}
void main()
{
TMOD=0x01;
TH0=(65536-1000)/256; //11.0592M晶振定时1ms数为1000
TL0=(65536-1000)%256;
EA=1;
ET0=1;
TR0=1;
while(1)
{
if(num==10) //如果到了10次,说明10ms秒时间
{
if(k1==0)
{
kn++;
if(kn>200)//长按标志
led1=1;
}
if(k1==1)
{
if(kn>0&&kn<100)//短按判定
{
led1=~led1;
kn=0;
}
if(kn>200)//长按判定
{
kn=0;
IT0 = 1;
EX0 = 1;
PCON = 0x02;
delay(10);//手册中写到,唤醒会执行中断命令后一条语句之后转向中断服务程序,故在此设置一个唤醒执行语句。
}
}
num=0;//重新计数
}
}
}
void T_time()interrupt 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
num++;
}
void exint0() interrupt 0
{
uint x=0;
IT0=0;
EX0=0;
while(k1==0)
{
x++;
delay(10);
if(x>=1000)
led1=0;//唤醒标志
}
if(x<1000)
{
IT0=1;
EX0=1;
PCON=0x02;
delay(10);
}
}
|