<5> esp8266 iot 按键输入

Posted 疯狂程序

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了<5> esp8266 iot 按键输入相关的知识,希望对你有一定的参考价值。

目录

一、GPIO接口API

二、新建项目

三、新建文件

1.bsp_key.c

2.bsp_key.h

四、user_main.c

五、 程序运行


、GPIO接口API

二、新建项目

复制上节(<esp8266 iot LED灯闪烁>https://blog.csdn.net/qq_27558597/article/details/117672425?spm=1001.2014.3001.5502)工程,重命名为004_GPIO_KEY,如下:

三、新建文件

新建bsp_key.c、bsp_key.h文件,源代码文件新建方法请查看<esp8266 iot 软件延时>https://blog.csdn.net/qq_27558597/article/details/117728922?spm=1001.2014.3001.5502章节

1.bsp_key.c

/*
*********************************************************************************************************
*
*	程序名称: 按键驱动模块
*	文件名称: bsp_key.c
*	版    本: v1.0.0
*   编    写: 风巽云科技 lijiangmo
*	说    明: 支持单键,长键以及单键连发
*
*	版本记录: 
*	v1.0.0: 2021年6月9日,初版
*
*	Copyright (C), 2021-2031, 深圳市风巽云科技有限公司 https://fxymcu.taobao.com
*
*********************************************************************************************************
*/

#include "ets_sys.h"
#include "gpio.h"
#include "driver/bsp_key.h"

/* 按键时间定义 */
#define LONG_KEY_TIME 150     /* 判定为长键时间 = N*10ms */
#define AUTO_SEND_KEY_TIME 10 /* 自动发送长键间隔时间 = N*10ms */
#define AUTO_SEND_KEY_EN 0    /* 使能自动发送长键 */

/* 驱动引脚定义 */
/* KEY1 */
#define KEY1_PIN_NAME PERIPHS_IO_MUX_MTDO_U
#define KEY1_FUNC FUNC_GPIO15
#define KEY1_GPIO_ID 15
/* 读按键口线状态-高电平有效 */
#define KEY1_READ() (GPIO_INPUT_GET(GPIO_ID_PIN(KEY1_GPIO_ID)) == 1)

/* KEY2 */
#define KEY2_PIN_NAME PERIPHS_IO_MUX_MTDI_U
#define KEY2_FUNC FUNC_GPIO12
#define KEY2_GPIO_ID 12
/* 读按键口线状态-低电平有效 */
#define KEY2_READ() (GPIO_INPUT_GET(GPIO_ID_PIN(KEY2_GPIO_ID)) == 0)

/*
*********************************************************************************************************
*	函 数 名: bsp_InitKEY
*	功能说明: 配置用户按键相关的GPIO
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void ICACHE_FLASH_ATTR bsp_InitKEY(void)
{
    /* KEY1 */
    PIN_FUNC_SELECT(KEY1_PIN_NAME, KEY1_FUNC);  // GPIO设为IO口
    GPIO_DIS_OUTPUT(GPIO_ID_PIN(KEY1_GPIO_ID)); // GPIO禁止输出(输入)
    PIN_PULLUP_DIS(KEY1_PIN_NAME);              // GPIO禁止内部上拉
    /* KEY2 */
    PIN_FUNC_SELECT(KEY2_PIN_NAME, KEY2_FUNC);  // GPIO设为IO口
    GPIO_DIS_OUTPUT(GPIO_ID_PIN(KEY2_GPIO_ID)); // GPIO禁止输出(输入)
    PIN_PULLUP_EN(KEY2_PIN_NAME);               // GPIO使能内部上拉
}

/*
*********************************************************************************************************
*  	函 数 名: bsp_KEY_Driver
*  	功能说明: 按键驱动,需要周期性调用,推荐10ms频率
*  	形    参: 无
*  	返 回 值: 每个按键的单击、长按
*********************************************************************************************************
*/
uint8_t bsp_KEY_Driver(void)
{
    static uint8_t ucKeyState = 0;
    static uint16_t usKeyTime;
    static uint8_t bKeyDownFlag[2] = {0};
#if AUTO_SEND_KEY_EN
    static uint8_t ucAutoSendKeyEnFlag = 0;
#endif

    switch (ucKeyState)
    {
    case 0: /* 状态0-按键按下 */
        if (KEY1_READ() || KEY2_READ())
        {
            bKeyDownFlag[0] = 0;
            bKeyDownFlag[1] = 0;
#if AUTO_SEND_KEY_EN
            ucAutoSendKeyEnFlag = 0;
#endif
            ucKeyState = 1;
        }
        break;

    case 1: /* 状态1-消抖再次确定 */
        if (KEY1_READ())
        {
            bKeyDownFlag[0] = 1;
            ucKeyState = 2;
        }
        else if (KEY2_READ())
        {
            bKeyDownFlag[1] = 1;
            ucKeyState = 2;
        }
        else
        {
            ucKeyState = 0;
        }
        usKeyTime = 0;
        break;

    case 2: /* 状态2-确定状态 */
        if (!KEY1_READ() && bKeyDownFlag[0])
        {
            ucKeyState = 0;
            return KEY1_S_KEY;
        }
        else if (!KEY2_READ() && bKeyDownFlag[1])
        {
            ucKeyState = 0;
            return KEY2_S_KEY;
        }
        else if (usKeyTime > LONG_KEY_TIME - 2) /* 减掉前两个状态时间 */
        {
            usKeyTime = 0;
            ucKeyState = 3;
            if (KEY1_READ())
            {
                return KEY1_L_KEY;
            }
            else if (KEY2_READ())
            {
                return KEY2_L_KEY;
            }
        }
        else
        {
            usKeyTime++;
        }
        break;

    case 3: /* 状态3-等待所有按键释放 */
        if (!KEY1_READ() && !KEY2_READ())
        {
            ucKeyState = 0;
        }
#if AUTO_SEND_KEY_EN
        else /* 长按时间超过长键2倍判定值自动发送单键 */
        {
            if (ucAutoSendKeyEnFlag)
            {
                usKeyTime++;
                if (usKeyTime > AUTO_SEND_KEY_TIME - 1)
                {
                    usKeyTime = 0;
                    if (KEY1_READ())
                    {
                        return KEY1_S_KEY;
                    }
                    else if (KEY2_READ())
                    {
                        return KEY2_S_KEY;
                    }
                }
            }
            else
            {
                usKeyTime++;
                if (usKeyTime > LONG_KEY_TIME * 2 - 1)
                {
                    usKeyTime = 0;
                    ucAutoSendKeyEnFlag = 1;
                }
            }
        }
#endif
        break;
    }
    return N_KEY;
}

/********************************************* End of file **********************************************/

2.bsp_key.h

/*
*********************************************************************************************************
*
*	程序名称: 按键驱动模块
*	文件名称: bsp_key.h
*	版    本: v1.0.0
*   编    写: 风巽云科技 lijiangmo
*   日    期: 2021年6月9日
*
*	Copyright (C), 2021-2031, 深圳市风巽云科技有限公司 https://fxymcu.taobao.com
*
*********************************************************************************************************
*/

#ifndef __BSP_KEY_H
#define __BSP_KEY_H

/* 按键枚举值 */
typedef enum
{
    N_KEY,      /* 无键 */
    KEY1_S_KEY, /* 键1单键 */
    KEY2_S_KEY, /* 键2单键 */
    KEY1_L_KEY, /* 键1长键 */
    KEY2_L_KEY, /* 键2长键 */
} KEY_Type;

/* 供外部调用函数 */
void ICACHE_FLASH_ATTR bsp_InitKEY(void);
uint8_t ICACHE_FLASH_ATTR bsp_KEY_Driver(void);

#endif

/********************************************* End of file **********************************************/

四、user_main.c

/*
 * ESPRESSIF MIT License
 *
 * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
 *
 * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

/*
*********************************************************************************************************
*
*	程序名称: 按键输入
*	文件名称: user_main.c
*   MCU型号 : ESP8266 FLASH:4MB RAM: 160KB(64KB为iRAM,96KB为dRAM)
*   运行平台: ESP8266 IoT开发板
*	版    本: v1.0.0
*   编    写: 风巽云科技 lijiangmo
*	说    明: 配置GPIO为入模式
*
*	版本记录:
*	v1.0.0: 2021年6月9日,初版
*
*	Copyright (C), 2021-2031, 深圳市风巽云科技有限公司 https://fxymcu.taobao.com
*
*********************************************************************************************************
*/

#include "ets_sys.h"
#include "osapi.h"
#include "mem.h"
#include "user_interface.h"
#include "sntp.h"
#include "smartconfig.h"
#include "espconn.h"

#include "driver/uart.h"
#include "driver/bsp_delay.h"
#include "driver/bsp_led.h"
#include "driver/bsp_key.h"

/* FLASH分区表 */
#if ((SPI_FLASH_SIZE_MAP == 0) || (SPI_FLASH_SIZE_MAP == 1))
#error "The flash map is not supported"
#elif (SPI_FLASH_SIZE_MAP == 2)
#define SYSTEM_PARTITION_OTA_SIZE 0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR 0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR 0xfb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR 0xfc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR 0xfd000
#define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR 0x7c000
#elif (SPI_FLASH_SIZE_MAP == 3)
#define SYSTEM_PARTITION_OTA_SIZE 0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR 0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR 0x1fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR 0x1fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR 0x1fd000
#define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR 0x7c000
#elif (SPI_FLASH_SIZE_MAP == 4)
#define SYSTEM_PARTITION_OTA_SIZE 0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR 0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR 0x3fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR 0x3fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR 0x3fd000
#define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR 0x7c000
#elif (SPI_FLASH_SIZE_MAP == 5)
#define SYSTEM_PARTITION_OTA_SIZE 0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR 0x101000
#define SYSTEM_PARTITION_RF_CAL_ADDR 0x1fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR 0x1fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR 0x1fd000
#define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR 0xfc000
#elif (SPI_FLASH_SIZE_MAP == 6)
#define SYSTEM_PARTITION_OTA_SIZE 0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR 0x101000
#define SYSTEM_PARTITION_RF_CAL_ADDR 0x3fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR 0x3fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR 0x3fd000
#define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR 0xfc000
#else
#error "The flash map is not supported"
#endif

#define SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM SYSTEM_PARTITION_CUSTOMER_BEGIN

static const partition_item_t at_partition_table[] = {
    {SYSTEM_PARTITION_BOOTLOADER, 0x0, 0x1000},
    {SYSTEM_PARTITION_OTA_1, 0x1000, SYSTEM_PARTITION_OTA_SIZE},
    {SYSTEM_PARTITION_OTA_2, SYSTEM_PARTITION_OTA_2_ADDR, SYSTEM_PARTITION_OTA_SIZE},
    {SYSTEM_PARTITION_RF_CAL, SYSTEM_PARTITION_RF_CAL_ADDR, 0x1000},
    {SYSTEM_PARTITION_PHY_DATA, SYSTEM_PARTITION_PHY_DATA_ADDR, 0x1000},
    {SYSTEM_PARTITION_SYSTEM_PARAMETER, SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR, 0x3000},
    {SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM, SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM_ADDR, 0x1000},
};

/*
*********************************************************************************************************
*	函 数 名: user_pre_init
*	功能说明: 注册分区表
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void ICACHE_FLASH_ATTR user_pre_init(void)
{
    os_printf("->SPI_FLASH_SIZE_MAP = %d\\r\\n", SPI_FLASH_SIZE_MAP);
    if (!system_partition_table_regist(at_partition_table, sizeof(at_partition_table) / sizeof(at_partition_table[0]), SPI_FLASH_SIZE_MAP))
    {
        os_printf("->system_partition_table_regist fail\\r\\n");
        while (1)
        {
        }
    }
    os_printf("->system_partition_table_regist success\\r\\n");
}

/*
*********************************************************************************************************
*	函 数 名: PrintfSystempInfo
*	功能说明: 打印例程名称和例程发布日期
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
static void ICACHE_FLASH_ATTR PrintfSystempInfo(void)
{
    os_printf("\\r\\n\\r\\n");
    os_printf("-------------------------------------------------------------\\r\\n");
    os_printf("->ESP8266 IoT\\r\\n");
    /* SDK版本 */
    os_printf("->SDK: %s\\r\\n", system_get_sdk_version());
    /* 编译时间 */
    os_printf("->Build: %s %s\\r\\n", __DATE__, __TIME__);
    /* 芯片ID */
    os_printf("->CPU ID: 0x%X\\r\\n", system_get_chip_id());
    /* CPU时钟 */
    os_printf("->CPU Freq: %dMHz\\r\\n", system_get_cpu_freq());
    /* FLASH ID */
    os_printf("->FLASH ID: 0x%X\\r\\n", spi_flash_get_id());
    /* 查询系统剩余可用heap区空间 */
    os_printf("->Heap Size: %dByte %dKB\\r\\n", system_get_free_heap_size(), system_get_free_heap_size() / 1024);
    /* 打印系统内存空间分配,打印信息包括 data/rodata/bss/heap */
    system_print_meminfo();
    os_printf("-------------------------------------------------------------\\r\\n\\r\\n");
}

/*
*********************************************************************************************************
*	函 数 名: user_init
*	功能说明: 用户应用初始化
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void ICACHE_FLASH_ATTR user_init(void)
{
    partition_item_t partition_item;
    uint8_t ucKey;

    if (!system_partition_get_item(SYSTEM_PARTITION_CUSTOMER_PRIV_PARAM, &partition_item))
    {
        os_printf("Get partition information fail\\r\\n");
    }

    /* 硬件初始化 */
    //system_update_cpu_freq(SYS_CPU_80MHZ);     /* CPU频率80MHz-默认 */
    //UART_SetPrintPort(0);                      /* 系统Debug信息从串口0输出-默认 */
    //uart_init(BIT_RATE_74880, BIT_RATE_74880); /* 初始化波特率-默认 */
    os_delay_us(1000);
    bsp_InitLED();
    bsp_InitKEY();

    /* 串口打印系统信息 */
    PrintfSystempInfo();

    while (1)
    {
        /* 按键驱动 */
        ucKey = bsp_KEY_Driver();
        if (ucKey == KEY1_S_KEY) /* 按键1单键 */
        {
        	os_printf("->KEY1_S_KEY\\r\\n");
        }
        if (ucKey == KEY2_S_KEY) /* 按键2单键 */
        {
        	os_printf("->KEY2_S_KEY\\r\\n");
        }
        else if (ucKey == KEY1_L_KEY) /* 按键1长键 */
        {
        	os_printf("->KEY1_L_KEY\\r\\n");
        }
        else if (ucKey == KEY2_L_KEY) /* 按键2长键 */
        {
        	os_printf("->KEY2_L_KEY\\r\\n");
        }
        bsp_DelayMs(10);
    }
}

/********************************************* End of file **********************************************/

程序解析:bsp_InitKEY初始化按键输入端口,while主循环10ms周期扫描bsp_KEY_Driver按键状态,按键驱动支持单键,长键以及单键连发。

五、 程序运行


 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 25964, room 16 
tail 12
chksum 0x13
ho 0 tail 12 room 4
load 0x3ffe8000, len 1272, room 12 
tail 12
chksum 0x72
ho 0 tail 12 room 4
load 0x3ffe8500, len 1732, room 12 
tail 8
chksum 0x4f
csum 0x4f
->SPI_FLASH_SIZE_MAP = 4
->system_partition_table_regist success
V2
Mo
Backup
�rf cal sector: 1019
freq trace enable 0
rf[112] : 00
rf[113] : 00
rf[114] : 01
w_flash

SDK ver: 3.0.4(9532ceb) compiled @ May 22 2020 16:26:04
phy ver: 1156_0, pp ver: 10.2



-------------------------------------------------------------
->ESP8266 IoT
->SDK: 3.0.4(9532ceb)
->Build: Jun  9 2021 10:29:47
->CPU ID: 0x551D1F
->CPU Freq: 80MHz
->FLASH ID: 0x1640D8
->Heap Size: 53064Byte 51KB
data  : 0x3ffe8000 ~ 0x3ffe84f6, len: 1270
rodata: 0x3ffe8500 ~ 0x3ffe8bc4, len: 1732
bss   : 0x3ffe8bc8 ~ 0x3ffeef80, len: 25528
heap  : 0x3ffeef80 ~ 0x3fffc000, len: 53376
-------------------------------------------------------------

->KEY1_S_KEY
->KEY2_S_KEY
->KEY1_L_KEY
->KEY2_L_KEY

 

以上是关于<5> esp8266 iot 按键输入的主要内容,如果未能解决你的问题,请参考以下文章

<5> esp8266 iot 按键输入

预告中ESP 保姆级教程 疯狂点灯篇 —— 案例:ESP8266 + LED + 按键 + 巴法云平台 + 微信小程序控制(包括项目完整代码)

ESP 保姆级教程疯狂点灯篇 —— 案例:ESP8266 + 风扇 + 按键(模拟按键控制电器设备开关)

<1> esp8266 iot 开发环境搭建(AiThinkerIDE_V1.5.2)

<1> esp8266 iot 开发环境搭建(AiThinkerIDE_V1.5.2)

ESP8266入门教程-ESP8266按键控制Led灯亮灭