正点原子STM32cubeide学习——按键控制原理

使用的是正点原子的精英版,单片机STM32F103ZET6,本例程实现实现KEY UP控制蜂鸣器响停,KEY1控制LED1翻转,KEY0控制LED0翻转。先看原理图

 

主要使用到的是开发板上面的KEY_UP, KEY0, KEY1 三个按键分别对应的是PA0,PE4, PE3三个IO口,根据电路图可以知道 KEY_UP是接到高电平3.3V上面,KEY0, KEY1接到GND上面。当KEY_UP按下时PA0就会读取到高电平,所以为了读取到准确的高低电平,我们需要将PA0设置为下拉输入,KEY0, KEY1与KEY_UP相反即可。

下面我们开始操作,复制黏贴上一节蜂鸣器的代码,参考上一章代码,打开图形化配置将PB8进行如下配置 

 

 

按照上图进行配置,KEY0与KEY1一样配置即可(标签不一样),其他的都不需要更改,点击上面齿轮生成代码,在BSP文件下新建KEY文件里面新建key.c与key.h工程,和上章一样将路径添加进去即可, 

 

好的,接下来在key.c中添加以下代码 

#include "key.h"

/**
 * @brief       按键扫描函数
 * @note        该函数有响应优先级(同时按下多个按键): WK_UP > KEY1 > KEY0!!
 * @param       mode:0 / 1, 具体含义如下:
 *   @arg       0,  不支持连续按(当按键按下不放时,只有第一次调用会返回键值,
 *                  必须松开以后,再次接下才会返回其他键值)
 *   @arg       1,  支持连续按(当按键按下不放时,每次调用该函数都会返回键值)
 * @retval      键值,定义如下:
 *              KEY0_PRES, 1, KEY0按下
 *              KEY1_PRES, 2, KEY1按下
 *              WKUP_PRES, 3, WKUP按下
 */
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 || WK_UP == 1))  /* 按键松开标志为1,且有任意一个按键按下了 */
    {
        HAL_Delay(10);           /* 去抖动 */
        key_up = 0;                /* 模式:不支持连续按 */

        if (KEY0 == 0)  keyval = KEY0_PRES;//当检测到KEY0按下时,返回值为KEY0_PRES,也就是1

        if (KEY1 == 0)  keyval = KEY1_PRES;//当检测到KEY1按下时,返回值为KEY1_PRES,也就是2

        if (WK_UP == 1) keyval = WKUP_PRES;//当检测到WK_UP按下时,返回值为WKUP_PRES,也就是3
    }
    else if (KEY0 == 1 && KEY1 == 1 && WK_UP == 0) /* 没有任何按键按下,标记按键松开 */
    {
        key_up = 1;              /* 模式:支持连接 */
    }

    return keyval;              /* 返回键值 */
}

在key.h中添加以下代码

#ifndef BSP_KEY_KEY_H_
#define BSP_KEY_KEY_H_

#include "main.h"
#define KEY0        HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)     /* 读取KEY0引脚 */
#define KEY1        HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)     /* 读取KEY10引脚  */
#define WK_UP       HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin)     /* 读取WKUP引脚  */

#define KEY0_PRES    1              /* KEY0按下 */
#define KEY1_PRES    2              /* KEY1按下 */
#define WKUP_PRES    3              /* KEY_UP按下(即WK_UP) */
uint8_t key_scan(uint8_t mode);     /* 按键扫描函数 */
#endif /* BSP_KEY_KEY_H_ */

在main.c中添加以下代码 

/* USER CODE BEGIN Includes */
#include "led.h"
#include "beep.h"
#include "key.h"

/* USER CODE END Includes */
int main(void)
{

  /* USER CODE BEGIN 1 */
	uint8_t key=0;
  /* 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 */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  
	  key=key_scan(0);//模式,不支持连续按
	  if(key==KEY0_PRES)/* KEY0按下 */
	  {
		LED0_TOGGLE();//电平翻转
	  }
	  else if(key==KEY1_PRES)/* KEY1按下 */
	  {
		  LED1_TOGGLE();//电平翻转
	  }
	  else if(key==WKUP_PRES)/* KEY_UP按下(即WK_UP) */
	  {
		  BEEP_TOGGLE();//电平翻转
	  }
	  HAL_Delay(10);//消抖
    /* USER CODE END WHILE */

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

完成之后编译下载,即可实现KEY UP控制蜂鸣器响停,KEY1控制LED1翻转,KEY0控制LED0翻转。 

### 关于正点原子STM32按键输入的示例代码与教程 #### 使用STM32CubeMX初始化项目 为了实现按键输入功能,首先需要通过STM32CubeMX工具创建一个新的工程,并配置相应的外设。具体来说,在Pinout & Configuration界面中设置GPIO端口作为输入模式来连接物理按键[^1]。 #### 配置GPIO用于按键检测 对于STM32F1系列微控制器而言,可以利用内部上拉电阻的方式简化电路设计。当没有按下按钮时,默认状态为高电平;而一旦按下,则会切换至低电平触发中断或轮询读取该引脚的状态变化来进行事件处理。 ```c // 初始化 GPIOA 的 PA0 作为按键输入引脚 void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; // 或者使用 GPIO_PULLUP 启用内部上拉 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` #### 实现简单的按键扫描逻辑 下面给出了一段基于轮询机制的简单程序片段,用来持续监测指定IO口上的电压水平从而判断是否有按键动作发生: ```c #include "main.h" int main(void) { HAL_Init(); SystemClock_Config(); // 设置系统时钟 MX_GPIO_Init(); // 初始化 GPIO while (1) { if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){ // 当PA0处于低电平时表示按键被按下 // 执行相应操作... // 添加去抖动延迟 HAL_Delay(50); // 确认按键已经释放再继续循环 while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) != GPIO_PIN_SET); } // 主循环延时防止CPU占用过高 HAL_Delay(10); } } ``` 此段代码展示了如何在一个无限循环内不断检查特定I/O管脚的状态,以此方式捕捉到用户的交互行为。同时注意到加入了简单的软件消抖措施以提高可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值