关于51单片机矩阵键盘的问题。 50

/*问题是:在检测矩阵键盘的时候为什么要每次都要对P3赋值?对单片机检测矩阵键盘的方式还不是很明白。我的理解是每次检测前对于P3口要先赋高电平,然后才能读取(如果是这样的... /*问题是 :在检测矩阵键盘的时候为什么要每次都要对P3赋值?
对单片机检测矩阵键盘的方式还不是很明白。
我的理解是每次检测前对于P3口要先赋高电平,然后才能读取(如果是这样的话请高手指教为什么要先赋高电平才能读取)
接下来我就不能理解uchar keyscan()程序中的思想了。我的想法是矩阵键盘每一个键被按下的情况都一一对应一种8为的2进制情况,既然这样,就直接利用这个值来标识每一次所对应的操作
以下是我的程序的一部分
void main()
{
wei=1; //数码管的位选开
P0=0x00;
wei=0; //数码管的位选关
while(1)
{
P3=0xff;
temp=P3;
duan=1;//数码管的段选
switch(temp)
{
case 0xee:P0=0xfe;break;
相对应的还有7种情况0xde,0xbe等。
}
duan=0;

}
}
想知道为什么,谢谢大家了。

*/
uchar keyscan()
{
P3=0xfe; //比如这里
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}

P3=0xfd;//比如这里
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
break;
case 0x7d:num=8;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}

P3=0xfb;//比如这里
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=9;
break;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}

P3=0xf7;//比如这里
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=14;
break;
case 0xb7:num=15;
break;
case 0x77:num=16;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
return num;

}
展开
 我来答
qjb910702
2013-02-05 · TA获得超过190个赞
知道答主
回答量:114
采纳率:0%
帮助的人:37.2万
展开全部
(1)P3口是准双向IO口(注意与双向IO口的区别),它 的硬件结构决定着,读取之前先写1,再读取,读取的结果才可能是正确的,你可以区域查查书。
(2)4X4 矩阵键盘的8根线直接连在IO上,而独立按键有一根线固定是接地的,这就意味着必须采取扫面或者线反转的方法。比如其中一根行线赋0,相当于这一行的四个按键变成了四个独立按键,在读取列线的值就知道了究竟哪个按键被按下了。 此时P3口就出现了特定的电平组合,相当于特征码了,然后再认为映射一下功能就可以了。
追问
还有一些不明白。
比如在case 0xee:num=1;
break; 中,
读取来的P3值与0xee(1110 1110)比较。我觉得每个键被按下的情况都是唯一,为什么还要之前的P3=0xfe;
temp=P3;
temp=temp&0xf0;,这些命令的目的是判断是否在第一行有键被按下。
但是如果一开始就去判断P3是不是==0xee不是更简单吗?
就比如我的程序中的思路为什么是错的。
谢谢啦
追答
你需要一行一行扫描啊0xfe 0xfd 0xfb 0xf7就是依次对四行扫描,你换成二进制看一看,只有一个0吧。P3=0xfe相当于是第一行按键行线接地,只有当你按下“1”的时候,P3读回来才会变成0xee。之所以没有直接判断是不是0Xee是因为键盘需要消抖,要不然会误动作(从按下开始的5~10ms是不稳定的)。
temp=P3;
temp=temp&0xf0;,
针对第一行的4个按键,要不然你得写16个,那不得疯了。
没味鞋
2013-02-05 · 超过22用户采纳过TA的回答
知道答主
回答量:106
采纳率:0%
帮助的人:46.2万
展开全部
大概看了下 ,你这个矩阵键盘是4x4的键盘,P3口的高四位和低四位组成的行列键盘,其实这个比较简单,P3=FE=11111110,这段是判断按键是否在第一行(假定低四位为行,高四位为列),依次类推,P3=FD=11111101,这段是判断按键是否在第二行,直到低四位扫描完,就确定了是在哪一行按下的键,接下来判断哪里列,原理还一样,这样就把哪个按键确定下来了,中间那个DELAY(5)你应该知道是防抖动的延时程序
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
GUEL86
2013-02-05 · TA获得超过5854个赞
知道大有可为答主
回答量:5538
采纳率:86%
帮助的人:2649万
展开全部
单片机矩阵键盘,如上述是 4x4 的矩阵键盘,
P3=0xfe; //比如这里 1111 1110 这是扫描第一组 4 个键,按下 4 个键 读到的数据为
1110 1110 (0xee)、1101 1110 (0xde)、1011 1110 (0xbe)、0111 1110 (0x7e)
P3=0xfd; //比如这里 1111 1101 这是扫描第二组 4 个键,按下 4 个键 读到的数据为
1110 1101 (0xed)、1101 1101 (0xdd)、1011 1101 (0xbd)、0111 1101 (0x7d)
P3=0xfb; //比如这里 1111 1011 这是扫描第三组 4 个键,按下 4 个键 读到的数据为
1110 1011 (0xeb)、1101 1011 (0xdb)、1011 1011 (0xbb)、0111 1011 (0x7b)
P3=0xf7; //比如这里 1111 0111 这是扫描第二组 4 个键,按下 4 个键 读到的数据为
1110 0111 (0xe7)、1101 0111 (0xd7)、1011 0111 (0xb7)、0111 0111 (0x77)
这样可以得到 16 个键值。如果不用 4 次扫描 就不能得到 16 种状态。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
waterayay
2013-02-05 · TA获得超过574个赞
知道小有建树答主
回答量:1144
采纳率:33%
帮助的人:602万
展开全部
当检测按键时用的是它的输入功率,先把按键的一端接地,另一端与单片机的某个I/0口相连,开始时先给该I/0口赋一高电平,然后让单片机不断地检测该I/0口是否变为低电平,当按键闭合时,即相当于该I/0口通过按键与地相连,变成低电平,程序一旦检测到I/0变为低电平则说明按键被按下,然后执行相应的指令。
追问
请问一下,我的编程思路错在什么地方?谢啦。。
追答
你可以参照一下,郭天祥有个单片机实例,分析一下就知道了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式