当前位置: 首页 > article >正文

【鸿蒙开发】Hi3861学习笔记- GPIO之按键

00. 目录

文章目录

    • 00. 目录
    • 01. GPIO概述
    • 02. 按键概述
    • 03. 硬件设计
    • 04. 软件设计
    • 05. 实验现象
    • 06. 附录

01. GPIO概述

GPIO(General-purpose input/output)即通用型输入输出。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。

基本概念

GPIO又俗称为I/O口,I指的是输入(in),O指的是输出(out)。可以通过软件来控制其输入和输出,即I/O控制。

  • GPIO输入

    输入是检测各个引脚上的电平状态,高电平或者低电平状态。常见的输入模式有:模拟输入、浮空输入、上拉输入、下拉输入。

  • GPIO输出

    输出是当需要控制引脚电平的高低时需要用到输出功能。常见的输出模式有:开漏输出、推挽输出、复用开漏输出、复用推挽输出。

02. 按键概述

按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时,开关断开。一般机械按键按下和松开时存在抖动情况,如下:
在这里插入图片描述

这种抖动可能会影响程序误判,造成严重后果,通常会使用软件延时 10ms来消斗。例如,当按键按下后,引脚为低电平;所以首先读取

引脚电平,若引脚为低电平,则延时 10ms 后再次读取引脚电平,若为低电平,则证明按键已按下。

消抖方案对比

方案优点缺点
RC滤波成本低、简单易实现响应速度较慢
RS锁存器无抖动、可靠性高需要额外逻辑芯片
软件消抖无需硬件、灵活可调依赖MCU资源及代码质量

03. 硬件设计

在这里插入图片描述

由图可知,P1 端子的 KEY1-KEY2 脚为按键控制端,要检测按键是否被按下,只需读取端子的 KEY1-KEY2 脚是否为低电平,因此可使用

导线将芯片的 IO 口与P1 端子的 KEY1-KEY2 脚连接。

04. 软件设计

bsp_key.h

#ifndef BSP_KEY_H
#define BSP_KEY_H

#include "cmsis_os2.h"
#include "hi_io.h"
#include "hi_gpio.h"


//管脚定义
#define KEY1_PIN         HI_IO_NAME_GPIO_11
#define KEY1_GPIO_FUN    HI_IO_FUNC_GPIO_11_GPIO

#define KEY2_PIN         HI_IO_NAME_GPIO_12
#define KEY2_GPIO_FUN    HI_IO_FUNC_GPIO_12_GPIO


//使用宏定义独立按键按下的键值
#define KEY1_PRESS  1
#define KEY2_PRESS  2
#define KEY_UNPRESS 0 


//函数声明
void key_init(void);
uint8_t key_scan(uint8_t mode);

#endif

bsp_key.c

#include "bsp_key.h"
#include <unistd.h>

//按键初始化
void key_init(void)
{
    hi_gpio_init();                                            // GPIO初始化
    hi_io_set_pull(KEY1_PIN, HI_IO_PULL_UP);                   // 设置GPIO上拉
    hi_io_set_func(KEY1_PIN, KEY1_GPIO_FUN);                   // 设置IO为GPIO功能
    hi_gpio_set_dir(KEY1_PIN, HI_GPIO_DIR_IN);                // 设置GPIO为输入模式

    hi_io_set_pull(KEY2_PIN, HI_IO_PULL_UP);                   // 设置GPIO上拉
    hi_io_set_func(KEY2_PIN, KEY2_GPIO_FUN);                   // 设置IO为GPIO功能
    hi_gpio_set_dir(KEY2_PIN, HI_GPIO_DIR_IN);                // 设置GPIO为输入模式
}

/*******************************************************************************
* 函 数 名       : key_scan
* 函数功能        : 检测独立按键是否按下,按下则返回对应键值
* 输    入       : mode=0:单次扫描按键
                  mode=1:连续扫描按键
* 输    出       : KEY1_PRESS:K1按下
                  KEY2_PRESS:K2按下
                  KEY_UNPRESS:未有按键按下
*******************************************************************************/
uint8_t key_scan(uint8_t mode)
{
    static uint8_t key1=0;
    static uint8_t key2=0;

    hi_gpio_get_input_val(KEY1_PIN,&key1);
    hi_gpio_get_input_val(KEY2_PIN,&key2);

    if(key1==0 || key2==0)
    {
        usleep(10*1000);//消抖
        hi_gpio_get_input_val(KEY1_PIN,&key1);
        hi_gpio_get_input_val(KEY2_PIN,&key2);
        if(key1==0 || key2==0)
        {
            if(key1==0)return KEY1_PRESS;
            else if(key2==0)return KEY2_PRESS;
        }
    }
    return KEY_UNPRESS;   
}

template.c

#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "bsp_key.h"
#include "bsp_led.h"


//按键控制任务
osThreadId_t KEY_Task_ID; //任务ID

void KEY_Task(void)
{
    uint8_t key=0;

    led_init();//LED初始化
    key_init();//按键初始化

    while (1) 
    {
        key=key_scan(0);//按键扫描
        if(key==KEY1_PRESS)LED(1);//点亮
        else if(key==KEY2_PRESS)LED(0);//熄灭

        usleep(10*1000);
    }
}
//按键控制任务创建
void key_task_create(void)
{
    osThreadAttr_t taskOptions;
    taskOptions.name = "keyTask";            // 任务的名字
    taskOptions.attr_bits = 0;               // 属性位
    taskOptions.cb_mem = NULL;               // 堆空间地址
    taskOptions.cb_size = 0;                 // 堆空间大小
    taskOptions.stack_mem = NULL;            // 栈空间地址
    taskOptions.stack_size = 1024;           // 栈空间大小 单位:字节
    taskOptions.priority = osPriorityNormal; // 任务的优先级

    KEY_Task_ID = osThreadNew((osThreadFunc_t)KEY_Task, NULL, &taskOptions); // 创建任务1
    if (KEY_Task_ID != NULL)
    {
        printf("ID = %d, Task Create OK!\n", KEY_Task_ID);
    }
}

/**
 * @description: 初始化并创建任务
 * @param {*}
 * @return {*}
 */
static void template_demo(void)
{
    printf("-Hi3861开发板--按键控制实验\r\n");

    key_task_create();//按键任务
}
SYS_RUN(template_demo);

05. 实验现象

下载程序前,按照如下接线
在这里插入图片描述

实验现象:按键 K1-K2 控制 LED 指示灯亮灭。

06. 附录


http://www.kler.cn/a/584071.html

相关文章:

  • 小白学习:提示工程(什么是prompt)
  • PostgreSQL存储管理体系结构学习笔记2
  • Linux第二次练习
  • hive-进阶版-1
  • 嵌入式开发工程师笔试面试指南-模电基础
  • 查找某个端口是否被占用
  • 【数据结构】4线性表综合实验
  • 前端学习笔记(三)——ant-design vue表单传递数据到父页面
  • 项目组织管理类型-职能式组织和矩阵式组织的区别
  • 单机DeepSeek做PPT,YYDS!
  • 大语言模型的潜力是否被高估
  • C# 发送邮件 报错:此请求已被阻止,因为当用在 GET 请求中时,会将敏感信息透漏给第三方网站。
  • Denoising as Adaptation Noise-Space Domain Adaptation for Image Restoration
  • 【守护蓝色星球】《海洋环境保护法》的重要性与遵守主体
  • Redis三大件 穿透、雪崩、击穿
  • 如何自己做奶茶,从此告别奶茶店
  • Appium高级操作--ActionChains类、Toast元素识别、Hybrid App操作、手机系统API的操作
  • CSS-复合选择器、元素显示模式、背景
  • Java核心技术卷1
  • 得物 Android Crash 治理实践