找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7172|回復: 15
收起左側

單片機按鍵程序 按一下開,再按一下關,怎么寫?

  [復制鏈接]
ID:901805 發(fā)表于 2021-4-7 12:38 | 顯示全部樓層 |閱讀模式
學了幾天了,今天想寫個開關,結果下載后不是想要的,有沒有哪位大神指導下,看看哪里出了問題,初學小白,勿噴呀!
#include<reg52.h>
sbit key1=P3^2;

unsigned char i;
void delayms(unsigned int z)
{  

    unsigned int k,j;
    for(k=z;k>0;k--)
    for(j=110;j>0;j--);


}



    void key()
{
         
    if(key1==0)
    {
        delayms(20);
        if(key1==0)
        {
       key1=i;
       i++;
        }
      if(i>=2)
      {
        i=0;
      }


    }  
}
void main()
{
while(1)
{

    key();
    if(i==0)
    {
        P0=0x00;

    }  
     if(i==1)
     {
         P0=0xfe;

     }



    }
}

回復

使用道具 舉報

ID:752974 發(fā)表于 2021-4-8 08:31 | 顯示全部樓層
判斷按鍵,如果是有效按鍵,輸出取反即可。
回復

使用道具 舉報

ID:883167 發(fā)表于 2021-4-8 09:14 | 顯示全部樓層
你這個沒有加入 松鍵檢測哦,
例如: while(!key);
把這個加進去,這樣會檢測到你手松
另外還可以加一個取反的代碼,比如  i=~i;
回復

使用道具 舉報

ID:853896 發(fā)表于 2021-4-8 09:52 | 顯示全部樓層
功能簡單,在線仿真一下便可讓你得出原因,同時,也會給你以后分析復雜程序帶來經驗
回復

使用道具 舉報

ID:899171 發(fā)表于 2021-4-8 10:36 | 顯示全部樓層
ccnnzz315 發(fā)表于 2021-4-8 09:52
功能簡單,在線仿真一下便可讓你得出原因,同時,也會給你以后分析復雜程序帶來經驗

問個初學者問題?在線仿真怎么弄,有推薦的軟件嗎?
回復

使用道具 舉報

ID:894154 發(fā)表于 2021-4-8 12:52 | 顯示全部樓層
1 i 先賦初值 unsigned char i=0;
2 key1=i;這行注釋掉不要
3 第二個if(key1==0)內加松手檢測 while(key1==0);
回復

使用道具 舉報

ID:263701 發(fā)表于 2021-4-8 12:56 | 顯示全部樓層
key1=i 這個i是哪來的,p0口有上拉電阻么,還有程序運行很快,你想按鍵一直按下,i會一直變化,萬用表量不出來高低電平了。
if(key1==0)
        {
       P1=0x00;
        }else
      {
       P1=0xfe;
      }
回復

使用道具 舉報

ID:883031 發(fā)表于 2021-4-8 15:35 | 顯示全部樓層
按一次取一次反,
回復

使用道具 舉報

ID:668885 發(fā)表于 2021-4-9 11:59 | 顯示全部樓層
要加防抖延時
回復

使用道具 舉報

ID:207421 發(fā)表于 2021-4-9 13:22 | 顯示全部樓層
  • if(key1==0)
  • {
  •     delayms(20);
  •     if(key1==0)
  •     {
  •         i=~i;//用!或者~取反即可,此時i的值只有0和1
  •         while(key1==0);//等待松開按鍵
  •     }
  • }




回復

使用道具 舉報

ID:588399 發(fā)表于 2021-4-9 13:40 | 顯示全部樓層
你這個很簡單,用一個if判斷取奇數偶數的模就可以實現(xiàn)
回復

使用道具 舉報

ID:451629 發(fā)表于 2021-4-9 18:43 | 顯示全部樓層
用一個變量標志位。flag=~flag;取反就可以
回復

使用道具 舉報

ID:147710 發(fā)表于 2021-4-9 19:38 | 顯示全部樓層
盡量不要用阻塞延時去抖,下面這個更具實用價值,供你參考:
#include<reg52.h>
sbit key1=P3^2;
sbit LED=P0^7;
unsigned char ucKeySec=0;//鍵值
void key()
{
        static unsigned int uiKeyTimeCnt1 = 0; //按鍵去抖動,累加去抖定時器
        static bit ucKeyLock1=0;        //按鍵自鎖標志
        if (key1== 1) //IO是高電平,說明按鍵沒有被按下,清零標志位
        {
                ucKeyLock1 = 0; //按鍵自鎖標志清零
                uiKeyTimeCnt1 = 0; //按鍵去抖動延時計數器清零
        }else if (ucKeyLock1 == 0) { //有按鍵按下,且是第一次被按下
              uiKeyTimeCnt1++; //累加去抖
              if (uiKeyTimeCnt1 > 2000) {
                    uiKeyTimeCnt1 = 0;
                    ucKeyLock1 = 1; //自鎖按鍵置位,避免一直觸發(fā)
                    ucKeySec = 1; //觸發(fā)1號鍵
              }
        }
}
//

void main()
{
        while(1)
        {
           key();
           if(ucKeySec==1)
            {
                ucKeySec=0;  //鍵值復位
                 LED=!LED;
             }

       }
}
//


LED

LED
回復

使用道具 舉報

ID:817354 發(fā)表于 2021-4-10 09:29 | 顯示全部樓層
可以設置兩個不同標志位,每次按鍵動作后,標志位做變化,然后進行按鍵處理
回復

使用道具 舉報

ID:808223 發(fā)表于 2021-4-10 14:40 | 顯示全部樓層
可以在全局設定一個檢測bit i=0,按鍵函數內設定每按一次,i取反一次,然后在主函數內進行判斷,就不用計數按下次數,還有你程序缺少松手檢測:while(!key1);導致你每次按下,除非你按下速度超過按鍵掃描的速度,不然結果就很隨機,可能是點亮,可能是熄滅。
回復

使用道具 舉報

ID:607312 發(fā)表于 2021-4-10 16:38 | 顯示全部樓層
#include<reg52.h>
sbit key1=P3^2;
sbit Led=P2^0;

void delayms(unsigned int z)
{  
    unsigned int k,j;
   
            for(k=z;k>0;k--)
            for(j=110;j>0;j--);
}

void key()                //按鍵處理
{
        key1 = 1;
        if(!key1)
        {
                delayms(10);
                if(!key1)
                {
                        Led ^= Led;
                }
        }
}


void main()                //主函數
{
        while(1)
        {
                key();
        }
}
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

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