key.h-------------------------------------------------------------------------------------------------
#ifndef __KEY_H
#define __KEY_H
// 定义按键编号或GPIO引脚
typedef enum {
KEY_1 = 0, // 对应GPIOA_Pin0
KEY_2, // 对应GPIOA_Pin1
KEY_3, // 对应GPIOA_Pin2
KEY_4, // 对应GPIOA_Pin2
KEY_NUM // 按键总数
} Key_ID;
#include "stm32f4xx.h"
u8 Key_Scan(u8 mode);
void Key_PA0_Init(void);
u8 Key_Scanpro(Key_ID key_id, u8 mode);
#endif
---------------------------------------------------------------------------------------------------------
led.h---------------------------------------------------------------------------------------------------
#ifndef __LED_H
#define __LED_H
#include "stm32f4xx.h"
void Led_Init(void);
#endif
----------------------------------------------------------------------------------------------------------
key.c---------------------------------------------------------------------------------------------------
#include "key.h"
/************************************
引脚说明:
KEY0连接PA0
KEY0按下,PA0为低电平
KEY0未按下,PA0为高电平
KEY1、2、3连接PE2、3、4
************************************/
void Key_PA0_Init(void)
{
//结构体变量
GPIO_InitTypeDef GPIO_InitStruct;
//使能GPIOA组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //引脚0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //根据外面电路来设置即可
GPIO_Init(GPIOA, &GPIO_InitStruct);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 |GPIO_Pin_4; //引脚0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //根据外面电路来设置即可
GPIO_Init(GPIOE, &GPIO_InitStruct);
}
void delays(int n)
{
int i, j;
for(i=0; i<n; i++)
for(j=0; j<10000; j++);
}
u8 Key_Scan(u8 mode){
static u8 key_up = 1;//按键标志
if(mode == 1)
key_up = 1; //支持连按
if(key_up && GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0 ){
delays(10);
key_up = 0; //支持连按
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0){
return 1;
}
}
else if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1){
key_up = 1;
}
return 0;
}
u8 Key_Scanpro(Key_ID key_id, u8 mode){
static u8 key_up[KEY_NUM] = {1, 1, 1,1}; // 每个按键独立的状态标志
GPIO_TypeDef* port; // 按键对应的GPIO端口
u16 pin; // 按键对应的引脚
// 根据按键ID绑定GPIO引脚(需根据实际硬件修改)
switch (key_id) {
case KEY_1:
port = GPIOA;
pin = GPIO_Pin_0;
break;
case KEY_2:
port = GPIOE;
pin = GPIO_Pin_2;
break;
case KEY_3:
port = GPIOE;
pin = GPIO_Pin_3;
break;
case KEY_4:
port = GPIOE;
pin = GPIO_Pin_4;
break;
default:
return 0; // 无效按键
}
if (mode == 1) {
key_up[key_id] = 1; // 连按模式强制重置状态
}
// 检测按键按下
if (key_up[key_id] && GPIO_ReadInputDataBit(port, pin) == 0) {
delays(10); // 去抖动
if (GPIO_ReadInputDataBit(port, pin) == 0) {
key_up[key_id] = 0; // 标记为按下状态
return 1; // 返回按键按下事件
}
} else if (GPIO_ReadInputDataBit(port, pin) == 1) {
key_up[key_id] = 1; // 按键释放时重置状态
}
return 0;
}
----------------------------------------------------------------------------------------------------------------
led.c----------------------------------------------------------------------------------------------------------
#include "led.h"
/************************************
引脚说明:
LED0连接在PF9
PF9输出低电平,灯亮;输出高电平,灯灭
LED1 -- PF10
LED2 -- PE13
LED3 -- PE14
************************************/
void Led_Init(void)
{
//结构体变量
GPIO_InitTypeDef GPIO_InitStruct;
//使能GPIOE组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
//使能GPIOF组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //引脚9 10
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//输出
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;//25MHZ速度
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //无上下拉
GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; //引脚13 14
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//输出
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;//25MHZ速度
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //无上下拉
GPIO_Init(GPIOE, &GPIO_InitStruct);
//灯全灭
GPIO_SetBits(GPIOF, GPIO_Pin_9);
GPIO_SetBits(GPIOF, GPIO_Pin_10);
GPIO_SetBits(GPIOE, GPIO_Pin_13);
GPIO_SetBits(GPIOE, GPIO_Pin_14);
}
----------------------------------------------------------------------------------------------------------------
main.c.------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include "led.h"
#include "key.h"
//粗延时(就是延时不一定准确的意思)
void delay(int n)
{
int i, j;
for(i=0; i<n; i++)
for(j=0; j<10000; j++);
}
int main(void)
{
//初始化后GPIOF_ODR默认为低电平,所以灯亮
Led_Init();
Key_PA0_Init();
// while(1)
// {
// //判断引脚是否为低电平
// if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
// {
// delay(15); // 15ms延时消抖
// //第二检测
// if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
// {
// //按键按下
// GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
// }
// }
// else if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) == 0){
// delay(15); // 15ms延时消抖
// //第二检测
// if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) == 0)
// {
// //按键按下
// GPIO_ToggleBits(GPIOF, GPIO_Pin_10);
// }
// }
// else if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0){
// delay(15); // 15ms延时消抖
// //第二检测
// if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0)
// {
// //按键按下
// GPIO_ToggleBits(GPIOE, GPIO_Pin_13);
// }
// }
// else if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) == 0){
// delay(15); // 15ms延时消抖
// //第二检测
// if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) == 0)
// {
// //按键按下
// GPIO_ToggleBits(GPIOE, GPIO_Pin_14);
// }
// }
// }
while(1){
// 检测多个按键,0是不支持连按,1是支持连按
u8 key1 = Key_Scanpro(KEY_1, 0);
u8 key2 = Key_Scanpro(KEY_2, 0);
u8 key3 = Key_Scanpro(KEY_3, 0);
u8 key4 = Key_Scanpro(KEY_4, 0);
// 根据按键触发动作
if (key1 == 1) {
GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
}
if (key2 == 1) {
GPIO_ToggleBits(GPIOF, GPIO_Pin_10);
}
if (key3 == 1) {
GPIO_ToggleBits(GPIOE, GPIO_Pin_13);
}
if (key4 == 1) {
GPIO_ToggleBits(GPIOE, GPIO_Pin_14);
}
}
return 0;
}
-----------------------------------------------------------------------------------------------------------