你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

[nucleo-H7A3ZI-Q] 2、按键输入 -- 支持短按,长按和组合按键检测的代码移植

[复制链接]
ALanStewart 发布时间:2024-5-22 12:07

image.png

前言

**cubeMX** 是一个很好的工具,提高了在配置外设的效率,故本文不对外设寄存器进行讲解,百度和官方参考手册一直都是最好的答案。因此本文会简单介绍板子原理图,cubeMX的配置流程,以及移植代码的关键步骤。 **[本文对应的代码在此,可以提前克隆下来](https://github.com/ALanStewart47/Project-H7A3ZI-Q/tree/main/Software/2.key)**

原理图

image.png 由图可知,当按下按键时候,PC13会得到一个高电平;反之,**没有按键按下时候则是低电平** 这里稍微说一下,当按键按下时候,电流经过按键流到ESD管,由于器件有齐纳二极管一样的特性,当反向偏置的时候可以流过微小电流,并二极管两端电压保持稳定,由下图可以得知该器件的稳压值(反向截止电压)为3V,选择3V应该也是考虑到齐纳二极管的特性即稳压值会有误差;不过该器件主要功能应该是进行ESD保护。**** image.png

CubeMX配置

在cubemx新建工程,选择官方开 发板进行配置(Board Selector),搜索NUCLEO-H7A3ZI-Q,并进入配置界面,弹出是否按照默认配置的时候,选择YES即可。** ![在这里插入图片描述](**https://img-![image.png](data/attachment/forum/202405/23/154927j4rpplq8drxqdsi6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "image.png")blog.csdnimg.cn/direct/90b848fa93384e57b3b6d286fb6cb965.png**) **进入配置界面后,会看到软件已经帮我们配置好开发板的按键、串口等外设了,我们只需配置想要的系统时钟即可,当然我们也可以不进行修改,按照默认的96MHz系统时钟生成代码工程。

代码移植

本文的按键功能是通过移植安富莱的按键板级支持包来实现的,而板级支持包是如何实现的,请移步到 STM32H7的GPIO应用之按键FIFO 此网站学习。此BSP支持短按,长按和组合按键检测功能,功能还是十分强大的。

简单介绍下移植的代码过程

1、拷贝bsp_key.c和bsp_key.h到你的工程里,如下图** image.png 需要注意的是,我把bsp_key.h的文件放在User\Bsp\inc文件夹里面。 2、通过MDK加入bsp_key.c和把对应头文件地址,如下图

image.png

image.png

到这里我们已经把bsp_key的代码部分已经拷到自己的工程里面了。 接下来就到了真正的移植代码的部分啦

代码修改部分

  1. 头文件。源代码是依赖于bsp.h,我们这里并没有这个.h文件,故改为依赖HAL库stm32h7xx_hal.h,但是这里我把hal.h的依赖改到bsp_key.h里面,这样显得更整齐。
#include "bsp_key.h"

#define HARD_KEY_NUM        1                               /* 实体按键个数(根据自己的项目实际来) */  
#define KEY_COUNT           (HARD_KEY_NUM + 0)  /* 1个独立建 + 0个组合按键 */

/* 使能GPIO时钟 */
#define ALL_KEY_GPIO_CLK_ENABLE() { \
        __HAL_RCC_GPIOB_CLK_ENABLE();   \
        __HAL_RCC_GPIOC_CLK_ENABLE();   \
        __HAL_RCC_GPIOG_CLK_ENABLE();   \
        __HAL_RCC_GPIOH_CLK_ENABLE();   \
        __HAL_RCC_GPIOI_CLK_ENABLE();   \
    };

这里还有一个HARD_KEY_NUM 需要修改的,改成你硬件上的按键数量,这里板上仅有一个功能按键。因为只有一个按键也无法带来组合按键的玩法,暂时就不展开这个功能了。

  1. 确定激活电平。激活电平意思是当按键按下的时候,对应IO的电平是低电平还是高电平,H7A3ZI板子按键是低电平(上面有介绍),故激活电平为0,这里bsp_key.c是用结构体数组的方式储存按键端口,pin和激活电平。
/* 依次定义GPIO */
typedef struct
{
    GPIO_TypeDef* gpio;
    uint16_t pin;
    uint8_t ActiveLevel;    /* 激活电平 */
}X_GPIO_T;

/* GPIO和PIN定义 */
static const X_GPIO_T s_gpio_list[HARD_KEY_NUM] = {
    {GPIOC, GPIO_PIN_13, 1},    /* K1 -- PC13 , 激活电平为1(高电平)*/
};  

/* 定义一个宏函数简化后续代码 
    判断GPIO引脚是否有效按下
*/
static KEY_T s_tBtn[KEY_COUNT] = {0};
static KEY_FIFO_T s_tKey;       /* 按键FIFO变量,结构体 */
  1. 屏蔽或者删除组合按键的代码
/*
*********************************************************************************************************
*   函 数 名: IsKeyDownFunc
*   功能说明: 判断按键是否按下。单键和组合键区分。单键事件不允许有其他键按下。
*   形    参: 无
*   返 回 值: 返回值1 表示按下(导通),0表示未按下(释放)
*********************************************************************************************************
*/
static uint8_t IsKeyDownFunc(uint8_t _id)
{
    /* 实体单键 */
    if (_id < HARD_KEY_NUM)
    {
        uint8_t i;
        uint8_t count = 0;
        uint8_t save = 255;

        /* 判断有几个键按下 */
        for (i = 0; i < HARD_KEY_NUM; i++)
        {
            if (KeyPinActive(i)) 
            {
                count++;
                save = i;
            }
        }

        if (count == 1 && save == _id)
        {
            return 1;   /* 只有1个键按下时才有效 */
        }   

        return 0;
    }

    /* 组合键 部分 */
    if (_id == HARD_KEY_NUM + 0)
    {
        /*
        if (KeyPinActive(KID_K1) && KeyPinActive(KID_K2))
        {
            return 1;
        }
        else
        {
            return 0;
        }
        */
    }

    /* 组合键 部分 */
    if (_id == HARD_KEY_NUM + 1)
    {
        /*
        if (KeyPinActive(KID_K2) && KeyPinActive(KID_K3))
        {
            return 1;
        }
        else
        {
            return 0;
        }
        */
    }

    return 0;
}

可以看到此处已经屏蔽了组合按键的代码了

4、(可选)删除一些没用到的宏定义或者结构体内容。在bsp_key.h里面,还有很多其他按键的宏定义,可以根据实际情况屏蔽或者删掉,本文暂不作拓展。

5、编写main函数。定义一个unsigned char的变量s_keyCode

    uint8_t s_KeyCode   ;

在while循环里面,加入bsp_KeyScan10ms(),该函数为周期性检测按键,然后通过bsp_GetKey()获取按键数值。

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
        HAL_Delay(10);
        bsp_KeyScan10ms();
        s_KeyCode=bsp_GetKey();
        if(s_KeyCode    !=  KEY_NONE)
        {

            if(s_KeyCode    ==  KEY_DOWN_K1)
            {
                printf("Key 1 down\r\n");
            }

            if(s_KeyCode    ==  KEY_1_UP)
            {
                printf("Key 1 up\r\n");
            }
            if(s_KeyCode    ==  KEY_1_LONG)
            {
                printf("Key 1 long\r\n");
            }
        }

    /* USER CODE BEGIN 3 */
  }

下载验证

通过本链接即可获得本文的代码**,编译下载到H7A3ZI-Q开发板后,打开串口工具,会发现串口会发送用户按键动作行为。

image.png

image.png
image.png
image.png
收藏 评论0 发布时间:2024-5-22 12:07

举报

0个回答

所属标签

ST中文论坛活动

即日起开启活动话题入口,之后的活动统一都放在此处,欢迎大家的加入!


最新内容

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版