基于ESP-IDF 的 EC11 旋转编码器程序例子
该例子演示了 EC11 旋转编码器的 AB相旋转判断的实现。基于 ESP-IDF 平台,一下贴出核心代码。
注意:这里我用的芯片模组是老的 ESP32 芯片的。
#define EC11_IO_A() gpio_get_level(GPIO_NUM_4) // A 相 IO 电平读取
#define EC11_IO_B() gpio_get_level(GPIO_NUM_15) // B 相 IO 电平读取
uint8_t flag = 0; // 全局标志位
uint8_t icnt = 0; // 中断计数变量
/* 外部中断服务函数定义 */
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
// 计数变量为 0,并且 a 相为低电平
// 在 if 内部判断 b 相电平,这样就可以确保 a b 两相的电平一高一低了
// 也就滤出了可能出现的 ab 两相电平同时为高或同时为低的情况
// 中断计数的作用是只有该判断为真,并且 icnt 为 1 的情况才进行下一次的判断
if (EC11_IO_A() == 0 && icnt == 0)
{
flag = 0; // 初始化标志位
if (EC11_IO_B()) flag = 1; // 判断 B相电平为高,为高 flag 设置为 1
icnt = 1; // 中断计数
}
// 中断计数为 1,并且 a 相为高电平
// 因为 这是第二次的判断,所以要判断a相为高电平,也就是中断的上升沿
// 然后就是判断编码器的旋转方向,这里用到了 b 相的状态
// 通过判断两次 b 相的高低变化就可以判断旋转方向了
if (icnt && EC11_IO_A())
{
// 判断 b 相为低,并且上次 b 相为高
if(EC11_IO_B() == 0 && flag == 1) xtp_system.test_num += 1;
// 判断 b 相为高,并且上次 b 相为低
if(EC11_IO_B() && flag == 0) xtp_system.test_num -= 1;
icnt = 0;
}
vTaskNotifyGiveFromISR(show_task_handle, NULL); // 通知显示任务及时显示 xtp_system.test_num 的值
}
/**
* @brief 该函数主要用来执行初始化之类的操作,我们只让该函数执行一次。
* 如果要该函数不退出一直运行下去可以在函数尾部加上 while(1)
*/
void app_main(void)
{
/* 创建 io 配置变量,并配置 io 中断触发 */
gpio_config_t io_conf = {};
// A 相 IO 配置为中断上升沿/下降沿都触发的模式
io_conf.intr_type = GPIO_INTR_ANYEDGE; /* 上升沿/下降沿都触发 */
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = 1ULL<<4; // A 相接 D4
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_NUM_4, gpio_isr_handler, (void*)0);
// B 相 IO 配置为普通的输入模式
io_conf.intr_type = GPIO_INTR_DISABLE; /* 禁用中断 */
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = 1ULL<<15; // B 相接 D15
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
经过验证效果非常好。

浙公网安备 33010602011771号