OpenEdv-开源电子网

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

3*3矩阵键盘扫描程序,没有反应

[复制链接]

86

主题

984

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1850
金钱
1850
注册时间
2013-4-15
在线时间
163 小时
发表于 2014-6-17 11:06:11 | 显示全部楼层 |阅读模式
5金钱
#define PA11 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)
#define PA12 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)
#define PA15 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)

#define KEY_UpdateFont 1  
#define KEY_Up 2
#define KEY_Plus 3
#define KEY_Left 4  
#define KEY_MakeSure 5
#define KEY_Right 6
#define KEY_Cancel 7  
#define KEY_Down 8
#define KEY_Subtract 9

/********************
  *按键初始化子函数*
********************/
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/*使能GPIOA和GPIOC时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

/*初始化GPIOA0/GPIOA1,推挽输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); 
GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);

/*初始化GPIOC13,推挽输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_13);

/*初始化GPIOA11/GPIOA12/GPIOA15,下拉输入*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_15); 
}

/***********************************************
  *按键扫描子函数*
  *返回值:键值*
***********************************************/
u8 KEY_Scan(void)
{
static u8 key_up=1;
GPIO_SetBits(GPIOA, GPIO_Pin_0);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
if(key_up && (PA11==1 || PA12==1 || PA15==1))
{
delay_ms(5);
if(PA11==1 || PA12==1 || PA15==1)
{
key_up = 0;
if(PA11 == 1)
return KEY_UpdateFont;
else if(PA12 == 1)
return KEY_Up;
else if(PA15 == 1)
return KEY_Plus;
}
else 
return 0;
}

GPIO_SetBits(GPIOA, GPIO_Pin_1);
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
if(key_up && (PA11==1 || PA12==1 || PA15==1))
{
delay_ms(5);
if(PA11==1 || PA12==1 || PA15==1)
{
key_up=0;
if(PA11 == 1)
return KEY_Left;
else if(PA12 == 1)
return KEY_MakeSure;
else if(PA15 == 1)
return KEY_Right;
}
else 
return 0;
}

GPIO_SetBits(GPIOC, GPIO_Pin_13);
GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);
if(key_up && (PA11==1 || PA12==1 || PA15==1))
{
delay_ms(5);
if(PA11==1 || PA12==1 || PA15==1)
{
key_up = 0;
if(PA11 == 1)
return KEY_Cancel;
else if(PA12 == 1)
return KEY_Down;
else if(PA15 == 1)
return KEY_Subtract;
}
else 
return 0;
}
else if(PA11==0 && PA12==0 && PA15==0) //松手检测
key_up=1; 

return 0;
}


合肥-文盲
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

86

主题

984

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1850
金钱
1850
注册时间
2013-4-15
在线时间
163 小时
 楼主| 发表于 2014-6-17 11:10:02 | 显示全部楼层
合肥-文盲
回复

使用道具 举报

86

主题

984

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1850
金钱
1850
注册时间
2013-4-15
在线时间
163 小时
 楼主| 发表于 2014-6-17 12:51:00 | 显示全部楼层
发现此前的IO口,有JATG口,修改如下,还是有问题
#define PC0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)
#define PC1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)
#define PC2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)

#define KEY_UpdateFont 1  
#define KEY_Up 2
#define KEY_Plus 3
#define KEY_Left 4  
#define KEY_MakeSure 5
#define KEY_Right 6
#define KEY_Cancel 7  
#define KEY_Down 8
#define KEY_Subtract 9

/********************
  *按键初始化子函数*
********************/
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/*使能GPIOA和GPIOC时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

/*初始化GPIOA0/GPIOA1,推挽输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); 
GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);

/*初始化GPIOC13,推挽输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_13);

/*初始化GPIOA11/GPIOA12/GPIOA15,下拉输入*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2); 
}

/***********************************************
  *按键扫描子函数*
  *返回值:键值*
***********************************************/
u8 KEY_Scan(void)
{
static u8 key_up=1;
GPIO_SetBits(GPIOA, GPIO_Pin_0);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
if(key_up && (PC0==1 || PC1==1 || PC2==1))
{
delay_ms(5);
if(PC0==1 || PC1==1 || PC2==1)
{
key_up = 0;
if(PC0 == 1)
return KEY_UpdateFont;
else if(PC1 == 1)
return KEY_Up;
else if(PC2 == 1)
return KEY_Plus;
}
else 
return 0;
}

GPIO_SetBits(GPIOA, GPIO_Pin_1);
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
if(key_up && (PC0==1 || PC1==1 || PC2==1))
{
delay_ms(5);
if(PC0==1 || PC1==1 || PC2==1)
{
key_up=0;
if(PC0 == 1)
return KEY_Left;
else if(PC1 == 1)
return KEY_MakeSure;
else if(PC2 == 1)
return KEY_Right;
}
else 
return 0;
}

GPIO_SetBits(GPIOC, GPIO_Pin_13);
GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);
if(key_up && (PC0==1 || PC1==1 || PC2==1))
{
delay_ms(5);
if(PC0==1 || PC1==1 || PC2==1)
{
key_up = 0;
if(PC0 == 1)
return KEY_Cancel;
else if(PC1 == 1)
return KEY_Down;
else if(PC2 == 1)
return KEY_Subtract;
}
else 
return 0;
}
else if(PC0==0 && PC1==0 && PC2==0) //松手检测
key_up=1; 

return 0;
}


合肥-文盲
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-6-17 12:53:54 | 显示全部楼层
仿真看寄存器数值变化
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

86

主题

984

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1850
金钱
1850
注册时间
2013-4-15
在线时间
163 小时
 楼主| 发表于 2014-6-17 13:29:28 | 显示全部楼层
回复【4楼】Badu_Space:
---------------------------------
现在可以扫描到了,但键值从2到6,出现一种现象,有点像抖动,但我去抖了呀
合肥-文盲
回复

使用道具 举报

20

主题

121

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-10-16
在线时间
44 小时
发表于 2015-8-11 21:04:05 | 显示全部楼层
请问你这个方案问题解决了么?
奋斗才能新生
回复

使用道具 举报

1

主题

374

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1334
金钱
1334
注册时间
2014-7-23
在线时间
424 小时
发表于 2015-8-11 22:09:50 | 显示全部楼层
回复【6楼】待机唤醒:
---------------------------------
 void  delay(uchar x)
{ uchar j;
    while((x--)!=0)  //CPU执行x*12次
    { for(j=0;j<125;j++)
         {;}
    }
}

/*************************************************************
*                                                            *
* 键扫描子程序  (4*3 的矩阵) 0.4 0.5 0.6 0.7为行         *
*   0.1 0.2 0.3为列             *
*                              *
*************************************************************/

 void  keyscan(void)
 {  temp = 0;
    //P1=0xF0;                 //高四位输入   行为高电平  列为低电平
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |  GPIO_Pin_9 |  GPIO_Pin_10 |  GPIO_Pin_11 ; // 选择所有脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //配置成推挽式输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式下 I/O输出速度 50M HZ
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初PA口始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |  GPIO_Pin_13 |  GPIO_Pin_14 |  GPIO_Pin_15 ; // 选择所有脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //配置成推挽式输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式下 I/O输出速度 50M HZ
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初PA口始化

GPIO_Write(GPIOB,0XF0FF); //初始化端口
    delay(1);  //延时
//temp=P1;               //读P1口 
    temp=(GPIO_ReadInputData(GPIOB))>>8&0xF0;  //高8位的屏蔽低四位
    temp=~((temp>>4)|0x00F0); //将高四位移到地位处处理    
    if(temp==1)   // p0.4 被拉低
        key=1;   //第一个按键值
    else if(temp==2)   // p0.5 被拉低
        key=2;  //第2个按键值
    else if(temp==4)   // p0.6 被拉低
        key=3;   //第3个按键值
    else if(temp==8)   // p0.7 被拉低
         key=4;    //第4个按键值
    else
        key=16;
        
    //P1=0x0F;             //低四位输入  列为高电平 行为低电平
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |  GPIO_Pin_9 |  GPIO_Pin_10 |  GPIO_Pin_11 ; // 选择所有脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //配置成推挽式输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式下 I/O输出速度 50M HZ
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初PA口始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |  GPIO_Pin_13 |  GPIO_Pin_14 |  GPIO_Pin_15 ; // 选择所有脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //配置成推挽式输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式下 I/O输出速度 50M HZ
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初PA口始化

GPIO_Write(GPIOB,0X0FFF);


    delay(1);  //延时
//temp=P1;             //读P1口
    temp=(GPIO_ReadInputData(GPIOB)>>8)&0x0F;
    temp=~(temp|0xF0);
if(temp==1)    //p0.0  被拉低
        key=key+0;
    else if(temp==2)    //p0.1  被拉低
        key=key+4;
    else if(temp==4)   //p0.2  被拉低
        key=key+8;
    else if(temp==8) //p0.3  被拉低
        key=key+12;
    else
        key=16;  
    
     dis_buf = key;     //键值入显示缓存
     dis_buf = dis_buf & 0x0f;
 
 }

/*************************************************************
*                                                           *
*判断键是否按下                                             *
*                                                           *
*************************************************************/

 void  keydown(void)
 {   int retval;
   //P1=0xF0;       //将高4位全部置1 低四位全部置0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |  GPIO_Pin_9 |  GPIO_Pin_10 |  GPIO_Pin_11 ; // 选择所有脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //配置成推挽式输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式下 I/O输出速度 50M HZ
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初PA口始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 |  GPIO_Pin_13 |  GPIO_Pin_14 |  GPIO_Pin_15 ; // 选择所有脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //配置成推挽式输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式下 I/O输出速度 50M HZ
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初PA口始化
    
GPIO_Write(GPIOB,0XF0FF);
//P1!=0xF0
retval =  GPIO_ReadInputData(GPIOB); //读PB口状态
if(retval>>8!=0xF0)  //判断按键是否按下 如果按钮按下 会拉低P1其中的一个端口
{
  keyscan();  //调用按键扫描程序
    }
 }
//////////////////////////////////////////////////////////////////////////////////
看你满天满找,就找的一个一看就懂的。。。。至于测试可以debug差状态即可,发串口看,打印在液晶也可以,随你挑了,还有键盘扫描都一样的,这个没什么实用价值旨在领会键盘检测,这里用的是反转法。。。。。
回复

使用道具 举报

20

主题

121

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-10-16
在线时间
44 小时
发表于 2015-8-12 10:25:31 | 显示全部楼层
回复【5楼】合肥-文盲:
---------------------------------
矩阵键盘按下时,稳定么?我感觉不是很稳定,求解
奋斗才能新生
回复

使用道具 举报

20

主题

121

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-10-16
在线时间
44 小时
发表于 2015-8-12 14:49:27 | 显示全部楼层
回复【7楼】guset_03:
---------------------------------
谢谢解答,感激不尽,谢谢
奋斗才能新生
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-23 19:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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