上期學習了數(shù)碼管的靜態(tài)顯示,這次我們來學習獨立按鍵&矩陣按鍵
獨立按鍵
原理很簡單,當作為獨立按鍵使用時,跳線帽的23接在一起,此時按鍵如果按下,則按鍵連接的IO口電平會被拉低,通過捕獲IO的電平變化,就可以判斷按鍵是否按下。
按鍵消抖
什么是按鍵消抖?按鍵為什么會有抖動?
通常的按鍵所用開關(guān)為機械彈性開關(guān)。由于機械觸電的彈性作用,按鍵在閉合及斷開的瞬間均伴隨有一連串的抖動。鍵抖動會引起一次按鍵被誤讀多次。為了確保CPU對鍵的一次閉合僅作一次處理,必須去除抖動。
如何消抖?
硬件消抖:硬件消抖的典型做法是:采用 R-S觸發(fā)器 或RC積分電路。在沒有MCU的情況下通常使用這種方法,但在嵌入式開發(fā)中,我們比較常用的時軟件消抖。
軟件消抖:軟件消抖是當檢測出鍵閉合后執(zhí)行一個10ms~20ms的延時程序,再一次檢測鍵的狀態(tài),如仍保持閉合狀態(tài),則確認真正有按鍵按下。
矩陣按鍵
作為矩陣按鍵使用時,跳線帽的12腳連接在一起。
矩陣按鍵的優(yōu)點:可以通過比較少的IO實現(xiàn)對多個按鍵的控制,節(jié)省IO口。
缺點:在使用時需要對按鍵進行掃描。
掃描
對于獨立按鍵,它的每一個IO都對應著一行或一列,通過讀取按鍵按下時的行和列,就可以確定是哪一個按鍵按下。
掃描就是對按鍵的每一行(列)進行掃描,從而得到按鍵按下的行(列),從而確定是否有按鍵按下,以及按鍵按下的鍵碼值。目前按鍵掃描的方法,主要分為行掃描和列掃描兩種。
所謂行掃描就是,先把每一行和每一列的上的電平拉高,然后分別把每一行的電平依次拉低,去檢測每一個列上的電平是否跟著被拉低,如果被拉低,說明按鍵按下,則可以去讀到當前的行和列,計算出按下的鍵碼值。
列掃描則和行掃描的邏輯相反,這里不做贅述。
代碼實現(xiàn)
1.main.c
#include <STC15F2K60S2.H>
#include <INTRINS.h>
#include "Key.h"
#include "LS138.h"
//效果:當有按鍵按下時,會在數(shù)碼管上顯示當前按下按鍵的鍵碼值
//當沒有按鍵按下時,數(shù)碼管會顯示上一次按下的鍵碼值
void main()
{
unsigned int i =0;
LS138_Init();
Key_Init(); //初始化函數(shù)
while(1)
{
if(Get_KeyBoard_Num()) //判斷矩陣按鍵是否有按下
{
i = Get_KeyBoard_Num(); //如果按下則,改變當前變量的值,
}
SEG_Write_Num(i); //通過數(shù)碼管顯示矩陣按鍵按下的鍵碼值
}
}
2.Key.h
#ifndef __KEY_H_
#define __KEY_H_
#include <STC15F2K60S2.H>
#include <INTRINS.h>
sbit Key7 = P3^0;
sbit Key6 = P3^1;
sbit Key5 = P3^2;
sbit Key4 = P3^3;
sbit Col1 = P4^4;
sbit Col2 = P4^2;
sbit Col3 = P3^5;
sbit Col4 = P3^4;
#define Row1 Key4
#define Row2 Key5
#define Row3 Key6
#define Row4 Key7
//延時函數(shù),可以延時xms的時間
void Delayxms(unsigned int x); //@11.0592MHz
//初始化函數(shù)
void Key_Init(void);
//按鍵掃描函數(shù),由按鍵按下時返回值為1,否則為0
unsigned char Key_Scan(void);
//獲取當前按鍵按下的數(shù)值,返回結(jié)果為4~7
//當沒有按鍵按下是,返回值為0
//函數(shù)內(nèi)部由兩種實現(xiàn)方法,一直延時,一種不延時。可以按需要使用
unsigned int Get_Key_Num(void);
//獲取當前矩陣按鍵中按下健的值
//返回值為4~19
//當沒有按鍵按下時,返回值為0
unsigned int Get_KeyBoard_Num(void);
#endif /*__KEY_H_*/
這里有一個Delayxms()延時函數(shù),可以延時xms.這個不是static 修飾的,外部可調(diào)用
3.Key.c
#include "Key.h"
//延時函數(shù),可以延時xms的時間
void Delayxms(unsigned int x) //@11.0592MHz
{
unsigned char i,j,k;
for(k=0;k<x;k++)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
//初始化函數(shù)
void Key_Init(void)
{
Key7 = Key6 = Key5 = Key4 =1;
Col1 = Col2 = Col3 = Col4=1;
}
//按鍵掃描函數(shù),由按鍵按下時返回值為1,否則為0
unsigned char Key_Scan(void)
{
static unsigned char Key_Count =0;
if(Key7==0 | Key6==0 | Key5==0 | Key4==0 )
{
Key_Count++;
Delayxms(1);
if(Key_Count >= 100)
{
return 1;
Key_Count=0;
}
}
return 0;
}
//獲取當前按鍵按下的數(shù)值,返回結(jié)果為4~7
//當沒有按鍵按下是,返回值為0
//函數(shù)內(nèi)部由兩種實現(xiàn)方法,一直延時,一種不延時??梢园葱枰褂?/span>
unsigned int Get_Key_Num(void)
{
#if 1 //這個是沒有延時的,需要多次進入函數(shù)。
static unsigned char Key_Count = 0;
if(Key7==0 | Key6==0 | Key5==0 | Key4==0 )
{
Key_Count++;
Delayxms(1);
if(Key_Count >= 100)
{
if(Key7 == 0)
{
return 7;
}
if(Key6 == 0)
{
return 6;
}
if(Key5 == 0)
{
return 5;
}
if(Key4 == 0)
{
return 4;
}
Key_Count=0;
}
}
return 0;
#if 0 //這個是有延時的,只需要進入函數(shù)一次,但是會導致系統(tǒng)Delay在函數(shù)內(nèi)部
if(Key7==0 | Key6==0 | Key5==0 | Key4==0 )
{
Delayxms(20);
if(Key7 == 0)
{
while(!Key7)
{
}
return 7;
}
if(Key6 == 0)
{
while(!Key6)
{
}
return 6;
}
if(Key5 == 0)
{
while(!Key5)
{
}
return 5;
}
if(Key4 == 0)
{
while(!Key4)
{
}
return 4;
}
}
else
{
return 0;
}
#endif
}
//獲取當前矩陣按鍵中按下健的值
//返回值為4~19
//當沒有按鍵按下時,返回值為0
unsigned int Get_KeyBoard_Num(void)
{
unsigned char i;
for(i=0;i<4;i++)
{
P3 =0x03F;
Col1 = Col2 = 1;
P3 =~(0x08>>i); //Rowi = 1; //第一行為0
// Delayxms(1);
if(Col1==0 | Col2==0 | Col3==0 | Col4==0) //掃描每一列是否有按鍵按下
{
Delayxms(20);
if(~Col1)
{
return i+4;
}
if(~Col2)
{
return i+8;
}
if(~Col3)
{
return i+12;
}
if(~Col4)
{
return i+16;
}
}
}
return 0;
}
這里面獲取獨立按鍵的鍵碼值的函數(shù),我寫了兩種實現(xiàn)方式,
區(qū)別就是一個用到的軟件消抖(使用了延時函數(shù)),另一個沒有使用軟件消抖,但是需要多次調(diào)用進入函數(shù)才可以使用,具體實現(xiàn)方法可以自己看代碼的。需要使用哪一種方法,可以自行選擇。
為什么這么寫:在后面如果學習使用到了定時器的話,在函數(shù)內(nèi)部進行延時,可能會影響其他對時間要求比較嚴格的模塊。造成不必要的損失。文章來源:http://www.zghlxwxcb.cn/news/detail-414223.html
總結(jié)
獨立按鍵&矩陣按鍵這一部分比較簡單,原理也容易看懂,我這里只實現(xiàn)了基本的按鍵控制功能,大家也可以嘗試著去實現(xiàn),長按、短按、雙擊、等功能,我就不再去多寫啦。好好努力吧!文章來源地址http://www.zghlxwxcb.cn/news/detail-414223.html
到了這里,關(guān)于藍橋杯單片機學習4——獨立按鍵&矩陣按鍵的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!