使用STM32GPIO读取按键实现按键操作(STM32_08)

一、开发板按键设置

    在"STM32-PZ6806L"开发板上除了复位按键外,还设计了4个按键,分别标为"UP"、"DOWN"、"LEFT"和"RIGHT",其电路如下:

根据电路连接得知K_UP按键一端与GPIOA_0连接,另一端通过一个1KΩ电阻接3.3V,所以在对GPIOA_0配置时应设置工作方式为“下拉输入”,当按键松开时为低电平,按键按下时为高电平;K_LEFT、K_DOWN和K_RIGHT三个按键的一端分别与GPIOE_2、GPIOE_3和GPIOE_4相连,另一端接地,所以对GPIOE_2、GPIOE_3和GPIOE_4要配置为“上拉输入”方式,按键松开时为高电平,按键按下时为低电平。

二、项目基本配置

该项目在音乐播放项目基础上设计。实现分别按这四个键时,蜂鸣器发出不同的声音。音乐播放项目实现参看:使用STM32控制无源蜂鸣器发声播放音乐(STM32_07)

1、复制pMusic项目文件夹,将文件夹改名为"pKey";

2、在"pKey/User"文件夹下新建"Key"文件夹;

3、使用"Keil uVision5"打开"pKey"文件夹下的项目"pMusic"(项目名称没有改变);

4、新建"key.h"和"key.c"文件,保存在"pKey/User/Key"文件夹中;

5、将"key.c"文件添加到项目的"User"组中;

6、配置项目,在"C/C++"选项卡中的"Include Paths"中添加对".\User\Key"路径的包含,便于其他程序包含"key.h"头文件时,系统能找到。

三、编程实现按键功能

1、"key.h"头文件程序

在头文件中定义按键GPIO端口宏、按键引脚宏和读取引脚值的宏,定义Key_Init和ReadKey两个函数的声明。内容如下:

#ifndef __KEY__H

#define __KEY__H

#include "system.h"

#include "stm32f10x_gpio.h"

#define KEY_UP_PORT                         GPIOA

#define KEY_OTHER_PORT        GPIOE

#define KEY_UP                                               GPIO_Pin_0

#define KEY_LEFT                                 GPIO_Pin_2

#define KEY_DOWN                              GPIO_Pin_3

#define KEY_RIGHT                              GPIO_Pin_4

//使用库函数方式读取按键

#define K_UP                                           GPIO_ReadInputDataBit(KEY_UP_PORT, KEY_UP)

#define K_LEFT                                       GPIO_ReadInputDataBit(KEY_OTHER_PORT, KEY_LEFT)

#define K_DOWN                                      GPIO_ReadInputDataBit(KEY_OTHER_PORT, KEY_DOWN)

#define K_RIGHT                                      GPIO_ReadInputDataBit(KEY_OTHER_PORT, KEY_RIGHT)

void Key_Init(void);

u8 ReadKey(u8 mode);

#endif

2、"key.c"程序文件程序

"Key_Init"函数实现对GPIOA和GPIOE的使能,配置GPIOA_0为下拉输入方式,配置GPIOE_2、GPIOE_3和GPIOE_4为上拉输入方式。"ReadKey"函数实现按键扫描,通过参数"mode"选择单次扫描(mode=0, 按键从按下到松开为一次按键)和连续扫描(mode=1,按键按下时到松开可以被视为多次按键)。

#include "key.h"

#include "stm32f10x_Rcc.h"

#include "SysTick.h"

void Key_Init()

{

         GPIO_InitTypeDef GPIO_mode;

         //使能GPIOA和GPIOE时钟

         RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE, ENABLE );    

         GPIO_mode.GPIO_Mode = GPIO_Mode_IPD;

         GPIO_mode.GPIO_Pin = KEY_UP;

         GPIO_mode.GPIO_Speed = GPIO_Speed_50MHz;

         GPIO_Init(KEY_UP_PORT,&GPIO_mode);

        

         GPIO_mode.GPIO_Mode = GPIO_Mode_IPU;

         GPIO_mode.GPIO_Pin = KEY_DOWN|KEY_LEFT|KEY_RIGHT;

         GPIO_mode.GPIO_Speed = GPIO_Speed_50MHz;

         GPIO_Init(KEY_OTHER_PORT,&GPIO_mode);

}

/*

mode=0--单次扫描

mode=1--连续扫描

*/

u8 ReadKey(u8 mode)

{

         static u8 key = 1;

         if(key==1&&(K_UP==1||K_DOWN==0||K_LEFT==0||K_RIGHT==0))

         {

                   delay_ms(10);

                   key = 0;

                   if(K_UP==1)

                   {

                            return 1;

                   }

                   else if(K_DOWN==0)

                   {

                            return 2;

                   }

                   else if(K_LEFT==0)

                   {

                            return 3;

                   }

                   else if(K_RIGHT==0)

                   {

                            return 4;

                   }

         }

         else if(K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1)//按键松开

         {

                   key = 1;

         }

         if(mode==1)

         {

                   key = 1;

         }

         return 0;

}

3、"main.c"程序

在主函数中,首先初始化SysTick、蜂鸣器IO口、Key按键IO口,然后反复读取按键,根据按键值调用"beep.c"中的Sound函数实现发声。程序如下:

#include "beep.h"

#include "SysTick.h"

#include "key.h"

int main()

{

         u8 key, i;

         u16 tone[] = {0,262,294,330,349};

         SysTick_Init(72);

         BEEP_Init();

         Key_Init();

         while(1)

         {

                   key = ReadKey(0);

                   if(key!=0){

                            for(i=0; i<100;i++)

                                     Sound(tone[key]);

                   }

         }

}

4、下载hex文件到开发板,按"UP"、"DOWN"、"LEFT"和"RIGHT"能听到蜂鸣器发出Do,Re,Mi,Fa的声音。