久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6334|回復: 6
收起左側

單片機按鍵延時開關燈問題求助

[復制鏈接]
ID:140489 發表于 2017-7-20 16:44 | 顯示全部樓層 |閱讀模式
//這單片機程序實現的功能是: 按鍵按下,延時1秒燈亮,如果按鍵按住不放,燈就一直亮,松手后,延時30秒燈熄滅;
//上面描述的功能實現了,我想加一個功能,如果在燈沒有熄滅的情況下,再次按下按鍵,延時熄滅的時間在上次延時時間上累加,
//想了好久,沒能實現第二個功能,請大神們看下,該怎么寫呢
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

bit a;//計時標志

uint num;//計時變量

sbit LED1 = P1^0;

sbit K1 = P3^0;

void delay(uint x)
{
  uint i,j;
  for(i=x;i>0;i--)
          for(j=120;j>0;j--);
}
void main(void)
{                                                                            //模擬點動延時開關燈
     EA = 1;
     ET0 = 1;
     TMOD = 0x01;
     TH0 =(65536-50000)/256;//定時50ms應該要50000
     TL0 =(65536-50000)%256;
         TR0=1;
        while(1)
            {
              if(K1==0)
                {
                  delay(1000);
                          if(K1==0)
                                  {
                             LED1=0;         //LED1亮,一直按住K1, LED1就一直亮。測試通過
                                         while(!K1);         //松手后
                                         a=1;


                                   }
                  }
        
                if(num==600)//num 50毫秒加1,延時30秒 即30000/50=600次
                {
                                num = 0;// 計時值必須清零,否則第2次按開關,燈會長亮
                        a = 0;    //清除標志
                        LED1 = 1; //燈熄滅        
                }

             }   
}


void time0() interrupt 1
{
     TH0 =(65536-50000)/256;
     TL0 =(65536-50000)%256;
        if(a==1)num++;  //判斷計時標志是否為1,為1就開始計時
}

回復

使用道具 舉報

ID:211467 發表于 2017-7-20 23:03 | 顯示全部樓層
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
bit a;//計時標志
uint num;//計時變量uchar num2;//在次按下次數標志
sbit LED1 = P1^0;
sbit K1 = P3^0;

void delay(uint x)
{
  uint i,j;
  for(i=x;i>0;i--)
          for(j=120;j>0;j--);
}

void main(void)
{                                                                            //模擬點動延時開關燈
     EA = 1;
     ET0 = 1;
     TMOD = 0x01;
     TH0 =(65536-50000)/256;//定時50ms應該要50000
     TL0 =(65536-50000)%256;
     TR0=1;
     while(1)
      {
         if(K1==0)
         {
            delay(1000);
             if(K1==0)
                {
                LED1=0;         //LED1亮,一直按住K1, LED1就一直亮。測試通過
                while(!K1);         //松手后
                a=1;
                 }
                 if(K1==0)
                  {
                 delay(1000);
                    if(K1==0)
                       num2++;
                  }
       }
      if(num==(600*num2))    //num 50毫秒加1,延時30秒 即30000/50=600次
          {
          num = 0;// 計時值必須清零,否則第2次按開關,燈會長亮
          a = 0;    //清除標志
          LED1 = 1; //燈熄滅        
        }
     }   
}

void time0() interrupt 1
{
     TH0 =(65536-50000)/256;
     TL0 =(65536-50000)%256;
        if(a==1)num++;  //判斷計時標志是否為1,為1就開始計時
}




程序寫的不完善 ,不過我覺著按照找個思路,應該可以達到你的要求
回復

使用道具 舉報

ID:123289 發表于 2017-7-21 00:14 | 顯示全部樓層
1、做兩個鍵標記,K_LAST、K_THIS,一個記上次鍵值,一個記本次鍵值。按下為1。
   這樣就能知道按下、彈起、按住不放了。提示:所謂上次、本次都應經防彈動過濾(自己去做防彈動)。
2、做一個1S計時器:R_1S,一個起動標記B_1S。
   T0中斷后:如果B_1S=1,就將R_1S+1,當R_1S=1秒時:就清B_1S=0,不再計時,并亮燈。
   主程序中:當鍵“按下”(K_LAST=0、K_THIS=1)時:置B_1S=1。
3、做一個30S計時器:R_30S,一個起動標記B_30S。
   T0中斷后:如果B_30S=1,就將R_30S-1,當R_30S=0秒時:就清B_30S=0,不再計時,并滅燈。
   主程序中:當按鍵彈起時(K_LAST=1、K_THIS=0),置B_30S=1,R_30S=R_30S+30秒(提示:應防溢出)。
就這么簡單!
提示:掃鍵時,將讀到的健值放入K_THIS,然后做鍵處理、判定,結束后將K_LAST=K_THIS,準備下次采樣。
回復

使用道具 舉報

ID:213173 發表于 2017-7-21 09:43 | 顯示全部樓層
修改后完美解決你的問題,有詳細注釋
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
bit sign_a=0,sign_b=0,sign_c=0,sign_d=0;//標志
uint count1=0,count2=0;                                        //計數器
sbit LED1 = P1^0;
sbit key = P3^0;

void keyscan()                                        //按鍵掃描程序
{
        static uchar count=0;                //消抖計數變量                       
        if(key==0)                                        //檢測按鍵如果為0
        {
                count++;                                //消抖計數
                if(count>=100)                        //重復檢測按鍵如果為0
                {                       
                        count=100;                        //防止溢出
                        if(sign_c==0)                //按鍵自鎖標志為0
                        {
                                sign_a=1;                //延時1秒啟動標志
                                sign_c=1;                //按鍵自鎖標志置1,防止一次按鍵多次響應
                                EA = 0;                        //關閉總中斷,防止改變count2時與中斷沖突
                                count2+=600;        //每30秒延時累加(600),最大累加到54.5分鐘,超過109次溢出
                                EA = 1;                        //開啟總中斷
                        }
                }
        }
        else                                                //按鍵抬起
        {
                if(sign_c==1)                        //如果按鍵自鎖標志為1
                {
                        sign_c=0;                        //按鍵自鎖標志清0
                        sign_d=1;                        //按鍵按下后再抬起標志為1
                }
                count=0;                                //消抖計數清0
        }
}

void main(void) //@12T、12MHz、定時50ms
{
        TMOD = 0x01;
        TH0 =(65536-50000)/256;                //設置定時初值
        TL0 =(65536-50000)%256;                //設置定時初值
        TR0=1;
        EA = 1;
        ET0 = 1;
        while(1)
        {
                keyscan();                                //按鍵掃描
/*******顯示部分********/
                if(sign_b==1)                        //1秒延時結束
                        LED1 = 0;                        //LED1亮
                else
                        LED1 = 1;                        //LED1滅
        }   
}

void time0() interrupt 1
{
        TH0 =(65536-50000)/256;                //設置定時重載值
        TL0 =(65536-50000)%256;                //設置定時重載值
        if(sign_a==1)                                  //判斷計時標志,啟動延時1秒
        {
                count1++;                                //計數器1自+1
                if(count1>=20)                        //1秒延時到
                {
                        count1=0;                        //計數1清0
                        sign_a=0;                        //1秒延時標志清0
                        sign_b=1;                        //30秒延時標志
                }
        }
        if((sign_b==1)&(sign_d==1)) //30秒延時標志與按鍵抬起標志
        {
                count2--;                                //計數器2自-1
                if(count2==0)                        //N+30秒延時到
                {
                        sign_b=0;                        //30秒延時標志清0
                        sign_d=0;                        //按鍵抬起標志清0
                }
        }
}

回復

使用道具 舉報

ID:140489 發表于 2017-7-21 15:17 | 顯示全部樓層
wulin 發表于 2017-7-21 09:43
修改后完美解決你的問題,有詳細注釋
#include  
#define uchar unsigned char

謝謝,測試了一下,實現了所要的效果
回復

使用道具 舉報

ID:140489 發表于 2017-7-21 16:36 | 顯示全部樓層
剛才又寫了一個小程序
//功能:按鍵按下,延時1秒燈亮,如果按鍵按住不放,燈一直亮,松手后延時30秒燈熄滅;
//      如果在燈沒熄滅的時候,再次按下按鍵不放,燈一直亮,松手后延時30秒燈熄滅。
//模擬點動延時開關燈,測試通過
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

uchar R_1S;                  //1秒計時變量
uint R_30S=600;                 //30秒計時變量
bit B_1S;                         //1秒計時標志
bit B_30S;                         //30秒計時標志

sbit LED1 = P1^0;   //定義LED燈端口
sbit K1 = P3^0;            //定義按鍵端口


void main(void)
{                                                                           
     EA = 1;
     ET0 = 1;
     TMOD = 0x01;
     TH0 =(65536-50000)/256;//定時50ms應該要50000
     TL0 =(65536-50000)%256;
//         TR0=1;
        while(1)
            {
              if(K1==0)                           //按鍵按下
                {
                          TR0=1;                          //啟動定時器
                  B_1S=1;                          //1秒計時標志置1
                          if(R_1S==20)          //如果1秒計時變量為20,說明1秒時間到
                                {
                                        if(K1==0)          //如果按鍵還在按下狀態
                                          {          
                                                 TR0=0;          //關閉定時器
                                     R_1S=0;  //1秒計時變量清零
                                                 LED1=0;       //LED1亮,一直按住K1, LED1就一直亮。
                                                 while(!K1);   //松手后
                                                 TR0=1;                   // 啟動定時器
                                                 B_1S=0;           //1秒計時標志清零
                                                 B_30S=1;           //30秒計時標志置1
                                        }
                                }
                  }

                          if(R_30S>0 && R_30S<600 )        //如果30秒計時變量大于0,并小于600,這時燈是亮的,再延時熄滅的過程
                          {
                                  if(K1==0)                                //這時如果按鍵按下
                                {
                                        B_1S=1;                                //1秒計時標志置1
                                        if(R_1S==20)                //如果1秒計時變量為20,說明1秒時間到
                                        {
                                                if(K1==0)                //如果按鍵還在按下狀態
                                                {       
                                                        TR0=0;                //關閉定時器
                                                        R_30S=1;        //30秒計時變量清1
                                                        LED1=0;                // LED1就一直亮
                                                        R_1S=0;                //1秒計時變量清零
                                                        B_30S=0;        //30秒計時標志清零
                                                        while(!K1);        //松手后
                                                        TR0=1;                   // 啟動定時器
                                                        B_1S=0;                   //1秒計時標志清零
                                                        B_30S=1;           //30秒計時標志置1
                                                        R_30S=R_30S+599; //30秒計時變量位1+599=600,計時自減用       
                                                }       
                                        }       
                                }
                          }
                       
             }   
}


void time0() interrupt 1
{
    TH0 =(65536-50000)/256;          //重裝初值
    TL0 =(65536-50000)%256;          //重裝初值
       
        if(B_1S==1)           //如果1秒計時標志為1
        R_1S++;                   //1秒計時變量自加1
       
        if(B_30S==1)   //如果30秒計時標志為1
        R_30S--;           //30秒計時變量自減1
               
        if(R_30S==0)   //30秒計時變量為0
        {
                R_30S=600; //30秒計時變量賦值600,以備下次自減
                LED1=1;           //熄滅LED燈
                B_30S=0;   //30秒計時標志清零
                TR0=0;           //關閉定時器
        }

}
回復

使用道具 舉報

ID:858627 發表于 2022-5-17 15:23 | 顯示全部樓層
大神 我想實現按鍵按下1分鐘后燈亮 一直按著一直亮,松開后延時2分鐘后燈滅,延時段內再次按下不起作用。如何實現。我改了一下咋不合適
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产大片黄色 | 欧美成人免费 | 91九色婷婷 | 精品免费国产一区二区三区四区介绍 | 中文字幕一区二区三区四区 | 欧美日韩国产高清 | 亚洲精品一区二区三区 | 99视频免费| 蜜桃精品噜噜噜成人av | 我要看黄色录像一级片 | 亚洲区一区二 | 91在线视频免费观看 | 国产在线观看一区二区三区 | 狠狠av | 国产精品1区2区3区 国产在线观看一区 | 欧美一区二区三区四区在线 | 人人澡人人爱 | 天天看天天摸天天操 | 欧美一区二 | 中国一级大毛片 | 精品一区二区三区在线视频 | 中文字幕一区在线观看视频 | 精品福利视频一区二区三区 | 久久国产精品视频免费看 | 国产日韩欧美另类 | 黑人久久久 | 日韩免费看片 | 国产精品99久久久久久大便 | 国产精品视频免费看 | 国产区精品 | 亚洲乱码一区二区三区在线观看 | 草逼网站| 亚洲av毛片成人精品 | 高清av电影 | 影音先锋中文在线 | 日韩毛片视频 | 精品在线看 | 操久久| www.9191| 干干天天| 91在线视频播放 |