OpenEdv-开源电子网

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

发一个挺简单的ministm32 4x4矩阵键盘库函数版本源代码

[复制链接]

14

主题

97

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2014-12-16
在线时间
10 小时
发表于 2015-1-23 23:29:19 | 显示全部楼层 |阅读模式


目前工作正常,顺便请大家帮看看有没有问题。
key.h

#include "sys.h"

#define ROWPINS GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3  //行针
#define COLPINS GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13 //列针
void KEY_Init(void);//IO初始化
u8 KEY_Scan(void);   //按键扫描函数
u8 ReScan(u16 colPin,u8 colIndex);//二次扫描

key.c

#include "key.h"
#include "delay.h"

u8 lastKey,currentKey;

u16 rowPin[4] = {GPIO_Pin_0,GPIO_Pin_1,GPIO_Pin_2,GPIO_Pin_3};
u16 colPin[4] = {GPIO_Pin_10,GPIO_Pin_11,GPIO_Pin_12,GPIO_Pin_13};
u8 otherPin[4] = {14,13,11,7};//GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3,GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2};     
//按键初始化函数
void KEY_Init(void)
{
 
 GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能PORTC时钟
 
 GPIO_InitStructure.GPIO_Pin  = ROWPINS;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置成推挽输出
  GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC 0-3
 GPIO_ResetBits(GPIOC,ROWPINS);
 
 GPIO_InitStructure.GPIO_Pin  = COLPINS;//PC5
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
  GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC 10-13
}
u8 ReScan(u16 colPin,u8 colIndex)
{
 u8 i;
 for(i = 0;i<4;i++){
  GPIO_ResetBits(GPIOC,rowPin);
  GPIO_SetBits(GPIOC,otherPin);
  delay_ms(10);//据说是消除抖动,但是去掉工作也正常
  if((GPIO_ReadInputDataBit(GPIOC, colPin) == 0)){
   GPIO_ResetBits(GPIOC,ROWPINS);
   return colIndex*4+i+1;//返回的数据为1-16 对应4x4键盘的16个键
  }
 }
 GPIO_ResetBits(GPIOC,ROWPINS);
 return 0;
}

u8 KEY_Scan(void)
{  
u8 i;
for(i = 0;i<4;i++)
{
if(GPIO_ReadInputDataBit(GPIOC,colPin) == 0){
currentKey = ReScan(colPin,i);
if(currentKey == 0)
{
lastKey = 0;
return 0;
}
else
{
if(currentKey != lastKey)
{
lastKey = currentKey;
return lastKey;
}
else
{
lastKey = currentKey;
return 0;
}
}
}
}
lastKey = 0;
return 0;
}


调用:
while(1)
{
  u8 a = KEY_Scan();
  if(a!=0)
   printf("KEY:%d\r\n",a);
  delay_ms(10);
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2015-1-24
在线时间
17 小时
发表于 2015-1-31 21:39:19 | 显示全部楼层
谢谢分享啦
回复 支持 反对

使用道具 举报

8

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2015-3-26
在线时间
0 小时
发表于 2015-5-11 14:49:03 | 显示全部楼层
#include "key.h"
#include "delay.h"

u8 lastKey,currentKey;

u16 rowPin[4] = {GPIO_Pin_0,GPIO_Pin_1,GPIO_Pin_2,GPIO_Pin_3};
u16 colPin[4] = {GPIO_Pin_4,GPIO_Pin_5,GPIO_Pin_6,GPIO_Pin_7};
u8 otherPin[4] = {14,13,11,7};//GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3,GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2};      
//按键初始化函数 
void KEY_Init(void)
{
 
 GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PORTC时钟
 
 GPIO_InitStructure.GPIO_Pin  = ROWPINS;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置成推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOC 0-3
 GPIO_ResetBits(GPIOB,ROWPINS);
 
 GPIO_InitStructure.GPIO_Pin  = COLPINS;//PC5
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOC 10-13

u8 ReScan(u16 colPin,u8 colIndex)
{
 u8 i;
 for(i = 0;i<4;i++){
  GPIO_ResetBits(GPIOB,rowPin);
  GPIO_SetBits(GPIOB,otherPin);
  delay_ms(10);//据说是消除抖动,但是去掉工作也正常
  if((GPIO_ReadInputDataBit(GPIOB, colPin) == 0)){
   GPIO_ResetBits(GPIOB,ROWPINS);
   return colIndex*4+i+1;//返回的数据为1-16 对应4x4键盘的16个键
  }
 }
 GPIO_ResetBits(GPIOB,ROWPINS);
 return 0;
}

u8 KEY_Scan(void)
{  
u8 i;
for(i = 0;i<4;i++)
{
if(GPIO_ReadInputDataBit(GPIOB,colPin) == 0){
currentKey = ReScan(colPin,i);
if(currentKey == 0)
{
lastKey = 0;
return 0;
}
else
{
if(currentKey != lastKey)
{
lastKey = currentKey;
return lastKey;
}
else
{
lastKey = currentKey;
return 0;
}
}
}
}
lastKey = 0;
return 0;
}

为什么我只有第三行的键才可以用呢?我的是mini版
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2015-10-27
在线时间
0 小时
发表于 2015-10-28 09:49:13 | 显示全部楼层
谢谢分享。。
小菜鸟要学飞
回复 支持 反对

使用道具 举报

4

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
289
金钱
289
注册时间
2015-10-7
在线时间
32 小时
发表于 2016-1-18 17:33:57 | 显示全部楼层
想问一下有STM32带松手检测的矩阵键盘程序吗?
回复 支持 反对

使用道具 举报

4

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
321
金钱
321
注册时间
2016-9-22
在线时间
62 小时
发表于 2016-12-26 14:31:32 | 显示全部楼层
ReScan函数的GPIO_ResetBits(GPIOC,rowPin);  GPIO_SetBits(GPIOC,otherPin);
KEY_Scan函数的if(GPIO_ReadInputDataBit(GPIOC,colPin) == 0)     currentKey = ReScan(colPin,i);编译不通过。
rowPin、otherPin、colPin提示错误
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2019-2-24
在线时间
2 小时
发表于 2019-2-25 15:39:56 来自手机 | 显示全部楼层
请问一下,那矩阵键盘和单片机怎么连接呢
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2019-8-12
在线时间
9 小时
发表于 2019-8-19 14:57:19 | 显示全部楼层
感谢楼主分享。我在调试的时候报错。仔细检查后经过三处修改后,成功了。
这个函数u8 ReScan(u16 colPin,u8 colIndex) 内的
GPIO_ResetBits(GPIOB,rowPin);
GPIO_SetBits(GPIOB,otherPin);
我改为了
GPIO_ResetBits(GPIOB,rowPin[i]);
GPIO_SetBits(GPIOB,otherPin[i]);
还有u8 KEY_Scan(void)里面的
currentKey = ReScan(colPin,i);
改为了
currentKey = ReScan(colPin[i],i);

往配置IO口添加了
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
之后就可以用了。
在此感谢楼主分享。
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2019-7-20
在线时间
12 小时
发表于 2019-9-15 12:11:11 | 显示全部楼层
111111111111111111
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

高级会员

Rank: 4

积分
852
金钱
852
注册时间
2018-10-11
在线时间
69 小时
发表于 2020-5-15 10:27:27 | 显示全部楼层
谢谢你,学习了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-1 02:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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