找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 51|回复: 0
打印 上一主题 下一主题
收起左侧

按键翻页程序无法实现翻页功能

[复制链接]
跳转到指定楼层
楼主
ID:1155631 发表于 2025-7-16 11:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为什么我的按键翻页的程序他好像卡死了,翻不了页?

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Key_TurnPage.h"
#include "OLED.h"
#include <stdio.h>

uint32_t HAL_Init(void);                //定义用于接收按键键码的变量

// 系统初始化
void System_Init(void) {
    OLED_Init();    // 初始化OLED
    Key_Init();     // 初始化按键
    OLED_Clear();   // 清屏
}

const char* pageContent[] = {
                        "Page 1: Main",
                        "Page 2: Temp",
                        "Page 3: Humi"                                                                               
};

// 显示当前页
void ShowCurrentPage(void) {
        OLED_Clear();
        OLED_ShowString(0, 0, (char*)pageContent[currentPage]);       
    OLED_ShowString(0, 0, (char*)pageContent[currentPage]);
    // 添加页码显示(例如:1/10)
    char pageStr[16];
    sprintf(pageStr, "Page:%d/%d", currentPage+1, totalPages);
    OLED_ShowString(0, 2, pageStr);
}

//主程序
int main(void)
{
        /*模块初始化*/
    System_Init();
    ShowCurrentPage();  // 显示初始页
       
        while (1)
        {
        PageAction action = Key_Scan();

        switch (action)
                        {
            case PAGE_UP:                                                                                // 执行向上翻页操作
                printf("Page Up: %d\n", currentPage);
                break;

            case PAGE_DOWN:                                                                                // 执行向下翻页操作
                printf("Page Down: %d\n", currentPage);
                break;

            case PAGE_NONE:                                                                                // 无按键动作
                break;
                        }

        // 其他任务...


        // 按键扫描(假设在按键驱动中实现)
        Key_Scan();

        // 处理向上翻页
        if (keyUpState == KEY_STATE_PRESSED) {
            keyUpState = KEY_STATE_RELEASED;  // 清除按键状态
            if (currentPage > 0) {
                currentPage--;
                ShowCurrentPage();
            }
        }

        // 处理向下翻页
        if (keyDownState == KEY_STATE_PRESSED) {
            keyDownState = KEY_STATE_RELEASED;  // 清除按键状态
            if (currentPage < totalPages - 1) {
                currentPage++;
                ShowCurrentPage();
            }
        }

        // 处理按键连发(长按快速翻页)
        if (keyUpState == KEY_STATE_REPEAT) {
            if (currentPage > 0) {
                currentPage--;
                ShowCurrentPage();
                Delay_ms(100);  // 连发速度控制
            }
        }

        if (keyDownState == KEY_STATE_REPEAT) {
            if (currentPage < totalPages - 1) {
                currentPage++;
                ShowCurrentPage();
                Delay_ms(100);  // 连发速度控制
            }
        }

        Delay_ms(10);  // 主循环延时
        }
}

#include "stm32f10x.h"


// 按键定义
#define KEY_UP_PIN     GPIO_Pin_4
#define KEY_UP_PORT    GPIOA
#define KEY_DOWN_PIN   GPIO_Pin_6
#define KEY_DOWN_PORT  GPIOA

// 按键状态
typedef enum {
    KEY_STATE_RELEASED,                                                                                                        //按键释放/未按下状态
    KEY_STATE_PRESS_DETECTED,                                                                                        //检测到按键按下(初始按下状态)
    KEY_STATE_PRESSED,                                                                                                        //按键持续按下状态
    KEY_STATE_REPEAT                                                                                                        //按键保持触发连发状态
} KeyState;

// 翻页控制
typedef enum {                                                                               
    PAGE_UP,                                                                                                                        //向上翻页
    PAGE_DOWN,                                                                                                                        //向下翻页
    PAGE_NONE                                                                                                                        //无翻页动作
} PageAction;

// 全局变量
static KeyState keyUpState = KEY_STATE_RELEASED;                                                //向上按键的当前状态
static KeyState keyDownState = KEY_STATE_RELEASED;                                                //向下按键的当前状态
static uint32_t keyPressTimer = 0;                                                                                //按键按下计时器(用于长按检测)
static uint8_t currentPage = 0;                                                                                        //当前显示页面的索引(从0开始)
static uint8_t totalPages = 10;                                                                                 // 假设总共有10页

// 按键初始化
void Key_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = KEY_UP_PIN | KEY_DOWN_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                                 // 上拉输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

volatile uint32_t sysTickCount = 0;

uint32_t GetTick(void)
{
    return sysTickCount;                                                                                                  // 返回当前滴答值
}

// 按键扫描函数(非阻塞式)
PageAction Key_Scan(void) {
    static uint32_t lastScanTime = 0;
    //uint32_t currentTime = HAL_GetTick();       
    uint32_t currentTime = GetTick();
       
    // 每10ms扫描一次按键
    if (currentTime - lastScanTime < 10) {
        return PAGE_NONE;
    }
    lastScanTime = currentTime;

    // 检测KEY_UP
    if (GPIO_ReadInputDataBit(KEY_UP_PORT, KEY_UP_PIN) == Bit_RESET) {         // 按键按下
        switch (keyUpState) {
            case KEY_STATE_RELEASED:
                keyUpState = KEY_STATE_PRESS_DETECTED;
                keyPressTimer = currentTime;
                break;

            case KEY_STATE_PRESS_DETECTED:
                if (currentTime - keyPressTimer > 20) {                                 // 消抖
                    keyUpState = KEY_STATE_PRESSED;
                    currentPage = (currentPage == 0) ? totalPages - 1 : currentPage - 1;
                    return PAGE_UP;
                }
                break;

            case KEY_STATE_PRESSED:
                if (currentTime - keyPressTimer > 500) {                                 // 长按500ms后开始自动重复
                    keyUpState = KEY_STATE_REPEAT;
                    keyPressTimer = currentTime;
                }
                break;

            case KEY_STATE_REPEAT:
                if (currentTime - keyPressTimer > 100) {                                 // 每100ms重复一次
                    keyPressTimer = currentTime;
                    currentPage = (currentPage == 0) ? totalPages - 1 : currentPage - 1;
                    return PAGE_UP;
                }
                break;
        }
    } else {                                                                                                                         // 按键释放
        keyUpState = KEY_STATE_RELEASED;
    }

    // 检测KEY_DOWN
    if (GPIO_ReadInputDataBit(KEY_DOWN_PORT, KEY_DOWN_PIN) == Bit_RESET) {
        switch (keyDownState) {
            case KEY_STATE_RELEASED:
                keyDownState = KEY_STATE_PRESS_DETECTED;
                keyPressTimer = currentTime;
                break;

            case KEY_STATE_PRESS_DETECTED:
                if (currentTime - keyPressTimer > 20) {                                 // 消抖
                    keyDownState = KEY_STATE_PRESSED;
                    currentPage = (currentPage + 1) % totalPages;
                    return PAGE_DOWN;
                }
                break;

            case KEY_STATE_PRESSED:
                if (currentTime - keyPressTimer > 500) {                                 // 长按500ms后开始自动重复
                    keyDownState = KEY_STATE_REPEAT;
                    keyPressTimer = currentTime;
                }
                break;

            case KEY_STATE_REPEAT:
                if (currentTime - keyPressTimer > 100) {                                 // 每100ms重复一次
                    keyPressTimer = currentTime;
                    currentPage = (currentPage + 1) % totalPages;
                    return PAGE_DOWN;
                }
                break;
        }
    } else {
        keyDownState = KEY_STATE_RELEASED;
    }

    return PAGE_NONE;
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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