野机工程师 发表于 2 小时前

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

本帖最后由 野机工程师 于 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={       = {       .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,      },        = {      .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,      },        = {      .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





页: [1]
查看完整版本: 《机智云Gokit3开发篇》5 KEY按键介绍与驱动移植实现长短按