搜索
bottom↓
回复: 11

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

[复制链接]

出0入0汤圆

发表于 2011-8-31 13:41:18 | 显示全部楼层 |阅读模式
//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_ioport  C //行线1
#define keyboard_line_column_2_ioport  C //行线2
#define keyboard_line_column_3_ioport  C //行线3
#define keyboard_line_column_4_ioport  C //行线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

//按键编码:
//bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
//第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;
}

//按键编码:
//bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
//第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 ' ';
  }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2011-8-31 13:44:41 | 显示全部楼层
可以定义MCU的任意8个引脚来驱动4x4矩阵键盘

出0入0汤圆

发表于 2011-8-31 14:05:27 | 显示全部楼层
感觉很繁琐。

出0入0汤圆

 楼主| 发表于 2011-8-31 14:13:59 | 显示全部楼层
回复【2楼】chen3bing
感觉很繁琐。
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-8-31 15:11:35 | 显示全部楼层
是很繁琐

出0入0汤圆

发表于 2011-8-31 21:56:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-31 22:11:59 | 显示全部楼层
干嘛写那么多,乱码很多。

出0入0汤圆

发表于 2011-9-1 11:31:21 | 显示全部楼层
用AD键盘做过参数设置卡,感觉还不错

出0入0汤圆

发表于 2014-1-14 22:52:40 | 显示全部楼层
学习了,感谢

出0入0汤圆

发表于 2014-1-14 22:58:35 来自手机 | 显示全部楼层
受教了,谢谢楼主!

出0入0汤圆

发表于 2014-1-30 13:17:03 | 显示全部楼层
学习了 慢慢看

出0入0汤圆

发表于 2015-2-4 10:55:27 | 显示全部楼层
如何实现长按,双击等功能
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表