Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
STM32 Discovery能否区分短按键和长按键_C_Stm32f4discovery - Fatal编程技术网

STM32 Discovery能否区分短按键和长按键

STM32 Discovery能否区分短按键和长按键,c,stm32f4discovery,C,Stm32f4discovery,如果我能在我的项目中实现长按钮和短按钮,它将派上用场。我正在使用STM32F4发现工具包并用C编程。我准备了一个引脚作为外部输入,修改了中断处理程序 模式: 现在,我把它设置为在下降和上升时触发。我看不到明显的方法来检测长推和短推。有什么办法吗?一个选项是按下按钮后立即启动计时器,松开按钮后停止计时器。根据计时器中经过的滴答声的数量,您可以采取正确的操作,但是您需要确定滴答声的阈值数量,以区分长按和短按 作为对上述建议的改进。您可以配置为IO中断源,而不是将按钮连接的引脚配置为GPIO。此方法

如果我能在我的项目中实现长按钮和短按钮,它将派上用场。我正在使用STM32F4发现工具包并用C编程。我准备了一个引脚作为外部输入,修改了中断处理程序

模式:


现在,我把它设置为在下降和上升时触发。我看不到明显的方法来检测长推和短推。有什么办法吗?

一个选项是按下按钮后立即启动计时器,松开按钮后停止计时器。根据计时器中经过的滴答声的数量,您可以采取正确的操作,但是您需要确定滴答声的阈值数量,以区分长按和短按


作为对上述建议的改进。您可以配置为IO中断源,而不是将按钮连接的引脚配置为GPIO。此方法也有助于您解决谴责问题。

一个选项是,按下按钮后立即启动计时器,松开按钮后停止计时器。根据计时器中经过的滴答声的数量,您可以采取正确的操作,但是您需要确定滴答声的阈值数量,以区分长按和短按


作为对上述建议的改进。您可以配置为IO中断源,而不是将按钮连接的引脚配置为GPIO。此方法也有助于您解决谴责问题。

第一个EXTI中断对按钮非常有害。您应该使用定时器中断并定期检查按钮的状态。即使你有一个电容器,它可能不足以与老化按钮去抖动

你可以看到我的按钮库-长,短,双击,任何数量的按钮


第一个EXTI中断对按钮非常有害。您应该使用定时器中断并定期检查按钮的状态。即使你有一个电容器,它可能不足以与老化按钮去抖动

你可以看到我的按钮库-长,短,双击,任何数量的按钮


是的,这是可行的,在STM32上的中断处理程序中有一个解决方案

全球变量:

static uint32_t lastUserButtonI = 700;
static uint32_t lastUserButtonRisingI = 700;
static uint32_t lastUserButtonFallingI = 700;
HAL\u GPIO\u EXTI\u Callback()中

uint32\u t now=HAL\u GetTick();
uint8_t rising=HAL_GPIO_ReadPin(按钮\u GPIO_端口,pButton);
如果((lastEdge==上升)||

(rising==0&((now-lastUserButtonFallingI)是的,这是可行的,在STM32上的中断处理程序中有一个解决方案

全球变量:

static uint32_t lastUserButtonI = 700;
static uint32_t lastUserButtonRisingI = 700;
static uint32_t lastUserButtonFallingI = 700;
HAL\u GPIO\u EXTI\u Callback()中

uint32\u t now=HAL\u GetTick();
uint8_t rising=HAL_GPIO_ReadPin(按钮\u GPIO_端口,pButton);
如果((lastEdge==上升)||

(上升==0&((现在-lastUserButtonFallingI)1.我想创建一个按钮读取结构,它不会中断主返回流和长、短推状态。这不是一个按钮吗?保存数据集的BT_User_State变量,button pressed long,pressed short?我定义了两个单独的BT_User_Flag_ShortPress和BT_User_Flag_LongPress变量将数据加上一个BT_User_时间变量,该变量将在持续时间内保持不变

typedef enum{
Flag_Reset,
Flag_Set
}   Button_Flag;

typedef enum{
Button_Released,
Button_Pressed
}   Button_State;

Button_State    BT_User_State = Button_Released;
Button_Flag     BT_User_Flag_ShortPress = Flag_Reset;
Button_Flag     BT_User_Flag_LongPress = Flag_Reset;
uint16_t        BT_User_Time = 0;
2.每1ms还有一个计时器。完成此操作后,计时器溢出:

if(HAL_GPIO_ReadPin(BT_User_GPIO_Port, BT_User_Pin) == GPIO_PIN_SET)
{
   BT_User_State = Button_Pressed;
   BT_User_Time++;
} 
else 
{
   if(BT_User_Time >= 750)
{
    BT_User_Flag_LongPress = Flag_Set;
} 
else if (BT_User_Time >= 50) 
{
    BT_User_Flag_ShortPress = Flag_Set;
}
BT_User_Time = 0;
BT_User_State = Button_Released;
}
3.如果在切割时按下按钮,我将按钮状态更改为“已打印”,并添加了保持持续时间的变量1。 如果在切割发生时未按下按钮,我首先检查保持该值的变量,从大值开始并设置必要的标志。最后,我重置保持持续时间的变量,并将按钮状态更改为Dropped

在主循环中:

    if(BT_User_Flag_ShortPress == Flag_Set && BT_User_State == Button_Released)
    {
        HAL_GPIO_TogglePin(LD_Blue_GPIO_Port, LD_Blue_Pin);
        BT_User_Flag_ShortPress = Flag_Reset;
    }

    if(BT_User_Flag_LongPress == Flag_Set && BT_User_State == Button_Released)
    {
        HAL_GPIO_TogglePin(LD_Red_GPIO_Port, LD_Red_Pin);
        BT_User_Flag_LongPress = Flag_Reset;
    }

1.我想创建一个按钮读取结构,它不会中断主返回流和长、短按下状态。这不是一个按钮吗?BT_用户_状态变量保存数据集,按钮按下长,按下短?我定义了两个单独的BT_用户_标志_短按和BT_用户_标志_长按变量保存将数据加上一个BT_User_时间变量,该变量将在持续时间内保持不变

typedef enum{
Flag_Reset,
Flag_Set
}   Button_Flag;

typedef enum{
Button_Released,
Button_Pressed
}   Button_State;

Button_State    BT_User_State = Button_Released;
Button_Flag     BT_User_Flag_ShortPress = Flag_Reset;
Button_Flag     BT_User_Flag_LongPress = Flag_Reset;
uint16_t        BT_User_Time = 0;
2.每1ms还有一个计时器。完成此操作后,计时器溢出:

if(HAL_GPIO_ReadPin(BT_User_GPIO_Port, BT_User_Pin) == GPIO_PIN_SET)
{
   BT_User_State = Button_Pressed;
   BT_User_Time++;
} 
else 
{
   if(BT_User_Time >= 750)
{
    BT_User_Flag_LongPress = Flag_Set;
} 
else if (BT_User_Time >= 50) 
{
    BT_User_Flag_ShortPress = Flag_Set;
}
BT_User_Time = 0;
BT_User_State = Button_Released;
}
3.如果在切割时按下按钮,我将按钮状态更改为“已打印”,并添加了保持持续时间的变量1。 如果在切割发生时未按下按钮,我首先检查保持该值的变量,从大值开始并设置必要的标志。最后,我重置保持持续时间的变量,并将按钮状态更改为Dropped

在主循环中:

    if(BT_User_Flag_ShortPress == Flag_Set && BT_User_State == Button_Released)
    {
        HAL_GPIO_TogglePin(LD_Blue_GPIO_Port, LD_Blue_Pin);
        BT_User_Flag_ShortPress = Flag_Reset;
    }

    if(BT_User_Flag_LongPress == Flag_Set && BT_User_State == Button_Released)
    {
        HAL_GPIO_TogglePin(LD_Red_GPIO_Port, LD_Red_Pin);
        BT_User_Flag_LongPress = Flag_Reset;
    }

我不会在按钮上使用边缘中断,因为它们很有弹性。使用轮询,这样就更容易计算出时间。这不是一个真正的编程问题。@r_ahlskog:使用中断来检测边缘很好,但当然这是不够的。@ThomasJager:这只是一个软件问题。但它太宽泛了。不是吗硬件有所有的准备来做这件事。阅读数据表,多练习嵌入式软件也不会有什么坏处。我不会对按钮使用边缘中断,因为它们很容易反弹。使用轮询,也更容易计算出时间。这不是真正的编程问题。@r_ahlskog:使用中断来检测边缘我托马斯贾格:这不过是一个软件问题。但它太宽泛了。硬件已经具备了实现这一点的所有条件。阅读数据表,更多地练习嵌入式软件也不会有什么坏处。EXTI对于按钮来说很好。如果你必须尽可能多地节省电源,它们也是一种方式可能。也不需要电容器(不是一个小电容器会痛,但EMI比去抖动更有趣)。@Tooonestforthis site EXTI对按钮不友好。醒来是不一样的