读书人

stm32f2xx 的四*4键盘矩阵模块keypad驱

发布时间: 2012-11-16 14:12:15 作者: rapoo

stm32f2xx 的4*4键盘矩阵模块keypad驱动代码已写完【亲测成功】

我用的是 微雪(waveshare) 电子那个keypad 。通过用万用表测量,分析到键盘的位置,并在单片机用宏定义把 1~8端口定位 K1~K8 。

给出图:

stm32f2xx 的四*4键盘矩阵模块keypad驱动代码已写完【亲测成功】

驱动文件包括 key.h 和 key.c 。

有两个函数:

void Keyinit(void);   //初始化函数unsigned char Getkey(void);   //得到键值


给main的接口就上面两个了,下面把代码贴出来。

**************************key.h*******************************

#ifndef __KEY_H#define __KEY_H#include "stm32f2xx.h" #define K1 GPIO_Pin_10  #define K2 GPIO_Pin_9 #define K3GPIO_Pin_8   #define K4GPIO_Pin_7   #define K5 GPIO_Pin_1   #define K6 GPIO_Pin_0 #define K7GPIO_Pin_15  #define K8GPIO_Pin_14  //宏定义使得变换方便typedef struct{                                            GPIO_TypeDef *GPIOX;                 unsigned short GPIO_pin;}IOport; //结构体变量一定要用静态的,因为 key.c 和 main.c 都包含了 key.h,不然会多重定义的。void Keyinit(void);  //初始化,千万别忘了unsigned char Getkey(void);   //得到键值#endif

**************************key.c*******************************

#include "key.h"static IOport row[4] = {{GPIOE, K1}, {GPIOE, K2},{GPIOE, K3},{GPIOE, K4}};static IOport col[4] = {{GPIOD, K5}, {GPIOD, K6},{GPIOD, K7},{GPIOD, K8}};void Keyinit(void)//初始化的目的是把下面的Getkey 和这个分开,初始化一次,而经常调用Getkey。{ unsigned char i; GPIO_InitTypeDef  GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOD, ENABLE);   //时钟的启动,换端口时记得换这个。  //下面设置的是行扫描线,这个等等是拿来置位的,都置1初始化,然后让轮着变0。 //从单片机输出啊,搞个推挽输出,驱动能力牛啊。 GPIO_InitStructure.GPIO_Pin = K1 | K2 | K3 | K4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOE, &GPIO_InitStructure); //下面设置的是列扫描线。这个明显拿来接收检测的。 //那就是输入咯,先用上拉电阻拉高(初始化),然后键盘一按,就变低,检测判断。 GPIO_InitStructure.GPIO_Pin = K5 | K6 | K7 | K8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   //既然说了是 GPIO out type ennumeration ,那输入就不用它了。// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //输出送到输入那里,跟上面的一样的。 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOD, &GPIO_InitStructure); for(i=0;i<4;i++)//把那四个行扫描的推挽输出模式输出置 1 。  GPIO_SetBits(row[i].GPIOX, row[i].GPIO_pin);  }         //上面的初始化完成后,下面开始我们的算法之旅。unsigned char Getkey(void) {  unsigned char i,j,k;  for(i=1;i<=4;i++)  { GPIO_ResetBits(row[i-1].GPIOX, row[i-1].GPIO_pin);for(j=1;j<=4;j++){   if(GPIO_ReadInputDataBit(col[j-1].GPIOX, col[j-1].GPIO_pin)==0)   k=(4-j)*4+i;}GPIO_SetBits(row[i-1].GPIOX, row[i-1].GPIO_pin);   }  return k; }


顺便把当时测试的main代码贴下来吧。那块开发板中,

GPIOC_Pin_6,GPIOC_Pin_7,GPIOC_Pin_8,GPIOC_Pin_9 连着LED灯的。

**************************main.c*******************************


 #include "stm32f2xx.h" #include "delay.h"   #include "key.h" main() { GPIO_InitTypeDef  GPIO_InitStructure;   //这个一定要放在前面,之前将Keyinit()放在第一句,然后报错了。//error: declaration may not appear after executable statement in block 说明声明应该放在前面,不能放在执行语句后。 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);   //时钟的启动,换端口时记得换这个。  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6| GPIO_Pin_7| GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); Keyinit();//初始化keypad。  while(1)  {   if(Getkey()==5)   //看看我按第5个键有没有用先,哈哈   {   GPIO_SetBits(GPIOC,GPIO_Pin_6);   }   if(Getkey()==14)  //看看我按第14个键有没有用先,哈哈   {   GPIO_ResetBits(GPIOC,GPIO_Pin_6);   }  } }


结果: 果然不出所料,按第5个键和第14个键起作用了,其他怎么按都没用。

分享到这里,大家知道思想是怎么样了吧。

最后想说一句,到现在别告诉我你不知道 stm32f2xx_conf.h 包含了所有外设的头文件,stm32f2xx_it.h 声明了中断的模板,stm32f2xx_it.c 往函数里面填写你的中断就可以了,当然我们这个矩阵键盘没用到中断(不过我的那个delay 用到了Systick的中断)。

算了,不废话了~~~

读书人网 >编程

热点推荐