OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8701|回复: 21

矩阵按键实现,欢迎来分享更好的矩阵按键实现方案!

[复制链接]

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2014-12-9
在线时间
28 小时
发表于 2014-12-13 16:36:12 | 显示全部楼层 |阅读模式


注意:IO口都要上拉。


一、IO口设置为开漏输出:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_OD;   
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_Init(GPIOA, &GPIO_InitStructure);

二、扫描程序:
uint8_t KeyScan(void)
{
int tmp;
    static int KeyConter = 0;
 int keyval;
 keyval = 0xFF;
    if (KeyConter < 1)
    {//去抖
                KeyConter++;
    }
else 
{
keyval = 0xFF;
GPIO_Write(GPIOA, 0x0F);          //GPIOA低四位置1,既行选全置1
tmp = (GPIO_ReadInputData(GPIOA) | 0xF0);//读取此时的列选的值
keyval &= tmp;
GPIO_Write(GPIOA, 0xF0);//列选全置1
tmp = (GPIO_ReadInputData(GPIOA) | 0x0F);//读取此时的行选的值
keyval &= tmp; //两次的结果相与得到是一个唯一值,既一个按键按下只有一个keyval与之对应
switch (keyval)
                {                                                  
                case 0xee:    return 1; 
                case 0xde:    return 2;
                case 0xbe:    return 3;
                case 0x7e:    return 4;              
                case 0xed:    return 5;
                case 0xdd:    return 6;
                case 0xbd:    return 7;
                case 0x7d:    return 8;
                case 0xeb:    return 9;
                case 0xdb:    return 10; //*
                case 0xbb:    return 11;
                case 0x7b:    return 12;  //#
case 0x77:    return 13; //下一位
                default:      return 0;
                }               

KeyConter=0;
}  
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-12-13 18:39:41 | 显示全部楼层
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

3

主题

138

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2014-5-12
在线时间
4 小时
发表于 2014-12-13 19:28:16 | 显示全部楼层
好好,瞬间懂了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-12-14 11:41:12 | 显示全部楼层
谢谢分享.....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2014-12-9
在线时间
28 小时
 楼主| 发表于 2014-12-15 11:51:49 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
回复【2楼】八度空间:
---------------------------------
客气了,我从这个论坛也学到了不少东西,希望大家把已经实现的结果都拿出来分享,这样才有助于共同进步!
回复 支持 反对

使用道具 举报

55

主题

1231

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2624
金钱
2624
注册时间
2014-2-13
在线时间
514 小时
发表于 2014-12-23 09:30:52 | 显示全部楼层
 感谢分享                                                                                 
技术交流,Sell 中颖单片机,欢迎私信骚扰
回复 支持 反对

使用道具 举报

3

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2014-5-18
在线时间
0 小时
发表于 2015-1-12 13:52:16 | 显示全部楼层
为啥不用设置IO输入就直接读呢?
回复 支持 反对

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2014-12-9
在线时间
28 小时
 楼主| 发表于 2015-1-15 10:07:18 | 显示全部楼层
回复【7楼】oceanzi:
------------------------
你的IO口多的用不掉的话可以。。
回复 支持 反对

使用道具 举报

4

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
289
金钱
289
注册时间
2015-10-7
在线时间
32 小时
发表于 2016-1-19 13:37:53 | 显示全部楼层
我想问一下要是在硬件上没有加的上拉电阻这个程序可以吗?是不是不行了?
回复 支持 反对

使用道具 举报

8

主题

136

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
427
金钱
427
注册时间
2015-4-24
在线时间
85 小时
发表于 2016-6-27 16:35:52 | 显示全部楼层
楼主您好,看到程序还有些不懂的地方想请教下,望解答,谢谢。
首先是GPIO_Write(GPIOA, 0x0F);          //GPIOA低四位置1,既行选全置1
tmp = (GPIO_ReadInputData(GPIOA) | 0xF0);//读取此时的列选的值
上面的语句如果只读列的话,为什么不用&而是|。还有一个问题是当开关按下的时候,两端是低电平的时候导通,为什么不是高电平,开关两端的上拉对这个电平没有影响吗
回复 支持 反对

使用道具 举报

4

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2016-5-16
在线时间
28 小时
发表于 2016-6-29 16:06:08 | 显示全部楼层
本帖最后由 150315175 于 2016-6-29 16:07 编辑

请教一下,单片机引脚应该是读取电阻右边的电平吧?
GPIO_Write(GPIOA, 0x0F);          //GPIOA低四位置1,既行选全置1
tmp = (GPIO_ReadInputData(GPIOA) | 0xF0);//读取此时的列选的值
PA0~PA3置1,假设S1按下,那么PA4读取的状态是跟PA0相同是1吧?PA5~PA7(S2~S4)右侧没信号,但是左侧上拉应该读取都是1吧。
不是很明白,求解惑
回复 支持 反对

使用道具 举报

8

主题

136

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
427
金钱
427
注册时间
2015-4-24
在线时间
85 小时
发表于 2016-7-5 09:12:44 | 显示全部楼层
150315175 发表于 2016-6-29 16:06
请教一下,单片机引脚应该是读取电阻右边的电平吧?
GPIO_Write(GPIOA, 0x0F);          //GPIOA低四位置1 ...

我自己的理解是这样的,当拉高后是高电平,两边都是1;但是在按键按下的时候由于两边电平一样就会变成0,所以在开关按下的时候应该是低电平。还有tmp = (GPIO_ReadInputData(GPIOA) | 0xF0);//读取此时的列选的值;这句我感觉是不是应该读取行的值
回复 支持 反对

使用道具 举报

8

主题

136

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
427
金钱
427
注册时间
2015-4-24
在线时间
85 小时
发表于 2016-7-11 16:36:00 | 显示全部楼层
伟好好学习 发表于 2016-1-19 13:37
我想问一下要是在硬件上没有加的上拉电阻这个程序可以吗?是不是不行了?

你好,问一下,没有上拉电阻还能正常使用吗
回复 支持 反对

使用道具 举报

3

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-6-22
在线时间
56 小时
发表于 2016-7-12 09:29:19 | 显示全部楼层
bruellyyang 发表于 2016-6-27 16:35
楼主您好,看到程序还有些不懂的地方想请教下,望解答,谢谢。
首先是GPIO_Write(GPIOA, 0x0F);           ...

1、是可以用&的,但你后面“keyval&=tmp”就不能用&而用|。
2、因为已经用了GPIO_Write(GPIOA,0X0F)这个函数已经把高四位置低电平了,所以按下的时候不是高电平了。
不知道我这样理解的对不对。。。
回复 支持 反对

使用道具 举报

8

主题

136

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
427
金钱
427
注册时间
2015-4-24
在线时间
85 小时
发表于 2016-7-12 14:34:44 | 显示全部楼层
下一个定义 发表于 2016-7-12 09:29
1、是可以用&的,但你后面“keyval&=tmp”就不能用&而用|。
2、因为已经用了GPIO_Write(GPIOA,0X0F)这 ...

这个地方已经明白了,上面的没问题。按键输入,为什么把IO口配置成开漏输出的
回复 支持 反对

使用道具 举报

3

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-6-22
在线时间
56 小时
发表于 2016-7-12 17:13:25 | 显示全部楼层
bruellyyang 发表于 2016-7-12 14:34
这个地方已经明白了,上面的没问题。按键输入,为什么把IO口配置成开漏输出的

这个我也不太懂,可能是因为用了GPIO_Write函数
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2016-9-6
在线时间
5 小时
发表于 2017-3-9 09:03:45 | 显示全部楼层
该函数的调用间隔必须要大于按键抖动的时间。至少调用两次才能获取按键值
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2016-9-6
在线时间
5 小时
发表于 2017-3-9 09:14:56 | 显示全部楼层
bruellyyang 发表于 2016-7-11 16:36
你好,问一下,没有上拉电阻还能正常使用吗

不接上拉电阻在管脚拉低时电源3.3v直接进芯片会把IO口烧坏的吧
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-6-11
在线时间
7 小时
发表于 2019-6-30 16:59:18 | 显示全部楼层
MARK一下
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2019-8-12
在线时间
3 小时
发表于 2019-8-12 09:14:09 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2023-10-10
在线时间
8 小时
发表于 2023-11-3 17:02:43 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

7

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2016-4-11
在线时间
54 小时
发表于 2024-6-12 11:42:23 | 显示全部楼层
思路不错
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 19:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表