hc32l13x 多个编码器开关,带按键功能、防抖功能、检测上升沿,正转计数增加,反转计数减少,主函数、中断函数、初始化函数分开
时间: 2024-05-15 13:14:04 浏览: 86
以下是基于HC32L13x的多个编码器开关的带按键功能、防抖功能、检测上升沿,正转计数增加,反转计数减少的实现方法:
首先,在初始化函数中需要对GPIO进行配置,包括输入/输出模式、上下拉电阻等的设置。同时,也需要对TIMER进行配置,以便于中断函数的使用。
```c
void Encoder_Init(void)
{
stc_gpio_config_t stcGpioCfg;
stc_timer3_config_t stcTimer3Cfg;
// 打开GPIO和TIMER3的时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE);
// 配置GPIO
Gpio_StructInit(&stcGpioCfg);
stcGpioCfg.u16PinAttr = Pin_PU;
Gpio_Init(ENCODER1_A_PORT, ENCODER1_A_PIN, &stcGpioCfg);
Gpio_Init(ENCODER1_B_PORT, ENCODER1_B_PIN, &stcGpioCfg);
Gpio_Init(ENCODER1_BTN_PORT, ENCODER1_BTN_PIN, &stcGpioCfg);
Gpio_Init(ENCODER2_A_PORT, ENCODER2_A_PIN, &stcGpioCfg);
Gpio_Init(ENCODER2_B_PORT, ENCODER2_B_PIN, &stcGpioCfg);
Gpio_Init(ENCODER2_BTN_PORT, ENCODER2_BTN_PIN, &stcGpioCfg);
// 配置TIMER3
Timer3_StructInit(&stcTimer3Cfg);
stcTimer3Cfg.u16ClkDiv = TIMER3_CLK_DIV1;
stcTimer3Cfg.u16CmpValue = 0xFFFF;
Timer3_Cfg(TIM3_CH1, &stcTimer3Cfg);
Timer3_ClrIntFlag(TIM3_CH1);
Timer3_ClrCount(TIM3_CH1);
Timer3_Cmd(TIM3_CH1, TRUE);
}
```
接着,需要编写中断函数来处理编码器的旋转和按键的触发。在中断函数中,需要判断是哪个编码器发生了变化,并根据变化的方向进行正转计数或反转计数的操作。同时,还需要对按键进行防抖处理,防止误触发。
```c
void Encoder_IRQHandler(void)
{
static uint32_t cnt1 = 0, cnt2 = 0;
static uint32_t last1 = 0, last2 = 0;
static uint32_t debounce1 = 0, debounce2 = 0;
uint32_t cur1 = Gpio_GetInputIO(ENCODER1_A_PORT, ENCODER1_A_PIN) << 1 | Gpio_GetInputIO(ENCODER1_B_PORT, ENCODER1_B_PIN);
uint32_t cur2 = Gpio_GetInputIO(ENCODER2_A_PORT, ENCODER2_A_PIN) << 1 | Gpio_GetInputIO(ENCODER2_B_PORT, ENCODER2_B_PIN);
uint32_t btn1 = Gpio_GetInputIO(ENCODER1_BTN_PORT, ENCODER1_BTN_PIN);
uint32_t btn2 = Gpio_GetInputIO(ENCODER2_BTN_PORT, ENCODER2_BTN_PIN);
// 编码器1
if (cur1 != last1)
{
if (last1 == 0x00 && cur1 == 0x01)
{
cnt1++;
}
else if (last1 == 0x01 && cur1 == 0x03)
{
cnt1++;
}
else if (last1 == 0x03 && cur1 == 0x02)
{
cnt1++;
}
else if (last1 == 0x02 && cur1 == 0x00)
{
cnt1++;
}
else if (last1 == 0x00 && cur1 == 0x02)
{
cnt1--;
}
else if (last1 == 0x02 && cur1 == 0x03)
{
cnt1--;
}
else if (last1 == 0x03 && cur1 == 0x01)
{
cnt1--;
}
else if (last1 == 0x01 && cur1 == 0x00)
{
cnt1--;
}
last1 = cur1;
}
// 编码器2
if (cur2 != last2)
{
if (last2 == 0x00 && cur2 == 0x01)
{
cnt2++;
}
else if (last2 == 0x01 && cur2 == 0x03)
{
cnt2++;
}
else if (last2 == 0x03 && cur2 == 0x02)
{
cnt2++;
}
else if (last2 == 0x02 && cur2 == 0x00)
{
cnt2++;
}
else if (last2 == 0x00 && cur2 == 0x02)
{
cnt2--;
}
else if (last2 == 0x02 && cur2 == 0x03)
{
cnt2--;
}
else if (last2 == 0x03 && cur2 == 0x01)
{
cnt2--;
}
else if (last2 == 0x01 && cur2 == 0x00)
{
cnt2--;
}
last2 = cur2;
}
// 按键1
if (btn1 == 0)
{
debounce1++;
if (debounce1 >= DEBOUNCE_TIME)
{
// 触发按键事件
// ...
}
}
else
{
debounce1 = 0;
}
// 按键2
if (btn2 == 0)
{
debounce2++;
if (debounce2 >= DEBOUNCE_TIME)
{
// 触发按键事件
// ...
}
}
else
{
debounce2 = 0;
}
Timer3_ClrIntFlag(TIM3_CH1);
}
```
最后,在主函数中调用初始化函数,并加入一个死循环来保持程序运行。
```c
int main(void)
{
// 初始化
Encoder_Init();
while (1)
{
// do something
}
}
```
需要注意的是,以上代码仅为示例代码,实际使用时需要根据硬件连接和需求进行相应的修改。
阅读全文