STM32F103 独立按键控制LED灯

简介

本篇文章主要写的是关于本人对于STM32F103 按键控制LED灯的学习,功能为:

①按键1控制 LED0

②按键2 控制 LED1 亮
③按键3 控制 LED0 和 LED1 翻转
④WK_UP 关闭 LED0 和 LED1 

原理介绍:

LED:

        上图为STM32F103中的LED0和LED1的原理图,当输入为0时,二者导通。当输入为1时,二者阻滞。故输入为低电平时,LED0与1才会亮。

KEY:

        从原理图来看,KEY0、KEY1 和 KEY2 是低电平有效的,而 KEY_UP 则是高电平有 效的,并且外部都没有上下拉电阻,所以需要在 STM32F103 内部设置上下拉,来确定设置空闲 电平状态。

代码部分:

LED:        

#include "./BSP/LED/led.h"

 void led_init(void)
 {
	 GPIO_InitTypeDef GPIO_LD;
	 
    LED0_GPIO_CLK_ENABLE();
	  LED1_GPIO_CLK_ENABLE();
	  GPIO_LD.Pin = LED0_GPIO_PIN;
	  GPIO_LD.Mode = GPIO_MODE_OUTPUT_PP;
	  GPIO_LD.Pull = GPIO_PULLUP;
	  GPIO_LD.Speed = GPIO_SPEED_FREQ_HIGH;
	  HAL_GPIO_Init(LED0_GPIO_PORT,&GPIO_LD);
	 
	  GPIO_LD.Pin = LED1_GPIO_PIN;
	  HAL_GPIO_Init(LED1_GPIO_PORT,&GPIO_LD);
	 	 
	  LED0(1);
	  LED1(1); 
	 
 }
#ifndef __LED_H
#define __LED_H
#include "./SYSTEM/sys/sys.h"

#define  LED0_GPIO_PORT	    GPIOB
#define  LED0_GPIO_PIN	    GPIO_PIN_5
#define  LED0_GPIO_CLK_ENABLE()     do{__HAL_RCC_GPIOB_CLK_ENABLE();}while(0)

#define  LED1_GPIO_PORT	    GPIOE
#define  LED1_GPIO_PIN	    GPIO_PIN_5
#define  LED1_GPIO_CLK_ENABLE()     do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)

#define LED0(x)   do{ x ?\
	HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
	HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)      

#define LED1(x)   do{ x ?\
	HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
	HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0) 

#define LED0_TogglePin() do{HAL_GPIO_TogglePin(LED0_GPIO_PORT,LED0_GPIO_PIN);} while(0)
#define LED1_TogglePin() do{HAL_GPIO_TogglePin(LED1_GPIO_PORT,LED1_GPIO_PIN);} while(0)

void led_init(void);

#endif

以上为led.c与led.h的代码led.h主要是进行宏定义,使得功能看起来比较清晰,led.c的功能是开时钟以及设置LED有关引脚的输出模式以及频率。

KEY:

#ifndef  __KEY_H
#define  __KEY_H

#include "./SYSTEM/sys/sys.h"

#define  KEY0_GPIO_PORT	    GPIOE
#define  KEY0_GPIO_PIN	    GPIO_PIN_4
#define  KEY0_GPIO_CLK_ENABLE()     do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)

#define  KEY1_GPIO_PORT	    GPIOE
#define  KEY1_GPIO_PIN	    GPIO_PIN_3
#define  KEY1_GPIO_CLK_ENABLE()     do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)

#define  KEY2_GPIO_PORT	    GPIOE
#define  KEY2_GPIO_PIN	    GPIO_PIN_2
#define  KEY2_GPIO_CLK_ENABLE()     do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)

#define  WKUP_GPIO_PORT	    GPIOA
#define  WKUP_GPIO_PIN	    GPIO_PIN_0
#define  WKUP_GPIO_CLK_ENABLE()     do{__HAL_RCC_GPIOA_CLK_ENABLE();}while(0)

#define  KEY0 HAL_GPIO_ReadPin(KEY0_GPIO_PORT,KEY0_GPIO_PIN) 
#define  KEY1 HAL_GPIO_ReadPin(KEY1_GPIO_PORT,KEY1_GPIO_PIN) 
#define  KEY2 HAL_GPIO_ReadPin(KEY2_GPIO_PORT,KEY2_GPIO_PIN) 
#define  WKUP HAL_GPIO_ReadPin(WKUP_GPIO_PORT,WKUP_GPIO_PIN) 

#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define WKUP_PRES 4

uint8_t key_scan(uint8_t mode);
void key_init(void);

#endif
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"

void key_init(void)
{

    GPIO_InitTypeDef GPIO_ANJIAN;

    KEY0_GPIO_CLK_ENABLE();
    KEY1_GPIO_CLK_ENABLE();
    KEY2_GPIO_CLK_ENABLE();
    WKUP_GPIO_CLK_ENABLE();

  GPIO_ANJIAN.Pin = KEY0_GPIO_PIN;
	GPIO_ANJIAN.Mode = GPIO_MODE_INPUT;
	GPIO_ANJIAN.Pull = GPIO_PULLUP;
	GPIO_ANJIAN.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(KEY0_GPIO_PORT,&GPIO_ANJIAN);

  GPIO_ANJIAN.Pin = KEY1_GPIO_PIN;
	GPIO_ANJIAN.Mode = GPIO_MODE_INPUT;
	GPIO_ANJIAN.Pull = GPIO_PULLUP;
	GPIO_ANJIAN.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(KEY1_GPIO_PORT,&GPIO_ANJIAN);

  GPIO_ANJIAN.Pin = KEY2_GPIO_PIN;
	GPIO_ANJIAN.Mode = GPIO_MODE_INPUT;
	GPIO_ANJIAN.Pull = GPIO_PULLUP;
	GPIO_ANJIAN.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(KEY2_GPIO_PORT,&GPIO_ANJIAN);

  GPIO_ANJIAN.Pin = WKUP_GPIO_PIN;
	GPIO_ANJIAN.Mode = GPIO_MODE_INPUT;
	GPIO_ANJIAN.Pull = GPIO_PULLDOWN;
	GPIO_ANJIAN.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(WKUP_GPIO_PORT,&GPIO_ANJIAN);
}

    uint8_t key_scan(uint8_t mode)
{
    static uint8_t key_up = 1; 
    uint8_t keyval = 0;

    if(mode)
    {
        key_up = 1;
    }

    
    if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WKUP == 1))
    {
        delay_ms(10);
        key_up = 0; 
        if (KEY0 == 0)
            keyval = KEY0_PRES;
        if (KEY1 == 0)
            keyval = KEY1_PRES;
        if (KEY2 == 0)
            keyval = KEY2_PRES;
        if (WKUP == 1)
            keyval = WKUP_PRES;
    }
    else if( KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WKUP == 0)
    {
        key_up = 1;
    }

    return keyval;
}

key.c中:

void key_init(void) 用于初始化按键。它首先使能了按键所在GPIO端口的时钟,然后配置了每个按键的GPIO属性(如模式、上拉/下拉电阻、速度等),最后调用HAL_GPIO_Init函数来初始化GPIO。

uint8_t key_scan(uint8_t mode)里定义了一个key_scan函数,用于检测按键的状态。使用静态变量key_up来记录按键是否处于释放状态,并在按键被按下时通过条件判断来设置相应的按键keyval。通过mode参数来重置按键状态,以及在检测到按键状态变化时进行了消抖。如果所有按键都未被按下,则重置key_up为释放状态。

key.h中:

主要用于定义与按键相关的宏和声明按键操作的函数。

MAIN:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include <stdio.h>

int main(void)
{
    HAL_Init();                                 
    sys_stm32_clock_init(RCC_PLL_MUL9);        
    delay_init(72);                           
	  led_init(); 
	  key_init();
	  uint8_t key;
	   
    while(1)
    {  
		key = key_scan(0);
		if (key)
		{
			switch(key)
			{
				case KEY0_PRES:
				  LED0(0);
				  break;
				case KEY1_PRES:
				  LED1(0);
				  break;
				case KEY2_PRES:
				  LED0_TogglePin();
				  LED1_TogglePin();
				  break;
				case WKUP_PRES:
				  LED0(1);
				  LED1(1);
				  break;
			}
		}   				
	}   						    
}

while(1) 循环用于不断检测按键的状态。

key = key_scan(0);:调用key_scan函数扫描按键状态,并将结果保存在key变量中。0作为参数传递给key_scan,可能表示不需要重置按键状态。

if (key):如果key的值不为0(即有按键被按下)。

switch(key):根据key的值选择相应的case来执行。

KEY0_PRES:如果按键0被按下,打开LED0。

KEY1_PRES:如果按键1被按下,打开LED1。

KEY2_PRES:如果按键2被按下,LED1与LED0的状态进行翻转。

WKUP_PRES:如果WKUP按键被按下,关闭LED0和LED1。

演示视频:

按键控制led演示

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值