803|11

4

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

来自新手的疑惑, [复制链接]

 

uint8_t anjian(void)

{

uint8_t a,b;

a=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);

HAL_Delay(10);

b=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);

if(a==b)

return 1;

}

———————————————————————————————————————————————————————————

while (1)

{

if(anjian()==0)

HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);

当上面的return 1;  anjian()==0改成 return 0; anjian()==1时,一个效果是按键的时候动作,一个是松开按键时动作     

 

此帖出自stm32/stm8论坛

最新回复

因为你的这个anjian()只判断了电平变化,没判断电平状态。翻转也是只判断电平变化就翻转。   详情 回复 发表于 2024-5-22 11:25
点赞 关注
 

回复
举报

6822

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

疑惑的什么呢

这段按键控制程序好像与硬件有关系吧

消抖处理了没有

此帖出自stm32/stm8论坛

点评

有延时不会抖的,存在按下按钮和松开按钮的区别,灯起始状态是灭的,第一种是按下按钮灯亮松开按钮灯保持亮,再次按下按钮灯灭松开按钮灯保持灭,改了两个地方0和1之后,变成第二种按下按钮灯一直灭松开按钮灯亮,再  详情 回复 发表于 2024-3-15 10:49
 
 

回复

6523

帖子

9

TA的资源

版主

板凳
 

anjian()==0,里面只有return 1,这样有效果吗?不知道你问的是什么效果,你应该里面设置一个变量来返回

此帖出自stm32/stm8论坛

点评

有效果的,现在是存在按下按钮和松开按钮的区别,灯起始状态是灭的,第一种是按下按钮灯亮松开按钮灯保持亮,再次按下按钮灯灭松开按钮灯保持灭,改了两个地方0和1之后,变成第二种按下按钮灯一直灭松开按钮灯亮,再  详情 回复 发表于 2024-3-15 10:51
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 

回复

6106

帖子

4

TA的资源

版主

4
 
本帖最后由 damiaa 于 2024-3-15 08:41 编辑

uint8_t anjian(void)

{

    uint8_t a,b;

    a=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);

    HAL_Delay(10);

    b=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);

    if(a==b)

        return 1;

    else

        return 0;

}

while (1)

{

    if(anjian()==0)

        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);

}

此帖出自stm32/stm8论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

5
 

我这个效果是,按一下按钮松开,亮灯,再按一下按钮松开,灭灯, 加了你这个else语句之后,按下按钮灯亮,松开灯就灭了

此帖出自stm32/stm8论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

6
 
Jacktang 发表于 2024-3-15 07:27 疑惑的什么呢 这段按键控制程序好像与硬件有关系吧 消抖处理了没有

有延时不会抖的,存在按下按钮和松开按钮的区别,灯起始状态是灭的,第一种是按下按钮灯亮松开按钮灯保持亮,再次按下按钮灯灭松开按钮灯保持灭,改了两个地方0和1之后,变成第二种按下按钮灯一直灭松开按钮灯亮,再次按下按钮灯一直亮松开按钮灯灭,还没想清楚里面的逻辑,为什么会有这种区别

此帖出自stm32/stm8论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

7
 
秦天qintian0303 发表于 2024-3-15 08:27 anjian()==0,里面只有return 1,这样有效果吗?不知道你问的是什么效果,你应该里面设置一个变量来返回

有效果的,现在是存在按下按钮和松开按钮的区别,灯起始状态是灭的,第一种是按下按钮灯亮松开按钮灯保持亮,再次按下按钮灯灭松开按钮灯保持灭,改了两个地方0和1之后,变成第二种按下按钮灯一直灭松开按钮灯亮,再次按下按钮灯一直亮松开按钮灯灭,还没想清楚里面的逻辑,为什么会有这种区别

此帖出自stm32/stm8论坛
 
 
 

回复

6106

帖子

4

TA的资源

版主

8
 

因为你的这个anjian()只判断了电平变化,没判断电平状态。翻转也是只判断电平变化就翻转。

 

如果你要具体按下亮 松开灭

就要

uint8_t anjian(void)
{
    uint8_t a,b,rt_val =2;
    a=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);
    HAL_Delay(10);
    b=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);
    if((a==GPIO_PIN_RESET)||(b ==GPIO_PIN_SET)) //上升
        rt_val =1;
   if((b==GPIO_PIN_RESET)||(a ==GPIO_PIN_SET)) //下降
        rt_val =0;       
   return rt_val;//没有动作返回2 上升返回 1 下降返回0
}

while (1)
{
    uint8_t  c =anjian();
    if( c ==0)
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);//下降点亮(这个要根据你的灯的连接方式确定)
    if( c ==1)
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);//上升灭灯(这个要根据你的灯的连接方式确定)
    // c=2 不动作
}

 

此帖出自stm32/stm8论坛
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

9
 
以下是个人觉得,详细原因写在后面的,你的可以慢慢看。
看了你的代码,你想通过在两个时刻获取到的电平不同来判断是否有按键按下,但是你的代码里面存在很严重的问题,就anjian()这个函数当中,你只做出了按键值相同时return 1,但你对于按键值不同的情况并未返回;
这就会导致一个问题,anjian()函数在按键值(a与b)不同的时候,函数的返回值到底是什么,你想的应该是0,因为你后面判断anjian()==0;但实际上这个值并不是这样的,下面就来具体说明;
在通常的arm架构芯片当中,会以寄存器r0来作为函数返回值使用,对于return 1;  anjian()==0这种情况,当按键没按下时,函数使用return 1返回,这是r0就是1,当按键按下时,函数不再是return 1返回,这时的函数没有显示的return语句,r0的值未知,可能是0,也可能不是,可能你的刚好是0,所以anjian()==0成立,就有了动作;
改成 return 0; anjian()==1时也是同理,当按键保持按下时,读到的按键值a与b的相同,使用return 0返回,这时anjian()==1不成立;当按键松开时,此时的函数返回没有使用return,r0的值就是未知的,你的可能刚好r0=1,所以anjian()==1成立,就有了动作。

如果你想问为什么这么巧合,r0前面那个就是0,后面这个就变成了1;这我想说,这涉及到编译器和处理器架构的知识,如果你完全遵循C语言的规范进行C代码开发,这些问题基本不会遇到,后面的你可以当听个笑话。
可能是受到b=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12);这句的影响,这里面可能涉及到函数返回这些,可能就修改了r0的值。
如果按下后引脚电平是低,HAL_GPIO_ReadPin就会返回0,这句就会为b赋值为0,就可能r0的值会是0,当按键按下后anjian()==0就成立了;
改成return 0; anjian()==1后,这时,b=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12)这句,HAL_GPIO_ReadPin返回1,b就会赋值成1,这时r0可能是1,所以anjian()==1就成立了

代码不止给机器用,也是给人看的,编写代码时要做到相应的规范,该写详细的地方就写详细一点,该打的括号就打上,虽然有些地方省了语法上没什么问题,但对于维护和使用代码的来说,可能带来一些麻烦。
此帖出自stm32/stm8论坛
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

10
 
本帖最后由 CrazyTT 于 2024-3-22 14:33 编辑

你想问的那个问题总结就是,anjian(void)这个函数的逻辑上还存在缺陷,语法上也有问题,缺少 a!=b 这一种情况的返回,导致在按键按下或者松开时,anjian(void)函数的返回值是不确定的,你的这个代码中这个不确定的返回值可能就刚好受 b=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12); 这句语句的影响。

 

如果按键按下后是低电平,松开后是高电平;

当按键按下时,HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12)返回0赋值给b,由于此时a与b不同,anjian(void)没有return语句,这个0同时作为了anjian(void)的返回值,也就满足了anjian()==0,所以return 1;  anjian()==0时是按下时响应;

当按键松开时,HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12)返回1赋值给b,由于此时a与b不同,anjian(void)没有return语句,这个1同时作为了anjian(void)的返回值,也就满足了anjian()==1,所以return 0;  anjian()==1时是松开时响应;

没有按键动作的时候,是通过if(a==b)这儿return返回的,return的是多少anjian()就等于多少。

 

总结一下就是,函数的逻辑要写全,需要返回值的函数,一定要显示的return,不能想当然,一定要按照规范来,不然编译器也不知道你到底想做什么。

此帖出自stm32/stm8论坛
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(中级)

11
 

还有你这个代码在编译时,应该会报警告信息,提示你anjian(void)这个函数缺少return;你可以详细去找一找,编译时的警告最好不要放过,要确定为什么会出现这个警告,明确这个警告会不会对你的代码逻辑产生影响。

此帖出自stm32/stm8论坛
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(中级)

12
 

因为你的这个anjian()只判断了电平变化,没判断电平状态。翻转也是只判断电平变化就翻转。

此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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