單片機AD按鍵設計

在設計中如果用到IO口不夠用,我們肯定第一時間想到的就是通過電阻分壓,根據按下不同按鍵,來讓不同阻值的電阻接到分壓電路中,然後單片機ADC模塊做電壓數據讀取分析對應按鍵按下。下文就和大家分享下單片機設計AD按鍵的內容。

AD按鍵設計硬件部分的電路有兩種電路形式,一種的電阻串聯,另一種是電阻並聯,這兩種都是通過電阻分壓的原理實現的,下面通過電路圖一一介紹,並給出一個案例程序參考。

電阻並聯型AD按鍵

單片機AD按鍵設計

電阻並聯型AD按鍵

上圖有10個按鍵,不同按鍵按下,分到的電壓值不同,電阻值我已經計算好了,有部分誤差,但已經是算成最小誤差值了,以後大家可直接使用。對應的分壓值依次有0.1Vref、0.2Vref ~ 0.9Vref、0.99Vref,共10個檔位。單片機ADC通過讀取電路中ADCIN處的電壓識別對應按鍵按下。

上圖電阻並聯型AD按鍵電路有一個缺點就是如果有兩個按鍵同時按下,會有錯誤識別的可能出現,抗干擾差,所以並聯型AD按鍵電路很少使用。

電阻串聯型AD按鍵

單片機AD按鍵設計

電阻串聯線AD按鍵

上圖中有10個按鍵,對應電阻值按照ADCIN處的電壓分別為Vref的x/10(x=1,2,3...9,10)倍算好,使用的電阻值也已經按照最小誤差定的,可直接使用。不同按鍵按下,ADCIN處的電壓不同,單片機ADC模塊讀出ADC值,從而識別對應哪個按鍵按下。

上圖中電阻使用串聯的方式接在電路中,這樣也就有一個電阻壞,就會影響到其他按鍵檢測的問題。如果兩個按鍵按下,只會識別一個靠近圖中ADCIN處的按鍵,這樣不會有像並聯型AD按鍵電路那樣有識別錯誤的問題存在,但是這裡電阻的誤差不好控制,所以我對上面電路做了改進。如下圖:

單片機AD按鍵設計

等值電阻電阻串聯型AD按鍵

這個電路的好處就是這裡將串聯的電阻設計成等值的形式,這樣在生產時也不必買更多阻值的電阻了。具體怎麼分壓的相信大家一看就懂,這裡只是巧妙的應用了一個1M的電阻。一個電阻和大於它很多倍(一般理解為10倍以上)的電阻並聯,並聯後的阻值依然可以理解為和這個電阻值相等。同樣的可以將電阻並聯型AD按鍵電路改成等阻值的,這裡就不在做出解答,有興趣的朋友可以發揮下自己的腦力看看怎麼設計。

使用AD按鍵時有個需要注意的地方就是,按鍵儘量選擇好些的。因為按鍵本身按下也是有阻值的,特別是用了久的按鍵,其按鍵接觸點容易氧化,造成按鍵按下,有一定的按鍵阻值接在電路中。從而影響程序的識別,特別是我國南方較潮溼的地區,差一點的按鍵觸點特別容易生鏽氧化。所以AD按鍵也就存在了比單獨通過讀IO電平識別的按鍵的壽命短的問題。所以這種按鍵也不是很推薦使用的。特別是按鍵數量越多,出現問題的數量也就越多。

AD按鍵程序設計

在程序設計前,首先要明白AD按鍵設計的原理和程序設計的思路。如果一個8位的ADC模塊,要設計成10個按鍵,就是將8位ADC滿值255等分成10份,每份之間有大約25個差值,比如一個按鍵按下的ADC值在25±11的位置,那麼它臨近的按鍵就是50±11的位置。對應的識別這些值,就可以識別哪個按鍵按下了。當然為了抗干擾強,最好等分的數要少,8位的話等分最好不要超過8個,否則抗干擾不是很好,如果是8個按鍵的話每個按鍵的ADC差值為32,按鍵間的ADC差值越大,越有利於抗干擾。

AD按鍵程序思路:

單片機AD按鍵設計

按鍵抖動濾波原理

每隔10ms(這個時間是按鍵抖動的濾波時間,可以根據實際情況更改)讀一次ADC按鍵值,根據值的範圍,將對應的按鍵數值加到AD按鍵FIFO中(這裡緩衝區8個字節長),如果AD按鍵FIFO滿了,若FIFO前4個值是0(對應按鍵沒按下),最後2個值是相等的(對應按鍵已經穩定按下),中間的2個值對應按鍵抖動時的值,不用管,相當於有20ms的抖動濾波時間,那麼就認為最後這兩個相等的值的對應按鍵按下了。

unsigned char ucReadFromAdFifo(unsigned char *pData)//從按鍵fifo緩存區讀取按鍵值數據到參數變量指針pData,並按照對應的數值發出按鍵事件和點亮LED
{
unsigned char ucResult = 0;
// if( (ucAdResult[(sucAdKeyHead+2) % (AD_RESULT_BUFFER_LENTH)] == 0) ){
// if( (ucAdResult[(sucAdKeyHead+4) % (AD_RESULT_BUFFER_LENTH)] != 0) ){
// if( (ucAdResult[(sucAdKeyHead+4) % (AD_RESULT_BUFFER_LENTH)] == \\
// ucAdResult[(sucAdKeyHead+5) % (AD_RESULT_BUFFER_LENTH)]) ){
// ucResult = ucAdResult[(sucAdKeyHead+5) % (AD_RESULT_BUFFER_LENTH)];
// if( (ucAdResult[sucAdKeyHead] == 0) && (ucAdResult[sucAdKeyTail] != 0) ){
// if( ucAdResult[sucAdKeyTail] == \\
// ucAdResult[(sucAdKeyHead+2) & (AD_RESULT_BUFFER_LENTH-1)] ){
if( (ucAdResult[sucAdKeyHead] == 0) && \\
(ucAdResult[(sucAdKeyHead+4) & (AD_RESULT_BUFFER_LENTH-1)] != 0) ){
if( ucAdResult[sucAdKeyTail] == \\
ucAdResult[(sucAdKeyHead+6) & (AD_RESULT_BUFFER_LENTH-1)] ){
ucResult = ucAdResult[sucAdKeyTail];


vKeyResultHandle(ucResult);//key值處理

*pData = ucResult;
vInitAdFifo();
return ucResult;
}

else return 0;
}
else return 0;
}

unsigned char ucWriteToAdFifo(unsigned short usKeyAdValue)
{
if(usKeyAdValue < KEY_DEFAULT_AD_MAX_VALUE){
ucKeyNum = 0;
}
else if((usKeyAdValue<key1>KEY1_AD_MIN_VALUE)){
ucKeyNum = 1;
}
else if((usKeyAdValue<key2>KEY2_AD_MIN_VALUE)){
ucKeyNum = 2;
}
else if((usKeyAdValue<key3>KEY3_AD_MIN_VALUE)){
ucKeyNum = 3;
}
else if((usKeyAdValue<key4>KEY4_AD_MIN_VALUE)){
ucKeyNum = 4;
}
else if((usKeyAdValue<key5>KEY5_AD_MIN_VALUE)){
ucKeyNum = 5;
}
else if(usKeyAdValue>KEY6_AD_MIN_VALUE){
ucKeyNum = 6;
}
else {


}
if(((sucAdKeyTail+1) & (AD_RESULT_BUFFER_LENTH-1)) == sucAdKeyHead) {//存滿
ucAdResult[sucAdKeyHead] = ucKeyNum;
sucAdKeyTail = sucAdKeyHead;
sucAdKeyHead = (sucAdKeyHead + 1) & (AD_RESULT_BUFFER_LENTH-1);
return 1;
} else {//沒存滿
ucAdResult[sucAdKeyTail] = ucKeyNum;
sucAdKeyTail = (sucAdKeyTail + 1) & (AD_RESULT_BUFFER_LENTH-1);
return 0;
}
}
/<key5>/<key4>/<key3>/<key2>/<key1>

void vAdKeyScan(void){
unsigned char i =0;

if(ucReadKeyFlag >= 15){ //每15ms掃描一次按鍵值並更新顯示
if(ucWriteToAdFifo(usGetAdcValue(KEYADCCHANNEL))){//如果讀到按鍵的值,填到按鍵ADC緩衝滿
if(ucReadFromAdFifo(&i)){//如果讀到有效按鍵值,更新指示燈顯示值
// if(ucReadFromAdFifo(&ucKeyEvent)){//如果讀到有效按鍵值,更新指示燈顯示值
// vLedShow();//更新按鍵顯示
}
}
ucReadKeyFlag = 0;//清讀按鍵ADC值標誌
}
}


void vInitAdFifo(void)
{
unsigned char i = 0;
sucAdKeyTail = 0;
sucAdKeyHead = 0;
for(i=0;i ucAdResult[i] = 0;
}
}

最後歡迎大家轉發評論交流!如果大家覺得我寫的好就來個轉發吧,分享給更多愛技術的人。也歡迎大家關注我的頭條號:單片機嵌入式愛好者。會有源源不斷的乾貨分享,能真正快速幫大家解決實際工作中遇到的問題哦!


分享到:


相關文章: