当前位置:文档之家› 第3套题矩阵键盘扫描分析

第3套题矩阵键盘扫描分析

分析一下题第三套综合题的键盘扫描问题,图如下(借用群里别人传的图)
//*KEYOUTPUT是键盘扫描时的输出地址,KEYINPUT是键盘读入时的地址
#define KEYOUTPUT (*(volatile INT8U *)0x56000044)
#define KEYINPUT (*(volatile INT8U *)0x56000044)
INT16U ScanKey()
{
INT16U key=0xFFFF; //注意key与i定义都是16位的数值
INT16U i;
INT8U temp=0xFF,output; //这里temp与output定义为8位的数值rGPECON= ((rGPECON &0xFFFFFF00) | 0x00000055); //初始化GPE0~GPE3为输出
rGPECON= rGPECON & 0xFFFF00FF;//初始化GPE4~GPE7为输入这里寄存器的初始化我就不多啰嗦了
for (i=1;(( i<= 8)&&(i>0));i<<=1 ) 下面是按行扫描,共四行,所以扫描4次(i从等于1开始,左移4次结果为8)。

注意第1次i的值为0x0001,化为二进制数是0000000000000001。

第2次,i左移1位(在二进制里左移),故值为0000000000000010,化为16进制数0x0002,第3次再左移1位,0x0004,第4次值为0x0008
{
output |= 0xFF; 这句是对output初始化
output &= (~i); 按行给低电平。

比如现在扫描到第二行,即 i为0x0002,取反后为0xFFFD,接下来output(0xFF)与~i相与,0xFF&0xFFFD值为0xFFFD(注意前面说到output定义为8位数值,它与16位数值相与后,只能保存8位数值),故最后output值为0xFD。

(将output的值由16进制化为2进制11111101。

根据上图如果对应到IO口就是GPE7-GPE0。

可以看到是给GPE1给了个低电平。

GPE1对应第2行)
KEYOUTPUT=output; 将output的值传给KEYOUTPUT
temp = KEYINPUT; 这句是读入输入的值
if ((temp&0xF0)!= 0xF0) temp读入的是GPE7-GPE0的值,可以看到如果有输入,那么GPE4-GPE7必然不会全为1。

做temp&0xF0是为了取出GPE7-GPE4的数据,后一个0xF0是用来判断列信号是否有0。

如果有则进入if语句。

{
key = (~i); 假设按下的键是6,它在第2行,则~i=0xFFFD,赋值后
key=0x0xFFFD。

key <<= 8; 将key值左移8位,即在16进制下是在末尾加2个零,为0x0xFFFD00,但key是16位数,故需要舍弃前两个FF,最终结果是key=0xFD00 key |= ((temp&0xF0)|0x0F); 刚说了按键6在第二行第3列,第3列对应GPE6为0,所以temp的值为1011****,(前面说了temp读入的是GPE7-GPE0的值,但此时GPE3-GPE0不需要过多考虑)即为0xB*。

与0xF0相与,再与0x0F 相或,结果为0xBF。

最后是key值与0xBF相或,的到最终结果0xFDBF
return (key); //函数返回按键对应的值
}
}
前面说了一大堆,可能有点啰嗦,这是为了给打算研究矩阵键盘的人看的,如果只是为了考试,可以看看下面简单的算法。

(仅限于此图,其他连接方法需要稍作修改)
比如按下的是‘确认’键,看一下行和列。

1行4列。

直接从if语句看
key = (~i); 第1行,给1取反是0xFFFE(怎么来的这在前面有,这个是基础)key <<= 8; 左移八位结果是0xFE00
key |= ((temp&0xF0)|0x0F) 将对应的列进行运算。

第4列对应GPE7=0,temp 值为0x7*,与0xF0相与,再和0x0F相或,值为0x7F。

0x7F再和key(0xFE00)相或,结果是0xFE7F。

晚上编辑的,部分解释语句难免有错误,如果大家有什么简洁易懂的解释方法可以在此基础上编辑,然后传到群里大家共享。

谢谢合作。

相关主题