|
楼主 |
发表于 2011-6-26 09:32:22
|
显示全部楼层
回复【2楼】machao
-----------------------------------------------------------------------
谢谢马老师指点,昨天发完帖子吃饭回来后那个键盘就给搞定了,马老师您说的对,我自己觉得我也经常犯一些很小的错误
一直改不掉啊。我太粗心了。。。。我原来的错误理解是:把PORTD = ~key_line;当成PORTD = key_line;(我错看成把key_line取反
2次后还是key_line了,其实~key_line后key_line并没有改变啊)
再次谢谢马老师的教导。。。
下面是我把您书上那个矩阵按键移植到LPC2132上的程序
使用时直接在主函数里包含那个h文件后调用读键盘函数即可。。。。
keyboard_matrix.h文件里的代码:
#ifndef _keyboard_matrix_h_
#define _keyboard_matrix_h_
#define Keyboard_DIR IO1DIR //用端口1的P1.16-P1.23 8个管脚
#define Keyboard_PIN (IO1PIN>>16) //使用P1[25:16]中的前6个管脚,16-21脚
#define Keyboard_PORT_High IO1SET //
#define Keyboard_PORT_Low IO1CLR
#define No_key 17 //这个数对应0xFF,作用是不按键时数码管什么都不显示
#define K1_1 1
#define K1_2 2
#define K1_3 3
#define K2_1 4
#define K2_2 5
#define K2_3 6
#define K3_1 7
#define K3_2 8
#define K3_3 9
#define K4_1 10
#define K4_2 0
#define K4_3 11
#define Key_mask 0x2A //列的电平值,0b0010 1010
void Keyboard_Matrix_Init();//矩阵键盘初始化
unsigned char Read_keyboard_Matrix();//矩阵键盘读端口函数接口
#endif
keyboard_matrix.c文件里的代码:
#include <NXP/iolpc2132.h>
#include "keyboard_matrix.h"
#include "..\driver\LPC_Uart.h" //调试用的
void Keyboard_Matrix_Init()
{
//P1[25:16]连接到GPIO功能
PINSEL2=PINSEL2 &(~0x08); //这句话一般不用改 //23 19 16位
//行输出,列输入,1111 1111 1101 0101 1111 1111 1111 1111
//先要把低6位置成0后再和0xD5或才能实现行输出,列输入的效果,2011-06-23
Keyboard_DIR =(Keyboard_DIR & 0xFFC0FFFF)|(0x15<<16);
}
unsigned char Read_keyboard_Matrix()
{
static unsigned char key_state=0; //按键的状态
static unsigned char key_value; //按键值
//static unsigned char key_line; //行线,本程序中不要行线,2011-06-25
unsigned char i;
//如果要让按键按下后返回的数只显示一次,把下面的static去掉即可,2011-06-25
static unsigned char key_return = No_key;
switch (key_state)
{
case 0:
//key_line = 0x14;//0B00 010100,第0行输出低,其他两行输出为高,本程序中不要行线,2011-06-25
for(i=1; i<4; i++) //行扫描,扫3遍即3行
{
if(i==1)//下面的几个if语句取代了以前的移位操作
{
Keyboard_PORT_High =0x00140000;// 输出行线电平,第0行输出低,其他两行输出为高
Keyboard_PORT_Low =0x00010000;//0000 0000 0001 0100 ,使其中的那两位输出为0
}
else if(i==2)
{
Keyboard_PORT_High =0x00110000;// 输出行线电平,第1行输出低,其他两行输出为高
Keyboard_PORT_Low =0x00040000;//0000 0000 0001 0001 ,使其中的那两位输出为0
}
else if(i==3)
{
Keyboard_PORT_High =0x00050000;// 输出行线电平,第2行输出低,其他两行输出为高
Keyboard_PORT_Low =0x00100000;//0000 0000 0000 0101 ,使其中的那两位输出为0
}
key_value = Key_mask & Keyboard_PIN;// 读列电平
if (key_value != Key_mask)
{
key_state++; // 有按键,停止扫描
break; // 转消抖确认状态
}
}
break;
case 1:
if (key_value == (Key_mask & Keyboard_PIN)) // 再次读列电平,
{ //与状态0的相同,确认按键
switch ((unsigned char)Keyboard_PIN)
{ // 键盘编码,返回编码值
case 0xFC:
key_return = K1_1;
break;
case 0xF6:
key_return = K1_2;
break;
case 0xDE:
key_return = K1_3;
break;
case 0xF9:
key_return = K2_1;
break;
case 0xF3:
key_return = K2_2;
break;
case 0xDB:
key_return = K2_3;
break;
case 0xED:
key_return = K3_1;
break;
case 0xE7:
key_return = K3_2;
break;
case 0xCF:
key_return = K3_3;
break;
case 0x46:
key_return = K4_1;
break;
case 0x45:
key_return = K4_2;
break;
case 0x43:
key_return = K4_3;
break;
}
key_state++;// 转入等待按键释放状态
}
else
key_state--;//两次列电平不同返回状态0(消抖处理)
break;
case 2: // 等待按键释放状态
Keyboard_PORT_Low = 0x15<<16; // 行线全部输出低电平,0B0001 0101
if ( (Key_mask & Keyboard_PIN) == Key_mask)
key_state=0; // 列线全部为高电平返回状态0
break;
}
return key_return;
}
键盘的连接为:
(原文件名:11.jpg) |
|