找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4432|回復(fù): 7
收起左側(cè)

用stc15w101單片機(jī)寫(xiě)的按鍵單擊雙擊長(zhǎng)按程序,怎么加上休眠功能?

[復(fù)制鏈接]
ID:60656 發(fā)表于 2019-1-24 22:44 | 顯示全部樓層 |閱讀模式
#include <STC15F2K60S2.H>
#include"intrins.h"
sbit key=P3^5;
sbit LED=P3^4;
unsigned char L,value,time,num;
bit S,flag;
void  delay_ms(unsigned char         z)
{
        unsigned int x,y;
        for(x=z; x>0; x--)
                for(y=848; y>0; y--);
}
void HY()
{ if(!S)
    {
                 switch(L)
                        {
                         case 0: LED=1;break;
                         case 1: LED=0;delay_ms(2);LED=1;delay_ms(8);break;
                         case 2: LED=0;delay_ms(4);LED=1;delay_ms(6);break;
                         case 3: LED=0;delay_ms(6);LED=1;delay_ms(4);break;
                         case 4: LED=0;break;
                        }
         }
if(S)
   {
         switch(L)
                 {
                         case 0: LED=1;break;
                         case 1: LED=0;delay_ms(45);LED=1;delay_ms(255);break;
                         case 2: LED=0;delay_ms(80);LED=1;delay_ms(220);break;
                         case 3: LED=0;delay_ms(150);LED=1;delay_ms(150);break;
                         case 4: LED=0;delay_ms(10);LED=1;delay_ms(90);break;
                 }
   }
}

void Timer0Init(void)                //12.000MHz
{
        AUXR &= 0x7F;
        TMOD &= 0xF0;
        TL0 = 0x00;
        TH0 = 0xEE;
        TF0 = 0;
        TR0 = 1;
        EA = 1;
        ET0 = 1;
}
unsigned char getkey()
{         
         static unsigned char lp=0;
          switch(lp)
                {
                case 0:
                         if(!key)lp++;
                         else if(flag)
                                   {
                                        if(++time>50)
                                          {
                                           value=1;
                                           time=0,
                                           flag=0;
                                           }
                                        }
                        break;
                        case 1:if(!key)lp++;else lp=0;break;
                        case 2:
                             if(key)
                                   {
                                    lp++;
                                    if(flag)
                                      {
                                       value=2;
                                       flag=0;
                                      }
                                     else flag=1;
                                    }
                                  else if(++num>250)
                                {
                                         flag=0;
                                         value=3;
                                         lp++;
                                        }
                                        break;
                        case 3:if(key){lp=0;num=0;time=0;}break;
                  }
return value;
}        

main()
   {
                LED=1;
          L=0;S=0;flag=0;value=0;         
    Timer0Init();
          while(1)
   {  

        HY();         
   }
}
         
void timer()interrupt 1
{
switch(getkey())
           {  
           case 1:         
                 L++;
                             value=0;        
                              if(L>4) L=1;
                       break;
           case 2: S=~S;L=1;value=0;break;
           case 3: L=0;value=0; break;
          }
}


回復(fù)

使用道具 舉報(bào)

ID:60656 發(fā)表于 2019-1-26 19:14 | 顯示全部樓層
yzwzfyz 發(fā)表于 2019-1-26 08:19
你的編程邏輯構(gòu)思上存在問(wèn)題:一時(shí)說(shuō)不清,給你一個(gè)任務(wù),如果你能完成,則會(huì)有很大的進(jìn)步。
任務(wù):
不許 ...

謝謝你的指點(diǎn),我基礎(chǔ)差,有愛(ài)好自學(xué),謝謝你的經(jīng)驗(yàn)
回復(fù)

使用道具 舉報(bào)

ID:123289 發(fā)表于 2019-1-26 08:19 | 顯示全部樓層
你的編程邏輯構(gòu)思上存在問(wèn)題:一時(shí)說(shuō)不清,給你一個(gè)任務(wù),如果你能完成,則會(huì)有很大的進(jìn)步。
任務(wù):
不許任何地方用硬延時(shí)(例如程序中的:delay_ms()),用中斷的方式來(lái)做。
硬延時(shí):占用CPU時(shí)間,特別是中斷服務(wù)程序中還使用,是件很糟糕的事,初學(xué)者都在做這個(gè)事。估計(jì)老師水平差,不教學(xué)生如何正確處理延時(shí);蛘邔W(xué)生也懶,硬延也時(shí)簡(jiǎn)單,就一直用了。

評(píng)分

參與人數(shù) 1黑幣 +10 收起 理由
zxq9781 + 10 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:60656 發(fā)表于 2019-1-25 22:04 | 顯示全部樓層
yzwzfyz 發(fā)表于 2019-1-25 13:02
一個(gè)主循環(huán)的末端可以安排進(jìn)入“休眠”。
在它的下一條指令,安排跳轉(zhuǎn)向主循環(huán)入口(C語(yǔ)言自動(dòng)完成)
這 ...

謝謝你的提示, 修改后的程序可休眠,但是按鍵口外部中斷喚醒后 我處理不好, 按鍵這個(gè)地方有問(wèn)題,上電后進(jìn)入休眠,第一次按按鍵 功能直接跳第2檔(L1 初始化是0,中斷喚醒判斷按鍵有效 L=1,推出出中斷,開(kāi)定時(shí)器中斷),相當(dāng)于L=2了,這個(gè)時(shí)候如果長(zhǎng)按在休眠,不掉電 在單擊啟 有不連跳 ,搞不明白 請(qǐng)教一下這里怎么改。想來(lái)幾天了搞不定,幫忙指點(diǎn)一下
回復(fù)

使用道具 舉報(bào)

ID:60656 發(fā)表于 2019-1-25 21:55 | 顯示全部樓層
yzwzfyz 發(fā)表于 2019-1-25 13:02
一個(gè)主循環(huán)的末端可以安排進(jìn)入“休眠”。
在它的下一條指令,安排跳轉(zhuǎn)向主循環(huán)入口(C語(yǔ)言自動(dòng)完成)
這 ...

#include <STC15F2K60S2.H>
#include"intrins.h"
sbit key=P3^5;
sbit LED=P3^4;
unsigned char L,value,time,num;
bit S,flag,d;
void  delay_ms(unsigned char         z)
{
        unsigned int x,y;
        for(x=z; x>0; x--)
                for(y=848; y>0; y--);
}
void HY()
{ if(!S)
    {
                 switch(L)
                        {
                         case 0: LED=1;break;
                         case 1: LED=0;delay_ms(2);LED=1;delay_ms(8);break;
                         case 2: LED=0;delay_ms(4);LED=1;delay_ms(6);break;
                         case 3: LED=0;delay_ms(6);LED=1;delay_ms(4);break;
                         case 4: LED=0;break;
                        }
         }
if(S)
   {
         switch(L)
                 {
                         case 0: LED=1;break;
                         case 1: LED=0;delay_ms(45);LED=1;delay_ms(255);break;
                         case 2: LED=0;delay_ms(80);LED=1;delay_ms(220);break;
                         case 3: LED=0;delay_ms(150);LED=1;delay_ms(150);break;
                         case 4: LED=0;delay_ms(10);LED=1;delay_ms(90);break;
                 }
   }
}

void Timer0Init(void)                //5毫秒@12.000MHz
{
        AUXR &= 0x7F;                //定時(shí)器時(shí)鐘12T模式
        TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
        TL0 = 0x00;                //設(shè)置定時(shí)初值
        TH0 = 0xEE;                //設(shè)置定時(shí)初值
        TF0 = 0;                //清除TF0標(biāo)志
        TR0 = 1;                //定時(shí)器0開(kāi)始計(jì)時(shí)
        EA = 1;
        ET0 = 1;
}
unsigned char getkey()
{         
         static unsigned char lp=0;
          switch(lp)
                {
                case 0:
                         if(!key)lp++;
                         else if(flag)
                                   {
                                        if(++time>50)
                                          {
                                           value=1;           //單擊
                                           time=0,
                                           flag=0;
                                           }
                                        }
                        break;
                        case 1:if(!key)lp++;else lp=0;break; //        消抖動(dòng)
                        case 2:
                             if(key)
                                   {
                                    lp++;
                                    if(flag)
                                      {
                                       value=2;                 //連擊
                                       flag=0;
                                      }
                                     else flag=1;
                                    }
                                  else if(++num>250)
                                {
                                         flag=0;
                                         value=3;                  //長(zhǎng)按
                                         lp++;
                                        }
                                        break;
                        case 3:if(key){lp=0;num=0;time=0;}break;
                  }
return value;
}       

main()
   {
                LED=1;
          L=0;S=0;flag=0;value=0,d=0;         
    Timer0Init();
          while(1)
   {  
         if(d==0&&key==1)
           {
                 LED=1;        
     ET0 = 0;
           INT_CLKO |= 0x20;              //INT3 Enable
                 PCON = 0x02;             //MCU進(jìn)入掉電模式
                 _nop_();
                 _nop_();
                 _nop_();
                 _nop_();                  
           }
        HY();         
   }
}
         
void timer()interrupt 1
{
switch(getkey())
           {  
           case 1:        
                 L++;
                             value=0;       
                              if(L>4) L=1;
                       break;
           case 2: S=~S;L=1;value=0;break;
           case 3: L=0;value=0;d=0; break;
          }
}

void INT3_int (void) interrupt 11
{       
         INT_CLKO &= 0xDF;
         delay_ms(30);
   if(key==0)
          {d=1;
     L=1;       
           ET0 = 1;
         }
}
回復(fù)

使用道具 舉報(bào)

ID:123289 發(fā)表于 2019-1-25 13:02 | 顯示全部樓層
一個(gè)主循環(huán)的末端可以安排進(jìn)入“休眠”。
在它的下一條指令,安排跳轉(zhuǎn)向主循環(huán)入口(C語(yǔ)言自動(dòng)完成)
這個(gè)每次主循環(huán)結(jié)束時(shí)都會(huì)休眠,而循環(huán)的連續(xù)則是由中斷打破休眠后完成的。

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:60656 發(fā)表于 2019-1-25 12:23 | 顯示全部樓層
wojiaoguogai 發(fā)表于 2019-1-25 10:12
休眠?操作時(shí)來(lái)個(gè)中斷

現(xiàn)在我碰到的問(wèn)題是, 想要上電喚醒后也要響應(yīng)功能,按鍵處理不好, 我加入休眠和中斷喚醒后, 第一次上電后單擊按鍵,會(huì)直接跳到第2個(gè)功能上(就L=2了), 不斷電后續(xù)再循環(huán)休眠喚醒視乎正常 。
回復(fù)

使用道具 舉報(bào)

ID:415064 發(fā)表于 2019-1-25 10:12 | 顯示全部樓層
休眠?操作時(shí)來(lái)個(gè)中斷
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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