欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
一種全新的單片機按鍵程序寫法思路,請大家指教,點評
[打印本頁]
作者:
2448289424
時間:
2019-7-21 01:11
標題:
一種全新的單片機按鍵程序寫法思路,請大家指教,點評
最近帖子已經有人在此提到充分利用CPU中斷的重要性,,再次我就不要說了。此按鍵demo支持短按,長按,多個按鍵同時按下,由于是用掃描的方式,各個按鍵的按下和松獨立處理,不互相干擾,避免要按鍵死等的情況。對于特殊的按鍵消抖時間可單獨一條線掃描檢測。。由于是各個按鍵,一位位檢測,檢測到一位就進行處理,之后再進行處理下一位,所以有先后順序。廢話不多說,下面講思路,有錯誤的地方大家可以一起學習,探討,,,,,,,,
按鍵的最終狀態無非就兩種,按下或者松開。我用的是STC8單片機,現在的一些增強型或許新型號應該內部都有上拉電阻,,所以我們是按鍵低電平觸發。
對于只作為輸入口用于按鍵檢測,,我們可以默認他的IO口狀態,不要去操作IO寄存器,,,(如果是即作為輸入又作為輸出的話,,在讀取狀態的時候記得先寫1,延時2個NOP,再去讀,保證讀取的準確性),,假設按鍵沒按下去默認就是1了,按鍵按下去就是0,也就是1->0的過程,,松開的話就是0->1,恢復到最初狀態。這里就有兩個變化1->0,和0->1,,理解這個之后我們就定義兩個變量 value 變化值 buf 最終狀態值 我們兩個變化1->0,和0->1進行異或就是1,,說明了按鍵有按下或松開的動作,我們就去執行對應的函數,,執行完后按鍵的最終只buf也跟著更新,也就是0(按下) 1(松開),,(一直按下的過程)此時端口值0 和buf0 異或就是0 ,咱就不再去執行按鍵按下的程序,,(松開后的過程)此時端口值1 和buf1 異或就是0 ,咱就不再去執行按鍵松開的程序,,這樣就保證了按下 或者松開 只執行一次動作,,因此加入一些標志位。,結合中斷就可以做一些長按功能了。提供的demo里有做了一個實例是長按2秒開關蜂鳴器,,其他的按鍵按下或者松開的子函數用戶自己增加自己需要的功能,,里面只是寫了一些簡單的點燈功能用于調試,,自己驗證了一下程序是可行,,所以提供出來,,大部分都有注釋,看看有什么不足之處,在進行修改,,后面會在此基礎加入矩陣掃描,原理一樣,接著進一步完善demo,做成一個能實現操作常見的外設demo出來,,程序不足之處多多見諒,大家多多批評,一起學習,,,,,下面按鍵的流程圖,也不知道這個畫得不到,老感覺自己的表達能力有待提高,,或者也會多發貼,把自己的一些表達能力加強,,
按鍵流程圖.png
(104.75 KB, 下載次數: 74)
下載附件
按鍵流程圖
2019-7-21 01:09 上傳
1 file文件夾為項目的硬件端口表 功能書 原理圖等資料
2 inc文件 為系統配置文件
3 lib文件 各個外設文件
4 program文件 為項目文件
單片機源程序如下:
#include<stc8.h>
#include <intrins.h>
sbit led1=P0^4;
sbit led2=P0^5;
sbit led3=P0^6;
sbit led4=P0^7;
sbit led5=P1^3;
sbit led6=P1^4;
sbit led7=P1^5;
sbit led8=P1^6;
sbit beep=P1^7;
#define D_ScanLine 2 //定義掃描線的數量,
#define D_ESTTime 10 //單位ms,消除抖動時間。實際以為你外設消抖時間為準
#define P0_key 0xFc //定義用到的端口按鍵(低電平有效,用到p00 p01)
//#define P1_key 0x00 //定義用到的端口按鍵(低電平有效,用到8個)
#define P2_key 0x00 //定義用到的端口按鍵(低電平有效,用到8個)
//#define P3_key 0x00 //定義用到的端口按鍵(低電平有效,用到8個)
u8 R_key_buf[D_ScanLine]; //定義存儲每一行按鍵變化后最終的數值
u8 R_key_value[D_ScanLine]; //定義存儲每一行按鍵變化中的數值
u8 R_key_douce; //按鍵消抖時基
u8 R_key_num; //按鍵編號(對應各個按鍵函數)
u8 D_ScanLineDec; //當前掃描線
u8 beep_flag; //蜂鳴器標志
u16 beep_time; //計時
//按鍵消抖
void F_key_douce()
{
if(R_key_douce!=0)
{
R_key_douce=R_key_douce-1;
}
}
//蜂鳴器計時
void F_beep_time()
{
if(beep_flag==1)
{
if(beep_time!=0)
beep_time=beep_time-1;
}
}
//蜂鳴器檢測
void F_beep_check()
{
if(beep_flag==1)
{
if(beep_time==0)
{
beep=~beep ;
beep_flag=0;
}
}
}
//對應按鍵按下子函數
void F_key1_dn()
{
led1=~led1;
}
void F_key2_dn()
{
led2=~led2;
}
void F_key3_dn()
{
led3=~led3;
}
void F_key4_dn()
{
led4=~led4;
}
void F_key5_dn()
{
}
void F_key6_dn()
{
}
void F_key7_dn()
{
}
void F_key8_dn()
{
}
void F_key9_dn()
{
led5=~led5;
}
void F_key10_dn()
{
led6=~led6;
}
void F_key11_dn()
{
led7=~led7;
}
void F_key12_dn()
{
led8=~led8;
}
void F_key13_dn()
{
beep_flag=1;
beep_time=0x07d0; //2秒
}
void F_key14_dn()
{
}
void F_key15_dn()
{
}
void F_key16_dn()
{
}
//------------------------------------------------------
//對應按鍵松開子函數
void F_key1_up()
{
}
void F_key2_up()
{
// R_key_num=8;
// led=~led;
}
void F_key3_up()
{
// R_key_num=8;
// led=~led;
}
void F_key4_up()
{
// R_key_num=8;
// led=~led;
}
void F_key5_up()
{
// R_key_num=8;
// led=~led;
}
void F_key6_up()
{
// R_key_num=8;
// led=~led;
}
void F_key7_up()
{
// R_key_num=8;
// led=~led;
}
void F_key8_up()
{
// R_key_num=8;
// led1=~led1;
}
void F_key9_up()
{
// R_key_num=8;
// led1=~led1;
}
void F_key10_up()
{
// R_key_num=8;
// led=~led;
}
void F_key11_up()
{
// R_key_num=8;
// led=~led;
}
void F_key12_up()
{
// R_key_num=8;
// led=~led;
}
void F_key13_up()
{
beep_flag=0;
beep_time=0x07d0; //2秒
}
void F_key14_up()
{
// R_key_num=8;
// led=~led;
}
void F_key15_up()
{
// R_key_num=8;
// led=~led;
}
void F_key16_up()
{
// R_key_num=8;
// led=~led;
}
//按鍵按下總函數
void key_dn()
{
switch(R_key_num+1)
{
case 1:
F_key1_dn();
break;
case 2:
F_key2_dn();
break;
case 3:
F_key3_dn();
break;
case 4:
F_key4_dn();
break;
case 5:
F_key5_dn();
break;
case 6:
F_key6_dn();
break;
case 7:
F_key7_dn();
break;
case 8:
F_key8_dn();
break;
case 9:
F_key9_dn();
break;
case 10:
F_key10_dn();
break;
case 11:
F_key11_dn();
break;
case 12:
F_key12_dn();
break;
case 13:
F_key13_dn();
break;
case 14:
F_key14_dn();
break;
case 15:
F_key15_dn();
break;
case 16:
F_key16_dn();
break;
default:
break;
}
}
//按鍵松開總函數
void key_up()
{
switch(R_key_num+1)
{
case 1:
F_key1_up();
break;
case 2:
F_key2_up();
break;
case 3:
F_key3_up();
break;
case 4:
F_key4_up();
break;
case 5:
F_key5_up();
break;
case 6:
F_key6_up();
break;
case 7:
F_key7_up();
break;
case 8:
F_key8_up();
break;
case 9:
F_key9_up();
break;
case 10:
F_key10_up();
break;
case 11:
F_key11_up();
break;
case 12:
F_key12_up();
break;
case 13:
F_key13_up();
break;
case 14:
F_key14_up();
break;
case 15:
F_key15_up();
break;
case 16:
F_key16_up();
break;
default:
break;
}
}
void Keyscan_task()
{
u8 ar;
u8 ax;
u8 i;
D_ScanLineDec=D_ScanLineDec+1;
if(D_ScanLineDec==1) //掃描第一條線
{
ar=P0;
ax=P0_key;
ar=ar^ax;
ar=ar|ax; //獲取按鍵值
}
if(D_ScanLineDec==2) //掃描第二條線
{
ar=P2;
ax=P2_key;
ar=ar^ax;
ar=ar|ax; //獲取按鍵值
}
ax=R_key_value[D_ScanLineDec-1]; //跟變化的按鍵值比較
ax=ar-ax;
if(ax!=0) //不等于0說按鍵有動作(按下或者松開)
{
R_key_value[D_ScanLineDec-1]=ar; //記錄當前的按鍵值,然后進行消抖
R_key_douce=D_ESTTime; //設置消抖時間
D_ScanLineDec=D_ScanLine; //重新更新掃描線,重新開始掃描
}
else
{
if(R_key_douce==0) //中斷消抖,,判斷消抖時間到了?
{
ax=R_key_buf[D_ScanLineDec-1]; //把按鍵變化后值拿出來
ar=R_key_value[D_ScanLineDec-1]; //把變化中的按鍵值拿出來
ar=ar^ax;
if(ar!=0) //按鍵發生變化 ar
{
ax=ar&ax;
if(ax!=0) //按鍵按下
{
for(i=0;i<8;i ++)
{
ax=(ar>>i)&1; //取出具體是哪一位的按鍵有變化,一次只取一位
if(ax==1)
{
R_key_num=i;
ar=0x01<<i;
R_key_buf[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1]^ar; //保存最終的按鍵值
R_key_value[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1]; //保存最終的按鍵變化值
for(ar=1;ar<=D_ScanLineDec-1;ar++)
{
R_key_num=R_key_num+8;
}
key_dn();
}
}
}
else //按鍵松開原理同按鍵按下一樣
{
for(i=0;i<8;i ++)
{
ax=(ar>>i)&1;
if(ax==1)
{
R_key_num=i;
ar=0x01<<i;
R_key_buf[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1]^ar; //保存最終的按鍵值
R_key_value[D_ScanLineDec-1]=R_key_buf[D_ScanLineDec-1];
for(ar=1;ar<=D_ScanLineDec-1;ar++)
{
R_key_num=R_key_num+8;
}
key_up();
}
}
}
}
else
{
} /////按鍵沒按下
}
}
}
void F_Keyscan()
{
D_ScanLineDec=0;
while(D_ScanLine-D_ScanLineDec)
{
Keyscan_task();
}
}
void F_Key_buf_value_init()
{
u8 i;
for(i=0;i<D_ScanLine;i ++)
{
R_key_buf[i]=0xff;
R_key_value[i]=0xff;
}
}
復制代碼
所有程序51hei打包下載:
STC8 實驗3 -按鍵.rar
(92.31 KB, 下載次數: 19)
2019-7-21 01:11 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
鵬博士PBs
時間:
2019-7-21 10:33
希望可以更簡單明了一些
作者:
2448289424
時間:
2019-7-21 14:59
鵬博士PBs 發表于 2019-7-21 10:33
希望可以更簡單明了一些
程序上還可以在優化一下,但這個按鍵思路跟常見的按鍵觸發方法比,我覺得是是比較好的,嘻嘻
作者:
tieq1952
時間:
2019-7-22 07:10
謝謝分享!!!
作者:
zhuyuye
時間:
2019-7-22 08:38
NICE!!!!
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1