上岛清风 2024-11-02 19:15 采纳率: 66.7%
浏览 19

魔女开发板第二个按键实现不了按下进行灯的亮灭翻转

以下的代码烧录进去后,第一个按键能正常实现亮灭状态改变,但是第二个不行 板子是f103rct6
main 主函数

#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"

#define GPIOB_ODR_Addr    (GPIOB_BASE+0X0C)
#define PBout(n)     *(unsigned int*)((GPIOB_ODR_Addr & 0xF0000000)+0x2000000+((GPIOB_ODR_Addr & 0x00FFFFFF)<<5)+(n<<2))

#define GPIOA_IDR_Addr    (GPIOA_BASE+0X08)
#define PAin(n)     *(unsigned int*)((GPIOA_IDR_Addr & 0xF0000000)+0x2000000+((GPIOA_IDR_Addr & 0x00FFFFFF)<<5)+(n<<2))
    
void Delay( uint32_t count)
{
    for(; count!=0;count--);
}

int main(void)
{
    
    LED_GPIO_Config();
    KEY_GPIO_Config();
#if 0
            while(1)
    {
//        GPIO_SetBits(LED_B_GPIO_PORT, LED_B_GPIO_PIN);
//        LED_R(ON);
        PBout(2) = 1;
        Delay(0xFFFFF);
        
//        GPIO_ResetBits(LED_B_GPIO_PORT, LED_B_GPIO_PIN);
//        LED_R(OFF);
        PBout(2) = 0;
        Delay(0xFFFFF);
    }

#else     
    while(1)
    {
        if( PAin(0) == KEY_ON)
        {
            while(PAin(0) == KEY_ON);
            LED_R_TOGGLE;
        }    
        if( PAin(1) == KEY_ON)
        {
            while(PAin(1) == KEY_ON);
            LED_R_TOGGLE;
        }
    } 
#endif
}

这是bsp_led.h函数

#ifndef __BSP_LED_H
#define __BSP_LED_H

#include "stm32f10x.h"

#define LED_B_GPIO_PIN         GPIO_Pin_2
#define LED_B_GPIO_PORT        GPIOB
#define LED_B_GPIO_CLK         RCC_APB2Periph_GPIOB



#define ON         1
#define OFF        0

//\ 续航符
#define LED_R(q)  if(q)\
                    GPIO_SetBits(LED_B_GPIO_PORT, LED_B_GPIO_PIN); \
                   else \
                    GPIO_ResetBits(LED_B_GPIO_PORT, LED_B_GPIO_PIN);
         
#define LED_R_TOGGLE           {LED_B_GPIO_PORT->ODR ^= LED_B_GPIO_PIN;}                   
                   
void LED_GPIO_Config(void);

#endif /*__BSP_LED_H*/



这是bsp_led.c函数

// bsp: board support package 板级支持包
#include "bsp_led.h"

void LED_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    RCC_APB2PeriphClockCmd(LED_B_GPIO_CLK, ENABLE);
    GPIO_InitStruct.GPIO_Pin = LED_B_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(LED_B_GPIO_PORT, &GPIO_InitStruct);
}


bsp_key.C 函数

#ifndef __BSP_KEY_H
#define __BSP_KEY_H

#include "stm32f10x.h"

#define KEY_ON               Bit_SET     //1
#define KEY_OFF              Bit_RESET   //0

#define KEY1_GPIO_PIN         GPIO_Pin_0
#define KEY1_GPIO_PORT        GPIOA
#define KEY1_GPIO_CLK         RCC_APB2Periph_GPIOA

#define KEY2_GPIO_PIN         GPIO_Pin_1
#define KEY2_GPIO_PORT        GPIOA
#define KEY2_GPIO_CLK         RCC_APB2Periph_GPIOA

void KEY_GPIO_Config(void);
uint8_t Key_Scanf(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin);

#endif /*__BSP_KEY_H */


bsp_key.h 函数

#include "bsp_key.h"



void KEY_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);
    GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);
    
    
    RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK, ENABLE);
    GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);
}


uint8_t Key_Scanf(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
    if(GPIO_ReadInputDataBit(GPIOx,  GPIO_Pin) == KEY_ON )
    {
        //松手检测
        while(GPIO_ReadInputDataBit(GPIOx,  GPIO_Pin) == KEY_ON);
        return KEY_ON;
    }
    else return KEY_OFF;
}


下面是按键的原理图

img

  • 写回答

1条回答 默认 最新

  • 香格里辣 2024-11-02 19:16
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    看起来你已经成功实现了第一个按键的按键控制灯的亮灭翻转,但第二个按键不能正常工作。下面我会列出几个可能的问题和建议解决方案。这些建议主要基于你提供的代码和原理图:

    问题分析:

    1. 硬件连接问题:

    确保按键与对应的GPIO引脚正确连接,特别是确保电阻和电容的值符合电路设计的要求。错误的连接方式可能导致按键无法正常工作。请检查原理图确认硬件连接是否正确。

    2. 按键的读取方式:

    你的代码中使用了Key_Scanf函数来读取按键状态,这个函数看起来是检测按键是否被按下。根据你的原理图描述,KEY2可能需要下降沿跳变触发,而你的代码中可能并未处理这种情况。在C语言中处理下降沿跳变需要更复杂的逻辑,可能需要结合定时器和中断服务程序来实现。

    3. 按键消抖问题:

    虽然你提到已经做了硬件消抖,但是有时候硬件消抖并不能完全解决抖动问题。可能还需要在软件中增加一些延时或抖动消除的逻辑来保证按键状态的准确读取。特别是在按键释放时,可能需要额外的处理来确保不会误判为按键按下。

    4. 中断处理:

    如果你使用了外部中断来检测按键状态变化,需要正确配置中断优先级和服务程序。特别是需要正确处理按键上升沿或下降沿触发的事件。这可能需要对STM32的中断系统有更深入的了解。

    解决方案:

    1. 重新检查硬件连接:

    仔细检查硬件连接是否正确,包括电阻、电容和GPIO的连接。确保所有的连接都符合电路设计的要求。

    2. 调整按键读取逻辑:

    如果确认硬件没有问题,尝试调整软件中的按键读取逻辑,特别是在处理下降沿触发的情况下。可能需要使用外部中断或定时器来检测按键的释放事件。这需要对STM32的定时器和中断系统有深入的了解。具体的代码实现方式可能因具体的STM32型号而异。建议查阅相关文档或参考手册来了解具体的实现方法。你可能还需要使用软件消抖逻辑来进一步处理可能的抖动问题。在一些应用中,可以通过增加一个短暂的延时来消除抖动对按键状态的影响。请注意这种延时不宜过长,以免影响响应速度。一般来说延时应在几十到几百毫秒之间比较合适。但是需要注意的是过于频繁的短延时可能会对系统造成压力或者引发其他问题如稳定性问题等应该根据实际需要来进行适当调整一般最佳做法是编写一组针对各个操作的专用的函数避免在同一主函数中对某个任务重复的操作处理一般的控制程序的调试还需要进一步查看延时执行的条件设置以及按键相关控制参数的初始化等等注意虽然每个功能逻辑可能是独立的但其调试还是涉及到代码逻辑的连续性问题当出现问题时往往需要综合考虑所有可能的因素进行分析调试包括程序流程是否正确代码逻辑是否清晰以及代码是否简洁等以便找出问题的根源并解决它。在调试过程中可能还需要使用调试工具如调试器或仿真器来帮助定位和解决问题同时也要注意调试时要一步步执行以避免跳步带来的难以预见的问题这些问题解决之后就能够找到最适合实现代码功能需求并且又能高效稳定运行的最佳方法从而提高整个系统的稳定性和可靠性同时也要注意在编写代码时尽量遵循良好的编程习惯和规范以提高代码的可读性和可维护性从而更好地满足项目的需求和要求从而完成项目的目标同时也要充分考虑到安全性和健壮性对于重要的功能模块应当进行全面的测试和验证以确保其在各种条件下都能正常运行并具有很高的稳定性和可靠性保证产品的安全性和稳定性并能够在实际应用中发挥最大的作用以实现项目的最终目标同时也要注意不断学习和掌握新的技术和工具以提高自身的技能和知识水平从而更好地适应不断变化的市场需求和技术发展更好地完成项目的开发和实现目标最终保证项目的成功实现并能够取得良好的效果满足用户的需求和要求从而带来良好的效益和影响#### 无 论采用哪种方法重要的是要注意调整并实现最有效的方法来满足实际需求以达到最好的效果和表现以便获得更大的成功和问题解决方法尝试运行不同的测试代码并在实践中不断改进和完善以满足实际应用的特定需求和问题在这个过程中也要不断地反思和总结以更好地理解问题并提高解决问题的能力以便在未来遇到类似问题时能够更加熟练地应对并能够独立解决问题 总之要保证硬件连接的准确性处理好软件的逻辑并且不断的实践学习提高自己的技术能力最终一定能成功解决问题 实现代码功能并实现项目目标希望我的回答能够帮助到您并且带来实际的帮助祝您项目成功并顺利实现目标

    评论

报告相同问题?

问题事件

  • 修改了问题 11月2日
  • 修改了问题 11月2日
  • 创建了问题 11月2日