这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» MCU» 请教矩阵按键扫描的单片机程序问题

共8条 1/1 1 跳转至

请教矩阵按键扫描的单片机程序问题

工程师
2021-10-14 21:26:25 打赏

大家好!以下是某设备上的单片机程序,我有一些不明白的地方把它复制过来了,就是按键值的范围我不太理解

单片机源程序如下:


#include
#include
#define Keybus P0
unsigned char R_Keyno;

unsigned char Get_Keyno(void)
{
unsigned char Key_h,Key_l,Key_no;
_nop_();_nop_();_nop_();
Key_h=Keybus; //我的理解:此时Key_h=P0,应该是P0口的实际状态。
_nop_();_nop_();_nop_();_nop_();_nop_();
Keybus=0x0f;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
Key_l=Keybus; //我的理解:此时Key_l=0x0f
_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();
Keybus=0xf1;
Key_no=Key_h | Key_l; //我的理解:如果按位或的话那么 Key_no的值低四位永远是F
_nop_();
return Key_no;
}
这是矩阵键盘按键读取的子程序,

void keyin_work(void)
{
switch (R_Keyno) //这是其他引用按键的程序,它的后四位并不是F,请问大神们这个怎么得出来的
case 0xbc:
case 0xec:
case 0xea:
case 0xba:
case 0xda:
case 0xd6:
case 0xb6:
}
这是应用键盘值判断是哪个按键被按下的应用程序。




关键词: 按键 扫描 矩阵 源码

工程师
2021-10-14 23:10:07 打赏
2楼

结合硬件接线图,就一目了然了呀!


工程师
2021-10-14 23:17:25 打赏
3楼

基于, #define Keybus P0 , 所以,Keybus 就是 P0 的意思,是任何时候,而不是仅仅“此时”

所以: Key_h=Keybus; 就是把 P0 的 值 赋值给 Key_h

所以: Key_no=Key_h | Key_l; 只要有按键按下, 就不会等于 0xff

从你: Keybus=0x0f; Keybus=0xf1; 这两句看, 如果不是写错了。
那么,你的矩阵键盘就是 3x4 = 12 的矩阵。

所以,switch (R_Keyno) 里面的 Case, 随便找一个,转换成 二进制:
比如: 0xbc => 1011 1100居然 三个0??

看不懂了………… 你自己捉摸吧……


工程师
2021-10-14 23:27:38 打赏
4楼

Key_l=Keybus; //我的理解:此时Key_l=0x0f
这一句,输出“1”的位就是输入了,如果有按键按下,读回来的就不是“1”了。


工程师
2021-10-15 10:02:21 打赏
5楼
估计楼主用直接设置IO输入输出方向的MCU比较多,用传统51比较少,对这种转换输入方式不太理解。或者是一下没反应过来?



工程师
2021-10-15 10:19:53 打赏
6楼

从楼主给的现有条件来看,这个矩阵键盘用了6个端口组成3*3,只使用了7个按键。并且P0.0是被接地,P0.7空。否则不可能得到上述7个键码。
给你把按键代码顺序调整了一下,便于你理解键码是怎么产生的。这是验证程序:

#include

#define Keybus P0

unsigned char Get_Keyno(void)

{

unsigned char Key_h,Key_l,Key_no;

Keybus=0xf1;

Key_h=Keybus; //获取高4位状态

Keybus=0x0f;

Key_l=Keybus; //获取低4位状态

Key_no=Key_h | Key_l; //高低4位相加

return Key_no;

}

void keyin_work(void)

{

switch (Get_Keyno())

{

case 0xbc:P2=~0x01;break;//1011 1100

case 0xec:P2=~0x02;break;//1110 1100

case 0xea:P2=~0x03;break;//1110 1010

case 0xba:P2=~0x04;break;//1011 1010

case 0xda:P2=~0x05;break;//1101 1010

case 0xd6:P2=~0x06;break;//1101 0110

case 0xb6:P2=~0x07;break;//1011 0110

}

}

void main()

{

while(1)

{

keyin_work();

}

}




专家
2021-10-15 10:21:11 打赏
7楼

谢谢分享


工程师
2021-10-19 22:03:16 打赏
8楼

学到经验了


共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]