

在CT107D單片機綜合訓練平臺上,首先將J5處的跳帽接到2~3引腳,使按鍵S4~S7四個按鍵的另外一端接地從而成為4個獨立鍵盤,在掃描按鍵的程序中,發現有按鍵觸發信號后,先做去抖動處理,當確認為按鍵按下時,才進行相應的功能處理,

設計內容:
1.按下S7后抬起,L1點亮,再次按下S7,L1熄滅;
2.長按S6,L2點亮,松開,L2熄滅;
3.雙擊S5,L3點亮;再次雙擊S5,L3熄滅;
4.按下S4,L4點亮,長按S4,L4熄滅,
設計之前,大家需要思考一下,什么是按鍵的短按、長按、雙擊,他們之間有什么聯系,又有什么區別,簡單點來說,短按就是你按鍵時長要小于一個時間點,比如你手把按鍵按下去時長要小于0.5秒,這個時候你可以把這個按鍵動作稱為按鍵的短按,那相反把手按下按鍵大于0.5秒的按鍵動作可以理解為按鍵的長按,那雙擊又是什么呢?第一次按鍵按下后,在一段時間內這個按鍵又再次被按下,則稱為雙擊,如果第二次按鍵過了這段時間,則表示未完成雙擊,當然,這段時間是大家自己定義的,下面就是利用這種思路,筆者寫出了設計內容所要求的完整程式,

#include<stc15f2k60s2.h>
#define uchar unsigned char //定義無符號字符型別uchar
#define uint unsigned int //定義無符號整型型別uint
void delayms(int ms); //延時函式
void allinit(); //初始化函式
void keyscan(); //獨立按鍵程式
void Timer0Init(void); //1毫秒@12.000MHz
uchar key_up=1;//按鍵按松開標志,按下時為0,松開時為1
uchar keytime=0; //按鍵計時
uchar S7=0,S6=0,S5=0,key=0,cishu=0;
uint tt=0;
bit fla=0;
void main()//主函式
{
allinit(); //初始化函式
Timer0Init(); //定時器初始化
while(1)
{
keyscan(); //獨立按鍵程式
}
}
void keyscan()
{
if(P30==0) //判斷P30是否等于0
{
delayms(5); //延時5ms
if(P30==0) //再次判斷P30是否等于0
{
if(S7==0){S7=1;P2=0X80;P0&=0XFE;} //標志位S7,用于判斷L1燈亮滅狀態,當S7=1時,L1亮
else if(S7==1){S7=0;P2=0X80;P0|=0X01;} //標志位S7,用于判斷L1燈亮滅狀態,當S7=0時,L1滅
}
while(!P30); //如果按鍵不松開,則一直回圈
}
else if(P31==0) //判斷P31是否等于0
{
delayms(5); //延時5ms
if(P31==0) //再次判斷P31是否等于0
{
S6=1;P2=0X80;P0&=0XFD; //按鍵按下則S6置1,L2點亮
}
}
else if((S6==1)&&(P31==1)) //判斷按鍵是否為按下后松開狀態
{
S6=0;P2=0X80;P0|=0X02; //S6清零,L2熄滅
}
else if(P32==0) //判斷P32是否等于0
{
delayms(5); //延時5ms
if(P32==0) //再次判斷P32是否等于0
{
if(S5==0)
{
S5=1;cishu++;EA=1;ET0=1;tt=0; //第一次按鍵按下,S5標志位置1,按鍵次數+1,打開定時器開始計時
}
else if(S5==1) //判斷第二次按鍵是否按下
{
if((tt<=500)&&(cishu==1)) //判斷按下時按鍵是否是在500ms以內按下,并且有過一次2按鍵按下記錄
{
if(fla==0){fla=1;P2=0X80;P0&=0XFB;} //標志位fla,用于判斷L3燈亮滅狀態,當fla=1時,L3亮
else if(fla==1){fla=0;P2=0X80;P0|=0X04;} //標志位fla,用于判斷L3燈亮滅狀態,當fla=0時,L3滅
EA=0;ET0=0;tt=0;cishu=0;S5=0; //關閉定時器,定時器按鍵時長tt清零,按鍵次數清零,S5標志位置0
}
else
{
EA=0;ET0=0; //如果按鍵時長間隔大于500ms,則關閉定時器
tt=0;cishu=0;S5=0; //按鍵時長間隔tt清零,按鍵次數清零,S5標志位清零,便于下次按鍵記錄
}
}
}
while(!P32); //如果按鍵不松開,則一直回圈
}
else if((key_up==1)&&(P33==0)) //判斷按鍵是否按下
{
delayms(5); //延時5ms,消抖
if(P33==0) key_up=0; //再次判斷按鍵是否按下,key_up清零,說明確實有按鍵按下
}
else if(P33==1) //程式為松手檢測,所以在P33為1時判斷按鍵狀態
{
if(key_up==0) //判斷key_up是否為0
{
key_up=1; //key_up置1,為下次按鍵記錄做準備
if(keytime<50) //判斷按鍵計時是否小于500ms,即為短按
{
keytime=0; //按鍵計時清零
P2=0X80;P0&=0XF7; //執行短按狀態,讓L4點亮
}
keytime=0; //按鍵計時清零
}
}
if(key_up==0)//如果按鍵按下則按10ms時間計時
{
delayms(10); //延時10ms
keytime++; //keytime++,用于在按鍵按下時有多少個10ms時間流過,方便判斷按鍵長按短按
if(keytime>=50) //如果長按時間大于等于500ms則回傳按鍵長按,在此處設定按鍵長按時長
{
P2=0X80;P0|=0X08; //執行長按狀態,讓L4熄滅
}
}
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設定定時器模式
TL0 = 0x20; //設定定時初值
TH0 = 0xD1; //設定定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
}
void time0() interrupt 1 //定時器0中斷
{
if(++tt==1200); //定時器0計時
}
void delayms(int ms)//延時函式
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void allinit()//初始化函式
{
P2=0XA0;P0=0X00; //關閉蜂鳴器繼電器
P2=0X80;P0=0XFF; //關閉所有LED燈
P2=0XC0;P0=0XFF; //選中所有數碼管段選
P2=0XFF;P0=0XFF; //關閉所有數碼管
}
![]()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278168.html
標籤:其他
上一篇:Java Web 動漫小專案(未完成,希望有緣人可以繼續將其完成)
下一篇:GPS基站架設完整操作流程
