OpenEdv-开源电子网

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

求帮忙看一下这段实战篇按键的代码

[复制链接]

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
发表于 2018-10-6 09:51:54 | 显示全部楼层 |阅读模式
5金钱
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return 1;
else if(KEY1==0)return 2;
else if(KEY2==0)return 3;
else if(WK_UP==1)return 4;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0; //无按键按下
}  


这段代码是开发板实战篇里按键联系的代码。
哪位大神能帮忙解释一下标红的这句话的涵义啊,从代码逻辑来看,我怎么觉得无论mode是0还是1,最后key_up都会被赋值为1呢,但是实际情况mode不一样,确实会出现不一样的现象,求解惑为什么会这样。

最佳答案

查看完整内容[请看2#楼]

明白了,静态局部变量的坑。。。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
 楼主| 发表于 2018-10-6 09:51:55 | 显示全部楼层
明白了,静态局部变量的坑。。。
回复

使用道具 举报

90

主题

534

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1059
金钱
1059
注册时间
2017-4-12
在线时间
280 小时
发表于 2018-10-8 11:31:32 | 显示全部楼层
这不是坑 这是设计,
穷不可怕,可怕的是穷的是我~~~
回复

使用道具 举报

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
 楼主| 发表于 2018-10-8 18:23:51 | 显示全部楼层
烈日灼心 发表于 2018-10-8 11:31
这不是坑 这是设计,

为啥要这么设计呢,可读性很差啊
回复

使用道具 举报

90

主题

534

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1059
金钱
1059
注册时间
2017-4-12
在线时间
280 小时
发表于 2018-10-9 09:02:25 | 显示全部楼层
GAOSIY 发表于 2018-10-8 18:23
为啥要这么设计呢,可读性很差啊

可读性差是你C太差了,这样修饰的变量用完不会释放内存
穷不可怕,可怕的是穷的是我~~~
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2018-10-9 09:03:29 来自手机 | 显示全部楼层
这是实战的代码?
回复

使用道具 举报

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
 楼主| 发表于 2018-10-14 18:55:57 | 显示全部楼层
yklstudent 发表于 2018-10-9 09:03
这是实战的代码?

对的,实战代码
回复

使用道具 举报

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
 楼主| 发表于 2018-10-14 18:58:11 | 显示全部楼层
烈日灼心 发表于 2018-10-9 09:02
可读性差是你C太差了,这样修饰的变量用完不会释放内存

你说的这个是原理,我看了静态局部变量就已经了解了,但问题是为什么要这么做,这么做的好处是啥,比如说减少代码量?
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2018-10-14
在线时间
5 小时
发表于 2018-10-14 19:19:40 | 显示全部楼层
本帖最后由 萌萌的小x盆友 于 2018-10-14 19:26 编辑

原子按键 支持多键同时连按;
;
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,KEY_UP按下 即WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY_UP!!
u8 KEY_Scan(u8 mode)
{         
        static u8 key_up=1;//按键按松开标志
        u8 temp;
        if(mode==0xFF)                //模式0xFF 支持所有按键同时扫描
        {
          temp = 0;
                if(KEY0==0) temp |= 1<<0;   //位0_KEY0
                if(KEY1==0) temp |= 1<<1;   //位1_KEY1
                if(KEY2==0) temp |= 1<<2;   //位2_KEY2
                if(WK_UP==1) temp |= 1<<3;  //位3_WK_UP
                return  temp;                //返回所有按键状态
        }
        
        if(mode)key_up=1;  //支持连按
        if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
        {
                delay_ms(10);//去抖动
                key_up=0;
                if(KEY0==0)return 1;
                else if(KEY1==0)return 2;
                else if(KEY2==0)return 3;
                else if(WK_UP==1)return 4;
        }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;            
         return 0;// 无按键按下
}.
//////////////////////////////////////////////.
说明: 本来是要对多键同时进行解码, 来替换原子操作, 但考虑到原子为单键程序, 不过多键同时可以打游戏, 对要求高的地方用
回复

使用道具 举报

6

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
96
金钱
96
注册时间
2018-8-23
在线时间
12 小时
 楼主| 发表于 2018-10-15 08:43:53 | 显示全部楼层
萌萌的小x盆友 发表于 2018-10-14 19:19
原子按键 支持多键同时连按;
;
//按键处理函数

给力         
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2018-10-14
在线时间
5 小时
发表于 2018-10-16 09:37:02 | 显示全部楼层
本帖最后由 萌萌的小x盆友 于 2018-10-16 09:43 编辑

支持软件按键, 串口Usmart 发 KEY0_DOWN_Soft(); =key0;
.
同时代码更高明, 并支持之前所有功能;
///////////////////////////////////////////////.
/********************************************************************************/
u8  KEY_Soft_State = 0;                 //软件触发标志
/********************************************************************************/
//按键初始化函数
void KEY_Init(void)
{
        GPIO_InitTypeDef  GPIO_Structure;        //GPIO 结构体初始化
       
        /*** 打开GPIO 端口时钟 ***/
        __HAL_RCC_GPIOA_CLK_ENABLE();                  //GPIOA 时钟
        __HAL_RCC_GPIOC_CLK_ENABLE();                  //GPIOH 时钟
       
        /*** GPIO 初始化 ***/
        GPIO_Structure.Pin = GPIO_PIN_5;               //KEY1
        GPIO_Structure.Mode = GPIO_MODE_INPUT;         //输入
        GPIO_Structure.Speed = GPIO_SPEED_FREQ_HIGH;   //高速 (108/2)MHZ
        GPIO_Structure.Pull = GPIO_PULLUP;             //上拉
        HAL_GPIO_Init(GPIOA, &GPIO_Structure);         //初始化 GPIO
       
        /*** GPIOC 初始化 ***/
        GPIO_Structure.Pin = GPIO_PIN_13;              //KEY0
        HAL_GPIO_Init(GPIOC, &GPIO_Structure);         //初始化GPIO
}
/********************************************************************************/
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按; 0xFF,所有按键同时连按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,KEY_UP按下 即WK_UP
//同时按下,只会出现最后一个检测
u8 KEY_Scan(u8 mode)
{         
        static u8 key_sta=0; //按键按下标志
        u8 temp=0, res, i;

//        if(KEY0==0||KEY1==0||KEY2==0||WK_UP==1)     //检查按键是否动作
        if(KEY0==0||KEY1==0)     //检查按键是否动作
        {
                delay_ms(10);               //去抖动
                if(KEY0==0) temp |= 1<<0;   //位0_KEY0
                if(KEY1==0) temp |= 1<<1;   //位1_KEY1
//                if(KEY2==0) temp |= 1<<2;   //位2_KEY2
//                if(WK_UP==1) temp |= 1<<3;  //位3_WK_UP
        }
        if(KEY_Soft_State)            //检测到软件按键
        {
                temp = KEY_Soft_State; KEY_Soft_State = 0; return  temp;
        }
       
        if(mode)key_sta=0;  //支持连按
        if(mode==0xFF) return  temp;       //模式 0xFF 支持所有按键同时连按
        else
        {
                res = 0;
                for(i=0;i < 8;i++)                   //同时按下,只会出现最后一个检测
                {
                        if((temp&(1<<i)) || (key_sta&(1<<i))) //当前按键需要处理(已按下||需要标记按键弹起)
                        {
                                if((temp&(1<<i)) && (key_sta&(1<<i))==0) //检测到按下, 按键之前为释放
                                {
                                        key_sta |= 1<<i;               //保存当前按下的按键
                                        res = i+1;                       //返回当前扫描序号
                                }else if((temp&(1<<i))==0 && (key_sta&(1<<i))) //检测到弹起, 按键之前为按下
                                {
                                  key_sta &= ~(1<<i);            //清除当前按下的按键
                                }
                        }
                }
        }
        return  res;
}
/********************************************************************************/
/*** 虚拟按键函数 ***/

u8  KEY0_DOWN_Soft(void)    {KEY_Soft_State = KEY0_PRES; return 0;}
u8  KEY1_DOWN_Soft(void)    {KEY_Soft_State = KEY1_PRES; return 0;}
u8  KEY2_DOWN_Soft(void)    {KEY_Soft_State = KEY2_PRES; return 0;}
u8  KEY3_DOWN_Soft(void)    {KEY_Soft_State = KEY3_PRES; return 0;}
u8  WKUP_DOWN_Soft(void)    {KEY_Soft_State = WKUP_PRES; return 0;}
/********************************************************************************/
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-8 21:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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