欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
51單片機怎樣用按鍵控制長短按切換界面,求程序思路
[打印本頁]
作者:
lzj23642008
時間:
2019-7-29 17:09
標題:
51單片機怎樣用按鍵控制長短按切換界面,求程序思路
我要用兩個按鍵k1,k2。長按K2,切換到設置界面,短按K2切換到常規界面。弄了好久沒有弄好,請高手幫忙指導一下,謝謝!
作者:
1339337425
時間:
2019-7-29 19:54
請工程化,定制化你的單片機代碼
http://m.raoushi.com/bbs/dpj-162218-1.html
(出處: 單片機論壇)
作者:
xianfajushi
時間:
2019-7-29 20:44
一般使用狀態進行切換,你是怎么弄的不行?
作者:
wulin
時間:
2019-7-29 21:18
如果K2只是用于切換界面不必采用長短按方式,只要設置一個標志隨操作取反即可。如果K2是多功能鍵才有必要分長短按。給你一個簡單實用的長短按示例程序參考,希望對你有所幫助。
#include <REG51.H>
#define uint unsigned int
#define uchar unsigned char
#define key_S 20 //宏定義短按(20ms)
#define key_L key_S*50 //宏定義長按(1s)
sbit key1=P3^5;
sbit key2=P3^6;
sbit LED1=P1^0;
sbit LED2=P1^2;
sbit LED3=P1^4;
sbit LED4=P1^6;
uchar KeySec=0;
void Timer0Init()//1毫秒@12.000MHz
{
TMOD= 0x01; //設置定時器模式
TL0 = 0x18; //設置定時初值
TH0 = 0xFC; //設置定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
EA=1; //開總中斷
ET0=1; //開定時器0中斷
}
void keyscan() //按鍵掃描
{
static uint count1=0; //計數變量
static uint count2=0; //計數變量
if(!key1)
{
count1++;
if(count1==key_L) //長按
KeySec=2; //輸出鍵值2
if(count1>key_L) //防止count溢出
count1=key_L+1;
}
else //按鍵抬起
{
if(count1>key_S && count1<key_L)//短按
KeySec=1; //輸出鍵值1
count1=0; //count清0
}
if(!key2)
{
count2++;
if(count2==key_L) //長按
KeySec=4; //輸出鍵值4
if(count2>key_L) //防止count溢出
count2=key_L+1;
}
else //按鍵抬起
{
if(count2>key_S && count2<key_L)//短按
KeySec=3; //輸出鍵值3
count2=0; //count清0
}
}
void key_service() //按鍵服務程序
{
switch(KeySec) //按鍵服務狀態切換
{
case 1:LED2=!LED2;KeySec=0;break;
case 2:LED1=!LED1;KeySec=0;break;
case 3:LED4=!LED4;KeySec=0;break;
case 4:LED3=!LED3;KeySec=0;break;
default: break;
}
}
void main()
{
Timer0Init(); //初始化定時器
while(1)
{
key_service(); //按鍵服務程序
}
}
void timer0() interrupt 1//1毫秒@12.000MHz
{
TL0 = 0x18; //設置定時重裝值
TH0 = 0xFC; //設置定時重裝值
keyscan(); //按鍵掃描程序
}
復制代碼
作者:
Jun默默淡定
時間:
2019-7-29 22:34
這個可以用定時器來操作,假設K2按下的時間超過2S進入設置界面。配置好定時器計時計數,當檢測到K2按下時開啟計時。比如說100ms來一次中斷,計數值temp++,當來20次中斷后時間就為2S。判斷按鍵松開時temp的值是否大于20?當temp的值大于20就進入你所說的設置界面,小于20就進入頁面切換。這樣的小程序用51來操作很容易,但是要注意定時器計數器的初值裝載的問題,還有就是51單片機所用的晶振。12MHz的晶振和11.0592MHz的初值裝載是不一樣的。沒看懂的話就要回去看看51的定時器的知識了
作者:
cjm82
時間:
2019-7-29 23:59
隨手寫的,就寫了1個按鍵長按短按不同功能,不保證沒BUG.注釋標得也自認為是清楚了,你對著你想要的修改調試下應該就可以了.
#define Long_Push_Time n //長按功能按鍵時長(n乘以定時器中斷周期)
#define Short_Push_Time m //短按功能按鍵時間,需注意必須n 大于 m
sbit KEY = Px^x; //按鍵IO口定義
bit Flag_Short_Push_Funcation = 0; //短按觸發標志
bit Flag_Long_Push_Funcation = 0; //長按觸發標志
bit Flag_KEY_Pushed = 0; //按鍵曾經按下標志
void Init_T0() //定時器中斷設置
{
.....
}
void Short_Push_Prog()
{
..........
}
void Long_Push_Prog()
{
............
}
void mian()
{
Init_T0();
while(1)
{
if(Flag_Short_Push_Funcation) //如果短按功能被置1
{
Short_Push_Prog(); //執行短按功能對應的函數
Flag_Short_Push_Funcation = 0; //清短按功能標志.
}
if(Flag_Long_Push_Funcation) //長按功能,跟上面類同.
{
Long_Push_Prog();
Flag_Long_Push_Funcation = 0;
}
}
}
void T0_ISR() interrupt 1
{
TH0 = XXXX;
TL0 = XXXX;
if(!KEY) //按鍵按下
{
KEY_CNT++; //開始計時
Flag_KEY_Pushed= 1; //按鍵已經按過的標志置1
Flag_Short_Push_Funcation = 0; //短按無效
Flag_Long_Push_Funcation = 0; //長按無效
}
if(KEY && Flag_KEY_Pushed == 1 && KEY_CNT < Short_Push_Time)
/*如果按鍵沒有按下但按鍵曾經按下,可是按下時間很短,不足以觸發短按的設定時間,則認為是干擾*/
{
Flag_KEY_Pushed= 0; //清按鍵曾經按下標志
KEY_CNT = 0; //清按鍵按下計時變量
Flag_Short_Push_Funcation = 0; //短按無效
Flag_Long_Push_Funcation = 0; //長按無效
return; //如判斷為干擾,則下面的代碼無須執行,直接跳出.
}
if(KEY && Flag_KEY_Pushed == 1 && KEY_CNT>=Short_Push_Time &&
KEY_CNT < Long_Push_Time)
/*如果按鍵沒有按下, 但按鍵已經按過(用來判斷按過后彈起),
并且曾經按下時間超過 設定短按時間且不超過長按時間*/
{
Flag_Short_Push_Funcation = 1; //短按功能有效
Flag_Long_Push_Funcation = 0; //長按功能無效
KEY_CNT = 0; //清按鍵計時變量
Flag_KEY_Pushed= 0; //清按鍵曾經按下標志
return; //判斷完成,直接跳出
}
}
if(KEY && Flag_KEY_Pushed == 1 && KEY_CNT>=Long_Push_Time )
/*如果按鍵沒有按下, 但按鍵已經按過(用來判斷按過后彈起),
且曾經按下時間超過 長按時間*/
{
Flag_Short_Push_Funcation = 0; //短按功能無效
Flag_Long_Push_Funcation = 1; //長按功能有效
KEY_CNT = 0; //清按鍵計時變量
Flag_KEY_Pushed= 0; //清按鍵曾經按下標志
}
}
作者:
aaaaaa。
時間:
2019-7-30 08:27
cjm82 發表于 2019-7-29 23:59
隨手寫的,就寫了1個按鍵長按短按不同功能,不保證沒BUG.注釋標得也自認為是清楚了,你對著你想要的修改調試下 ...
謝謝分享
作者:
yzwzfyz
時間:
2019-7-30 08:31
要點:做一個計數器CJ來判定長按與短按,CJ的規則如下:
1、CJ計數只發生于定時器的中斷服務程序中,每次中斷+1,計滿不再計,即不回0。
2、CJ計數只發生于鍵按下的時候,未按下不計。
3、做一個鍵狀態判定觸發標記:B_OK,如果鍵未按下,但CJ<>0,則置B_OK=1,表示是判斷鍵狀態的時候了。
4、當B_OK=1,判斷鍵狀態的界定法則是:CJ<某個值為短按,CJ>某個值為長按,某個值是多少由你決定。建議事先將長短兩個界定值放置在某個寄存器中,這樣可以隨意變更界定值。
5、狀態界定完成后將:B_OK清0、CJ清0以備下次再界定。
作者:
yzwzfyz
時間:
2019-7-30 08:40
設置界面、常規界面各做一個標記如:B_SET、B_NOR。在哪個界面哪個置1。再多的界面也這樣做。如果只有兩個界面可以只用一個標記。界面分層疊進疊退時還需要增加次序(層面記憶),這里不說了。
長按以后的動作是:B_SET=1、其它B_NOR=0。
短按以后的動作是:B_NOR=1、其它B_SET=0。
作者:
yzwzfyz
時間:
2019-7-30 08:41
界面的切換,發生于B_SET、B_NOR有變化的時候。
作者:
wj_yuq
時間:
2019-7-30 10:47
參考文章“請工程化,定制化你的單片機代碼”,用中斷服務對按下鍵進行計數,根據計數的多少便可換算時間長短、便可根據不同時間長短執行不同的程序了。
作者:
月之光芒
時間:
2019-7-30 15:31
用定時器做,按下按鈕開始計數,放開按鈕結束計數,按鈕函數里面要加個防抖延時
作者:
lzj23642008
時間:
2019-8-1 16:47
謝謝!
作者:
lzj23642008
時間:
2019-8-2 16:45
cjm82 發表于 2019-7-29 23:59
隨手寫的,就寫了1個按鍵長按短按不同功能,不保證沒BUG.注釋標得也自認為是清楚了,你對著你想要的修改調試下 ...
Init_T0,void Short_Push_Prog(),void Long_Push_Prog().里邊的內容能否幫忙提供一下.謝謝!
作者:
小劉子啊咿呀喲
時間:
2019-8-4 10:47
當按鍵按下時,開啟定時器,并且在定時器中斷里面用一個變量來計數,當按鍵松開時再來判斷計數時間,如果小于0.5s,則判斷為短按,標志位給0,如果大于0.5s,標志位給1,然后根據標志位進行界面切換。定時器的計數時間要設置一個上限,否則如果時間太長可能會溢出,判斷按鍵按下或松開,可以用經典的三行代碼,其中有兩個變量,一個變量是用來判斷按鍵的“下降沿”(其實準確來說并不能定義為下降沿,只是按鍵按下時,第一遍執行程序時,對應的位會發生改變,當執行第二遍時就又變為0,有點類似于static的作用),另一個變量是用來檢測按鍵是否為按下狀態,可以用這兩個變量來判斷按鍵按下和松開,從而開啟或改變定時器,讀取計數值,讀取完計數值后需要將計數值清零,否則,第二次按下按鍵時則判斷不了短按。
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1