亚洲春色中文字幕久久久-三上亚,91精品国产亚一区二区三区,久久久九色综合亚洲成色777,涩涩视频下载,国产午夜亚洲精品午夜鲁丝片,国产精品A一区二区三区腾讯导航,影音先锋色情AV在线看片,蜜臀国产在线视频,极品少妇高潮啪啪无码吴梦梦 ,精品人妻无码一区二区三区手机版
標題:
STC32G12K128單片機使用P3.2/INT0,外部中斷當按鍵怎么實現進入掉電模式后長按開機?
[打印本頁]
作者:
2625860329
時間:
2025-10-9 10:25
標題:
STC32G12K128單片機使用P3.2/INT0,外部中斷當按鍵怎么實現進入掉電模式后長按開機?
一個鋰電產品,關機后要進入低功耗,用INT0(P3.2)引腳實現按鍵喚醒,現在情況是這樣,我寫的程序 在關機后能進入低功耗模式。但是在長按按鍵喚醒開機時出現下面兩種情況
1.按鍵按下直接就開機了,沒有經過檢測長按
2.按鍵需要按兩次,第一次按下喚醒,第二次按下可以實現長按開機
所以我想問問各位,怎么實現在 進入低功耗模式后,實現長按開機,麻煩各位給點思路
下面是我的代碼
void INT0_Isr(void) interrupt 0
{
delay_ms(20); // 消抖
}
void main() {
bit key_flag = 0; // 按鍵狀態標志位
u16 j;
EAXFR = 1; // 使能訪問XFR
CKCON = 0x00; // 設置外部數據總線速度為最快
WTST = 0x00; // 設置程序代碼等待參數,0等待時鐘,速度最快
GPIO_Init(); // 初始化IO
Timer0_Init(); // 初始化定時器(24MHz配置)
ADC_config(); //初始化ADC0
PWM_config();
Timer_config();
TurnOffAllLights();//上電初始化關閉所有輸出
IT0 = 1; // INT0下降沿中斷
EX0 = 1; // 使能外部中斷0
EA = 1; // 使能EA總中斷
system_state = SYSTEM_OFF; // 假設上電默認是關機狀態
while(1) {
Check_USB(); // 檢查USB狀態
j = Get_ADCResult(0); //讀取ADC0檢測的電壓值
keyvalue = key_multi(); //讀取鍵值
if(j >= 3500) //只有當P1.0/ADC0,測到有電壓,電機才會工作
{
MOTO_PLAY();
}else{
PWM8P_OUT_DIS();
}
if(keyvalue != KEY_STATE_0)
{
if (usb_state == USB_CONNECTED) {
beep_(1); // 短鳴提示USB插入,禁止操作
delay_ms(100);
}
else if(system_state == SYSTEM_OFF && keyvalue == Key1_Long_Click){
system_state = SYSTEM_ON; // 切換到開機狀態
press_count = 1;
Timer3_Run(1);Timer0_Run(1);
Display(); MODE_PLAY();UpdateTimer();
LED = 0;
beep_(2);
timer_count = 0; // 重置計時器
timer_running = 1; // 開始計時
} else if(system_state == SYSTEM_ON){
if(keyvalue == Key1_Single_Click){
press_count++; // 模式計數加1
if (press_count > 7) press_count = 1;
Display(); MODE_PLAY(); // 更新顯示
beep_(1); // 播放短按提示音
}else if(keyvalue == Key1_Long_Click){
system_state = SYSTEM_OFF; // 切換到關機狀態
TurnOffAllLights(); // 關閉所有燈光
beep_(3); // 播放關機音效
timer_running = 0; // 停止計時
IT0 = 1;
EX0 = 1;
EA = 1;
PD = 1; // 進入低功耗模式-IDLE空式
}
}
}
UpdateTimer(); // 更新計時器狀態
Display(); // 更新顯示(用于處理閃爍)
MODE_PLAY();
delay_ms(1); // 短暫延時,降低CPU占用
}
}
作者:
yzw846562238
時間:
2025-10-9 13:05
增加一個狀態,在休眠時,置起一個標志位,然后在中斷里面判斷該標志位置起,若置起,則進入等待長安狀態。在這個狀態中,屏幕不顯示、指示燈不亮,假裝自己還在休眠,一直檢測按鍵是否按下,按下持續2秒后,進入正常狀態,并把休眠狀態位取消。大概套路就是這樣
作者:
WL0123
時間:
2025-10-9 15:05
這個沒有難度。一旦按鍵按下系統即被喚醒,首先判斷長短按,長按即開機,小于長按預設值即算短按,再次進入低功耗睡眠。呈現的功能就是睡眠中短按無效,長按開機。實際短按也有效,只不過察覺不到。
作者:
WL0123
時間:
2025-10-9 15:16
給你一個示例,稍改一下即可滿足需求
//一鍵開/關機(掉電喚醒)
//適合STC15/STC8系列,測試平臺 TX-1C 開發板
#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標志
}
復制代碼
作者:
2625860329
時間:
2025-10-9 15:50
謝謝各位工程提供的建議,根據你們的建議,我已經實現了該功能!!
作者:
npn
時間:
2025-10-9 17:28
此長按開機與手機開機原理類似:
半喚醒:關機狀態開機鍵有按下,控制芯片開始工作并檢測電池電量是否符合開機條件,對開機鍵按住時間毫秒計數,松開后計數清零并重新休眠,計數滿后全喚醒:正式開機、屏幕等模塊開始工作。
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1