[ESP32] 编码旋钮驱动
此驱动适用于(2个引脚ENA,ENB)编码旋钮,当旋钮转动时会产生2个脉冲,若采用定时轮询的方式来获取引脚的电平序列则有可能会丢包。采用中断方式来处理会比较合适;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "esp_log.h"// 定义:旋钮引脚+确认健
#define KNOB_ENA_IO 7
#define KNOB_ENB_IO 8
#define KNOB_KEY_IO 9static SemaphoreHandle_t g_gpio_sem;// 顺时针扭动
void turn_clock_wise_proc()
{static uint8_t cnt = 0;printf("[%ld] CLOCK_WISE.%02X \n", esp_log_timestamp(), cnt++);
}// 逆时针扭动
void turn_not_clk_wise_proc()
{static uint8_t cnt = 0;printf("[%ld] N_CLK_WISE.%02X \n", esp_log_timestamp(), cnt++);
}
// 确认键按下
void click_middle_proc()
{static uint8_t cnt = 0;printf("[%ld] MIDD_BTN.\n", esp_log_timestamp(), cnt++);
}static void IRAM_ATTR gpio_isr_handler(void *arg)
{xSemaphoreGiveFromISR(g_gpio_sem, NULL);
}static void knob_intr_handle(void *arg)
{uint8_t pin_ena = 0;uint8_t pin_enb = 0;uint8_t knob_value = 0;uint8_t knob_value_old = 0;uint8_t pin_mid = 0; // 0:Down,1:Upuint8_t pin_mid_old = 1; // Default:Upuint8_t last_pos = 0; // 100:顺时针,200:逆时针printf("knob_intr_handle() start,configTICK_RATE_HZ=%d \n", configTICK_RATE_HZ);while (1){if (xSemaphoreTake(g_gpio_sem, pdMS_TO_TICKS(25))) // raw:portMAX_DELAY{pin_ena = gpio_get_level(KNOB_ENA_IO);pin_enb = gpio_get_level(KNOB_ENB_IO);knob_value = pin_ena << 1 | pin_enb;// printf("info=> %d,%d; old=%d, curr=%d \n", pin_ena,pin_enb,knob_value_old,knob_value);if (knob_value == 2 && knob_value_old == 1){last_pos = 100;}else if (knob_value == 3 && knob_value_old == 0){last_pos = 200;}knob_value_old = knob_value;if (knob_value == 2 || knob_value == 1){//if(last_pos==100)//防止误触turn_clock_wise_proc();}else if (knob_value == 3 || knob_value == 0){//if(last_pos==200)//防止误触turn_not_clk_wise_proc();}}pin_mid = gpio_get_level(KNOB_KEY_IO);if (pin_mid_old != pin_mid){pin_mid_old = pin_mid;if (pin_mid == 0)click_middle_proc();}}
}/*Init Knob & key*/
void Knob_key_Init(void)
{gpio_config_t io_cfg = {.intr_type = GPIO_INTR_DISABLE,.mode = GPIO_MODE_INPUT,.pin_bit_mask = BIT64(KNOB_ENA_IO) | BIT64(KNOB_ENB_IO) | BIT64(KNOB_KEY_IO),};gpio_config(&io_cfg);// install gpio isr servicegpio_install_isr_service(0); // 0=ESP_INTR_FLAG_DEFAULT// zero-initialize the config structure.gpio_config_t io_conf = {};// interrupt of rising edge// GPIO_INTR_ANYEDGE;//GPIO_INTR_POSEDGE;//GPIO_INTR_NEGEDGEio_conf.intr_type = GPIO_INTR_ANYEDGE; // GPIO_INTR_POSEDGE;//GPIO_INTR_NEGEDGEio_conf.pin_bit_mask = 1ULL << KNOB_ENA_IO;io_conf.mode = GPIO_MODE_INPUT;io_conf.pull_up_en = 1;gpio_config(&io_conf);g_gpio_sem = xSemaphoreCreateBinary();// start gpio taskxTaskCreate(knob_intr_handle, "knob_intr_handle", 1024 * 5, NULL, 10, NULL);gpio_isr_handler_add(KNOB_ENA_IO, gpio_isr_handler, NULL);
}