天天看點

單片機實驗3提示

鍵盤與LCD實驗

對4×4矩陣式鍵盤電路的鍵值進行編碼,程式設計實作在LCD液晶顯示器上顯示每個按鍵的ASCII碼。

(⊙﹏⊙)呃這個和去年一樣

​​單片機實驗說明<四>矩陣鍵盤與LCD基本使用​​

專欄:

 ​

#include "8052.h"

#define uchar unsigned char
#define uint unsigned int

#define lcden P1_2
#define lcdrs P1_0
#define rw P1_1

/* IO引腳配置設定定義 */
#define KEY_IN_1  P2_4  //矩陣按鍵的掃描輸入引腳1
#define KEY_IN_2  P2_5  //矩陣按鍵的掃描輸入引腳2
#define KEY_IN_3  P2_6  //矩陣按鍵的掃描輸入引腳3
#define KEY_IN_4  P2_7  //矩陣按鍵的掃描輸入引腳4
#define KEY_OUT_1 P2_0  //矩陣按鍵的掃描輸出引腳1
#define KEY_OUT_2 P2_1  //矩陣按鍵的掃描輸出引腳2
#define KEY_OUT_3 P2_2  //矩陣按鍵的掃描輸出引腳3
#define KEY_OUT_4 P2_3  //矩陣按鍵的掃描輸出引腳4

#define LSA P1_5  //LED位選譯碼位址引腳A
#define LSB P1_6  //LED位選譯碼位址引腳B
#define LSC P1_7  //LED位選譯碼位址引腳C

unsigned char disBuf=0;
uchar table1[] = "Welcome To CSLG!";
uchar table2[] = "0123456789ABCDEF";
uchar table3[] = "                ";
uchar num;

const unsigned char KeyCodeMap[4][4] = {  //矩陣按鍵到标準鍵碼的映射表
    { '0',  '1',  '2', '3' },  //
    { '4',  '5',  '6', '7' },  //
    { '8',  '9',  'a', 'b' },  //
    { 'c',  'd',  'e', 'f' }   //
};

unsigned char KeySta[4][4] = {  //全部矩陣按鍵的目前狀态
    {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1} };

/* 函數聲明 */
void KeyScan();
void KeyDriver();
void KeyAction(unsigned char keycode);

/* 按鍵驅動函數,檢測按鍵動作,排程相應動作函數,需在主循環中調用 */
void KeyDriver()
{
unsigned char i, j;
static unsigned char backup[4][4] = {  //按鍵值備份,儲存前一次的值
        {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
    };

for (i=0; i<4; i++)  //循環檢測4*4的矩陣按鍵
    {
for (j=0; j<4; j++)
        {
if (backup[i][j] != KeySta[i][j])    //檢測按鍵動作
            {
if (backup[i][j] != 0)           //按鍵按下時執行動作
                {
KeyAction(KeyCodeMap[i][j]); //調用按鍵動作函數
                }
backup[i][j] = KeySta[i][j];     //重新整理前一次的備份值
            }
        }
    }
}
/* 按鍵掃描函數,需在定時中斷中調用,推薦調用間隔1ms */
void KeyScan()
{
unsigned char i;
static unsigned char keyout = 0;   //矩陣按鍵掃描輸出索引
static unsigned char keybuf[4][4] = {  //矩陣按鍵掃描緩沖區
        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}
    };

//将一行的4個按鍵值移入緩沖區
keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
//消抖後更新按鍵狀态
for (i=0; i<4; i++)  //每行4個按鍵,是以循環4次
    {
if ((keybuf[keyout][i] & 0x0F) == 0x00)
        {   //連續4次掃描值為0,即4*4ms内都是按下狀态時,可認為按鍵已穩定的按下
KeySta[keyout][i] = 0;
        }
else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
        {   //連續4次掃描值為1,即4*4ms内都是彈起狀态時,可認為按鍵已穩定的彈起
KeySta[keyout][i] = 1;
        }
    }
//執行下一次的掃描輸出
keyout++;        //輸出索引遞增
keyout &= 0x03;  //索引值加到4即歸零
switch (keyout)  //根據索引值,釋放目前輸出引腳,拉低下次的輸出引腳
    {
case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
default: break;
    }
}

void KeyAction(unsigned char keycode)
{   
disBuf = keycode;   
}

void delay(uint z) {
uint x, y;
for(x = z; x > 0; x--)
for(y = 110; y > 0; y--);
}

void write_com(uchar com) {
lcdrs = 0;
P0 = com;
delay(5);
lcden = 1;
delay(5);
lcden = 0;
}

void write_data(uchar date) {
lcdrs = 1;
P0 = date;
delay(5);
lcden = 1;
delay(5);
lcden = 0;
}

void init() {   
rw = 0;
lcden = 0;
write_com(0x38);
write_com(0x0e);
write_com(0x06);
write_com(0x01);
}

void main() {
init();
write_com( 0x00 | 0x80 );
for(num = 0; num < 16; num++) {
write_data(table1[num]);
delay(100);
    }
write_com( 0x40 | 0x80 );
for(num = 0; num < 16; num++) {
write_data(table2[num]);
delay(100);
    }
write_com( 0x40 | 0x80 );
for(num = 0; num < 16; num++) {
write_data(table3[num]);
delay(100);
    }    
while(1)
    {
KeyScan();
KeyDriver();
write_com( 0x40 | 0x80 );
write_data(disBuf);
    }

}

      
單片機實驗3提示
單片機實驗3提示
單片機實驗3提示

繼續閱讀