2486|16

3190

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

再问矩阵键盘的问题 [复制链接]

 

我用STM32写了个矩阵键盘的程序,原来是查询方式,现在改成定时器方式。

 

原理图:

void KEY_Init(void)
{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);


}
/*******************************************************************************
* 函数名 : Timer4_Init_Config
* 描述 : Timer4初始化配置
* 输入 : 无
* 输出 : 无
* 返回 : 无 
* 说明 : 无
*******************************************************************************/
void Timer4_Init_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能Timer1时钟
//设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到200为20ms)
TIM_TimeBaseStructure.TIM_Period = 199;
TIM_TimeBaseStructure.TIM_Prescaler = 7199; //设置用来作为TIMx时钟频率除数的预分频值(10KHz的计数频率)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = TIM_CKD_DIV1
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE ); //使能TIM2指定的中断

TIM_Cmd(TIM4, ENABLE); //使能TIMx外设
}


/*******************************************************************************
* 函数名 : TIM4_IRQHandler
* 描述 : 定时器2中断断服务函数
* 输入 : 无
* 输出 : 无
* 返回 : 无 
* 说明 : 无
*******************************************************************************/
void TIM4_IRQHandler(void)
{

if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
if(KeyFlag == 1)
{

hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
if (hangvalue != 0x3f) // 读出的不是0x3f说明有按键被按下
{
keynum = 0;
keyvalue = 0;
KeyFlag = 2;

GPIO_ResetBits(GPIOE,GPIO_Pin_6); //PE.6输出低 
GPIO_SetBits(GPIOE,GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3);

delay_us(XD);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);

switch (hangvalue)
{
case 0x0F:

keyvalue=4;

break;
case 0x17:

keyvalue=5;

break;
case 0x1b: 
keyvalue=1;
break;
case 0x1d:


keyvalue=2;

break;
case 0x1e: 


keyvalue=3;

break;

default: break;

}

if(keyvalue==0)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_5 ); 
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_3);

delay_us(XD);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0300)>>5);


switch (hangvalue)
{
case 0x0F:



keyvalue=9;

break;
case 0x17:


keyvalue=10;

break;
case 0x1b: 


keyvalue=6;

break;
case 0x1d:


keyvalue=7;

break;
case 0x1e: 


keyvalue=8;

break;


default: break;

}
}

if(keyvalue==0)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_4 ); 
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_3 | GPIO_Pin_5);

delay_us(XD);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);



// 第一回合中算出行号
switch (hangvalue)
{
case 0x1F:



keyvalue=14;

break;
case 0x2F:


keyvalue=15;

break;
case 0x37: 


keyvalue=16;

break;
case 0x3B:


keyvalue=11;

break;
case 0x3D: 


keyvalue=12;

break;
case 0x3E: 


keyvalue=13;

break;
default: break;

}
}
if(keyvalue==0)
{
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_5);
GPIO_ResetBits(GPIOE, GPIO_Pin_3 ); 
delay_us(XD);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);

switch (hangvalue)
{
case 0x1F:



keyvalue=20;

break;
case 0x2F:


keyvalue=21;

break;
case 0x37: 


keyvalue=22;

break;
case 0x3B:


keyvalue=17;

break;
case 0x3D: 

keyvalue=18;

break;
case 0x3E: 


keyvalue=19;

break;
default: break;

}
}
GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3); //PE.6,5,4,3 输出低 
delay_us(XD);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
while (hangvalue != 0x3f)
{
delay_us(20);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
}
KeyFlag=0;
keynum = keyvalue;
if(S0_State == (S_INIT|S_CONN))
{
S0_Data&=~S_TRANSMITOK;

Write_SOCK_Data_Buffer(0, &keynum, 1);//指定Socket(0~7)发送数据处理,端口0发送23字节数据
}
}
else
KeyFlag = 0;
}
GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3); //PE.6,5,4,3 输出低 
delay_us(XD);
hangvalue=(GPIO_ReadInputData(GPIOE)&0x07)+((GPIO_ReadInputData(GPIOB)&0x0380)>>4);
if (hangvalue != 0x3f) // 读出的不是0x3f说明有按键被按下
{
KeyFlag = 1;
}
else
KeyFlag = 0;
// led^=0x01;
// GPIO_WriteBit(GPIOE,GPIO_Pin_7,led);
}
}
按下按键测试,通过网口打印出来:

可以看到,有的按键打印两次,实际按下一次。

还有的正确键值后面跟着一个0.

请高手指教,如何解决?谢谢!

此帖出自stm32/stm8论坛

最新回复

建议你不要搞状态机,功能套死了以后不好改  详情 回复 发表于 2020-7-13 18:21
点赞 关注
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 

回复
举报

4005

帖子

0

TA的资源

版主

沙发
 
中断里不要delay,取完状态就退出
此帖出自stm32/stm8论坛
 
 

回复

4005

帖子

0

TA的资源

版主

板凳
 
没有按键中断的时候你怎么实现扫描的?
此帖出自stm32/stm8论坛

点评

那时候也有这种情况  详情 回复 发表于 2020-7-12 18:42
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

4
 
huo_hu 发表于 2020-7-12 18:10 没有按键中断的时候你怎么实现扫描的?

那时候也有这种情况

此帖出自stm32/stm8论坛

点评

几行就能搞定的事,没那么麻烦  详情 回复 发表于 2020-7-12 21:33
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

回复

7454

帖子

2

TA的资源

五彩晶圆(高级)

5
 

哪颗片子?看看有没有硬件去抖,会方便很多。

此帖出自stm32/stm8论坛

点评

STM32F103VCT6  详情 回复 发表于 2020-7-13 08:02
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

4005

帖子

0

TA的资源

版主

6
 
chenbingjy 发表于 2020-7-12 18:42 那时候也有这种情况

几行就能搞定的事,没那么麻烦

此帖出自stm32/stm8论坛
 
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

7
 
freebsder 发表于 2020-7-12 20:50 哪颗片子?看看有没有硬件去抖,会方便很多。

STM32F103VCT6

此帖出自stm32/stm8论坛
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

回复

5218

帖子

236

TA的资源

管理员

8
 

再插入代码可以试试那个代码插入功能,代码部分的可读性会高些。

 

好久不见的矩阵键盘啊,现在还有哪些场合的人机交互用这种键盘?

此帖出自stm32/stm8论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

好的。 试验机上用  详情 回复 发表于 2020-7-13 10:19
好的。试验机上用。  详情 回复 发表于 2020-7-13 10:19
 
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

9
 
nmg 发表于 2020-7-13 09:25 再插入代码可以试试那个代码插入功能,代码部分的可读性会高些。   好久不见的矩阵键盘啊,现在 ...

好的。试验机上用。

此帖出自stm32/stm8论坛
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

10
 
nmg 发表于 2020-7-13 09:25 再插入代码可以试试那个代码插入功能,代码部分的可读性会高些。   好久不见的矩阵键盘啊,现在 ...

好的。

试验机上用

此帖出自stm32/stm8论坛
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

回复

637

帖子

2

TA的资源

版主

11
 

①轻触按键一般是需要消除抖动程序的。

②检测抖动间隔时间(我自己的程序)一般是20mS~50mS;

③抖动检测可用延时或状态机完成。

延时检测抖动,不建议在中断中执行;

对于ARM的芯片,状态机效果较好。

此帖出自stm32/stm8论坛

点评

谢谢!我检测抖动不是靠延时。程序里us级的延时不是消抖,是等待电平稳定。  详情 回复 发表于 2020-7-13 15:33
 
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

12
 
dingzy_2002 发表于 2020-7-13 11:20 ①轻触按键一般是需要消除抖动程序的。 ②检测抖动间隔时间(我自己的程序)一般是20mS~50mS; ③抖 ...

谢谢!我检测抖动不是靠延时。程序里us级的延时不是消抖,是等待电平稳定。

此帖出自stm32/stm8论坛
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

回复

6069

帖子

4

TA的资源

版主

13
 

消抖要在多次中断中完成。 程序搞复杂了。

此帖出自stm32/stm8论坛

点评

谢谢!消抖具体怎么在多次中断中完成?说说思路。 我程序复杂是有原因的,列线不在一组IO口上。  详情 回复 发表于 2020-7-13 16:53
 
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

14
 
damiaa 发表于 2020-7-13 15:54 消抖要在多次中断中完成。 程序搞复杂了。

谢谢!消抖具体怎么在多次中断中完成?说说思路。

我程序复杂是有原因的,列线不在一组IO口上。

此帖出自stm32/stm8论坛
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

回复

4005

帖子

0

TA的资源

版主

15
 
按键不一定非得用中断,晚个几十毫秒处理其实是无所谓的事,取新状态保存和旧状态比较就行了,列选不规则也没关系,上来全清除然后套个switch语句就行
此帖出自stm32/stm8论坛
 
 
 

回复

4005

帖子

0

TA的资源

版主

16
 
建议你不要搞状态机,功能套死了以后不好改
此帖出自stm32/stm8论坛

点评

 谢谢!我考虑考虑  详情 回复 发表于 2020-7-13 18:33
 
 
 

回复

3190

帖子

0

TA的资源

纯净的硅(高级)

17
 
huo_hu 发表于 2020-7-13 18:21 建议你不要搞状态机,功能套死了以后不好改

 谢谢!我考虑考虑

此帖出自stm32/stm8论坛
 
个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表