请教大神一个问题。只有一个按键使用P3.2。作为下载和开关机
如题:芯片STC32G12K128使用带开关的EC11编码器,开关使用使用端口P3.2。(USB下载时候长按P3.2进入下载模式)。
正常使用的时候作为一个菜单按键。
还要兼职长按关机。。在长按开机。可以实现吗?
省电模式,INT0中断唤醒,GPIO读按键,可行 此测试程序基本符合楼主需求,短按开机,正常工作期间可以用于菜单,长按关机。USB下载时候先按key再上电进入下载模式没有问题。
//一键开/关机(掉电唤醒)
//适合STC15/STC8系列,测试平台 TX-1C 开发板,MCU型号STC8H1K08
//#include <STC15F2K60S2.H>
#include <STC8H.H>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit key= P3^2;//S14
sbit GND= P3^4;//矩阵键盘模拟接地
uchar Temp;
uchar Key_value; //键值
uintkeyTim; //按键时长
bit flag1ms; //1ms中断标志
bit on_off; //开关标志
bit allow; //允许关机标志
void Timer0Init(void)//1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器自动重载模式
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //允许T0中断
// EA= 1; //开总中断
}
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 216;
j = 37;
do
{
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++;
P1=~Temp;//演示,LED低电平亮
}
if(Key_value==0x11)//长按关机
{
allow=1;//允许休眠
}
Key_value=0x00;//任务完成后键值清0
}
}
void Shutdown()//掉电模式函数
{
if(allow)
{
P1=0xff; //关闭LED显示
//关闭所有在用硬件,减小能耗
while(!key);//等待按键松手
Delay20ms();//消抖防止误动作
EX0 = 1; //开外部中断
PCON = 0x02;//MCU进入掉电模式
/************************************************/
_nop_(); //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序
_nop_(); //中断服务程序执行完再接着此句继续执行
while(!key);//等待按键松手,防止按键扫描程序误读
Delay20ms();//消抖防止误动作
//打开所有在用硬件,恢复正常运行
allow=0; //清0
on_off=0; //开关标志清0
P1=~Temp; //恢复LED显示
}
}
void main()
{
P0M0 = 0x00;//初始化IO
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;
GND= 0;
IT0 = 1;//设置INT0的中断类型为下降沿唤醒
// EX0 = 1;//使能INT0中断
EA= 1;//开总中断
Timer0Init();//定时器初始化函数
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标志
}
wulin 发表于 2026-2-22 17:13
此测试程序基本符合楼主需求,短按开机,正常工作期间可以用于菜单,长按关机。USB下载时候先按key再上电进 ...
非常感谢 wulin 发表于 2026-2-22 17:13
此测试程序基本符合楼主需求,短按开机,正常工作期间可以用于菜单,长按关机。USB下载时候先按key再上电进 ...
收藏了,感谢分享{:baoquan:}
页:
[1]