STM32F4xx.按键控制LED灯(标准库)

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;
}
 

-----------------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值