這個(gè)例程也是開發(fā)板上面的一個(gè)經(jīng)典例程,我對程序的框架進(jìn)行了修改,更適合以后的調(diào)用。具體的4*4鍵盤掃描原理較為基礎(chǔ)這里不再贅述,這里我認(rèn)為比較重要的是要養(yǎng)成一個(gè)良好的寫程序的習(xí)慣,想4*4鍵盤掃描這樣的函數(shù)可以寫成一個(gè)固定的C或者H文件,便于以后調(diào)用。先看看主程序:
/***********************************************
程序功能:掃描4X4鍵盤并將鍵值在數(shù)碼管上顯示
------------------------------------------------
測試說明:按動(dòng)K1~K16按鍵,觀察數(shù)碼管顯示
************************************************/
#include 《msp430x14x.h》
#include “Keypad.C”
//數(shù)碼管7位段碼:0--f
unsigned char scandata[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//記錄顯示位數(shù)的全局變量
unsigned char cnt = 0;
//顯示緩存
unsigned char Dispbuf[2];
//引用外部變量的聲明
extern unsigned char key_Pressed;
extern unsigned char key_val;
extern unsigned char key_Flag;
/********************主函數(shù)********************/
void main(void)
{
/*下面六行程序關(guān)閉所有的IO口*/
P1DIR = 0XFF;P1OUT = 0XFF;
P2DIR = 0XFF;P2OUT = 0XFF;
P3DIR = 0XFF;P3OUT = 0XFF;
P4DIR = 0XFF;P4OUT = 0XFF;
P5DIR = 0XFF;P5OUT = 0XFF;
P6DIR = 0XFF;P6OUT = 0XFF;
P6DIR |= BIT2;P6OUT |= BIT2; //關(guān)閉電平轉(zhuǎn)換
WDTCTL = WDT_ADLY_1_9; //設(shè)置內(nèi)部看門狗工作在定時(shí)器模式,1.9ms中斷一次
IE1 |= WDTIE; //使能看門狗中斷
_EINT(); //打開全局中斷
Init_Keypad();
while(1)
{
Key_Event();
if(key_Flag == 1)
{
key_Flag = 0;
Dispbuf[1] = key_val / 10;
Dispbuf[0] = key_val % 10;
}
}
}
/*******************************************
函數(shù)名稱:watchdog_timer
功 能:看門狗中斷服務(wù)函數(shù),在這里輸出數(shù)碼管的
段選和位選信號(hào)
參 數(shù):無
返回值 :無
********************************************/
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
P4OUT = 0xff;
P5OUT = scandata[Dispbuf[cnt]]; //輸出段選信號(hào)
P4OUT &= ~(1 《《 (cnt+2)); //輸出位選信號(hào)
cnt++; //位計(jì)數(shù)變量在0~1之間循環(huán)
if(cnt == 2) cnt = 0;
}
主程序較為簡單,具體的原理參見上一個(gè)筆記,在主程序中與鍵盤掃描相關(guān)的函數(shù)被擊中在Keypad.C中,需要說明的是在主函數(shù)中需要對Keypad.C的部分變量做聲明,這樣才能使用Keypad.C中的變量。Keypad.C代碼如下:
/********************************************************
4*4鍵盤掃描函數(shù)
作者:孫浩
修改時(shí)間:2010.8.2
程序說明:
此程序以開發(fā)板的例程做部分修改,更方便程序調(diào)用。
在調(diào)用之前需要注意需要在主函數(shù)中對程序中使用的變量做外部變量聲明
需要在主函數(shù)中聲明的變量如下:
//引用外部變量的聲明
extern unsigned char key_Pressed; //按鍵是否被按下:1--是,0--否
extern unsigned char key_val; //存放鍵值
extern unsigned char key_Flag; //按鍵是否已放開:1--是,0--否
另外對應(yīng)的鍵值可以在本文件的全局變量中修改,只需要對應(yīng)修改
數(shù)組uchar key_Map[]的對應(yīng)的值即可。
調(diào)用示例如下:
Init_Keypad(); //先進(jìn)行初始化
while(1)
{
Key_Event(); //在死循環(huán)中進(jìn)行鍵值掃描
if(key_Flag == 1)//用來判斷有無按鍵按下,從而讀取鍵值進(jìn)行操作
{
key_Flag = 0;//key_Flag需要手動(dòng)清零
}
}
**********************************************************/
#include 《msp430x14x.h》
//相應(yīng)的函數(shù)聲明
void Init_Keypad(void);//鍵盤初始化
void Check_Key(void);
void delay();
void Key_Event(void);//讀取鍵盤函數(shù),在使用時(shí)通過此函數(shù)進(jìn)行鍵盤掃描
//選擇對應(yīng)的端口
#define KEYOUT P1OUT
#define KEYIN P1IN
#define KEYDIR P1DIR
typedef unsigned char uchar;
typedef unsigned int uint;
/***************全局變量***************/
uchar key_Pressed; //按鍵是否被按下:1--是,0--否
uchar key_val; //存放鍵值
uchar key_Flag; //按鍵是否已放開:1--是,0--否
//設(shè)置鍵盤邏輯鍵值與程序計(jì)算鍵值的映射
uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
/*******************************************
函數(shù)名稱:Init_Keypad
功 能:初始化掃描鍵盤的IO端口
參 數(shù):無
返回值 :無
********************************************/
void Init_Keypad(void)
{
KEYDIR = 0xf0; //KEY.0~KEY.3設(shè)置為輸入狀態(tài), KEY.4~KEY.7設(shè)置為輸出狀態(tài)
KEYOUT |= 0xf0; // KEY.4~KEY.7輸出高電平
key_Flag = 0;
key_Pressed = 0;
key_val = 0;
}
/*********************************************
* Check_Key(),檢查按鍵,確認(rèn)鍵值
*********************************************/
/*******************************************
函數(shù)名稱:Check_Key
功 能:掃描鍵盤的IO端口,獲得鍵值
參 數(shù):無
返回值 :無
********************************************/
void Check_Key(void)
{
uchar row ,col,tmp1,tmp2;
tmp1 = 0x80;
for(row = 0;row 《 4;row++) //行掃描
{
KEYOUT = 0xf0; //KEY.4~KEY.7輸出全1
KEYOUT -= tmp1; //KEY.4~p1.7輸出四位中有一個(gè)為0
tmp1 》》=1;
if ((KEYIN & 0x0f) 《 0x0f) //是否KEYIN的KEY.0~KEY.3中有一位為0
{
tmp2 = 0x01; // tmp2用于檢測出那一位為0
for(col = 0;col 《 4;col++) // 列檢測
{
if((KEYIN & tmp2) == 0x00) // 是否是該列,等于0為是
{
key_val = key_Map[row * 4 + col]; // 獲取鍵值
return; // 退出循環(huán)
}
tmp2 《《= 1; // tmp2右移1位
}
}
}
}
/*******************************************
函數(shù)名稱:delay
功 能:延時(shí)約15ms,完成消抖功能
參 數(shù):無
返回值 :無
********************************************/
void delay()
{
uint tmp;
for(tmp = 12000;tmp 》 0;tmp--);
}
/*******************************************
函數(shù)名稱:Key_Event
功 能:檢測按鍵,并獲取鍵值
參 數(shù):無
返回值 :無
********************************************/
void Key_Event(void)
{
uchar tmp;
KEYOUT &= 0x00; // 設(shè)置KEYOUT全為0,等待按鍵輸入
tmp = KEYIN; // 獲取 p1IN
if ((key_Pressed == 0x00)&&((tmp & 0x0f) 《 0x0f)) //如果有鍵按下
{
key_Pressed = 1; // 如果有按鍵按下,設(shè)置key_Pressed標(biāo)識(shí)
delay(); //消除抖動(dòng)
Check_Key(); // 調(diào)用check_Key(),獲取鍵值
}
else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按鍵已經(jīng)釋放
{
key_Pressed = 0; // 清除key_Pressed標(biāo)識(shí)
key_Flag = 1; // 設(shè)置key_Flag標(biāo)識(shí)
}
else
{
_NOP();
}
}
具體的注意提防都已經(jīng)在注釋中做了說明,在原來的程序中這個(gè)文件是分為Keypad.C和Keypad.h兩個(gè)文件,鍵盤掃描函數(shù)的聲明單獨(dú)為一個(gè)頭文件,我覺得并不是特別需要。源程序中全局變量是單獨(dú)列為一個(gè)頭文件gdata.h的。這樣在全局變量比較多的情況下可以使程序更有條理可以參考。
-
數(shù)碼管
+關(guān)注
關(guān)注
32文章
1882瀏覽量
91124 -
程序
+關(guān)注
關(guān)注
117文章
3787瀏覽量
81049 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5050瀏覽量
97483
發(fā)布評論請先 登錄
相關(guān)推薦
評論