这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 【MAX32625PICO开发板】菜单系统

共1条 1/1 1 跳转至

【MAX32625PICO开发板】菜单系统

工程师
2025-06-02 19:07:39     打赏

【前言】

使用菜单系统可以分块展示用户所关心的内容,同时也可以为用户交互提供更加友好的界面。这一篇将分享如何创简单的菜单。

1、创建两个用户菜单的文件menu.c/h


image.png

2、菜单设计

这次设计了两个菜单,一个用于展示RTC日期与时间,另一个菜单用于展示心率与血氧。在menu.c中设计菜单显示如下:

// 显示日期页面
static void show_date_page(void)
{
    uint32_t timesecond;
    uint16_t year;
    uint8_t mon, day, hour, min, sec;

    timesecond = RTC_GetCount();
    RTC_GetDate(timesecond, &year, &mon, &day, &hour, &min, &sec);

    OLED_Clear(0);
    GUI_ShowString(0, 0, (uint8_t *)"Date Page", 16, 1);
    GUI_ShowString(0, 16, (uint8_t *)"------------", 16, 1);

    char date_str[20];
    snprintf(date_str, sizeof(date_str), "%04d-%02d-%02d", year, mon, day);
    GUI_ShowString(0, 32, (uint8_t *)date_str, 16, 1);

    char time_str[20];
    snprintf(time_str, sizeof(time_str), "%02d:%02d:%02d", hour, min, sec);
    GUI_ShowString(0, 48, (uint8_t *)time_str, 16, 1);

    OLED_Display();
}

// 显示心率页面
extern BloodData g_blooddata;
static void show_heart_rate_page(void)
{
    OLED_Clear(0);
    GUI_ShowString(0, 0, (uint8_t *)"Heart Rate Page", 16, 1);
    GUI_ShowString(0, 16, (uint8_t *)"------------", 16, 1);

    char hr_str[20];
    snprintf(hr_str, sizeof(hr_str), "HR: %d BPM", (int)g_blooddata.heart);
    GUI_ShowString(0, 32, (uint8_t *)hr_str, 16, 1);

    char spo2_str[20];
    snprintf(spo2_str, sizeof(spo2_str), "SpO2: %.1f%%", g_blooddata.SpO2);
    GUI_ShowString(0, 48, (uint8_t *)spo2_str, 16, 1);

    OLED_Display();
}

3、菜单的切换,我在前面分享了按键处理的文章:【MAX32625PICO开发板】高效按键处理-电子产品世界论坛

在它的工程基础上,实现当键按下后,实现两个菜单的切换,首先创建菜单刷新任务:

// 菜单刷新任务
void vTaskMenu(void *pvParameters)
{
    menu_init();
    TickType_t last_wake_time = xTaskGetTickCount();

    while (1)
    {
        if (xSemaphoreTake(xMenuMutex, pdMS_TO_TICKS(100)) == pdTRUE)
        {
            switch (current_menu)
            {
            case MENU_DATE:
                show_date_page();
                break;
            case MENU_HEART_RATE:
                show_heart_rate_page();
                break;
            default:
                break;
            }
            xSemaphoreGive(xMenuMutex);
        }

        vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(200));
    }
}

在按键任务中,如捕获取有按键按下,那么就执行menu中的menu_process_key,并传递event。

void vTaskKeyScan(void *pvParameters)
{
    key_init();

    while (1)
    {
        key_event_t event = key_get_click();

        if (event != KEY_NONE)
        {
            menu_process_key(event); // 关键修改:将按键事件传递给菜单系统
            printf("Key event: %d\n", event);
        }

        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

在菜单按键任执行后,解除锁,并根据按键不同,切换菜单

// 处理按键切换菜单
void menu_process_key(key_event_t key)
{
    if (xSemaphoreTake(xMenuMutex, pdMS_TO_TICKS(100)) == pdTRUE)
    {
        if (key == KEY_SW2_CLICK)
        {
            current_menu = (current_menu + 1) % MENU_COUNT;
            printf("Menu changed to: %d\n", current_menu);
        }
        else if (key == KEY_SW3_CLICK)
        {
            current_menu = (current_menu - 1 + MENU_COUNT) % MENU_COUNT;
            printf("Menu changed to: %d\n", current_menu);
        }
        xSemaphoreGive(xMenuMutex);
    }
}

最后,创建一个任务,并在main的任务创建中执行创建菜单任务:

void vCreateMenuTask(void)
{
    xTaskCreate(vTaskMenu, "MenuTask", 512, NULL, tskIDLE_PRIORITY + 2, NULL);
}

【实现效果】

按下开发板中的SW2、SW3实现菜单切换。




关键词: MAX32625PICO     按键     FreeRTOS         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]