硬汉嵌入式论坛

 找回密码
 立即注册
查看: 852|回复: 8
收起左侧

[有问必答] keil编写按键切换菜单的程序,但是调试的时候发现按键按下之后没有反应

[复制链接]

3

主题

5

回帖

14

积分

新手上路

积分
14
发表于 2023-3-14 23:07:04 | 显示全部楼层 |阅读模式
uint8_t func_index = 0;
uint16_t voltage,resistor;
void (*current_operation_index)();
void Key_Init(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能PB端口时钟       
       
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /*使能SWD 禁用JTAG*/

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        GPIO_InitTypeDef GPIO_InitStructure2;
        GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
        GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure2);
}

uint8_t Key_GetNum(void)
{
        uint8_t keynum = 0;
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0);
                Delay_ms(10);
                keynum = 1;
        }
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == 0);
                Delay_ms(10);
                keynum = 2;
        }
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10) == 0);
                Delay_ms(10);
                keynum = 3;
        }
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11) == 0);
                Delay_ms(10);
                keynum = 4;
        }
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) == 0);
                Delay_ms(10);
                keynum = 5;
        }
                if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 0);
                Delay_ms(10);
                keynum = 6;
        }
                if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0);
                Delay_ms(10);
                keynum = 7;
        }
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == 0)
        {
                Delay_ms(10);
                while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == 0);
                Delay_ms(10);
                keynum = 8;
        }
return keynum;
}

typedef struct
{
    uint8_t current;                                                                        //当前状态索引号
    uint8_t up;                                                                                 //向上
    uint8_t down;                                                                                 //向下
        uint8_t left;                                                                                 //向左
        uint8_t right;                                                                                 //向右
        uint8_t enter;                                                                                 //确定
        uint8_t one;                                                                                 //存储数据区1
        uint8_t two;                                                                                 //存储数据区2
        uint8_t three;                                                                                //存储数据区3
    void (*current_operation)(void);                                         //当前状态应该执行的操作
} Menu_table;

Menu_table  table[10]=
{
    {0,0,0,3,1,0,4,5,6,(*fun0)},//一级界面  时钟界面
    {1,1,1,0,2,1,1,1,1,(*fun1)},//二级界面第一行 CAN Mode
    {2,2,2,1,3,2,2,2,2,(*fun2)},//二级界面第二行 485 Mode
    {3,3,3,2,0,3,3,3,3,(*fun3)},//二级界面第三行 UART Mode
    {4,4,4,4,0,7,4,4,4,(*fun4)},//二级界面第四行 BACK
    {5,5,5,5,0,8,5,5,5,(*fun5)},
    {6,6,6,6,0,9,6,6,6,(*fun6)},//三级界面第一行 back
    {7,0,0,3,1,0,4,5,6,(*fun7)},
    {8,0,0,3,1,0,4,5,6,(*fun8)},
    {9,0,0,3,1,0,4,5,6,(*fun9)},
};

void  Menu_key_set(void)
{

  if(Key_GetNum()== 1)
  {   
    func_index=table[func_index].enter;//按键enter按下后的索引号
    OLED_Clear();
  }
  if(Key_GetNum()== 2)
  {
    func_index=table[func_index].left;//按键left按下后的索引号
    OLED_Clear();
  }
  if(Key_GetNum()== 3)
  {   
    func_index=table[func_index].right;//按键right按下后的索引号
    OLED_Clear();
  }
  if(Key_GetNum()== 4)
  {
    func_index=table[func_index].down;//按键down按下后的索引号
    OLED_Clear();
  }  if(Key_GetNum()== 5)
  {   
    func_index=table[func_index].up;//按键up按下后的索引号
    OLED_Clear();
  }
  if(Key_GetNum()== 6)
  {
    func_index=table[func_index].one;//按键one按下后的索引号
    OLED_Clear();
  }  if(Key_GetNum()== 7)
  {   
    func_index=table[func_index].two;//按键two按下后的索引号
    OLED_Clear();
  }
  if(Key_GetNum()== 8)
  {
    func_index=table[func_index].three;//按键three按下后的索引号
    OLED_Clear();
  }
  current_operation_index=table[func_index].current_operation;//执行当前索引号所对应的功能函数。
  (*current_operation_index)();//执行当前操作函数

}

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106882
QQ
发表于 2023-3-15 00:31:37 | 显示全部楼层
优先示波器测试产生波形没,然后看GPIO的IDR寄存器是否正常采集的数值
回复

使用道具 举报

0

主题

215

回帖

215

积分

高级会员

积分
215
发表于 2023-3-15 09:24:13 | 显示全部楼层
你这按键程序延迟太大了,要防抖,比如我20ms内,比如间隔2ms/5ms,每个IO都读一次, 然后读到按下时计数+1,然后等到了20ms,判断这个计数值,超过一定值就判断按键按下了。
或者是,一旦读到按键按下,记录下时间,然后继续循环读取(按照一定时间间隔),每次也是增加计数,等循环次数到了设定值,判断计数。
你这个如果所有的按键都按下,循环一次延时太大,也不能判断多个按键按下。
回复

使用道具 举报

11

主题

43

回帖

76

积分

初级会员

积分
76
发表于 2023-3-15 09:42:14 | 显示全部楼层
GPIO_Mode_IPD这个配置跟你的判断逻辑好像有问题,最好把原理图也贴出来看看
回复

使用道具 举报

11

主题

43

回帖

76

积分

初级会员

积分
76
发表于 2023-3-15 09:44:00 | 显示全部楼层
GPIO_Mode_IPD你这个输入下拉跟你判断按键按下的逻辑有点问题,把原理图贴出来看下
回复

使用道具 举报

2

主题

269

回帖

275

积分

高级会员

积分
275
发表于 2023-3-15 12:27:08 | 显示全部楼层
亲移植一个按键开源库叭
0x1abin/MultiButton 好多教程的。
回复

使用道具 举报

3

主题

5

回帖

14

积分

新手上路

积分
14
 楼主| 发表于 2023-3-15 17:44:52 | 显示全部楼层
谢谢大家,我Key_GetNum函数里每次调用都把键值重新赋值为0了(uint8_t keynum = 0),但是还是不太稳定,我参考一下上边那个兄弟的意见移植一下别人的按键开源教程再试一下。
SX9FMLL9}5%~_E30Z%H4)77.png
回复

使用道具 举报

0

主题

6

回帖

6

积分

新手上路

积分
6
发表于 2023-3-17 08:22:38 来自手机 | 显示全部楼层
regbbs 发表于 2023-3-15 09:24
你这按键程序延迟太大了,要防抖,比如我20ms内,比如间隔2ms/5ms,每个IO都读一次, 然后读到按下时计数+1 ...

死循环的延时,能不用尽可能不用。
回复

使用道具 举报

0

主题

6

回帖

6

积分

新手上路

积分
6
发表于 2023-3-17 08:24:51 来自手机 | 显示全部楼层
regbbs 发表于 2023-3-15 09:24
你这按键程序延迟太大了,要防抖,比如我20ms内,比如间隔2ms/5ms,每个IO都读一次, 然后读到按下时计数+1 ...

死循环的延时,能不用尽可能不用。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-8 15:30 , Processed in 0.191418 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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