低功耗和唤醒
我使用的芯片是STC8H4K64TLCD 需要做低功耗和IO口唤醒 我通过按键下降沿中断唤醒,也就是说在进入低功耗之前需要先将该IO口设置为上拉状态,但是手册上说要省电的话就要将IO设置为高阻输入并关闭数字输入,那这不是和我按键下降沿中断唤醒冲突吗
建议按键接外部中断INTx用作中断唤醒,设置准双向模式。其它功能扩展的设置全部按默认状态。 wulin 发表于 2026-5-15 17:28
建议按键接外部中断INTx用作中断唤醒,设置准双向模式。其它功能扩展的设置全部按默认状态。 ...
关闭数字输入了还能进入中断吗
我现在就是想通过按键能唤醒 然后做低功耗时候不能因为这个按键功耗增大 mppqgqha 发表于 2026-5-15 17:38
关闭数字输入了还能进入中断吗
我现在就是想通过按键能唤醒 然后做低功耗时候不能因为这个按键功耗增大 ...
IO口配置工具中4个基本配置就可以适合绝大多数应用场景,当然包括外部中断。所谓高级配置多数情况用不到,默认不开启。既然未使能就没有关闭一说,就当不存在,与外部中断何干?低功耗睡眠主要是应用于电池供电的设备。为了节电,单片机休眠时有可能因端口配置因素,受外围电路的影响导致低功耗电流达不到理想值。所以在休眠前关闭这些配置,减少功耗。唤醒后再恢复相关配置。
测试程序
//一键开/关机(掉电唤醒)
//适合STC15/STC8系列,测试平台STC8H3K48S2开发板
#include <STC8H.H>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit key= P3^2;//S14
uchar Temp;
uchar Key_value; //键值
uintkeyTim; //按键时长
bit flag1ms; //1ms中断标志
bit on_off; //开关标志
bit allow; //允许关机标志
//初始化单片机端口
void McuInit()
{
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
P6M0 = 0x00; P6M1 = 0x00;
P7M0 = 0x00; P7M1 = 0x00;
}
//关闭单片机端口
void McuSleep()
{
P0M0 = 0x00; P0M1 = 0xff;
P1M0 = 0x00; P1M1 = 0xff;
P2M0 = 0x00; P2M1 = 0xff;
P3M0 = 0x00; P3M1 = 0xf8;
P4M0 = 0x00; P4M1 = 0xff;
P5M0 = 0x00; P5M1 = 0xff;
P6M0 = 0x00; P6M1 = 0xff;
P7M0 = 0x00; P7M1 = 0xff;
}
void Timer0_Init() //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
void Delay20ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
i = 2;
j = 32;
k = 60;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void key_scan() //按键扫描函数
{
if(flag1ms)//1ms时间标志
{
flag1ms = 0;//1ms时间标志清0
if(!key && !on_off)
{
if(++keyTim>1000)keyTim=1001;//防止溢出
if(keyTim==20) //大于20ms小于1s算短按
{
Key_value=0x01;
}
if(keyTim==1000) //达到1s算长按
{
Key_value|=0x10;
}
}
else
{
keyTim=0; //按键松手keyTim清0
}
}
}
void key_service()//按键服务函数
{//短按等松手响应,长按达1s不论是否松手即响应
if((keyTim==0||keyTim==1000) && Key_value!=0x00)
{
if(Key_value==0x01)//短按任务
{
Temp++;
P4=~Temp;//演示,LED低电平亮
}
if(Key_value==0x11)//长按关机
{
allow=1;//允许休眠
}
Key_value=0x00;//任务完成后键值清0
}
}
void Shutdown()//掉电模式函数
{
if(allow)
{
McuSleep(); //关闭单片机端口
//关闭所有在用硬件,减小能耗
while(!key);//等待按键松手
Delay20ms();//消抖防止误动作
EX0 = 1; //开外部中断
PCON = 0x02;//MCU进入掉电模式
/************************************************/
_nop_(); //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序
_nop_(); //中断服务程序执行完再接着此句继续执行
while(!key);//等待按键松手,防止按键扫描程序误读
Delay20ms();//消抖防止误动作
//打开所有在用硬件,恢复正常运行
allow=0; //清0
on_off=0; //开关标志清0
McuInit();//初始化单片机端口
P4=~Temp; //恢复LED显示
}
}
void main()
{
McuInit();
IT0 = 1;//设置INT0的中断类型为下降沿唤醒
// EX0 = 1;//使能INT0中断
EA= 1;//开总中断
Timer0_Init();//定时器初始化函数
while (1)
{
key_scan(); //按键扫描函数
key_service(); //按键服务函数
Shutdown(); //掉电模式函数
}
}
//INT0中断服务程序
void exint0() interrupt 0
{
EX0 = 0; //关外部中断
on_off=1;//开关标志置1
}
//T0中断服务程序
void interruptTimer0() interrupt 1
{
flag1ms = 1; //1ms标志
}
我觉得这5点你应该按照 if - else if 的形式来判断。 而不是 if - if
页:
[1]