STM32WL开发之易智联LORA评估板上按键KEY的配置与应用

前言:在前一篇《STM32WL开发之LORA评估板上通过GPIO控制LED》中已经基于易智联的LoRa评估板LM401-Pro-Kit介绍了在其Demo例程上如何实现GPIO控制LED闪烁的功能,本文将介绍如何基于LoRa评估板和Demo例程实现按键KEY的配置与应用。

功能描述

本文将基于Demo例程实现一个通过按键KEY控制LED闪灯,当按键KEY按下,LED灯闪灯一次。

STM32中按键的工作原理

STM32中GPIO引脚自带上拉、下拉输入,因此硬件电路部分不需要加额外的电阻实现上拉下拉。主要有以下两种方式实现独立按键设计:

(一)高电平检测独立按键:

只需要从VCC引线通过一个按键开关到单片机I/O口,软件初始化配置为下拉输入或浮空输入。当按键开关按下时开关导通,单片机I/O口就检测到高电平输入。

(二)低电平检测独立按键:

同理从GND引线通过一个按键开关到单片机I/O口,软件初始化配置为上拉输入或浮空输入。当按键开关按下时开关导通,单片机I/O口就检测到低电平输入。

注意:

实现方式不同的独立按键,按键检测函数也不相同,需要修改到对应的检测方式功能才能正常使用,比如低电平和高电平的检测独立按键,它们的按键检测判断条件是相反的。接入的高电平使用对应STM32单片机GPIO引脚所能承受的最大电压(大多数IO能承受5V,推荐使用3.3V),否则将损坏芯片。

按键控制电路分析

LM401-Pro-Kit评估板上按键部分的原理图如下:

由上图可知,按键连接到PA0,低电平有效,所以按键配置为上拉输入,默认情况下读取到GPIO的电平为高电平,当按键按下时,相关管脚变成低电平。

GPIO控制函数

  1. 电平输入函数

       这里的输入是以MCU为参照而言的,也就是MCU读取指定GPIO端口的数据。

  1. 电平输出函数

       这里的输出也是以MCU为参照的,也就是MCU向指定GPIO端口写入数据。

  1. 电平翻转函数

       该函数完成GPIO端口状态0/1的变换,在前一篇文章中有解释。

实现代码

       本文的代码是在上文《STM32WL开发之LORA评估板上通过GPIO控制LED》的基础上开发的,LED灯也沿用上文中的LED1,本文主要介绍按键KEY部分的代码,LED 部分的代码就不再赘述。

1、宏定义

 /****** 在stm32wlxx_LM401.h文件中 ******/

typedef enum

{ 

  BUTTON_SW1 = 0,                      // 按键定义

  BUTTON_SW2 = 1,

  BUTTON_SW3 = 2,

}Button_TypeDef;



typedef enum

{ 

  BUTTON_MODE_GPIO = 0,

  BUTTON_MODE_EXTI = 1                 // 按键采用中断触发方式

}ButtonMode_TypeDef;



#define BUTTON_SW1_PIN                          GPIO_PIN_0

#define BUTTON_SW1_GPIO_PORT                    GPIOA

#define BUTTON_SW1_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOA_CLK_ENABLE()

#define BUTTON_SW1_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOA_CLK_DISABLE()

#define BUTTON_SW1_EXTI_LINE                    EXTI_LINE_0

#ifdef CORE_CM0PLUS

#define BUTTON_SW1_EXTI_IRQn                    EXTI1_0_IRQn

#else

#define BUTTON_SW1_EXTI_IRQn                    EXTI0_IRQn

#endif

#define H_EXTI_0                                hpb_exti[BUTTON_SW1]



#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__)    do { if ((__INDEX__) == BUTTON_SW1) BUTTON_SW1_GPIO_CLK_ENABLE(); else \

                                              if ((__INDEX__) == BUTTON_SW2) BUTTON_SW2_GPIO_CLK_ENABLE(); else \

                                              if ((__INDEX__) == BUTTON_SW3) BUTTON_SW3_GPIO_CLK_ENABLE();} while(0)



#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__)    do { if ((__INDEX__) == BUTTON_SW1) BUTTON_SW1_GPIO_CLK_DISABLE(); else \

                                              if ((__INDEX__) == BUTTON_SW2) BUTTON_SW2_GPIO_CLK_DISABLE(); else \

                                              if ((__INDEX__) == BUTTON_SW3) BUTTON_SW3_GPIO_CLK_DISABLE();} while(0)

2、按键初始化函数

/***** 在stm32wlxx_LM401.c文件中 *****/
int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
{
  GPIO_InitTypeDef gpio_init_structure = {0};
  static BSP_EXTI_LineCallback button_callback[BUTTONn] = {BUTTON_SW1_EXTI_Callback, BUTTON_SW2_EXTI_Callback, BUTTON_SW3_EXTI_Callback};
  static uint32_t button_interrupt_priority[BUTTONn] = {BSP_BUTTON_USER_IT_PRIORITY, BSP_BUTTON_USER_IT_PRIORITY, BSP_BUTTON_USER_IT_PRIORITY};
  static const uint32_t button_exti_line[BUTTONn] = {BUTTON_SW1_EXTI_LINE, BUTTON_SW2_EXTI_LINE, BUTTON_SW3_EXTI_LINE};

  /* Enable the BUTTON Clock */
  BUTTONx_GPIO_CLK_ENABLE(Button);
  
  gpio_init_structure.Pin = BUTTON_PIN[Button];
  gpio_init_structure.Pull = GPIO_PULLUP;
  gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;

  if(ButtonMode == BUTTON_MODE_GPIO)
  {
    /* Configure Button pin as input */
    gpio_init_structure.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure);
  }
  else /* (ButtonMode == BUTTON_MODE_EXTI) */
  {
    /* Configure Button pin as input with External interrupt */
    gpio_init_structure.Mode = GPIO_MODE_IT_FALLING;			// 按键采用下降沿中断触发的方式

    HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure);	// 按键所用的GPIO初始化

    (void)HAL_EXTI_GetHandle(&hpb_exti[Button], button_exti_line[Button]);
    (void)HAL_EXTI_RegisterCallback(&hpb_exti[Button],  HAL_EXTI_COMMON_CB_ID, button_callback[Button]);

    /* Enable and set Button EXTI Interrupt to the lowest priority */
    HAL_NVIC_SetPriority((BUTTON_IRQn[Button]), button_interrupt_priority[Button], 0x00);		// 设置中断优先级
    HAL_NVIC_EnableIRQ((BUTTON_IRQn[Button]));			// 启动中断
  }

  return BSP_ERROR_NONE;
}

3、中断处理函数

/***** 在stm32wlxx_it.c文件中 ****/
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(BUT1_Pin);		// 调用HAL层的中断处理函数
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}

/**
  * @brief  Handle EXTI interrupt request.
  * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

/***** 在subghz_phy_app.c文件中 *****/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  switch (GPIO_Pin)
  {
    case  BUTTON_SW1_PIN:			// 当按键SW1中断触发时
        BSP_LED_On(LED_BLUE) ;		// LED1的蓝灯亮
        HAL_Delay(200);				// 延迟200ms
        BSP_LED_Off(LED_BLUE) ;		// LED1的蓝灯灭
        APP_PRINTF("BUTTON SW1\r\n");
         
      break;
   
    default:
        APP_PRINTF("Unkonw Button\r\n");
      break;
  }
}

4、主函数

/***** 在main.c中 *****/
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  /* 系统时钟初始化 */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  /* 定时器初始化 */
  UTIL_TIMER_Init();

  /* 初始化LED灯 */
  BSP_LED_Init(LED_BLUE);

  /* 初始化按键,指定采用外部中断触发的方式 */
  BSP_PB_Init(BUTTON_SW1, BUTTON_MODE_EXTI);
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

测试验证

       编译工程后下载到LM401-Pro-Kit评估板上,按下PA0按键可看到LED1的蓝灯亮起,符合设计预期。

工程代码下载:

链接: https://pan.baidu.com/s/1MpVU_UDMYITYdjSG7bccqA

提取码: iyrz

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值