在调试按键设置模式过程中,发现会与按键冲突。虽然事后证明是一个乌龙事件,不过也算非常顺利地调试完成了按键裸机驱动。
其中比较核心的就是ESP32的IO口状态读取操作:
其中LIGHT_BUTTON_GPIO就是需要读取的IO口号,这里是:
#define LIGHT_BUTTON_GPIO 9
key_pin_state = (uint8_t)gpio_get_level((uint32_t)LIGHT_BUTTON_GPIO);
所以整个按键驱动裸机的方式就非常清楚了:
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "button_gpio.h"
#define LIGHT_BUTTON_GPIO 9 /* This is the button that is used for toggling the output */
#define LIGHT_BUTTON_ACTIVE_LEVEL 0
void key_driver_init(void)
{
gpio_config_t gpio_conf;
gpio_conf.intr_type = GPIO_INTR_DISABLE;
gpio_conf.mode = GPIO_MODE_INPUT;
gpio_conf.pin_bit_mask = (1ULL << LIGHT_BUTTON_GPIO);
if (LIGHT_BUTTON_ACTIVE_LEVEL) {
gpio_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE;
} else {
gpio_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
gpio_conf.pull_up_en = GPIO_PULLUP_ENABLE;
}
gpio_config(&gpio_conf);
}
unsigned char key_pin_state = 1;
unsigned int key_press_counter = 0;
unsigned char key_scan_first_flag = 0;
static void key_scan(void* arg)
{
for(;;) {
key_pin_state = (uint8_t)gpio_get_level((uint32_t)LIGHT_BUTTON_GPIO);
if(key_pin_state == 0)
{
if(key_scan_first_flag == 0)
{
key_press_counter++;
if(key_press_counter >= 150) //长按2S
{
printf("按键触发长按!\r\n");
key_scan_first_flag = 1;
key_press_counter = 0;
}
}
}else
{
key_scan_first_flag = 0;
key_press_counter = 0;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
key_driver_init();
xTaskCreate(key_scan, "key_scan_example", 2048, NULL, 10, NULL);
while(1){
printf("system run ...\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
运行示例: