图11.3.1.1 KEY实验程序流程图
11.3.2 GPIO函数解析
GPIO函数已在10.3.2章节中详细阐述,为避免重复,此处不再赘述。建议读者查阅第十章的函数解析章节,以获取更多关于GPIO函数的信息。
11.3.3 KEY驱动解析
在IDF版的02_key例程中,作者在01_key\components\BSP路径下新增了一个KEY文件夹,用于存放key.c和key.h这两个文件。其中,key.h文件负责声明KEY相关的函数和变量,而key.c文件则实现了KEY的驱动代码。下面,我们将详细解析这两个文件的实现内容。
1,key.h文件
/* 引脚定义 */
#define BOOT_GPIO_PIN GPIO_NUM_0
/*IO操作*/
#define BOOT gpio_get_level(BOOT_GPIO_PIN)
/* 按键按下定义 */
#define BOOT_PRES 1 /* BOOT按键按下 */
/* 函数声明 */
void key_init(void); /* 初始化按键 */
uint8_t key_scan(uint8_t mode); /* 按键扫描函数 */
此文件的核心内容已较为明确,无需过多阐述。它主要定义了BOOT宏,用于获取IO0的状态,并声明了key_init和key_scan函数,以便外部文件能够调用这些函数。通过这些声明和定义,该文件为其他部分的代码提供了必要的接口和功能支持。
2,key.c文件
此文件中定义了两个函数,分别为key_init和key_scan。接下来,我将对这两个函数进行详细的解析。
(1)key_init函数
/**
* @retval 无
*/
void key_init(void)
{
gpio_config_t gpio_init_struct;
gpio_init_struct.intr_type = GPIO_INTR_DISABLE; /* 失能引脚中断 */
gpio_init_struct.mode = GPIO_MODE_INPUT; /* 输入模式 */
gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE; /* 使能上拉 */
gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE; /* 失能下拉 */
gpio_init_struct.pin_bit_mask = 1ull << BOOT_GPIO_PIN; /* BOOT按键引脚 */
gpio_config(&gpio_init_struct); /* 配置使能 */
}
该函数主要配置IO0管脚为输入模式,这样就可以获取IO0的电平状态了。
(2)key_scan函数
/**
* @brief 按键扫描函数
* @param mode:0 / 1, 具体含义如下:
* 0, 不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,
* 必须松开以后, 再次按下才会返回其他键值)
* 1, 支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)
* @retval 键值, 定义如下:
* BOOT_PRES, 1, BOOT按下
*/
uint8_t key_scan(uint8_t mode)
{
uint8_t keyval = 0;
static uint8_t key_boot = 1; /* 按键松开标志 */
if(mode)
{
key_boot = 1;
}
if (key_boot && (BOOT == 0)) /* 按键松开标志为1,且有任意一个按键按下了 */
{
vTaskDelay(10); /* 去抖动 */
key_boot = 0;
if (BOOT == 0)
{
keyval = BOOT_PRES;
}
}
else if (BOOT == 1)
{
key_boot = 1;
}
return keyval; /* 返回键值 */
}
此函数只有一个形参mode,用于设置按键是否支持连续按下模式。当mode为0时,表示按键不支持连续按下;反之,则支持连续按下。值得注意的是,该函数内部已经对按键进行了消抖延时处理,因此,在其他地方调用此函数时,无需再进行额外的按键消抖操作。
11.3.4 CMakeLists.txt文件
打开本实验BSP下的CMakeLists.txt文件,其内容如下所示:
set(src_dirs
KEY
LED)
set(include_dirs
KEY
LED)
set(requires
driver)
idf_component_register(SRC_DIRS ${src_dirs}
INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})
component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)
上述的红色KEY驱动需要由开发者自行添加,以确保KEY驱动能够顺利集成到构建系统中。这一步骤是必不可少的,它确保了KEY驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。
11.3.5 实验应用代码
打开main/main.c文件,该文件定义了工程入口函数,名为app_main。该函数代码如下。
/**
* @brief 程序入口
* @param 无
* @retval 无
*/
void app_main(void)
{
uint8_t key;
esp_err_t ret;
ret = nvs_flash_init(); /* 初始化NVS */
if (ret == ESP_ERR_NVS_NO_FREE_PAGES
|| ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
led_init(); /* 初始化LED */
key_init(); /* KEY初始化 */
while(1)
{
key = key_scan(0); /* 获取键值 */
switch (key)
{
case BOOT_PRES: /* BOOT被按下 */
{
LED_TOGGLE(); /* LED状态翻转 */
break;
}
default:
{
break;
}
}
vTaskDelay(10);
}
}
可以看到应用代码中,在初始化完LED和按键后,就进入了一个while循环,在循环中,每间隔10毫秒就调用key_scan()函数扫描以此按键的状态,如果扫描到BOOT按键被按下,则反转对应LED的亮灭状态。
11.4 下载验证
在完成编译和烧录操作后,可以看到板子上的LED是处于亮起的状态,若此时按下并释放一次BOOT按键,则能够看到LED的亮灭状态发生了一次翻转,与预期的实验现象效果相符。