<5> esp8266 iot 按键输入
Posted 疯狂程序
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了<5> esp8266 iot 按键输入相关的知识,希望对你有一定的参考价值。
目录
、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 按键输入的主要内容,如果未能解决你的问题,请参考以下文章
预告中ESP 保姆级教程 疯狂点灯篇 —— 案例:ESP8266 + LED + 按键 + 巴法云平台 + 微信小程序控制(包括项目完整代码)
ESP 保姆级教程疯狂点灯篇 —— 案例:ESP8266 + 风扇 + 按键(模拟按键控制电器设备开关)
<1> esp8266 iot 开发环境搭建(AiThinkerIDE_V1.5.2)