0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

EmbeddedButton嵌入式按键驱动设计实现

冬至子 来源:530china 作者:530china 2023-08-28 15:47 次阅读

EmbeddedButton

简介

EmbeddedButton是一个轻量级简单易用的嵌入式按键驱动模块,可无限拓展按键,支持多连击、长按、短按长按等多种按键事件;该模块通过异步回调方式来简化程序结构,根据几个简单原则完成了整个代码逻辑的支撑。

使用方法

1.定义按键实体

struct button_obj_t button1;

2.建立键值映射表(设置回调事件)

const key_value_map_t button1_map[] =
{
{
.key_value = SINGLE_CLICK_KV,
.kv_func_cb = single_press_handle
},
{
.key_value = LONG_PRESEE_START,
.kv_func_cb = long_press_handle
},
{
.key_value = SINGLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = single_press_then_long_press_handle
},
};

3.初始化按键对象,参数含义分别为

按键实体
绑定按键的GPIO电平读取接口read_button1_pin()
设置有效触发电平
按键ID
键值映射表
键值映射表大小
button_init(&button1, read_button1_pin, 0, 0, button1_map, ARRAY_SIZE(button1_map));

4.启动按键

button_start(&button1);
5.设置一个5ms间隔的定时器循环调用按键后台处理函数

while(1) {
...
if(timer_ticks == 5) {
timer_ticks = 0;
button_ticks();
}
}

特性

1.依靠简单几个原则,支持起整个按键判断逻辑

只要键值非零,时间tick++
只要按键状态发生变化,改变一次键值(__append_bit()),tick时间清零(确保tick为按下或抬起的时间)
以tick时间的长短及按键抬起作为一次状态结束的判断依据,可以很好的实现短按长按等操作;

2.使用C语言实现,巧妙利用位运算来实现每个按键键值的二进制记录表示,1代表按下,0代表松开

1.jpg

3.利用数据驱动思想完成对应按键事件的调用:

typedef struct {
key_value_type_t key_value;
void ( kv_func_cb)(void );
} key_value_map_t;
const key_value_map_t button1_map[] =
{
{
.key_value = SINGLE_CLICK_KV,
.kv_func_cb = single_press_handle
},
{
.key_value = LONG_PRESEE_START,
.kv_func_cb = long_press_handle
},
{
.key_value = SINGLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = single_press_then_long_press_handle
},
};
for(size_t i = 0; i < button->map_size; i++) {
if((button->map_ptr[i].key_value == button->key_value)
&& (button->map_ptr[i].kv_func_cb))
{
button->map_ptr[i].kv_func_cb(button);
}
}

4.基于面向对象方式设计思路,每个按键对象单独用一份数据结构管理:

typedef struct button_obj_t {
uint8_t debounce_cnt : 4;
uint8_t active_level : 1;
uint8_t read_level : 1;
uint8_t read_level_update : 1;
uint8_t event_analyze_en : 1;
uint8_t id;
uint16_t ticks;
state_bits_type_t state_bits;
key_value_type_t key_value;
uint8_t (* read_button_func_ptr)(uint8_t button_id );
const key_value_map_t map_ptr;
size_t map_size;
struct button_obj_t
next;
}button_obj_t;
Examples
#include "embedded_button.h"
struct button_obj_t button1;
uint8_t read_button_pin(uint8_t button_id)
{
// you can share the GPIO read function with multiple Buttons
switch(button_id)
{
case 0:
return get_button1_value(); //Require self implementation
break;
default:
return 0;
break;
}
return 0;
}
void single_click_handle(void* btn)
{
//do something...
printf("/ single click /rn");
}
void double_click_handle(void* btn)
{
//do something...
printf("/ double click /rn");
}
void long_press_handle(void* btn)
{
//do something...
printf("/ long press /rn");
}
void single_click_then_long_press_handle(void* btn)
{
//do something...
printf("/ single click and long press /rn");
}
void double_click_then_long_press_handle(void* btn)
{
//do something...
printf("/ double click and long press /rn");
}
const key_value_map_t button1_map[] =
{
{
.key_value = SINGLE_CLICK_KV,
.kv_func_cb = single_click_handle
},
{
.key_value = DOUBLE_CLICK_KV,
.kv_func_cb = double_click_handle
},
{
.key_value = LONG_PRESEE_START,
.kv_func_cb = long_press_handle
},
{
.key_value = SINGLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = single_click_then_long_press_handle
},
{
.key_value = DOUBLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = double_click_then_long_press_handle
}
};
...
int main()
{
button_init(&button1, read_button_pin, 0, 0, button1_map, ARRAY_SIZE(button1_map));
button_start(&button1);
//make the timer invoking the button_ticks() interval 5ms.
//This function is implemented by yourself.
__timer_start(button_ticks, 0, 5);
while(1)
{}
}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式系统
    +关注

    关注

    40

    文章

    3430

    浏览量

    128221
  • 定时器
    +关注

    关注

    23

    文章

    3147

    浏览量

    112040
  • 状态机
    +关注

    关注

    2

    文章

    486

    浏览量

    27182
  • GPIO
    +关注

    关注

    16

    文章

    1135

    浏览量

    50578
  • 按键驱动
    +关注

    关注

    0

    文章

    11

    浏览量

    7100
收藏 人收藏

    评论

    相关推荐

    嵌入式Linux下USB蓝牙设备驱动

    设备驱动,从而有助于蓝牙设备在嵌入式领域广泛应用。【关键词】:蓝牙驱动;;USB设备;;MP;;嵌入式Linux【DOI】:CNKI:SUN:GWDZ.0.2010-02-025【正文
    发表于 04-24 09:30

    如何学习嵌入式系统【硬件篇】

    的正确性。如在Linux下实现流水灯,实现按键功能。  9、基于操作系统的电子设计  学习到这一步,就可以称得上嵌入式硬件高手了,因为你已经具备独自设计
    发表于 10-20 15:12

    如何学习嵌入式系统

    交叉编译环境将驱动程序编译并下载到目标板上,并且编写一段小测试程序验证驱动的正确性。如在Linux下实现流水灯,实现按键功能。  具体操作:
    发表于 08-17 10:18

    嵌入式系统中LCD驱动实现方法

    的人机界面的要求也越来越高,在应用需求的驱使下,许多工作在Linux下的图形界面软件包的开发和移植工作中都涉及到底层LCD驱动的开发问题。因此在嵌入式系统中开发LCD驱动得以广泛运用。  本文以三星公司
    发表于 07-05 08:31

    基于嵌入式操作系统μcLinux怎么实现对网卡的驱动

    优点的操作系统,非常适合用于具有网络功能的嵌入式系统。本文介绍了以S3C44B0X 的ARM处理器和RTL8019AS 以太网控制器为基础的网络接口设计,并阐述了怎样在嵌入式操作系统μcLinux 下实现对网卡的
    发表于 09-29 06:02

    嵌入式Linux网络驱动程序的体系结构和实现原理是什么

    嵌入式Linux网络驱动程序是什么嵌入式Linux网络驱动程序的体系结构和实现原理如何将设备驱动
    发表于 04-26 06:03

    嵌入式Linux网络驱动程序的实现原理是什么?

    嵌入式Linux网络驱动程序的结构是如何构成的?嵌入式Linux网络驱动程序的实现原理是什么?如何将设备
    发表于 06-04 06:25

    嵌入式按键控制 LED 实验

    嵌入式按键控制 LED 实验1.操作内容2.原理解释2.1 实验箱按键电路2.2 实验箱LED电路2.3 寄存器说明3.操作步骤3.1 编写键控制3.2 安装 USB 驱动3.2
    发表于 10-27 08:01

    Linux嵌入式驱动开发

    全部传送门Linux嵌入式驱动开发01——第一个驱动Hello World(附源码)Linux嵌入式驱动开发02——
    发表于 12-17 06:22

    嵌入式驱动的相关资料分享

    相关文章链接:【嵌入式驱动一】嵌入式驱动开发的前期准备(上)【嵌入式驱动二】
    发表于 12-20 08:16

    嵌入式软件和非嵌入式软件区别

    1.什么是嵌入式技术?嵌入式技术是以应用为中心,以计算机技术为基础的系统技术。它初起源于单片机技术,是各类数字化的电子、机电产品的核心,主要用于实现对硬件设备的控制、监视或管理等功能。2.嵌入
    发表于 12-21 07:41

    如何去实现嵌入式LINUX驱动的软件代码呢

    如何对嵌入式LINUX驱动的硬件信息进行配置呢?如何去实现嵌入式LINUX驱动的软件代码呢?
    发表于 12-24 07:31

    嵌入式驱动开发的教程

    从今天开始,我将写一系列嵌入式驱动开发的教程,大部分都是例程,使用的开发板是飞凌imx6Q。人无完人,文章难免有错误,希望大家邮箱告诉我,给我一个进步的机会,在这先谢谢大家!也感谢大家的阅读!如果
    发表于 12-24 06:10

    嵌入式XP内核设备驱动的设计与实现李虎平

    嵌入式XP内核设备驱动的设计与实现_李虎平
    发表于 03-14 08:00 0次下载

    LCD原理与基于嵌入式的LCD驱动的设计与实现

    主要的工作是驱动程序的开发。因此结合液晶显示器(LCD) 设备,本课题研究嵌入式Linux 的LCD 驱动的设计与实现。 本设计实现了LCD
    发表于 10-19 17:12 8次下载
    LCD原理与基于<b class='flag-5'>嵌入式</b>的LCD<b class='flag-5'>驱动</b>的设计与<b class='flag-5'>实现</b>