OpenEdv-开源电子网

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

关于矩阵键盘的问题

[复制链接]

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-5-5
在线时间
0 小时
发表于 2013-5-18 01:36:52 | 显示全部楼层 |阅读模式
我的矩阵键盘老是按了没反应  我用仿真看了下读下哪个按键的函数返回值老是0xff,  明明按了第一个键 keyval=1  但返回还是0xff。。。。。。求解 还有是否每个按键都需要消抖的程序  第一个按键没有(注释了)
主程序里定义了一个int8_t shu;  shu=keyboard();  为什么数每次都是0xff。。。。。。。。
程序如下:
#include "keyboard.h"

 /*
 * 函数名:Key_GPIO_Config
 * 描述  :配置按键用到的I/O口
 * 输入  :无
 * 输出  :无
 */
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //定义PF0到PF3为推挽输出。
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);
    GPIO_Init(GPIOF,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  //定义PF4到PF11为下拉输入。
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;

    GPIO_Init(GPIOF,&GPIO_InitStructure);
}
int8_t keyboard(void)  //实现矩阵键盘。返回值为各按键的键值,此键值由用户自己定义。
{
int8_t KeyVal=0; //keyVal为最后返回的键值。
// uint8_t WriteVal=0; //WriteVal为要写给PF口的数据。

GPIO_Write(GPIOF,(GPIOF->ODR & 0xfff0 | 0xf)); //先让PF0到PF3全部输出高。
if((GPIOF->IDR & 0x00f0)==0x0000)  //如果,PF4到PF7全为0,则,没有键按下。此时,返回值为-1.
return -1;
else if((GPIOF->IDR & 0x00f0)==0x0000)
{
Delay_ms(5);    //延时5ms去抖动。
if((GPIOF->IDR & 0x00f0)==0x0000)  //如果,延时5ms后,PF4到PF7又全为0,则,刚才引脚的电位变化是抖动产生的.
return -1;
}
else
{
GPIO_Write(GPIOF,(GPIOF->ODR & 0xfff0 | 0x1)); //让PF3到PF0输出二进制的0001.
switch(GPIOF->IDR & 0x00f0)                //对PF4到PF7的值进行判断,以输出不同的键值。
{
case 0x0010:
// Delay_ms(5);
// if(GPIOF->IDR & 0x00f0==0x0010)
KeyVal=1;
}break;
case 0x0020: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0020)
KeyVal=2;
}break;
case 0x0040:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0040)
KeyVal=3;
}break;
case 0x0080: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0080)
KeyVal=4;
}break;
}
GPIO_Write(GPIOF,(GPIOF->ODR & 0xfff0 | 0x2)); //让PA3到PA0输出二进制的0010.
switch(GPIOF->IDR & 0x00f0)                //对PF4到PF7的值进行判断,以输出不同的键值。
{
case 0x0010:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0010)
KeyVal=5;
}break;
case 0x0020: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0020)
KeyVal=6;
}break;
case 0x0040:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0040)
KeyVal=7;
}break;
case 0x0080: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0080)
KeyVal=8;
}break;
}
GPIO_Write(GPIOF,(GPIOF->ODR & 0xfff0 | 0x4)); //让PA3到PA0输出二进制的0100.
switch(GPIOF->IDR & 0x00f0)                //对PF4到PF7的值进行判断,以输出不同的键值。
{
case 0x0010:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0010)
KeyVal=9;
}break;
case 0x0020: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0020)
KeyVal=10;
}break;
case 0x0040:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0040)
KeyVal=11;
}break;
case 0x0080: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0080)
KeyVal=12;
}break;
}
GPIO_Write(GPIOF,(GPIOF->ODR & 0xfff0 | 0x8)); //让PA3到PA0输出二进制的1000.  
switch(GPIOF->IDR & 0x00f0)                //对PF4到PF7的值进行判断,以输出不同的键值。
{
case 0x0010:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0010)
KeyVal= 13;
}break;
case 0x0020: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0020)
KeyVal=14;
}break;
case 0x0040:
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0040)
KeyVal=15;
}break;
case 0x0080: 
Delay_ms(5);
if(GPIOF->IDR & 0x00f0==0x0080)
KeyVal=16;
}break;
}
}
if((GPIOF->IDR & 0x0f00)==0x0000)  //如果,PF4到PF7全为0,则,没有键按下。此时,返回值为-1.
return -1;
else if((GPIOF->IDR & 0x0f00)==0x0000)
{
Delay_ms(5);    //延时5ms去抖动。
if((GPIOF->IDR & 0x0f00)==0x0000)  //如果,延时5ms后,PF4到PF7又全为0,则,刚才引脚的电位变化是抖动产生的.
return -1;
}
else
{
switch(GPIOF->IDR & 0x0f00)                //对PF4到PF7的值进行判断,以输出不同的键值。
{
case 0x0100:
Delay_ms(5);
if(GPIOF->IDR & 0x0f00==0x0100)
KeyVal=17;
break;
}
case 0x0200: 
Delay_ms(5);
if(GPIOF->IDR & 0x0f00==0x0200)
KeyVal=18;
break;
}
case 0x0400:
Delay_ms(5);
if(GPIOF->IDR & 0x0f00==0x0400)
KeyVal=19;
break;
}
case 0x0800: 
Delay_ms(5);
if(GPIOF->IDR & 0x0f00==0x0800)
KeyVal=20;
break;
}
}
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-5-18 10:09:21 | 显示全部楼层
是不是你的代码执行到这里就退出了?
if((GPIOF->IDR & 0x00f0)==0x0000)  //如果,PF4到PF7全为0,则,没有键按下。此时,返回值为-1.
return -1;
else if((GPIOF->IDR & 0x00f0)==0x0000)
{
Delay_ms(5);    //延时5ms去抖动。
if((GPIOF->IDR & 0x00f0)==0x0000)  //如果,延时5ms后,PF4到PF7又全为0,则,刚才引脚的电位变化是抖动产生的.
return -1;
}
返回-1,刚好是0XFF。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-5-5
在线时间
0 小时
 楼主| 发表于 2013-5-19 21:35:54 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原子哥:前面的程序是我从网上找的一个不知道哪弄错了   之后又写了一遍好了(这次改的比较少。。。。。。)  但这个程序没有按键的消抖和等待按键回复的程序  但进过调试还是能用。。。。。。。这是为什么啊  下面是程序,  还有听你说systick精确延时不要用中断  为什么  我一直用的中断。。。。。。
#include "keyboard.h" 

 void Delay(__IO u32 nCount)
{
for(; nCount != 0; nCount--);


/*本文件的函数,主要实现矩阵键盘的功能。矩阵键盘使用PA0到PA7引脚,其中,PA0到PA3固定为推挽输出,PA4到PA7固定为
下拉输入。即,无键按下时,对应PA4到PA7为0,有键按下时,PA4到PA7中,对应的引脚为高。*/

void InitKeyBoard(void) //初始化矩阵键盘要使用的GPIO口。
{
GPIO_InitTypeDef  GPIOStru;

GPIOStru.GPIO_Mode = GPIO_Mode_Out_PP;  //定义PA0到PA3为推挽输出。
    GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
    GPIOStru.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_Init(GPIOA,&GPIOStru);

GPIOStru.GPIO_Mode = GPIO_Mode_IPD;  //定义PA4到PA7为下拉输入。
    GPIOStru.GPIO_Speed = GPIO_Speed_50MHz;
    GPIOStru.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;

//因为上面定义引脚为输出时,已经打开整个GPIOA的时钟了,所以此处不再需要函数RCC_APB2PeriphClockCmd()来打开时钟了。
    GPIO_Init(GPIOA,&GPIOStru);
}
void led(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/*开启按键端口(PE5)的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
}

int keyBoard(void)  //实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。
{
int KeyVal=0;  //keyVal为最后返回的键值。
// u16 WriteVal=0;  //WriteVal为要写给PA口的数据。

GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0xf)); //先让PA0到PA3全部输出高。

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

GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x1)); //让PA3到PA0输出二进制的0001.
switch(GPIOA->IDR & 0x00f0)                 //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=1; break;
case 0x0020: KeyVal=2; break;
case 0x0040: KeyVal=3; break;
case 0x0080: KeyVal=4; break;
}

GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x2)); //让PA3到PA0输出二进制的0010.
switch(GPIOA->IDR & 0x00f0)                 //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=5; break;
case 0x0020: KeyVal=6; break;
case 0x0040: KeyVal=7; break;
case 0x0080: KeyVal=8; break;
}

GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x4)); //让PA3到PA0输出二进制的0100.
switch(GPIOA->IDR & 0x00f0)                 //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=9; break;
case 0x0020: KeyVal=10; break;
case 0x0040: KeyVal=11; break;
case 0x0080: KeyVal=12; break;
}

GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x8)); //让PA3到PA0输出二进制的1000.  
switch(GPIOA->IDR & 0x00f0)                 //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=13; break;
case 0x0020: KeyVal=14; break;
case 0x0040: KeyVal=15; break;
case 0x0080: KeyVal=16; break;
}

return KeyVal;
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-5-20 00:30:19 | 显示全部楼层
你的板子不能JTAG仿真么?
不能的话,加printf协助调试也不错.
systick延时,因为中断的调用也是需要时间的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-5-5
在线时间
0 小时
 楼主| 发表于 2013-5-31 19:02:50 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
感谢原子哥  程序调试成功了 我又加了消抖的程序
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-19 04:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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