RT_Thread操作系统实现多个按键的短按和长按检测

RT_Thread操作系统实现多个按键的短按和长按检测

在RT-Thread操作系统中,实现多个按键的短按和长按操作,不占用线程和其他资源,使用软件定时器实现。

初始化按键的软件定时器

一个按键需要一个软件定时器

	key_1_timer =  rt_timer_create("key_1_timer",                 							// 软件定时器名称
                                   key_1_timer_IRQ,            									// 软件定时器超时函数
                                   RT_NULL,                    									// 超时函数参数
                                   300,                       									// 超时时间
                                   RT_TIMER_FLAG_ONE_SHOT |
                                   RT_TIMER_FLAG_SOFT_TIMER);  									// 软件定时器模式,一次模式
    key_2_timer =  rt_timer_create("key_2_timer",                 							// 软件定时器名称
                                   key_2_timer_IRQ,            									// 软件定时器超时函数
                                   RT_NULL,                    									// 超时函数参数
                                   300,                      										// 超时时间
                                   RT_TIMER_FLAG_ONE_SHOT |
                                   RT_TIMER_FLAG_SOFT_TIMER);  									// 软件定时器模式,一次模式
    key_3_timer =  rt_timer_create("key_3_timer",                 							// 软件定时器名称
                                   key_3_timer_IRQ,            									// 软件定时器超时函数
                                   RT_NULL,                    									// 超时函数参数
                                   300,                       									// 超时时间
                                   RT_TIMER_FLAG_ONE_SHOT |
                                   RT_TIMER_FLAG_SOFT_TIMER);  									// 软件定时器模式,一次模式

初始化按键

将按键的引脚初始化成沿边模式使能引脚的中断

void Key_panel_GPIO_Init(void)
{
    key_1 = rt_pin_get("PB.2");
    key_2 = rt_pin_get("PC.3");
    key_3 = rt_pin_get("PD.0");

    rt_pin_attach_irq(key_1, PIN_IRQ_MODE_RISING_FALLING, key_1_RISING_FALLING_IRQ, RT_NULL);
    rt_pin_irq_enable(key_1, PIN_IRQ_ENABLE);
    rt_pin_attach_irq(key_2, PIN_IRQ_MODE_RISING_FALLING, key_2_RISING_FALLING_IRQ, RT_NULL);
    rt_pin_irq_enable(key_2, PIN_IRQ_ENABLE);
    rt_pin_attach_irq(key_3, PIN_IRQ_MODE_RISING_FALLING, key_3_RISING_FALLING_IRQ, RT_NULL);
    rt_pin_irq_enable(key_3, PIN_IRQ_ENABLE);
}
INIT_DEVICE_EXPORT(Key_panel_GPIO_Init);

按键的中断函数

中断函数中,按键按下后启动定时器,按键松开后,没有超时标志,则按键为短按,关闭软件定时器

void key_1_RISING_FALLING_IRQ(void *arge)
{
    if(rt_pin_read(key_1) == 1)//松开
    {
        key_falg_t.key_1_down_falg = Key_released;
        rt_timer_stop(key_1_timer);
        if(key_falg_t.key_1_timeout_falg == Key_no_timeout)
        {
            key_falg_t.key_1_num = Key_Num_Short_press;
        }
    }
    else if(rt_pin_read(key_1) == 0)//按下
    {
        key_falg_t.key_1_down_falg = Key_Down;
        key_falg_t.key_1_timeout_falg = Key_no_timeout;
        rt_timer_start(key_1_timer);
    }
}

void key_2_RISING_FALLING_IRQ(void *arge)
{
    if(rt_pin_read(key_2) == 1)//松开
    {
        key_falg_t.key_2_down_falg = Key_released;
        rt_timer_stop(key_2_timer);
        if(key_falg_t.key_2_timeout_falg == Key_no_timeout)
        {
            key_falg_t.key_2_num = Key_Num_Short_press;
        }
    }
    else if(rt_pin_read(key_2) == 0)//按下
    {
        key_falg_t.key_2_down_falg = Key_Down;
        key_falg_t.key_2_timeout_falg = Key_no_timeout;
        rt_timer_start(key_2_timer);
    }
}


void key_3_RISING_FALLING_IRQ(void *arge)
{
    if(rt_pin_read(key_3) == 1)//松开
    {
        key_falg_t.key_3_down_falg = Key_released;
        rt_timer_stop(key_3_timer);
        if(key_falg_t.key_3_timeout_falg == Key_no_timeout)
        {
            key_falg_t.key_3_num = Key_Num_Short_press;
        }
    }
    else if(rt_pin_read(key_3) == 0)//按下
    {
        key_falg_t.key_3_down_falg = Key_Down;
        key_falg_t.key_3_timeout_falg = Key_no_timeout;
        rt_timer_start(key_3_timer);
    }
}

按键的超时函数

每个按键对应一个软件定时目的是为了防止按键同时按下,开启定时器后,定时结束,说明按键还没有松开,键值为长按

void key_1_timer_IRQ(void *parameter)
{
    key_falg_t.key_1_timeout_falg = Key_timeout;
    key_falg_t.key_1_num = Key_Num_Long_press;
    key_falg_t.key_1_down_falg = Key_released;
}
void key_2_timer_IRQ(void *parameter)
{
    key_falg_t.key_2_timeout_falg = Key_timeout;
    key_falg_t.key_2_num = Key_Num_Long_press;
    key_falg_t.key_1_down_falg = Key_released;
}
void key_3_timer_IRQ(void *parameter)
{
    key_falg_t.key_3_timeout_falg = Key_timeout;
    key_falg_t.key_3_num = Key_Num_Long_press;
    key_falg_t.key_1_down_falg = Key_released;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HTIAN1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值