OpenEdv-开源电子网

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

按键输入实验的问题

[复制链接]

8

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2011-11-10
在线时间
0 小时
发表于 2011-11-10 23:45:15 | 显示全部楼层 |阅读模式
小弟初来乍到,遇到如下问题:

 u8 KEY_Scan(void)

 static u8 key_up=1;//按键按松开标志 
 //JTAG_Set(JTAG_SWD_DISABLE);
 if(key_up&&(KEY0==0||KEY1==0||KEY2==1))
 {
  delay_ms(10);//去抖动
  key_up=0;
  if(KEY0==0)
  {
  // JTAG_Set(SWD_ENABLE);
   return 1;
  }
  else if(KEY1==0)
  {
  // JTAG_Set(SWD_ENABLE);
   return 2;
  }
  else if(KEY2==1)
  {
  // JTAG_Set(SWD_ENABLE);
   return 3;
  }
 }else if(KEY0==1&&KEY1==1&&KEY2==0)key_up=1;     
// JTAG_Set(SWD_ENABLE);
 return 0;// 无按键按下
}

以上代码中看似key_up没什么用处。但是我删掉之后仿真开发板,led灯好像就不太听使唤了。各位前辈高手能否指点一下key_up变量到底起到什么作用啊,为什么不能没有??
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

13

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2011-11-9
在线时间
0 小时
发表于 2011-11-11 00:54:55 | 显示全部楼层
回复【楼主位】llwwzz2007:
-----------------------------
在这样程序里是有用的,我不知道你删是删成什么样了, key_UP在这里是做判断用的,与按键值相与(&)如果不为0 说明有按键按下
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-11 01:36:22 | 显示全部楼层
回复【楼主位】llwwzz2007:
---------------------------------
防止一次按下多次触发.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2011-11-10
在线时间
0 小时
 楼主| 发表于 2011-11-14 00:13:04 | 显示全部楼层
u8 KEY_Scan(void)
{  
 //static u8 key_up=1;//按键按松开标志 
 //JTAG_Set(JTAG_SWD_DISABLE);
 if((KEY0==0||KEY1==0||KEY2==1))
 {
  delay_ms(10);//去抖动
  //key_up=0;
  if(KEY0==0)
  {
  // JTAG_Set(SWD_ENABLE);
   return 1;
  }
  else if(KEY1==0)
  {
  // JTAG_Set(SWD_ENABLE);
   return 2;
  }
  else if(KEY2==1)
  {
  // JTAG_Set(SWD_ENABLE);
   return 3;
  }
 }else if(KEY0==1&&KEY1==1&&KEY2==0);//key_up=1;     
// JTAG_Set(SWD_ENABLE);
 return 0;// 无按键按下

如上,就是将key_up的句子注释掉啊。
key_up如何起到防止一次按下多次触发”的作用呢?

谢谢两位的指点哈。 


回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-14 01:04:20 | 显示全部楼层
回复【4楼】llwwzz2007:
---------------------------------
这个比较简单,好好推理一下,就容易了.用假定法,自己试着推导下吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2011-11-14
在线时间
2 小时
发表于 2011-11-14 21:03:29 | 显示全部楼层
按下一次,确保led0或者led1的状态只变化一次,防止变化两次或两次以上,我的理解 不知对否,哈哈。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2011-11-8
在线时间
0 小时
发表于 2011-11-14 22:40:26 | 显示全部楼层
我改了一下按键的判断部分。按键就很灵敏了。 加了一松开再执行就很稳定了。

#include<stm32f10x_lib.h>
#include"key.h"
#include"delay.h"

void KEY_Init(void)
{
RCC->APB2ENR|=1<<2;    //使能PORTA时钟
GPIOA->CRL&=0XFFFFFFF0;    //使PA0设置成输入
GPIOA->CRL|=0X00000008;
GPIOA->CRH&=0X0F0FFFFF;    //PA13,15设置成输入
GPIOA->CRH|=0X80800000;    

GPIOA->ODR|=1<<13;    //PA13上拉,PA0默认下拉
GPIOA->ODR|=1<<15;    //PA15上拉

}

u8 KEY_Scan(void)
{
u8 Value;
Value = 250;
if(KEY0 ==0 || KEY1 ==0 || KEY2 ==1)
{
delay_ms(10);//去抖动
if(KEY0==0)
{
while((KEY0==0) && (Value>0))
{
Value--;
delay_ms(1);
}
return 1;
}

if(KEY1==0)
{
while((KEY1==0) && (Value>0))
{
Value--;
delay_ms(1);
}
return 2;
}
if(KEY2==1)
{
while((KEY2==1) && (Value>0))
{
Value--;
delay_ms(1);
}
return 3;
}

}
return 0;//没有键按下返回0
}


主函数

int main(void)
{
u8 Value;
Value =0;

Stm32_Clock_Init(9);
delay_init(72);
LED_Init();
KEY_Init();
while(1)
{
Value=KEY_Scan();
switch(Value)
{
case 1ED0 = !LED0;break;
case 2ED1 = !LED1;break;
case 3ED0 =!LED0;LED1 = !LED1;break;
}

}
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-15 00:42:02 | 显示全部楼层
大家可以自由发挥的.
如果觉得不错的,可以分享给我们.让更多人开阔视野.呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

101

帖子

2

精华

中级会员

Rank: 3Rank: 3

积分
493
金钱
493
注册时间
2011-9-6
在线时间
3 小时
发表于 2011-11-17 17:19:14 | 显示全部楼层
经典按键扫描程序http://www.openedv.com/posts/list/1722.htm
事无巨细 循序渐进
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2011-11-19
在线时间
2 小时
发表于 2011-11-19 19:32:04 | 显示全部楼层
我在按键这里也有个问题:
这个GPIO口在复位后是高阻态,引脚是低电平,各引脚其对应IDR值为0。当我们设置口功能为输入时即使按键没有按下,按照原子大侠写的程序,会被判定为按键已按下。这里是不是应该将按键设计为摁下后送入高电平呢?
回复 支持 反对

使用道具 举报

7

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2011-11-9
在线时间
0 小时
发表于 2011-11-19 21:04:16 | 显示全部楼层
回复【10楼】a88525:
---------------------------------
根据原理图:KEY0和KEY1是低电平有效,即当KEY1和KEY0按下时,对应的引脚上检测到的会是低电平,而KEY_UP刚好和二者相反。
互帮互助,共同进步
回复 支持 反对

使用道具 举报

8

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2011-11-10
在线时间
0 小时
 楼主| 发表于 2011-11-23 22:31:41 | 显示全部楼层
还是老大说得对哈,用假设推理就可以了:
当按下某个按键时,第一个if条件为真,程序往下执行,所以key_up=0,return某个对应值1~3.
若此时按键没抬起,主程序再次执行按键扫描程序时第一个if条件不再满足,因此执行else后面的语句,执行完后仍然有key_up=0
按键抬起后第一个条件仍不满足,但满足最后一个判断所有键都松开的if条件,因此key_up=1,从而可以响应下一次按键!!

呵呵,不容易哦,俺竟然还有一点逻辑能力哈。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-23 23:01:25 | 显示全部楼层
回复【12楼】llwwzz2007:
---------------------------------
呵呵.理解正确!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2011-12-4
在线时间
4 小时
发表于 2011-12-4 21:19:46 | 显示全部楼层
改了下按键, 很灵敏,有长按功能, 但是发现KEY2按下就有点假死的感觉,KEY0,KEY1非常灵敏。不知道为什么KEY2会有问题,求指教

u8 KEY_Scan(void)
{
u8 key_return=0,key_temp=0;    //返回的按键值,按键情况
static u8 key_state=0,key_time=0,key_last=0; //按键状态,按键按下的时间计数器,上次按键值
JTAG_Set(JTAG_SWD_DISABLE);
if(KEY0==0)key_temp = 1;
if(KEY1==0)key_temp = 2;
if(KEY2==1)key_temp = 3;
switch (key_state)
{
    case 0:       //状态0
    if(key_temp!=0)    //检测到有按键,转到状态1,相当于是消抖过程
{
key_state=1;
}
break;
case 1:     //状态1,有按键按下
if(key_temp!=0)    //再次检测到有按键,转到状态2
{
key_state=2;
key_time=0;   //清零按键时间计数器
key_last=key_temp; //保存键值,以便在释放按键状态返回键值  
}
else
{
key_state=0; //没有检测到按键,说明初始状态检测到是一个抖动,重新转到状态0
}
break;
case 2: //状态2,按键长按
if(key_temp==0)    //检测到按键松开
{
key_state=0; //状态转到初始状态
key_return=(key_last|0x10);   //输出"单击"的按键值
}
else
{
if(++key_time>=50)    //按下时间>1s
{
key_state=3;   //转到松开状态
key_time=0;   //清零按键时间计数器
}
}
break;
case 3:
if(key_temp==0)    //检测到按键松开
{
key_state=0; //状态转到初始状态
}
else
{
if(++key_time>=25)    //按下时间>0.5s
{
key_time=0;   //清零按键时间计数器
key_return=(key_last|0x20);    // 输出"连击"的按键值
}
}
break;
}
JTAG_Set(SWD_ENABLE);
return key_return;
}



-----------------------------------------------------------------------------------
int main(void)
{
u8 t;
u8 len;
u16 times=0;  
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72);      //延时初始化 
uart_init(72,9600);  //串口初始化为9600
LED_Init();     //初始化与LED连接的硬件接口    
while(1)
{
t = KEY_Scan();
if(t==0x11)printf(" 按键1按下\n");  
if(t==0x12)printf(" 按键2按下\n"); 
if(t==0x13)printf(" 按键3按下\n"); 
if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
delay_ms(10);   
}  
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-12-4 22:03:16 | 显示全部楼层
具体什么现象?可以软件仿真看看.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2011-12-4
在线时间
4 小时
发表于 2011-12-4 22:11:12 | 显示全部楼层
还没用软件仿,就是这个按1,2键的时候。非常好用。 一按就有输出。不会多也不会少
但是按3键, 只要按一次, 就卡在那了,按完3再按1,2键都没反应了,要复位并且要重新打开串口调试助手才能有输出。
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2011-12-4
在线时间
4 小时
发表于 2011-12-4 22:53:42 | 显示全部楼层
回复【16楼】icgra:
还没用软件仿,就是这个按1,2键的时候。非常好用。 一按就有输出。不会多也不会少
但是按3键, 只要按一次, 就卡在那了,按完3再按1,2键都没反应了,要复位并且要重新打开串口调试助手才能有输出。
---------------------------------
问题找到了,按键扫描时间有问题,没有用定时做,扫描时间的问题。在主程序改扫描时间就行了。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2012-7-6
在线时间
2 小时
发表于 2012-7-6 15:21:54 | 显示全部楼层
我想问问,switch (key_state) 后break跳出后,从u8 key_return=0,key_temp=0;    重新开始还是switch (key)开始
回复 支持 反对

使用道具 举报

18

主题

158

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
400
金钱
400
注册时间
2011-11-23
在线时间
0 小时
发表于 2012-7-24 10:33:18 | 显示全部楼层
回复【18楼】yang0354215:
---------------------------------
如果执行了break语句,直接跳出switch语句,执行switch后面语句
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-31
在线时间
0 小时
发表于 2013-3-31 12:43:15 | 显示全部楼层
新手第一次求教,思考了很久没懂。。在按键输入这个实验,仿真过程,开发指南截图如下第一附图,我的仿真第二幅图(用提供的代码)。
二者不一样,主要在于porte.2恢复高电平,porte.3变为低电平后,porte.5我仿真没有变化,与我对代码的理解效果一样。一开始,porte.2变为低电平,portb.5发生变化,此时m=0。接着改变porte2和porte.3,运行由于对于m=0,两个if都不成立。故没有变化。
如果先恢复porte.2为高电平,运行一下,符合后面一个if,m=1,再运行porte.3  则,porte.5发生变化。如第三幅图
跪求大神们告诉我问题在哪儿??开发指南中的效果是怎么出来的??T.T






回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-31
在线时间
0 小时
发表于 2013-3-31 12:48:23 | 显示全部楼层
回复【13楼】正点原子:
---------------------------------
大哥,求看19楼,多谢!
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-31
在线时间
0 小时
发表于 2013-3-31 14:52:37 | 显示全部楼层
回复【13楼】正点原子:
---------------------------------
在线等解答
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-31 15:06:35 | 显示全部楼层
截图没完整...
看不到哪个对哪个信号。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-31
在线时间
0 小时
发表于 2013-3-31 15:09:51 | 显示全部楼层
回复【23楼】正点原子:
---------------------------------
跟开发指南那副图顺序是一样的,按照开发指南一步步走的
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-31 15:27:15 | 显示全部楼层
默认出来的时候,就要勾选PE2,3,4。因为这几个是有上拉的,所以在执行第一次扫描之前,就应该设置PE2,3,4为高。
然后再执行扫描,之后按手册介绍仿真,就得到手册的图片了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-31
在线时间
0 小时
发表于 2013-3-31 15:40:21 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
是的,我勾选了也不一样。一开始,porte.2变为低电平,portb.5发生变化,此时key_up=0。接着,
①如果同时改变porte2(变高)和porte.3(变低有效),运行由于对于key_up=0 ,这时return还是0,porte.5没法变化,不是吗?
②如果先改变porte2(变高),运行一下,由于 else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)key_up=1;这时再改变porte.3(变低有效)运行,porte.5才发生改变
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-31 16:55:24 | 显示全部楼层
回复【26楼】perseverance:
---------------------------------
别纠结了
直接下载代码,测试下吧。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2013-8-30
在线时间
0 小时
发表于 2013-10-23 15:15:25 | 显示全部楼层
你好,,回复【21楼】perseverance:
---------------------------------
大侠,你引用的这个程序行吗,,怎么我下了这个代码,Mini板的跑马灯没有现象啊,这是什么情况 啊,大侠
u8 KEY_Scan(void) 

u8 key_return=0,key_temp=0;    //返回的按键值,按键情况 
static u8 key_state=0,key_time=0,key_last=0; //按键状态,按键按下的时间计数器,上次按键值 
JTAG_Set(JTAG_SWD_DISABLE); 
if(KEY0==0)key_temp = 1; 
if(KEY1==0)key_temp = 2; 
if(KEY2==1)key_temp = 3; 
switch (key_state) 

    case 0:       //状态0 
    if(key_temp!=0)    //检测到有按键,转到状态1,相当于是消抖过程 

key_state=1; 

break; 
case 1:     //状态1,有按键按下 
if(key_temp!=0)    //再次检测到有按键,转到状态2 

key_state=2; 
key_time=0;   //清零按键时间计数器 
key_last=key_temp; //保存键值,以便在释放按键状态返回键值   

else 

key_state=0; //没有检测到按键,说明初始状态检测到是一个抖动,重新转到状态0 

break; 
case 2: //状态2,按键长按 
if(key_temp==0)    //检测到按键松开 

key_state=0; //状态转到初始状态 
key_return=(key_last|0x10);   //输出"单击"的按键值 

else 

if(++key_time>=50)    //按下时间>1s 

key_state=3;   //转到松开状态 
key_time=0;   //清零按键时间计数器 


break; 
case 3: 
if(key_temp==0)    //检测到按键松开 

key_state=0; //状态转到初始状态 

else 

if(++key_time>=25)    //按下时间>0.5s 

key_time=0;   //清零按键时间计数器 
key_return=(key_last|0x20);    // 输出"连击"的按键值 


break; 

JTAG_Set(SWD_ENABLE); 
return key_return; 




----------------------------------------------------------------------------------- 
int main(void) 

u8 t; 
u8 len; 
u16 times=0;   
Stm32_Clock_Init(9); //系统时钟设置 
delay_init(72);      //延时初始化  
uart_init(72,9600);  //串口初始化为9600 
LED_Init();     //初始化与LED连接的硬件接口     
while(1) 

t = KEY_Scan(); 
if(t==0x11)printf(" 按键1按下\n");   
if(t==0x12)printf(" 按键2按下\n");  
if(t==0x13)printf(" 按键3按下\n");  
if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行. 
delay_ms(10);    
}   
}
人生需要不断的进取。。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2014-3-4
在线时间
0 小时
发表于 2014-3-13 20:49:14 | 显示全部楼层
回复【12楼】llwwzz2007:
---------------------------------
      若此时按键没抬起,主程序再次执行按键扫描程序时第一个if条件不再满足,后面的else if 条件也不满足,都不执行,所以key_up依然等于0。 
    如果没有key-up的话,虽然会一次按键多次触发,但是多次触发的返回值都是同一个,又有何不可呢?  
  迷惑啊!!!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2014-3-27
在线时间
2 小时
发表于 2014-5-7 14:51:17 | 显示全部楼层
每次执行扫描函数的时候 不是都有 static u8 key_up=1;这个语句把key_up拉高了吗?又怎么能实现连续按和不连续按的呢?很不解...有个按键被按下 的确key_up =0了,但是下次再执行scan()的时候 不是又 static u8 key_up=1拉高了吗
一花一世界,一叶一追寻。一曲一场叹,一生为一人!!
回复 支持 反对

使用道具 举报

12

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
360
金钱
360
注册时间
2014-5-14
在线时间
56 小时
发表于 2014-5-25 13:35:13 | 显示全部楼层
测试了源程序,实现不了连续和不连续按键,无论mod值为多少,都是一样,只要按下就连续触发,问题同楼上,求原子哥指点!
有梦想,哪里都是你的舞台。哪怕从零开始,日积月累。终将厚积薄发!
回复 支持 反对

使用道具 举报

4

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-8-17
在线时间
1 小时
发表于 2014-8-17 21:40:48 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
为什么我这么写也能多次触发呢?

int main(void)
{
   int ww=1,ee=0;
     int key_up=1;
    buzzer_init();
    KEY_Init();
    led_init();
while(1)
{
   
//  ww=((GPIOE->IDR)>>3)&1;
// 
//  if((ww==0)&&key_up)
//  {
//  delay(240);
//  key_up=0;
//       if(ww==0)
//  {GPIOB->ODR=ee<<5;
//    ee=!ee;}
//  }else  if(ww==1)key_up=1;
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-8-17 22:18:08 | 显示全部楼层
回复【32楼】qnmlgb:
---------------------------------
你这代码都被你注释了...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2014-9-11
在线时间
4 小时
发表于 2014-9-15 18:09:50 | 显示全部楼层
回复【26楼】perseverance:
---------------------------------
      楼上正解。
      我软仿这里的时候也出现了这个问题,当同时把PORTE.2改为高并把PORTE.3改为低时,输出PORTE.5是无法变化的,因为此时扫描程序返回的依然是0。
      原子哥这里在single模式下,key_up置位的唯一条件就是:四个输入按键都不按下的前提下,刷一遍扫描程序。
      所以在single模式下,就会出现,下载到板子上时,按住一个按键,再按下另一个按键时是没有现象的(无论优先级高低),因为这是无法满足else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)这个条件。
      另外,个人觉得,所谓的signle模式,实际当中的效果相当于“松手检测“,目的是防止一按多响效应,只是这里是按下即有效。
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2015-3-13
在线时间
1 小时
发表于 2015-3-13 15:53:19 | 显示全部楼层
//mode为0时候,即使长按,因为key_up为0,不会再进入if((key_up)&&(KEY0==0||KEY1==0))的处理语句内,
//从而t的值也不会改变,从而此处理函数一直执行;mode=1,连按每次还是进处理语句,且返回的t值不变,这样感觉mode=1多余
mode为0为1都可以实现长按,区别是是否会再次判断
回复 支持 反对

使用道具 举报

13

主题

201

帖子

0

精华

高级会员

Rank: 4

积分
671
金钱
671
注册时间
2015-4-26
在线时间
173 小时
发表于 2015-12-14 09:56:44 | 显示全部楼层
回复【13楼】正点原子:
---------------------------------
原子哥为什么我这样按照程序设置,将PA3和PA14都接电平的时候还是显示0x55?
void KEY_Init(void) 
  GPIO_InitTypeDef GPIO_InitStructure;
//init GPIOA.3,GPIOA.14  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 

  GPIO_Init(GPIOA, &GPIO_InitStructure);
//init GPIOA.0   
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 

GPIO_Init(GPIOA, &GPIO_InitStructure);

这两个程序是分开的
 void key_deal(void)
 {
 key_value = key_detetc();//扫描按键值  
 if(key_value==3)//两个按键都按下
 {
  send_state();
  USART1->DR=0xaa;
  while((USART1->SR&0X40)==0);//等待发送结束
 }
 else if(key_value==0)//两个按键都没有按下
 {
  send_state();
  USART1->DR=0x55;
  while((USART1->SR&0X40)==0);//等待发送结束
 }
 else
 {
 send_state();
  USART1->DR=0xff;
  while((USART1->SR&0X40)==0);//等待发送结束
 }
 }
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-21 07:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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