OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7194|回复: 4

【STM32F4探索者】按键输入实验按键不能正常识别问题

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2018-9-19
在线时间
4 小时
发表于 2018-10-16 15:57:07 | 显示全部楼层 |阅读模式
1金钱
1.首先上代码
/*****************************main.c*****************************/
int main(void)
{
        delay_init(168);
        led_init();
        beep_init();
        key_init();
               
        while(1)       
        {
                unsigned char key;
                key = key_scan(1);                        //不能连续按键
               

                switch(key)
                {
                        case 1:
                        {
                                LED_blue_on;          //DS1
                                LED_white_off;        //DS0
                                BEEP_OFF;
                        }break;
                        case 2:
                        {
                                static unsigned char key_cnt;
                                key_cnt++;
                                if(key_cnt%2 == 0)
                                {
                                        LED_blue_on;
                                        LED_white_on;
                                        BEEP_OFF;
                                }
                                else
                                {
                                        LED_blue_off;
                                        LED_white_off;
                                        BEEP_OFF;
                                }
                        }break;
                        case 3:
                        {
                                LED_white_on;
                                LED_blue_off;
                                BEEP_OFF;
                        }break;
                        case 4:
                        {
                                LED_blue_off;
                                LED_white_off;
                                BEEP_ON;
                        }break;
                        default:break;
                }
        }
}
/*****************************key.c*****************************/
void key_init(void)
{
        //使能外设时钟
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);

        //初始化按键WAKE_UP
        GPIO_InitTypeDef* KEY_wake_up;
        KEY_wake_up->GPIO_Mode = GPIO_Mode_IN;
        KEY_wake_up->GPIO_Pin = GPIO_Pin_0;
        KEY_wake_up->GPIO_PuPd = GPIO_PuPd_DOWN;
        KEY_wake_up->GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, KEY_wake_up);

        //初始化按键0,按键1和按键2
        GPIO_InitTypeDef* KEY_0_1_2;
        KEY_0_1_2->GPIO_Mode = GPIO_Mode_IN;
        KEY_0_1_2->GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
        KEY_0_1_2->GPIO_PuPd = GPIO_PuPd_UP;
        KEY_0_1_2->GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOE, KEY_0_1_2);
}

unsigned char key_scan(unsigned char mode)
{
        static unsigned char key_value;
        static unsigned char KEY_set = 1;
        if(mode == 0)                                //不能连续按键
        {
                KEY_set = 1;
        }
        if(KEY_set&&((KEY_0_read==0)||(KEY_1_read==0)||(KEY_2_read==0)||(KEY_wakeup_read==1)))
        {
                delay_ms(10);                //按键消抖
                KEY_set = 0;
                if(KEY_0_read==0)
                {
                        key_value = key_0_set;                //按键0按下
                        return key_value;
                }
                else if(KEY_1_read==0)
                {
                        key_value = key_1_set;                //按键1按下
                        return key_value;
                }
                else if(KEY_2_read==0)
                {
                        key_value = key_2_set;                //按键2按下
                        return key_value;
                }
                else if(KEY_wakeup_read==1)
                {
                        key_value = key_wakeup_set;                //按键WAKE_UP按下
                        return key_value;
                }
        }
        else
        {
                KEY_set = 1;
                key_value = 0;
        }
        return key_value;
}

/*****************************key.h*****************************/
#ifndef _KEY_H
#define _KEY_H

#define KEY_0_read        GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEY_1_read        GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define KEY_2_read        GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)
#define KEY_wakeup_read        GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)

#define key_0_set 1
#define key_1_set 2
#define key_2_set 3
#define key_wakeup_set 4

extern void key_init(void);                                        //按键初始化函数
extern unsigned char key_scan(unsigned char mode);         //按键值获取函数

#endif

硬件连接如图:
01.png
问题描述:程序编译下载后,DS1常量,按键没有反应。
调试结果:如图
02.png
按理说:端口输出化完成以后,GPIOA.0为0,GPIOE.2,.3,.4为1,
但是结果是GPIOA.0为0,GPIOE.2,.3,.4只有GPIOE.2为1,其他为0。为什么?

我在调试过程中在key.c端口初始化完毕后,读端口电平,添加了一个Value变量,神奇的是,程序竟然能够正常运转了,我并没有调用Value这个变量,
添加变量后代码如下:
/*****************************key.c*****************************/
void key_init(void)
{
        volatile unsigned char Value;
        //使能外设时钟
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);

        //初始化按键WAKE_UP
        GPIO_InitTypeDef* KEY_wake_up;
        KEY_wake_up->GPIO_Mode = GPIO_Mode_IN;
        KEY_wake_up->GPIO_Pin = GPIO_Pin_0;
        KEY_wake_up->GPIO_PuPd = GPIO_PuPd_DOWN;
        KEY_wake_up->GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, KEY_wake_up);
       
        Value = KEY_wakeup_read;

        //初始化按键0,按键1和按键2
        GPIO_InitTypeDef* KEY_0_1_2;
        KEY_0_1_2->GPIO_Mode = GPIO_Mode_IN;
        KEY_0_1_2->GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
        KEY_0_1_2->GPIO_PuPd = GPIO_PuPd_UP;
        KEY_0_1_2->GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOE, KEY_0_1_2);
       
        Value = KEY_0_read;
}


调试结果如下:
03.png
初始化竟然正常了,这是为何?
请各位大神指教,不胜感激。
最后我的KEIL中仿真时,Peripherals选项卡下没有general purpose I/O窗口,这个应如何设置?

Experiment3 Key_input.zip

4.37 MB, 下载次数: 25

最佳答案

查看完整内容[请看2#楼]

好了,再部门同事的指导下,我终于明白了,折磨了我两天了 GPIO_InitTypeDef* KEY_wake_up; KEY_wake_up->GPIO_Mode = GPIO_Mode_IN; KEY_wake_up->GPIO_Pin = GPIO_Pin_0; KEY_wake_up->GPIO_PuPd = GPIO_PuPd_DOWN; KEY_wake_up->GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, KEY_wake_up); 指针的使用这样子是没有错的,但是问题就在于这个指针指向什么呢,我在定 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2018-9-19
在线时间
4 小时
 楼主| 发表于 2018-10-16 15:57:08 | 显示全部楼层
本帖最后由 babett 于 2018-10-17 14:07 编辑

好了,再部门同事的指导下,我终于明白了,折磨了我两天了
        GPIO_InitTypeDef* KEY_wake_up;
        KEY_wake_up->GPIO_Mode = GPIO_Mode_IN;
        KEY_wake_up->GPIO_Pin = GPIO_Pin_0;
        KEY_wake_up->GPIO_PuPd = GPIO_PuPd_DOWN;
        KEY_wake_up->GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, KEY_wake_up);
指针的使用这样子是没有错的,但是问题就在于这个指针指向什么呢,我在定义这个指针的同时并没有对这个指针进行初始化,所以它会瞎JB乱指,导致初始化错误,称为野指针,因此在运用结构体指针的时候,建议这样使用,        GPIO_InitTypeDef  A;      
        GPIO_InitTypeDef* KEY_wake_up = &A;
        KEY_wake_up->GPIO_Mode = GPIO_Mode_IN;
        KEY_wake_up->GPIO_Pin = GPIO_Pin_0;
        KEY_wake_up->GPIO_PuPd = GPIO_PuPd_DOWN;
        KEY_wake_up->GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, KEY_wake_up);
这样就可以了,但是我前面遇到的一种情况,就是运用了一个Volatile类型的变量Value读取端口以后,依旧使用前面的代码,也可以正常初始化,这是为什么?有明白的大神,请指教,多谢。
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2018-10-16 18:22:54 | 显示全部楼层
帮顶
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-10-17 01:55:53 | 显示全部楼层
仿真找问题
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2018-9-19
在线时间
4 小时
 楼主| 发表于 2018-10-17 13:31:56 | 显示全部楼层

仿真,在运行到        GPIO_Init(GPIOE, KEY_0_1_2);这条语句时,前面的KEY_0_1_2的变量里面的值都没有正确赋值,这是为何
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 00:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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