亚洲春色中文字幕久久久-三上亚,91精品国产亚一区二区三区,久久久九色综合亚洲成色777,涩涩视频下载,国产午夜亚洲精品午夜鲁丝片,国产精品A一区二区三区腾讯导航,影音先锋色情AV在线看片,蜜臀国产在线视频,极品少妇高潮啪啪无码吴梦梦 ,精品人妻无码一区二区三区手机版

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1385|回復: 5
打印 上一主題 下一主題
收起左側

STC32G12K128單片機使用P3.2/INT0,外部中斷當按鍵怎么實現進入掉電模式后長按開機?

[復制鏈接]
跳轉到指定樓層
樓主
ID:1153575 發表于 2025-10-9 10:25 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一個鋰電產品,關機后要進入低功耗,用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占用
                        
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:458247 發表于 2025-10-9 13:05 | 只看該作者
增加一個狀態,在休眠時,置起一個標志位,然后在中斷里面判斷該標志位置起,若置起,則進入等待長安狀態。在這個狀態中,屏幕不顯示、指示燈不亮,假裝自己還在休眠,一直檢測按鍵是否按下,按下持續2秒后,進入正常狀態,并把休眠狀態位取消。大概套路就是這樣
回復

使用道具 舉報

板凳
ID:1133081 發表于 2025-10-9 15:05 | 只看該作者
這個沒有難度。一旦按鍵按下系統即被喚醒,首先判斷長短按,長按即開機,小于長按預設值即算短按,再次進入低功耗睡眠。呈現的功能就是睡眠中短按無效,長按開機。實際短按也有效,只不過察覺不到。
回復

使用道具 舉報

地板
ID:1133081 發表于 2025-10-9 15:16 | 只看該作者
給你一個示例,稍改一下即可滿足需求
  1. //一鍵開/關機(掉電喚醒)
  2. //適合STC15/STC8系列,測試平臺 TX-1C 開發板
  3. #include <STC8H.H>
  4. #include "intrins.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. sbit key  = P3^2;//S14
  8. sbit GND  = P3^4;//矩陣鍵盤模擬接地

  9. uchar Temp;
  10. uchar Key_value; //鍵值
  11. uint  keyTim;    //按鍵時長
  12. bit   flag1ms;   //1ms中斷標志
  13. bit   on_off;    //開關標志
  14. bit   allow;     //允許關機標志

  15. void Timer0Init(void)//1毫秒@11.0592MHz
  16. {
  17.         AUXR |= 0x80;                //定時器時鐘1T模式
  18.         TMOD &= 0xF0;                //設置定時器自動重載模式
  19.         TL0 = 0xCD;                        //設置定時初始值
  20.         TH0 = 0xD4;                        //設置定時初始值
  21.         TF0 = 0;                                //清除TF0標志
  22.         TR0 = 1;                                //定時器0開始計時
  23.         ET0 = 1;                                //允許T0中斷
  24. //        EA  = 1;                                //開總中斷
  25. }
  26. void Delay20ms()                //@11.0592MHz
  27. {
  28.         unsigned char i, j;

  29.         i = 216;
  30.         j = 37;
  31.         do
  32.         {
  33.                 while (--j);
  34.         } while (--i);
  35. }

  36. void key_scan()    //按鍵掃描函數
  37. {
  38.         if(flag1ms)  //1ms時間標志
  39.         {
  40.                 flag1ms = 0;//1ms時間標志清0
  41.                 if(!key && !on_off)
  42.                 {
  43.                         if(++keyTim>1000)keyTim=1001;//防止溢出

  44.                         if(keyTim==20) //大于20ms小于1s算短按
  45.                         {
  46.                                 Key_value=0x01;
  47.                         }
  48.                         if(keyTim==1000) //達到1s算長按
  49.                         {
  50.                                 Key_value|=0x10;
  51.                         }
  52.                 }
  53.                 else
  54.                 {
  55.                         keyTim=0;        //按鍵松手keyTim清0
  56.                 }
  57.         }
  58. }

  59. void key_service()//按鍵服務函數
  60. {//短按等松手響應,長按達1s不論是否松手即響應
  61.         if((keyTim==0||keyTim==1000) && Key_value!=0x00)
  62.         {
  63.                 if(Key_value==0x01)//短按任務
  64.                 {
  65.                         Temp++;
  66.                         P1=~Temp;//演示,LED低電平亮
  67.                 }
  68.                 if(Key_value==0x11)//長按關機
  69.                 {
  70.                         allow=1;//允許休眠
  71.                 }
  72.                 Key_value=0x00;//任務完成后鍵值清0
  73.         }
  74. }

  75. void Shutdown()//掉電模式函數
  76. {
  77.         if(allow)
  78.         {
  79.                 P1=0xff;                //關閉LED顯示
  80.                 //關閉所有在用硬件,減小能耗
  81.                 while(!key);//等待按鍵松手
  82.                 Delay20ms();//消抖防止誤動作
  83.                 EX0 = 1;                //開外部中斷
  84.                 PCON = 0x02;//MCU進入掉電模式
  85. /************************************************/
  86.                 _nop_();    //掉電模式被喚醒后,首先執行此語句,然后再進入中斷服務程序
  87.                 _nop_();    //中斷服務程序執行完再接著此句繼續執行
  88.                 while(!key);//等待按鍵松手,防止按鍵掃描程序誤讀
  89.                 Delay20ms();//消抖防止誤動作
  90.                 //打開所有在用硬件,恢復正常運行
  91.                 allow=0;                //清0
  92.                 on_off=0;        //開關標志清0
  93.                 P1=~Temp;        //恢復LED顯示
  94.         }
  95. }

  96. void main()
  97. {
  98.         P0M0 = 0x00;//初始化IO
  99.         P0M1 = 0x00;
  100.         P1M0 = 0x00;
  101.         P1M1 = 0x00;
  102.         P2M0 = 0x00;
  103.         P2M1 = 0x00;
  104.         P3M0 = 0x00;
  105.         P3M1 = 0x00;
  106.         P4M0 = 0x00;
  107.         P4M1 = 0x00;
  108.         P5M0 = 0x00;
  109.         P5M1 = 0x00;
  110.         P6M0 = 0x00;
  111.         P6M1 = 0x00;
  112.         P7M0 = 0x00;
  113.         P7M1 = 0x00;
  114.         GND  = 0;
  115.         IT0 = 1;//設置INT0的中斷類型為下降沿喚醒
  116. //        EX0 = 1;//使能INT0中斷
  117.         EA  = 1;//開總中斷                                                        
  118.         Timer0Init();//定時器初始化函數
  119.         while (1)
  120.         {
  121.                 key_scan();                //按鍵掃描函數
  122.                 key_service(); //按鍵服務函數
  123.                 Shutdown();                //掉電模式函數
  124.         }
  125. }
  126. //INT0中斷服務程序
  127. void exint0() interrupt 0
  128. {
  129.         EX0 = 0;                //關外部中斷
  130.         on_off=1;//開關標志置1
  131. }
  132. //T0中斷服務程序
  133. void interruptTimer0() interrupt 1
  134. {
  135.         flag1ms = 1;    //1ms標志
  136. }
復制代碼
回復

使用道具 舉報

5#
ID:1153575 發表于 2025-10-9 15:50 | 只看該作者
謝謝各位工程提供的建議,根據你們的建議,我已經實現了該功能!!
回復

使用道具 舉報

6#
ID:57657 發表于 2025-10-9 17:28 | 只看該作者
此長按開機與手機開機原理類似:
半喚醒:關機狀態開機鍵有按下,控制芯片開始工作并檢測電池電量是否符合開機條件,對開機鍵按住時間毫秒計數,松開后計數清零并重新休眠,計數滿后全喚醒:正式開機、屏幕等模塊開始工作。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表