关于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;
} 展开
对单片机检测矩阵键盘的方式还不是很明白。
我的理解是每次检测前对于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;
} 展开
展开全部
(1)P3口是准双向IO口(注意与双向IO口的区别),它 的硬件结构决定着,读取之前先写1,再读取,读取的结果才可能是正确的,你可以区域查查书。
(2)4X4 矩阵键盘的8根线直接连在IO上,而独立按键有一根线固定是接地的,这就意味着必须采取扫面或者线反转的方法。比如其中一根行线赋0,相当于这一行的四个按键变成了四个独立按键,在读取列线的值就知道了究竟哪个按键被按下了。 此时P3口就出现了特定的电平组合,相当于特征码了,然后再认为映射一下功能就可以了。
(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个,那不得疯了。
意法半导体(中国)投资有限公司
2020-01-15 广告
2020-01-15 广告
单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制...
点击进入详情页
本回答由意法半导体(中国)投资有限公司提供
展开全部
大概看了下 ,你这个矩阵键盘是4x4的键盘,P3口的高四位和低四位组成的行列键盘,其实这个比较简单,P3=FE=11111110,这段是判断按键是否在第一行(假定低四位为行,高四位为列),依次类推,P3=FD=11111101,这段是判断按键是否在第二行,直到低四位扫描完,就确定了是在哪一行按下的键,接下来判断哪里列,原理还一样,这样就把哪个按键确定下来了,中间那个DELAY(5)你应该知道是防抖动的延时程序
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
单片机矩阵键盘,如上述是 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 种状态。
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 种状态。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
当检测按键时用的是它的输入功率,先把按键的一端接地,另一端与单片机的某个I/0口相连,开始时先给该I/0口赋一高电平,然后让单片机不断地检测该I/0口是否变为低电平,当按键闭合时,即相当于该I/0口通过按键与地相连,变成低电平,程序一旦检测到I/0变为低电平则说明按键被按下,然后执行相应的指令。
追问
请问一下,我的编程思路错在什么地方?谢啦。。
追答
你可以参照一下,郭天祥有个单片机实例,分析一下就知道了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询