野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13311|回复: 11

哪位大神帮我看下怎么实现这个矩阵键盘

[复制链接]
发表于 2016-7-21 09:51:59 | 显示全部楼层 |阅读模式
本帖最后由 a18270826679 于 2016-7-21 10:05 编辑

QQ图片20160721100256.png
void KEY_Init(void)
{

                GPIO_InitTypeDef  GPIO_InitStructure;
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
                GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
                GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;
                GPIO_Init(GPIOB,&GPIO_InitStructure);

                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
                GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
                GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
                GPIO_Init(GPIOB,&GPIO_InitStructure);               
}

int KEY_Scan(void) //êμÏÖ¾ØÕó¼üÅì¡£·μ»ØÖμÎa£¬¸÷°′¼üμļüÖ죬′˼üÖμóéóû§×Ô¼o¶¨òå¡£{
        u8 KeyVal;         //keyValÎa×îoó·μ»ØμļüÖμ¡£

        GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);

        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)==0x0)
                return -1;
        else
        {        
                delay_ms(5);
                if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)==0x0)
                return -1;
        }
                GPIO_ResetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6);
                GPIO_SetBits(GPIOB,GPIO_Pin_3);
        
                printf("0x%X\n",(GPIOB->IDR&0x0780)>>7);
        switch((GPIOB->IDR&0x0780)>>7)
        {
                case 0x01: KeyVal=1;         break;
                case 0x02: KeyVal=2;        break;
                case 0x04: KeyVal=3;        break;
                case 0x08: KeyVal=4;        break;
        }
                while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)!=0x0);
                GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6);
                GPIO_SetBits(GPIOB,GPIO_Pin_4);
                printf("0x%X\n",(GPIOB->IDR&0x0780)>>7);
        switch((GPIOB->IDR&0x0780)>>7)
        {
                case 0x01: KeyVal=5;        break;
                case 0x02: KeyVal=6;        break;
                case 0x04: KeyVal=7;        break;
                case 0x08: KeyVal=8;        break;
        }
                while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)!=0x0);
        
        
                GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_6);
                GPIO_SetBits(GPIOB,GPIO_Pin_5);
        printf("0x%X",(GPIOB->IDR&0x0780)>>7);
        switch((GPIOB->IDR&0x0780)>>7)
        {
                case 0x01: KeyVal=13;        break;
                case 0x02: KeyVal=9;        break;
                case 0x04: KeyVal=5;        break;
                case 0x08: KeyVal=1;        break;
        }
               
                while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)!=0x0);
        
        
                GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);
                GPIO_SetBits(GPIOB,GPIO_Pin_6);
        printf("0x%X",(GPIOB->IDR&0x0780)>>7);
        switch((GPIOB->IDR&0x0780)>>7)
        {
                case 0x01: KeyVal=12;        break;
                case 0x02: KeyVal=8;        break;
                case 0x04: KeyVal=4;        break;
                case 0x08: KeyVal=0;        break;
        }        
                while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10)!=0x0);                                                         
        return KeyVal;               
}
原理图我是采用4*4  来实现3*4  这个代码实现了只能扫描一行,我觉得是行扫描那块没做好,
下面代码是可以实现的,但是他这个接口和我那个不一样。他采用的是PB8-PB15   我需要采用PB3-PB10 QQ图片20160721100342.png
void KEY_Init(void) //初始化矩阵键盘要使用的GPIO口。
{

     GPIO_InitTypeDef  GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

      GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;       //定义PB8到PB11为上拉输入、、。
      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
   GPIO_Init(GPIOB,&GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD;       //定义PB12到PB15为下拉输入。
      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
   //因为上面定义引脚为输出时,已经打开整个GPIOA的时钟了,
      //所以此处不再需要函数RCC_APB2PeriphClockCmd()来打开时钟了。
   GPIO_Init(GPIOB,&GPIO_InitStructure);         
}

int KEY_Scan(void) //实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。
{
      u8KeyVal;    //keyVal为最后返回的键值。
      GPIO_Write(GPIOB,(GPIOB->ODR& 0xf0ff | 0x0f00)); //先让PB8到PB11全部输出高。

      if((GPIOB->IDR& 0xf000)==0x0000)  //如果PB12到PB15全为0,则没有键按下。此时,返回值为-1.
           return-1;
      else
      {   
          delay_ms(5);    //延时5ms去抖动。
          if((GPIOB->IDR & 0xf000)==0x0000)//如果延时5ms后,PB12到PB15又全为0,则,刚才引脚的电位变化是抖动产生的.
         return -1;
      }

      GPIO_Write(GPIOB,(GPIOB->ODR& 0xf0ff | 0x0100));  //让PB11到PB8输出二进制的0001.

           switch(GPIOB->IDR& 0xf000)//对PB12到PB15的值进行判断,以输出不同的键值。
                 {
                      case0x1000: KeyVal=15; break;
                      case0x2000: KeyVal=11; break;
                      case0x4000: KeyVal=7;   break;
                      case0x8000: KeyVal=3;   break;
                 }

      GPIO_Write(GPIOB,(GPIOB->ODR& 0xf0ff | 0x0200));  //让PB11到PB8输出二进制的0.
           switch(GPIOB->IDR& 0xf000)               //对PB12到PB15的值进行判断,以输出不同的键值。
           {
                 case0x1000: KeyVal=14; break;
                 case0x2000: KeyVal=10; break;
                 case0x4000: KeyVal=6;   break;
                 case0x8000: KeyVal=2;   break;
           }

      GPIO_Write(GPIOB,(GPIOB->ODR& 0xf0ff | 0x0400));  //让PB11到PB8输出二进制的1011.
           switch(GPIOB->IDR& 0xf000)               //对PB12到PB15的值进行判断,以输出不同的键值。
           {
                 case0x1000: KeyVal=13; break;
                 case 0x2000: KeyVal=9;   break;
                 case0x4000: KeyVal=5;   break;
                 case0x8000: KeyVal=1;   break;
           }

       GPIO_Write(GPIOB,(GPIOB->ODR & 0xf0ff |0x0800));     //让PB11到PB8输出二进制的0111.
           switch(GPIOB->IDR& 0xf000)               //对PB12到PB15的值进行判断,以输出不同的键值。
           {
                 case0x1000: KeyVal=12; break;
                 case0x2000: KeyVal=8;   break;
                 case0x4000: KeyVal=4;   break;
                 case0x8000: KeyVal=0;   break;
           }                                                  
      returnKeyVal;         
}




回复

使用道具 举报

发表于 2016-7-21 09:54:42 | 显示全部楼层
把你说的那个可以的,用寄存器写的例程也发上来看看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 09:56:45 | 显示全部楼层
fire 发表于 2016-7-21 09:54
把你说的那个可以的,用寄存器写的例程也发上来看看

好  但是他这个接口和我这个不一样
回复 支持 反对

使用道具 举报

发表于 2016-7-21 09:58:23 | 显示全部楼层
a18270826679 发表于 2016-7-21 09:56
好  但是他这个接口和我这个不一样

你把他的原理图也发上来看看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 10:05:39 | 显示全部楼层
fire 发表于 2016-7-21 09:58
你把他的原理图也发上来看看

发上去了  
回复 支持 反对

使用道具 举报

发表于 2016-7-21 10:07:46 | 显示全部楼层
我有空再帮你看看,今天很忙
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 10:12:26 | 显示全部楼层
fire 发表于 2016-7-21 10:07
我有空再帮你看看,今天很忙

好  让你上心了
回复 支持 反对

使用道具 举报

发表于 2016-7-21 13:42:16 | 显示全部楼层
尤其是操作行和列不再同一个GPIO组的矩阵键盘更是烦人
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-21 14:55:20 | 显示全部楼层
火哥哥 发表于 2016-7-21 13:42
尤其是操作行和列不再同一个GPIO组的矩阵键盘更是烦人

是呀 我都弄了两天了
回复 支持 反对

使用道具 举报

发表于 2016-7-21 15:31:46 | 显示全部楼层
a18270826679 发表于 2016-7-21 14:55
是呀 我都弄了两天了

我也在调代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-22 12:38:20 | 显示全部楼层

真好  谢谢哈。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-7-23 08:10:10 | 显示全部楼层

火哥  弄的怎么样了
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-9-22 18:28 , Processed in 0.047484 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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