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