找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2073|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

遇到了一個(gè)奇怪的單片機(jī)程序問題,百思不得其解

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:686513 發(fā)表于 2023-5-19 09:55 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
sbit unit = P1^0;   //P1.0為外部中斷口(接菜單鍵)。我想實(shí)現(xiàn):開機(jī)時(shí)按此鍵為菜單切換鍵,長按時(shí)休眠,休眠后再短按一下開機(jī)。 目前可以實(shí)現(xiàn)開機(jī)時(shí)菜單切換,自動(dòng)休眠后再短按一下開機(jī),但長按給Low_Power =101;按理論上應(yīng)該可以進(jìn)入休眠,但是休眠瞬間又復(fù)位開機(jī)了。如果把這句 Power_Down_F = 0;        放在掉電模式STOP2后,可以實(shí)現(xiàn)菜單切換,長按時(shí)休眠,但休眠后短按開機(jī)又出現(xiàn)了以下幾個(gè)問題:1.自動(dòng)休眠后需按兩次才能開機(jī),(休眠后電流為:15uA,按下第一次電流升到1到2mA但不開機(jī),按下第二次才能開機(jī))2.長按按鍵休眠后待機(jī)電流為1-2mA(休眠電流應(yīng)該為:15uA,沒有完全休眠),這時(shí)只需按下一次會開機(jī)。

目前我的思路是借鑒論壇里 “家用廚房電子秤” 的休眠程序 :原程序中沒有長按關(guān)機(jī)功能,只是自動(dòng)休眠前把外部中斷打開,按下接外部中斷的開關(guān)觸發(fā)中斷退出休眠。和之前WULIN老師說的方法類似,“利用單片機(jī)休眠功能即可解決。初次上電自動(dòng)開機(jī),P1.0作為普通按鍵使用,短按切換菜單,長按執(zhí)行菜單下不同任務(wù)。只要再加一項(xiàng)菜單,長按打開外部中斷,執(zhí)行睡眠即可關(guān)機(jī)。在睡眠狀態(tài)由外部觸發(fā)喚醒,關(guān)閉外部中斷,恢復(fù)P1.0作為普通按鍵使用!
以下是按照上面的思路我寫的。
//休眠 ---------------------------------------------------------------------------------------------                                                
  if(XmCnt==1)                                        //XmCnt為定時(shí)器500mS到標(biāo)志,即500mS檢測一下是否進(jìn)來休眠
                {
     if(md1==0&&press<50)                            //如果md1==0&&press<50休眠
                                 
                          {
                                 Low_Power ++;        
                                }        
      else
                          {                        
                                 Low_Power = 0;        
                          }        
                 }

if(Low_Power > 100)             //50S休眠
                {
                        IT1=1;               //使能INT1下降沿中斷                        
                        EX1=1;               //使能INT1中斷

                       ET0=0;                    //關(guān)閉定時(shí)器0
                       ET1=0;                    //關(guān)閉定時(shí)器1                                
        WD_DIS                  // 看門狗關(guān)閉
                                                
//--配置IO模式 (確保不漏電)
                        P0M0 = 0x00; P0M1 = 0xff;
                        P1M0 = 0x00; P1M1 = 0xfe;      //P1.0為外部中斷口
                        P2M0 = 0x00; P2M1 = 0xff;
                        P3M0 = 0x00; P3M1 = 0xff;
                        P4M0 = 0x00; P4M1 = 0xff;
                                       
                        P0 = 0x00;
                        P1 = 0x01;             //P1.0為外部中斷口
                        P2 = 0x2E;             //p2.1 p2.2 p2.3 p2.5低電平驅(qū)動(dòng)四個(gè)數(shù)碼管的COM口
                        P3 = 0x00;
                        P4 = 0x00;
                         Power_Down_F = 0;        
                        
                                 _nop_();
                                        PCON |= 0x10;                        //進(jìn)入掉電模式STOP2
                                 _nop_();                        
                                       
         //-- 關(guān)機(jī) : 等待外部中斷喚醒 ---         
                                while(1)
                                {
                                        if(Power_Down_F)                                                        
                                        PCON        = 0x0C;                 //喚醒                                                        
                                }        
                   }        
   }
}

void EX_Int1 (void) interrupt 2       //INT1
{         
Power_Down_F = 1 ;
}

按鍵為低層和應(yīng)該用層掃描識別
void key_Service()       //應(yīng)用層
{                          
  switch(Key_Scan())      //key_Scan()  為底層 返回鍵值                                                     
    {               
      case 2:   if(Setflag == 1){ KeyNum=0; E2prom_Read_user();T1Cnt=0; SSCnt=0; keyflag=0; Setflag=0;}  else {KeyNum=0; wnd++; if(wnd>2) wnd=0; E2prom_write_user();}     break;     //短按P1.0 鍵值為2     菜單窗口wnd切換
          -
          -
          -
        case 22:     KeyNum=0;  Low_Power = 101;         E2prom_write_user();   Setflag = 1;     break;      //長按P1.0 鍵值為22  這里給 Low_Power = 101;  進(jìn)入上面的休眠部分,即   if(Low_Power > 100)    。            
        }
}                          




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:123289 發(fā)表于 2023-5-19 15:15 | 只看該作者
【開機(jī)時(shí)】:需要定義一個(gè)標(biāo)記B_ON,來識別當(dāng)前狀態(tài)是不是開機(jī)狀態(tài)。
【按此鍵為菜單切換鍵,長按時(shí)休眠】:需要定義一個(gè)標(biāo)記B_LONG,來識別長按與普通按。
【休眠后】:需要定義一個(gè)標(biāo)記B_SLEEP,來識別當(dāng)前狀態(tài)是不是休眠中。
組合B_ON、B_LONG、B_SLEEP就可以達(dá)成你的需要,要點(diǎn)是如何決定這三個(gè)變量的0、1:
1、B_ON:開機(jī)時(shí)通過檢查指定人RAM中不是不是特定的冷起動(dòng)碼,來修改B_ON值;或當(dāng)你執(zhí)行關(guān)機(jī)時(shí),修改B_ON值,以便于下次識別開機(jī);其它方法。
2、B_LONG:通過對按鍵按下的時(shí)間識別。
3、B_SLEEP:在進(jìn)行休眠前、后修改。
要點(diǎn):識別使用標(biāo)記后,復(fù)位各標(biāo)記。
回復(fù)

使用道具 舉報(bào)

板凳
ID:57657 發(fā)表于 2023-5-19 18:16 | 只看該作者
樓主用的什么型號? 并不是所有IO口都可以外部中斷。
回復(fù)

使用道具 舉報(bào)

地板
ID:213173 發(fā)表于 2023-5-25 15:53 | 只看該作者
芯易德的MCU沒有用過,既然是51的那就差不多,把管腳定義改一下就應(yīng)該能用。這個(gè)示例是按STC15編寫的,也適用于STC8系列。消除按鍵外部中斷喚醒后誤讀按鍵的缺陷,實(shí)際就是加電正常工作,按鍵正常操作。當(dāng)長按達(dá)1秒MCU睡眠。再按按鍵不論長短都能喚醒,但必須松手后才能進(jìn)入正常工作狀態(tài),避免按鍵掃描函數(shù)誤將外部中斷喚醒當(dāng)做正常操作。其實(shí)就加了一個(gè)識別標(biāo)志。這個(gè)按鍵掃描函數(shù)只寫了1個(gè)鍵,實(shí)際可以用于N個(gè)鍵的長短按。 一鍵開關(guān)機(jī)(掉電喚醒).rar (12.49 KB, 下載次數(shù): 9)

回復(fù)

使用道具 舉報(bào)

5#
ID:146507 發(fā)表于 2023-7-10 16:47 | 只看該作者
你是不是長按關(guān)機(jī)沒有判斷IO口松開就進(jìn)入休眠程序了,然后IO口又是低電平喚醒,所以會不斷的開機(jī)
回復(fù)

使用道具 舉報(bào)

6#
ID:111463 發(fā)表于 2023-7-10 16:54 | 只看該作者
1. 要注意該單片機(jī)從休眠喚醒后是會復(fù)位還是在之前程序中接著運(yùn)行
2. 要做好程序的健壯性,避免多次喚醒或重復(fù)進(jìn)入中斷
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表