29
140
662
高级会员
使用道具 举报 送花
97
7247
1万
超级版主
2
17
114
注册会员
//一键开/关机(掉电唤醒) //适合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; //键值 uint keyTim; //按键时长 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标志 }复制代码
wul*** 发表于 2026-2-22 17:13 此测试程序基本符合楼主需求,短按开机,正常工作期间可以用于菜单,长按关机。USB下载时候先按key再上电进 ...
24
522
1195
金牌会员
本版积分规则 发表回复 回帖后跳转到最后一页
|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )
GMT+8, 2026-3-7 16:50 , Processed in 0.107204 second(s), 67 queries .
Powered by Discuz! X3.5
© 2001-2026 Discuz! Team.