主要目的
學(xué)會按鍵掃描
1.延時函數(shù)
延時函數(shù)部分詳見鏈接: 單片機控制一盞燈的亮與滅程序解釋
void delay (uint k) //定義延時函數(shù)
{
uint i,j;
for(i<0;i<k;i++)
{
for(j=0;j<113;j++)
{
;
}
}
}
這個程序里面的延時函數(shù)的目的是按鍵消抖。
2.按鍵掃描模塊
這是本次實驗的重點,將詳細(xì)介紹。
先來觀察矩陣按鍵模塊的連接
總共8個口。
先實現(xiàn)關(guān)于列的掃描,設(shè)置初始值(0xf0),從高到低為
端口 | Value |
---|---|
P3.7 | 1 |
P3.6 | 1 |
P3.5 | 1 |
P3.4 | 1 |
P3.3 | 0 |
P3.2 | 0 |
P3.1 | 0 |
P3.0 | 0 |
那么當(dāng)按下按鍵0,4,8,c時,P3.4變成了0,于是P3就變成了0xe0
端口 | Value |
---|---|
P3.7 | 1 |
P3.6 | 1 |
P3.5 | 1 |
P3.4 | 0 |
P3.3 | 0 |
P3.2 | 0 |
P3.1 | 0 |
P3.0 | 0 |
從而由0xe0我們可以判斷是那一列按鍵按下,但還是不知道具體是哪一個按鍵按下,于是我們需要繼續(xù)進(jìn)行行掃描。
此時初始化P3
端口 | Value |
---|---|
P3.7 | 0 |
P3.6 | 0 |
P3.5 | 0 |
P3.4 | 0 |
P3.3 | 1 |
P3.2 | 1 |
P3.1 | 1 |
P3.0 | 1 |
同時現(xiàn)在當(dāng)按鍵0按下后
端口 | Value |
---|---|
P3.7 | 0 |
P3.6 | 0 |
P3.5 | 0 |
P3.4 | 0 |
P3.3 | 1 |
P3.2 | 1 |
P3.1 | 1 |
P3.0 | 0 |
經(jīng)過行列掃描之后就可以確定具體是哪個按鍵按下,有了上面的基礎(chǔ)之后,我們來學(xué)習(xí)按鍵掃描的程序。
void keyscan() //這個實驗的重點
{ uchar a;
P3=0xf0;
if(P3!=0xf0)
{
delay(10);
if(P3!=0xf0)
{
P3=0xf0; //進(jìn)行列掃描
switch(P3)
{
case(0xe0):keynumber=0;break; //11100000
case(0xd0):keynumber=1;break;//11010000
case(0xb0):keynumber=2;break;//10110000
case(0x70):keynumber=3;break;//01110000
}
P3=0x0f;
switch(P3)
{
case(0x0e):keynumber=keynumber;break; //switch case后面是冒號
case(0x0d):keynumber=keynumber+4;break;
case(0x0b):keynumber=keynumber+8;break;
case(0x07):keynumber=keynumber+12;break;
}
while ((a<50)&&(P3!=0x0f))
{
delay(10);
a++ ;
}
}
}
}
程序的邏輯是
讓P3的高四位為0,進(jìn)行列檢測,為什么是列檢測呢,很簡單,因為區(qū)分不出行。
如果按鍵按下,延時10ms,判斷是不是按鍵抖動,延時之后繼續(xù)判斷,發(fā)現(xiàn)仍然不為0xf0,說明按鍵確實按下了,然后還是給P3幅初始值0xf0,接下來進(jìn)行switch,case,不同P3情況下,對設(shè)置的keynumber進(jìn)行賦值,記得每一個case結(jié)束要加break。
只有列掃描,無法判斷是哪個按鍵按下,接下來進(jìn)行行掃描。
基本原理和上面一樣,但是注意按鍵值的變化。
最后當(dāng)兩個情況同時不成立后跳出循環(huán)。這兩個情況就是a>50和P3=0xf0,具體解釋就是a>50,按鍵還沒有松開,就認(rèn)為松開了,P3=0xf0按鍵按下之后松開了。
3.數(shù)碼管顯示模塊
這一部分也相對簡單,我的博客里面也有相應(yīng)的博文。在這里主要就是P0口接的是數(shù)碼管。這里進(jìn)行段選和位選。段選是根據(jù)keynumber的值,位選這里選了六個數(shù)碼管,則對應(yīng)11000000,再轉(zhuǎn)換為16進(jìn)制。
void display(uchar num)
{
P0=table[num];
duan=1;
duan=0;
P0=0xc0;//11000000
wei=1;
wei=0;
}
4.主函數(shù)
主要是設(shè)置段和位初始狀態(tài),之后調(diào)用前面的按鍵掃描和數(shù)碼管顯示模塊。
void main()
{
duan=0;
wei=0;
while(1)
{
keyscan();
display(keynumber);
}
}
完整代碼文章來源:http://www.zghlxwxcb.cn/news/detail-478046.html
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int //注意宏定義不能加分號
sbit duan = P2^6;
sbit wei = P2^7;
uchar keynumber;
uchar code table[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay (uint k) //定義延時函數(shù)
{
uint i,j;
for(i<0;i<k;i++)
{
for(j=0;j<113;j++)
{
;
}
}
}
void keyscan() //這個實驗的重點
{ uchar a;
P3=0xf0;
if(P3!=0xf0)
{
delay(10);
if(P3!=0xf0)
{
P3=0xf0; //進(jìn)行列掃描
switch(P3)
{
case(0xe0):keynumber=0;break; //11100000
case(0xd0):keynumber=1;break;//11010000
case(0xb0):keynumber=2;break;//10110000
case(0x70):keynumber=3;break;//01110000
}
P3=0x0f;
switch(P3)
{
case(0x0e):keynumber=keynumber;break; //switch case后面是冒號
case(0x0d):keynumber=keynumber+4;break;
case(0x0b):keynumber=keynumber+8;break;
case(0x07):keynumber=keynumber+12;break;
}
while ((a<50)&&(P3!=0x0f))
{
delay(10);
a++ ;
}
}
}
}
void display(uchar num)
{
P0=table[num];
duan=1;
duan=0;
P0=0xc0;//11000000
wei=1;
wei=0;
}
void main()
{
duan=0;
wei=0;
while(1)
{
keyscan();
display(keynumber);
}
}
運行結(jié)果
無法一一展示,這里只展示一部分。
好啦,今天矩陣按鍵模塊的學(xué)習(xí)就到這里啦。你學(xué)廢了嗎?有問題的話,歡迎共同交流。最近在準(zhǔn)備研究生復(fù)試,內(nèi)容比較粗糙,但個人比較喜歡有輸出的學(xué)習(xí)。以后有機會的話,會繼續(xù)更新完善的?。?!文章來源地址http://www.zghlxwxcb.cn/news/detail-478046.html
到了這里,關(guān)于單片機——矩陣按鍵模塊的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!