skyxjh 发表于 2011-8-31 13:41:18

4x4矩阵键盘通用驱动程序keyboard4x4

//4X4键盘扫描程序 keyboard4x4.h
#include <iom88v.h>
#include <macros.h>

//行线、列线引脚定义
#define keyboard_line_column_1    BIT(PC0) //行线1
#define keyboard_line_column_2                   BIT(PC1) //行线2
#define keyboard_line_column_3                   BIT(PC2) //行线3
#define keyboard_line_column_4                   BIT(PC3) //行线4

#define keyboard_line_column_1_ioportC //行线1
#define keyboard_line_column_2_ioportC //行线2
#define keyboard_line_column_3_ioportC //行线3
#define keyboard_line_column_4_ioportC //行线4

#define keyboard_line_row_1                           BIT(PC4) //列线1
#define keyboard_line_row_2                           BIT(PC5) //列线2
#define keyboard_line_row_3                           BIT(PD1) //列线3
#define keyboard_line_row_4                           BIT(PD0) //列线4

#define keyboard_line_row_1_ioport           C //列线1
#define keyboard_line_row_2_ioport           C //列线2
#define keyboard_line_row_3_ioport           D //列线3
#define keyboard_line_row_4_ioport           D //列线4

//按键编码:
//bit7bit6bit5bit4bit3bit2bit1bit0
//第4行 第3行 第2行 第1行第4列 第3列 第2列 第1列
//0: 表示该行(列)没有按键按下;1:表示该行(列)有按键按下
unsigned char keyboard_scan(void); //键盘扫描,返回按键编码

//按键解码:
//////////////////////////////////
//第1行   1   2   3   A   //
//第2行   4   5   6   B   //
//第3行   7   8   9   C   //
//第4行   *   0   #   D   //
//      第1列 第2列 第3列 第4列 //
//////////////////////////////////
unsigned char keyboard_decode(unsigned char keyboard_code);


//4X4键盘扫描程序 keyboard4x4.c
#include "keyboard4x4.h"

//双定义连接宏定义的字符串
#ifndef STRINGS_DEFINED_BY_MACROS_CONNECT
    #define STRINGS_DEFINED_BY_MACROS_CONNECT
    #define STR_CONNECT(a, b)a ## b //连接字符串
    #define PORT(x)                  STR_CONNECT(PORT, x)
    #define PIN(x)                           STR_CONNECT(PIN, x)
    #define DDR(x)                           STR_CONNECT(DDR, x)
#endif

void keyboard_init_column_out_row_in(void) //行输出低电平,列上拉输入
{
    //行输出低电平
    PORT(keyboard_line_column_1_ioport) &= ~keyboard_line_column_1;
    DDR(keyboard_line_column_1_ioport) |= keyboard_line_column_1;
    PORT(keyboard_line_column_2_ioport) &= ~keyboard_line_column_2;
    DDR(keyboard_line_column_2_ioport) |= keyboard_line_column_2;
    PORT(keyboard_line_column_3_ioport) &= ~keyboard_line_column_3;
    DDR(keyboard_line_column_3_ioport) |= keyboard_line_column_3;
    PORT(keyboard_line_column_4_ioport) &= ~keyboard_line_column_4;
    DDR(keyboard_line_column_4_ioport) |= keyboard_line_column_4;
    //列上拉输入
    PORT(keyboard_line_row_1_ioport) |= keyboard_line_row_1;
    DDR(keyboard_line_row_1_ioport) &= ~keyboard_line_row_1;
    PORT(keyboard_line_row_2_ioport) |= keyboard_line_row_2;
    DDR(keyboard_line_row_2_ioport) &= ~keyboard_line_row_2;
    PORT(keyboard_line_row_3_ioport) |= keyboard_line_row_3;
    DDR(keyboard_line_row_3_ioport) &= ~keyboard_line_row_3;
    PORT(keyboard_line_row_4_ioport) |= keyboard_line_row_4;
    DDR(keyboard_line_row_4_ioport) &= ~keyboard_line_row_4;
}

void keyboard_init_row_out_column_in(void) //列输出低电平,行上拉输入
{
    //列输出低电平
    PORT(keyboard_line_row_1_ioport) &= ~keyboard_line_row_1;
    DDR(keyboard_line_row_1_ioport) |= keyboard_line_row_1;
    PORT(keyboard_line_row_2_ioport) &= ~keyboard_line_row_2;
    DDR(keyboard_line_row_2_ioport) |= keyboard_line_row_2;
    PORT(keyboard_line_row_3_ioport) &= ~keyboard_line_row_3;
    DDR(keyboard_line_row_3_ioport) |= keyboard_line_row_3;
    PORT(keyboard_line_row_4_ioport) &= ~keyboard_line_row_4;
    DDR(keyboard_line_row_4_ioport) |= keyboard_line_row_4;
    //行上拉输入
    PORT(keyboard_line_column_1_ioport) |= keyboard_line_column_1;
    DDR(keyboard_line_column_1_ioport) &= ~keyboard_line_column_1;
    PORT(keyboard_line_column_2_ioport) |= keyboard_line_column_2;
    DDR(keyboard_line_column_2_ioport) &= ~keyboard_line_column_2;
    PORT(keyboard_line_column_3_ioport) |= keyboard_line_column_3;
    DDR(keyboard_line_column_3_ioport) &= ~keyboard_line_column_3;
    PORT(keyboard_line_column_4_ioport) |= keyboard_line_column_4;
    DDR(keyboard_line_column_4_ioport) &= ~keyboard_line_column_4;
}

unsigned char keyboard_read_line_row(void) //读列线信号
{
    unsigned char row_code = 0;
    if((PIN(keyboard_line_row_1_ioport) & keyboard_line_row_1) == 0) row_code |= BIT(0);
    if((PIN(keyboard_line_row_2_ioport) & keyboard_line_row_2) == 0) row_code |= BIT(1);
    if((PIN(keyboard_line_row_3_ioport) & keyboard_line_row_3) == 0) row_code |= BIT(2);
    if((PIN(keyboard_line_row_4_ioport) & keyboard_line_row_4) == 0) row_code |= BIT(3);
    return row_code;
}

unsigned char keyboard_read_line_column(void) //读行线信号
{
    unsigned char column_code = 0;
    if((PIN(keyboard_line_column_1_ioport) & keyboard_line_column_1) == 0) column_code |= BIT(4);
    if((PIN(keyboard_line_column_2_ioport) & keyboard_line_column_2) == 0) column_code |= BIT(5);
    if((PIN(keyboard_line_column_3_ioport) & keyboard_line_column_3) == 0) column_code |= BIT(6);
    if((PIN(keyboard_line_column_4_ioport) & keyboard_line_column_4) == 0) column_code |= BIT(7);
    return column_code;
}

//按键编码:
//bit7bit6bit5bit4bit3bit2bit1bit0
//第4行 第3行 第2行 第1行第4列 第3列 第2列 第1列
//0: 表示该行(列)没有按键按下;1:表示该行(列)有按键按下
unsigned char keyboard_scan(void) //键盘扫描,返回按键编码
{
    unsigned char keyboard_code = 0;
    keyboard_init_column_out_row_in();
    NOP();NOP();
    keyboard_code = keyboard_read_line_row();
    keyboard_init_row_out_column_in();
    NOP();NOP();
    keyboard_code |= keyboard_read_line_column();
    return keyboard_code;
}

//按键解码:
//////////////////////////////////
//第1行   1   2   3   A   //
//第2行   4   5   6   B   //
//第3行   7   8   9   C   //
//第4行   *   0   #   D   //
//      第1列 第2列 第3列 第4列 //
//////////////////////////////////
unsigned char keyboard_decode(unsigned char keyboard_code)
{
switch(keyboard_code)
{
    case 0x11: return '1';
    case 0x12: return '2';
    case 0x14: return '3';
    case 0x18: return 'A';
    case 0x21: return '4';
    case 0x22: return '5';
    case 0x24: return '6';
    case 0x28: return 'B';
    case 0x41: return '7';
    case 0x42: return '8';
    case 0x44: return '9';
    case 0x48: return 'C';
    case 0x81: return '*';
    case 0x82: return '0';
    case 0x84: return '#';
    case 0x88: return 'D';
    default:   return ' ';
}
}

skyxjh 发表于 2011-8-31 13:44:41

可以定义MCU的任意8个引脚来驱动4x4矩阵键盘

chen3bing 发表于 2011-8-31 14:05:27

感觉很繁琐。

skyxjh 发表于 2011-8-31 14:13:59

回复【2楼】chen3bing
感觉很繁琐。
-----------------------------------------------------------------------

是有点繁琐,但是通用性强,可以定义任意8个MCU引脚来驱动,只需在头文件keyboard4x4.h里修改引脚定义即可。

jetimchen 发表于 2011-8-31 15:11:35

是很繁琐

bingshuihuo888 发表于 2011-8-31 21:56:14

mark

jog0821 发表于 2011-8-31 22:11:59

干嘛写那么多,乱码很多。

TonyNoodleLee 发表于 2011-9-1 11:31:21

用AD键盘做过参数设置卡,感觉还不错

压坏一棵树 发表于 2014-1-14 22:52:40

学习了,感谢

jack_yu 发表于 2014-1-14 22:58:35

受教了,谢谢楼主!

dtdzlujian 发表于 2014-1-30 13:17:03

学习了 慢慢看

lnso 发表于 2015-2-4 10:55:27

如何实现长按,双击等功能
页: [1]
查看完整版本: 4x4矩阵键盘通用驱动程序keyboard4x4