標題:
單片機按鍵延時開關(guān)燈問題求助
[打印本頁]
作者:
lids
時間:
2017-7-20 16:44
標題:
單片機按鍵延時開關(guān)燈問題求助
//這單片機程序?qū)崿F(xiàn)的功能是: 按鍵按下,延時1秒燈亮,如果按鍵按住不放,燈就一直亮,松手后,延時30秒燈熄滅;
//上面描述的功能實現(xiàn)了,我想加一個功能,如果在燈沒有熄滅的情況下,再次按下按鍵,延時熄滅的時間在上次延時時間上累加,
//想了好久,沒能實現(xiàn)第二個功能,請大神們看下,該怎么寫呢
#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)
{ //模擬點動延時開關(guān)燈
EA = 1;
ET0 = 1;
TMOD = 0x01;
TH0 =(65536-50000)/256;//定時50ms應(yīng)該要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次按開關(guān),燈會長亮
a = 0; //清除標志
LED1 = 1; //燈熄滅
}
}
}
void time0() interrupt 1
{
TH0 =(65536-50000)/256;
TL0 =(65536-50000)%256;
if(a==1)num++; //判斷計時標志是否為1,為1就開始計時
}
作者:
大黃蜂001
時間:
2017-7-20 23:03
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
bit a;//計時標志
uint num;//計時變量uchar num2;//在次按下次數(shù)標志
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)
{ //模擬點動延時開關(guān)燈
EA = 1;
ET0 = 1;
TMOD = 0x01;
TH0 =(65536-50000)/256;//定時50ms應(yīng)該要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次按開關(guān),燈會長亮
a = 0; //清除標志
LED1 = 1; //燈熄滅
}
}
}
void time0() interrupt 1
{
TH0 =(65536-50000)/256;
TL0 =(65536-50000)%256;
if(a==1)num++; //判斷計時標志是否為1,為1就開始計時
}
程序?qū)懙牟煌晟?,不過我覺著按照找個思路,應(yīng)該可以達到你的要求
作者:
yzwzfyz
時間:
2017-7-21 00:14
1、做兩個鍵標記,K_LAST、K_THIS,一個記上次鍵值,一個記本次鍵值。按下為1。
這樣就能知道按下、彈起、按住不放了。提示:所謂上次、本次都應(yīng)經(jīng)防彈動過濾(自己去做防彈動)。
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秒(提示:應(yīng)防溢出)。
就這么簡單!
提示:掃鍵時,將讀到的健值放入K_THIS,然后做鍵處理、判定,結(jié)束后將K_LAST=K_THIS,準備下次采樣。
作者:
wulin
時間:
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; //計數(shù)器
sbit LED1 = P1^0;
sbit key = P3^0;
void keyscan() //按鍵掃描程序
{
static uchar count=0; //消抖計數(shù)變量
if(key==0) //檢測按鍵如果為0
{
count++; //消抖計數(shù)
if(count>=100) //重復檢測按鍵如果為0
{
count=100; //防止溢出
if(sign_c==0) //按鍵自鎖標志為0
{
sign_a=1; //延時1秒啟動標志
sign_c=1; //按鍵自鎖標志置1,防止一次按鍵多次響應(yīng)
EA = 0; //關(guān)閉總中斷,防止改變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; //消抖計數(shù)清0
}
}
void main(void) //@12T、12MHz、定時50ms
{
TMOD = 0x01;
TH0 =(65536-50000)/256; //設(shè)置定時初值
TL0 =(65536-50000)%256; //設(shè)置定時初值
TR0=1;
EA = 1;
ET0 = 1;
while(1)
{
keyscan(); //按鍵掃描
/*******顯示部分********/
if(sign_b==1) //1秒延時結(jié)束
LED1 = 0; //LED1亮
else
LED1 = 1; //LED1滅
}
}
void time0() interrupt 1
{
TH0 =(65536-50000)/256; //設(shè)置定時重載值
TL0 =(65536-50000)%256; //設(shè)置定時重載值
if(sign_a==1) //判斷計時標志,啟動延時1秒
{
count1++; //計數(shù)器1自+1
if(count1>=20) //1秒延時到
{
count1=0; //計數(shù)1清0
sign_a=0; //1秒延時標志清0
sign_b=1; //30秒延時標志
}
}
if((sign_b==1)&(sign_d==1)) //30秒延時標志與按鍵抬起標志
{
count2--; //計數(shù)器2自-1
if(count2==0) //N+30秒延時到
{
sign_b=0; //30秒延時標志清0
sign_d=0; //按鍵抬起標志清0
}
}
}
作者:
lids
時間:
2017-7-21 15:17
wulin 發(fā)表于 2017-7-21 09:43
修改后完美解決你的問題,有詳細注釋
#include
#define uchar unsigned char
謝謝,測試了一下,實現(xiàn)了所要的效果
作者:
lids
時間:
2017-7-21 16:36
剛才又寫了一個小程序
//功能:按鍵按下,延時1秒燈亮,如果按鍵按住不放,燈一直亮,松手后延時30秒燈熄滅;
// 如果在燈沒熄滅的時候,再次按下按鍵不放,燈一直亮,松手后延時30秒燈熄滅。
//模擬點動延時開關(guān)燈,測試通過
#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應(yīng)該要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) //如果按鍵還在按下狀態(tài)
{
TR0=0; //關(guān)閉定時器
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) //如果按鍵還在按下狀態(tài)
{
TR0=0; //關(guān)閉定時器
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; //關(guān)閉定時器
}
}
作者:
437565226
時間:
2022-5-17 15:23
大神 我想實現(xiàn)按鍵按下1分鐘后燈亮 一直按著一直亮,松開后延時2分鐘后燈滅,延時段內(nèi)再次按下不起作用。如何實現(xiàn)。我改了一下咋不合適
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1