试用 LVGL Pro,一套完整的工具包,助您高效构建、测试、分享和交付 UI!
LVGL
教程

在 STM32 上使用硬件按钮控制 LVGL

学习如何在 STM32F429I-DISC1 Discovery 开发板上将物理硬件按钮与 LVGL 集成,以控制 UI 元素和 LED。

SeyyahSeyyah4 分钟阅读

本教程演示了如何使用 STM32F429I-DISC1 Discovery 开发板测试 LVGL 的硬件按钮功能。该开发板有两个按键:USER 和 RESET [1]。我们将使用 USER 按键,它连接到 STM32F429ZIT6 的 I/O PA0 [2]。该开发板还有六个 LED,我们将使用 LD3(绿色 LED),它连接到 STM32F429ZIT6 的 I/O PG13 [2]。

我们的目标是在硬件按钮(USER 按键)和 UI 按钮都被点击时切换 LD3 LED。

硬件按钮驱动注册#

我们的硬件按钮驱动注册函数为:

void my_button_init(void)
{
  static lv_indev_t *indev;
  lv_indev_drv_t indev_drv;
 
  lv_indev_drv_init(&indev_drv);
 
  indev_drv.read = my_input_read;
  indev_drv.type = LV_INDEV_TYPE_BUTTON;
  indev = lv_indev_drv_register(&indev_drv);
 
  static lv_point_t points_array[] = { { 20, 20 } };
  lv_indev_set_button_points(indev, points_array);
}
c

其中:

  • type: LV_INDEV_TYPE_BUTTON - 外部(硬件按钮),分配到屏幕上的特定点
  • read: my_input_read - 读取硬件按钮状态(按下/释放)的函数
  • points_array: 这些点将分配给按钮,以按下屏幕上的特定点

创建 UI 按钮#

我们在屏幕上创建一个按钮。points_array 的第一个元素 (20px, 20px) 被选择在 UI 按钮区域内的任意点(x: 0-40px, y: 0-40px)。

static lv_obj_t *btn = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_size(btn, 40, 40);
lv_obj_set_pos(btn, 0, 0);
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, btn_click_action);
c

按钮点击动作#

我们的 btn_click_action 仅切换 LD3 LED:

static lv_res_t btn_click_action(lv_obj_t *btn) {
  HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13);
}
c

读取硬件按钮数据#

my_btn_read 函数读取硬件按钮数据并返回硬件按钮 ID:

uint8_t my_btn_read() {
  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == 0) {
    return 1;
  } else {
    return 0;
  }
}
c

输入读取函数#

my_input_read 函数在仍有数据需要读取(缓冲)时返回 true,否则返回 false:

bool my_input_read(lv_indev_data_t *data){
    static int8_t last_btn = 0;     /* 存储最后按下的按钮 */
    int8_t btn_pr = my_btn_read();  /* 获取被按下按钮的 ID (0,1,2...) */
 
    if(btn_pr > 0) {                /* 有按钮被按下吗? */
       last_btn = btn_pr;           /* 保存被按下按钮的 ID */
       data->state = LV_INDEV_STATE_PR;  /* 设置按下状态 */
    } else {
       data->state = LV_INDEV_STATE_REL; /* 设置释放状态 */
    }
 
    data->btn = last_btn;            /* 设置最后的按钮 */
 
    return false;                    /* 无缓冲,因此没有更多数据要读取 */
}
c

在主函数中初始化#

在最后一步,我们调用 button_init:

main() {
  // GPIO Init: LED, Button
  // LittlevGL
  button_init();
 
  while(1) {
    // ...
  }
}
c
完整项目

完整的项目示例将在未来更新中分享。

致谢#

本教程由我们与 Orhan Gunduz 共同准备。

参考资料#

  1. STM32F429I-DISC1 官网
  2. UM1670 用户手册 Discovery 开发板与 STM32F429ZI MCU
  3. LVGL issue 讨论
  4. YouTube 视频演示

关于作者

Seyyah
Seyyah

社区贡献者

软件开发者和 LVGL 社区贡献者,与 Ogunduz 合著了硬件按钮集成指南。

认识博客背后的作者们

了解那些分享 LVGL 知识的优秀作者们

查看作者

订阅我们的通讯 不错过任何关于 LVGL 的新闻。我们每月最多发送 2 封邮件。

LVGL

LVGL 是最受欢迎的免费开源嵌入式图形库,支持任何 MCU、MPU 和显示类型,助您构建精美的用户界面。

我们还提供 UI 设计、实现和咨询等服务。

© 2026 LVGL。保留所有权利。
YouTubeGitHubLinkedIn