关于矩阵键盘的扫描,这个简单的问题居然困扰了我一天。扫描原理:输入行值,读取列值;输入列值,读取行值。这是很常用的方法。代码如下:
//=======================================
// 矩阵键盘扫描,返回按键码
//=======================================
unsigned char KeyScan()
{
/*低四位为行线值,高四位为列线值*/
unsigned char code_h,code_l;
KeyPort = 0xf0; //令行线值为0
code_l=KeyPort&0xf0; //读取列线值
if(code_l!=0xf0)
{
DelayMs(10);//延时10毫秒
if((KeyPort&0xf0)==code_l)
{
KeyPort=0x0f;//令列线值为0
code_h=KeyPort&0x0f;//读取行线值
while(code_h==(KeyPort&0x0f));//while(KeyPort!=0xff); //等待松开按键
return (code_h|code_l); //返回组合码
}
}
return 0xff;
}
困扰我的就是KeyPort = 0xf0 ,我在想为什么用
KeyPort &= 0xf0 就不可以。这是一个魔咒,根源是不熟悉矩阵的物理结构以及它和单片机的关系。这没什么必要详述,中咒之人一看便知。但明慧的人自然不会着道,因此也没有必要了解。
以下内容仅提供给和我一样犯迷糊的人。
1.矩阵的结构
2.矩阵所连接的单片机端口
假如所用端口P3,在扫描过程中P3仅仅是用来检测矩阵的按键状态,P3原有的状态没有任何意义。我就是怕赋值语句改变端口状态才那么纠结。
3.顺便做个笔记
关于16位定时器0初值赋值:
TH0=(65536-3000)>>8; //重新赋值 3ms,高8
TL0=(65536-3000); //低8位
网上提到许多取16位数据高8位和低8位的方法,综合比较了一下,还是上面这种简单实在效率。常用的也有下面这种,效率略逊。
TH0=(65536-3000)/256; //重新赋值 3ms,高8
TL0=(65536-3000)%256; //低8位