#include "include.h" #if USER_KEY_QDEC_EN AT(.com_text.qdec) void qdec_key_msg_enqueue(u8 msg) { reset_sleep_delay_all(); //复位休眠计数 msg_enqueue(msg); } /* * 旋转编码器Quadrate Decode * QDEC_MAP_G1: A -> PB0, B -> PB1 * QDEC_MAP_G2: A -> PE1, B -> PE2 * QDEC_MAP_G3: A -> PE6, B -> PE7 */ AT(.com_text.qdec) void qdec_isr(void) { u32 qdeccon = QDECCON; if (qdeccon & BIT(1)) { //interrupt is enbale? if (qdeccon & BIT(30)) { //forward QDECCPND = BIT(30); qdec_key_msg_enqueue(MSG_QDEC_FORWARD); } if (qdeccon & BIT(31)) { //reverse QDECCPND = BIT(31); qdec_key_msg_enqueue(MSG_QDEC_REVERSE); } } } void bsp_qdec_init(void) { CLKGAT2 |= BIT(2); //qdec clk enable #if (USER_QDEC_MAPPING == QDEC_MAP_G1) GPIOBDIR |= 0x03; GPIOBDE |= 0x03; GPIOBFEN |= 0x03; GPIOBPU |= 0x03; #elif (USER_QDEC_MAPPING == QDEC_MAP_G2) GPIOEDIR |= 0x06; GPIOEDE |= 0x06; GPIOEFEN |= 0x06; GPIOEPU |= 0x06; #elif (USER_QDEC_MAPPING == QDEC_MAP_G3) GPIOEDIR |= 0xc0; GPIOEDE |= 0xc0; GPIOEFEN |= 0xc0; GPIOEPU |= 0xc0; #endif sys_irq_init(IRQ_QDEC_VECTOR, 0, qdec_isr); FUNCMCON2 = USER_QDEC_MAPPING; QDECCON = 45 << 3; //quadrate decode filter length QDECCPND = BIT(30) | BIT(31); QDECCON = BIT(0) | BIT(1); //qdec decode enable, interrupt enable } #elif USER_ADKEY_QDEC_EN /* * QDEC_A串接5.1K,QEC_B串接10K,接到同一IO上。IO开内部10K上拉,用ADC来采电压。 * 正旋:3.3v -- 1.113v -- 0.825v -- 1.65v -- 3.3v * 反旋:3.3v -- 1.65v -- 0.825v -- 1.113v -- 3.3v */ enum { QEC_AH_BH, //A输出高电平,B输出高电平,空闲状态 QEC_AL_BH, //A输出低电平,B输出高电平 QEC_AL_BL, //A输出低电平,B输出低电平 QEC_AH_BL, //A输出高电平,B输出低电平 }; typedef struct { u8 status[3]; u8 cnt; u8 pre_sta; } qdec_cb_t; static qdec_cb_t qdec_cb; AT(.com_rodata.pwrkey.table) const adkey_tbl_t qdec_adkey_table[6] = { {0x30, QEC_AH_BH}, {0x4C, QEC_AL_BL}, {0x6A, QEC_AL_BH}, {0x8A, QEC_AH_BL}, {0xFF, QEC_AH_BH}, }; void bsp_qdec_init(void) { u8 io_num = get_adc_gpio_num(USER_QDEC_ADCH); memset(&qdec_cb, 0, sizeof(qdec_cb_t)); if (io_num != IO_NONE) { gpio_t gpio; gpio_cfg_init(&gpio, io_num); gpio.sfr[GPIOxDE] |= gpio.pin; gpio.sfr[GPIOxDIR] |= gpio.pin; gpio.sfr[GPIOxPU] |= gpio.pin; saradc_set_channel(BIT(USER_QDEC_ADCH)); } } AT(.com_text.qdec) void qdec_key_msg_enqueue(u8 msg) { reset_sleep_delay_all(); //复位休眠计数 msg_enqueue(msg); } //每毫秒ADC采样值进行处理 AT(.com_text.qdec) void bsp_qdec_adc_process(u8 adc_val) { u8 num = 0; u8 qdec_cur_sta; while ((u8)adc_val > qdec_adkey_table[num].adc_val) { num++; } qdec_cur_sta = qdec_adkey_table[num].usage_id; if (qdec_cur_sta != qdec_cb.pre_sta) { if (qdec_cur_sta != QEC_AH_BH) { if (qdec_cb.pre_sta == QEC_AH_BH) { qdec_cb.cnt = 0; } if (qdec_cb.cnt < 3) { qdec_cb.status[qdec_cb.cnt++] = qdec_cur_sta; } } qdec_cb.pre_sta = qdec_cur_sta; } else { if (qdec_cur_sta == QEC_AH_BH) { //结束 if (qdec_cb.cnt == 3 && qdec_cb.status[1] == QEC_AL_BL) { if (qdec_cb.status[0] == QEC_AL_BH && qdec_cb.status[2] == QEC_AH_BL) { qdec_key_msg_enqueue(MSG_QDEC_FORWARD); //uart_putchar('F'); } else if (qdec_cb.status[2] == QEC_AL_BH && qdec_cb.status[0] == QEC_AH_BL) { qdec_key_msg_enqueue(MSG_QDEC_REVERSE); //uart_putchar('R'); } } memset(&qdec_cb, 0, sizeof(qdec_cb_t)); } } } #else void bsp_qdec_init(void) { } #endif // USER_ADKEY_QDEC_EN