在我的STM32F103ZET6核心板上有四个按键,其中一个是复位按键,其余三个原理图如下图所示。
其中KEY0和KEY1分别接在PE3和PE4上,然后低有效。WK_UP接在PA0上,高电平有效。而且根据原理图,在外部电路中是没有上下拉电阻的,所以我们需要在STM32中设置上下拉电阻。
一样,因为设置按键也是配置IO口工作方式。
main.c
/*******************************************************************************
* 文件名:main.c
* 描 述:
1.按下KEY0,LED0状态切换
2.按下KEY1,LED1状态切换
3.按下WK_UP,LED0和LED1状态切换
* 作 者:小默haa
* 版本号:v1.0
* 日 期: 2019年1月28日
* 备 注:独立按键控制LED点亮
*
*******************************************************************************/
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
static u8 flag = 0;
LED_Init();
KEY_Init();
delay_init();
while(1)
{
flag = KEY_Scan(0);
switch(flag)
{
case 1:LED0 = !LED0; break;
case 2:LED1 = !LED1; break;
case 3:LED0 = !LED0; LED1 = !LED1; break;
default:break;
}
}
}
LED.c
#include "led.h"
/*******************************************************************************
* 函数名 :LED_Init
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月26日
* 功能描述:LED初始化
* 备注 :
*******************************************************************************/
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);//设能PB和PE口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0->PB5 端口配置
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数设定参数配置GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1->PE5 端口配置
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure); //根据参数设定参数配置GPIO
}
LED.h
#ifndef __LED_H__
#define __LED_H__
#include "sys.h"
#define LED0 PBout(5)
#define LED1 PEout(5)
void LED_Init(void);
#endif
key.c
#include "key.h"
/*******************************************************************************
* 函数名 :KEY_Init
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月28日
* 功能描述:按键初始化
* 备注 :
*******************************************************************************/
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE, ENABLE);//设能PA和PE口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4; //GPIOE3,GPIOE4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置为上拉输入模式
GPIO_Init(GPIOE, &GPIO_InitStructure); //根据参数设定参数配置GPIOE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置为下拉输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据参数设定参数配置GPIOA
}
/*******************************************************************************
* 函数名 :KEY_Scan
* 输入值 :u8 mode
* 返回值 :按键值
* 作者 :小默haa
* 时间 :2019年1月28日
* 功能描述:按键扫描
* 备注 :mode = 0 -> 不支持按键长按
mode = 1 -> 支持按键长按
*******************************************************************************/
int KEY_Scan(u8 mode)
{
static u8 key_up = 1; //按键弹起标志
if(mode)
key_up = 1; //支持按键长按核心代码
if(key_up && (!KEY0 || !KEY1 || WK_UP)) //检测到按键按下
{
delay_ms(10); //延时10ms消抖
key_up = 0;
if(!KEY0)
return KEY0_PRESS;
else if(!KEY1)
return KEY1_PRESS;
else if(WK_UP)
return WK_UP_PRESS;
}
else if(KEY0 && KEY1 && !WK_UP)
key_up = 1;
return 0;
}
key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "sys.h"
#include "delay.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KEY0_PRESS 1 //KEY0按下
#define KEY1_PRESS 2 //KEY1按下
#define WK_UP_PRESS 3 //WK_UP按下
void KEY_Init(void);
int KEY_Scan(u8 mode);
#endif
在我的STM32F103ZET6核心板上有四个按键,其中一个是复位按键,其余三个原理图如下图所示。
其中KEY0和KEY1分别接在PE3和PE4上,然后低有效。WK_UP接在PA0上,高电平有效。而且根据原理图,在外部电路中是没有上下拉电阻的,所以我们需要在STM32中设置上下拉电阻。
一样,因为设置按键也是配置IO口工作方式。
main.c
/*******************************************************************************
* 文件名:main.c
* 描 述:
1.按下KEY0,LED0状态切换
2.按下KEY1,LED1状态切换
3.按下WK_UP,LED0和LED1状态切换
* 作 者:小默haa
* 版本号:v1.0
* 日 期: 2019年1月28日
* 备 注:独立按键控制LED点亮
*
*******************************************************************************/
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
static u8 flag = 0;
LED_Init();
KEY_Init();
delay_init();
while(1)
{
flag = KEY_Scan(0);
switch(flag)
{
case 1:LED0 = !LED0; break;
case 2:LED1 = !LED1; break;
case 3:LED0 = !LED0; LED1 = !LED1; break;
default:break;
}
}
}
LED.c
#include "led.h"
/*******************************************************************************
* 函数名 :LED_Init
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月26日
* 功能描述:LED初始化
* 备注 :
*******************************************************************************/
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);//设能PB和PE口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0->PB5 端口配置
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数设定参数配置GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1->PE5 端口配置
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure); //根据参数设定参数配置GPIO
}
LED.h
#ifndef __LED_H__
#define __LED_H__
#include "sys.h"
#define LED0 PBout(5)
#define LED1 PEout(5)
void LED_Init(void);
#endif
key.c
#include "key.h"
/*******************************************************************************
* 函数名 :KEY_Init
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月28日
* 功能描述:按键初始化
* 备注 :
*******************************************************************************/
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE, ENABLE);//设能PA和PE口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4; //GPIOE3,GPIOE4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置为上拉输入模式
GPIO_Init(GPIOE, &GPIO_InitStructure); //根据参数设定参数配置GPIOE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置为下拉输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据参数设定参数配置GPIOA
}
/*******************************************************************************
* 函数名 :KEY_Scan
* 输入值 :u8 mode
* 返回值 :按键值
* 作者 :小默haa
* 时间 :2019年1月28日
* 功能描述:按键扫描
* 备注 :mode = 0 -> 不支持按键长按
mode = 1 -> 支持按键长按
*******************************************************************************/
int KEY_Scan(u8 mode)
{
static u8 key_up = 1; //按键弹起标志
if(mode)
key_up = 1; //支持按键长按核心代码
if(key_up && (!KEY0 || !KEY1 || WK_UP)) //检测到按键按下
{
delay_ms(10); //延时10ms消抖
key_up = 0;
if(!KEY0)
return KEY0_PRESS;
else if(!KEY1)
return KEY1_PRESS;
else if(WK_UP)
return WK_UP_PRESS;
}
else if(KEY0 && KEY1 && !WK_UP)
key_up = 1;
return 0;
}
key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "sys.h"
#include "delay.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KEY0_PRESS 1 //KEY0按下
#define KEY1_PRESS 2 //KEY1按下
#define WK_UP_PRESS 3 //WK_UP按下
void KEY_Init(void);
int KEY_Scan(u8 mode);
#endif
举报