前言:

        回顾之前做过的两个实验,led灯和蜂鸣器,都是通过I/O配置引脚输出,今天,我们要做的按键检测,则是I/O的引脚输入。

正文:

一、项目概况

1.1项目需求

        第一个按键按下后蜂鸣器响,抬起后红灯亮,再按一下蜂鸣器响,抬起后红灯灭。

1.2项目来源

        作者脑洞。

1.3项目开发环境

        软件:keil5;
        硬件:野火挑战者开发板。

1.4项目意义

        作为洗衣机,电饭煲等家用电器的按钮使用。

二、开发步骤

        首先我们要做的第一件事,还是去查找电路原理图。看看关于按键部分的电路是什么样的。通过野火提供的硬件电路原理图我们看到有两个按键SW1和SW3,分别是通过PA0引脚和PC13引脚进行检测,通过电路图可以看到,当按键没有按下时,两个引脚都是接地,按下以后则是连通了3.3V,也就是说,两个引脚的逻辑完全相同,都是按键松开检测为低电平,按键按下检测为高电平。

嵌入式开发学习之--按键检测_单片机

        除了新增加的按键,我们还用到了之前实验中用到的led灯和蜂鸣器。所以我们新创建key.c和key.h这两个文件,同时把之前的led.c、led.h、beep.c、beep.h都复制过来。以模板工程为基础,创建新的工程。

嵌入式开发学习之--按键检测_学习_02

        接着来写一下key.c,key.h的引脚配置代码,大体步骤和之前的led、蜂鸣器基本类似,这里需要注意的是引脚的模式是配置成浮空输入模式,然后既不拉高也不拉低。

        key.h

#ifndef __KEY_H
#define __KEY_H

#include "stm32f4xx.h"

//引脚定义
/*******************************************************/
#define KEY1_PIN GPIO_Pin_0
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCC_AHB1Periph_GPIOA

#define KEY2_PIN GPIO_Pin_13
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_CLK RCC_AHB1Periph_GPIOC
/*******************************************************/


#define KEY_ON 1
#define KEY_OFF 0

#define KEY1_READ GPIO_ReadInputDataBit(KEY1_GPIO_PORT ,KEY1_PIN)
#define KEY2_READ GPIO_ReadInputDataBit(KEY2_GPIO_PORT ,KEY2_PIN)

void Key_GPIO_Config(void);

#endif

        key.c

#include "key.h" 

//按键引脚初始化
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;


RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);


GPIO_InitStructure.GPIO_Pin = KEY1_PIN;

//配置成输入模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;


GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;


GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = KEY2_PIN;


GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);
}

        有了上述代码,我们可以通过Key_GPIO_Config对引脚进行初始化,然后通过KEY1_READ和KEY2_READ获取两个按键的状态。这里我们只需要用KEY1_READ就可以了,获取到按键状态,然后根据按键状态去控制led灯和蜂鸣器。

        main.c

#include "stm32f4xx.h"
#include "led.h"
#include "beep.h"
#include "key.h"


void bsp_init(void)
{
BEEP_GPIO_Config();
Key_GPIO_Config();
LED_GPIO_Config();
}

uint8_t key1_inspect()
{
if(KEY1_READ==KEY_ON){
return KEY_ON;
}else if(KEY1_READ==KEY_OFF){
return KEY_OFF;
}
}

uint8_t key2_inspect()
{
if(KEY2_READ==KEY_ON){
return KEY_ON;
}else if(KEY2_READ==KEY_OFF){
return KEY_OFF;
}
}

int main(void)
{
uint8_t led_status;
led_status=OFF;
bsp_init();

while(1){

if(key1_inspect()==KEY_ON){
led_status=!led_status;
BEEP_ON;
while(key1_inspect()==KEY_ON){

}
BEEP_OFF;
}
LED1(led_status);
}
}

总结:

        I/O输入是一很简单的输入,但是有了输入也就是有互动了,也就是说学会I/O输入就可以通过按钮对机器进行控制。而且按键输入也是嵌入式设备上应用十分广泛的一种输入方式,主要就是简单,便宜。