收藏官网首页
查看: 8|回复: 0

[资料] 《机智云Gokit3开发篇》5 KEY按键介绍与驱动移植实现长短按

跳转到指定楼层
楼主
 楼主| 发表于 1 小时前 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
校园创客福利
本帖最后由 野机工程师 于 2025-12-17 14:10 编辑

注:文章结尾附本文章源码、原理图 资料链接



概述:本文介绍了gokit3的板载按键、按键原理,以及移植官方GOkit3 HAL库的驱动按键状态机实现长短按的功能


一、key按键的原理
Key原理图:
截取《gokit3功能板原理图V3.0.PDF》第3页的 The Key 部分。



上拉电阻(R25, R26,R27):讲解 R25 (1K) 的作用。说明默认状态下按键引脚是 高电平 (3.3V),按下后接地变为 低电平 (0V) —— 即“低电平有效”。

如果STM32的GPIO口检测是 0 (RESET) -> 代表按键被按下。

如果STM32的GPIO口检测是 1 (SET) -> 代表按键松开。


二、Gokit3板载的按键介绍





原理图如上:因为这里按键是放在SOC功能板上,然后又通过排针与MCU核心板相连,所以可以得到这三个按键响应的GPIO口

Key1 -- PA8
Key2 -- PB10
Key3 -- PA1


实物图



三、机智云按键驱动移植

我们选择用官方的按键驱动源码移植到我们自己的工程。官方的驱动按键代码方便好用,直接拿来用就可以了

1、把官方key源码添加进自己的工程文件(这里官方的源码可以从机智云官网生成数据点后下载MCU源码,也可以直接看我的链接里面的资料直接下载即可)
为了实现长短按功能,我们不重复造轮子,直接移植机智云官方提供的高质量按键驱动。该驱动采用状态机 (Finite State Machine) 思想,通过定时器轮询按键状态,效率极高




2、打开keil工程添加进工程
这里注意添加一下头文件引用路径


3、因为此驱动主要逻辑是状态机检测按键,所以这里要先配置一个Tim2定时器中断作为时钟源
打开CubeMx然后开始配置定时器
这里配置1ms的定时器中断
驱动需要一个精准的时间基准来判断“按下了多久”。我们使用 TIM2。
Clock Source: Internal Clock。
Prescaler (预分频): 72 - 1 (假设主频72MHz)。
Counter Period (重装载值): 1000 - 1。

计算公式:72MHz / 72 / 1000 = 1000Hz = 1ms





记得打开定时器的NVIC中断配置

在 NVIC Settings 选项卡中,勾选 TIM2 global interrupt,开启中断!



4、配置按键用到的GPIO

这里GOkit3板载的按键可以通过原理图看到所用的3个按键用到的GPIO口

Key1 -- PA8
Key2 -- PB10
Key3 -- PA1

5、通过CubeMX配置对应按键GPIO口
为输入模式
根据前面的引脚关系,在 CubeMX 中将 PA8, PB10, PA1 配置为 GPIO_Input
Pull-up/Pull-down:选择 No Pull(因为板子上已经有外部上拉电阻了,如果板子没电阻则需选 Pull-up)




点击生成代码,打开工程


四、实验:长短按实现切换RGB灯的效果

这里分别对这个代码驱动的三个按键的长按短按进行驱动测试
1、先封装一个函数,用于开启定时器的计时与溢出中断
void timerInit(void)
{
   HAL_TIM_Base_Start_IT(&htim2);
}


2、编写定时器2的中断回调函数,给key实现长短按提供时钟时基
在里面添加keyHandle(); 这个驱动提供的函数,在内部会计算按键的长短时间

//编写定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim2)
{
   keyHandle();   
}
}

在此处定义和**即可




3、定义各按键的短按长按回调函数,这样想要的实现的逻辑就可以在此回调函数中编写代码即可,非常方便

这是本驱动最方便的部分,你不需要在主循环里写 if(key==0),只需要定义好“按下去要干什么”的函数(回调函数)即可。

Key1短按回调函数
void key1ShortPress(void)
{
  
}
Key1长按回调函数
void key1LongPress(void)
{
   
}
Key2短按回调函数
void key2ShortPress(void)
{
}
Key2长按回调函数
void key2LongPress(void)
{
}
void key3ShortPress(void)
{
}
void key3LongPress(void)
{
}

写在此处即可

4、key初始化函数与调用keyinit来创建按键与定义对应的按键
也就是说

我们需要告诉驱动,KEY1 对应哪个引脚,以及它对应的回调函数是谁


void keyInit(void)
{
    /* Key parameter initialization*/
    keyCategory_t keys[KEY_NUM]={
        [KEY1] = {
        .fsm.keyGpio.keyPort = KEY1_GPIO_Port,
        .fsm.keyGpio.keyPin = KEY1_Pin,
        //Key1 State Machine Init
        .fsm.keyShield = ENABLE,
        .fsm.keyDownLevel = Bit_RESET,
        //Key1 Callback function init
        .func.ShortPressCb = key1ShortPress,
        .func.longPressCb = key1LongPress,
        },
        [KEY2] = {
        .fsm.keyGpio.keyPort = KEY2_GPIO_Port,
        .fsm.keyGpio.keyPin = KEY2_Pin,
        //Key2 State Machine Init
        .fsm.keyShield = ENABLE,
        .fsm.keyDownLevel = Bit_RESET,
        //Key2 Callback function init
        .func.ShortPressCb = key2ShortPress,
        .func.longPressCb = key2LongPress,
        },
        [KEY3] = {
        .fsm.keyGpio.keyPort = KEY3_GPIO_Port,
        .fsm.keyGpio.keyPin = KEY3_Pin,
        //Key2 State Machine Init
        .fsm.keyShield = ENABLE,
        .fsm.keyDownLevel = Bit_RESET,
        //Key2 Callback function init
        .func.ShortPressCb = key3ShortPress,
        .func.longPressCb = key3LongPress,
        },
    };
    keyParaInit(keys);
}

5、主函数调用定时器初始化函数与按键key初始化函数





6、实现想要的逻辑,例如我想要短按key1,实现亮RGB红灯,长按key1,亮绿灯,短按key2,亮绿灯,长按key2,亮白灯,短按key3关闭灯光;
在对应按键的回调函数里写逻辑即可,非常方便


void key1ShortPress(void)
{
  ledRgbControl(255,0,0); //亮红灯
}






7、编译烧录之后




通过本实验,我们不仅掌握了Gokit3的按键硬件原理,更重要的是学会了“注册回调”这种高级的编程思维。这种方式将“按键检测”和“业务逻辑”完全解耦,以后想修改按键功能,只需要改回调函数里的代码,完全不用动驱动层,非常适合后续接入机智云复杂的配网逻辑。

本文到此结束,谢谢大家!

源码、原理图资料链接
原理图:
链接: https://pan.baidu.com/s/19mmg4zj4c9RA-ejn64NxfQ?pwd=WPC1 提取码: WPC1


源码:
链接: https://pan.baidu.com/s/1wqErf1tXGLQYLwW7y4UNww?pwd=WPC1 提取码: WPC1





15.png (463.85 KB, 下载次数: 3)

15.png
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表