关于编码器
我个人喜欢称为滚轮,不知道为什么要叫编码器。
一般的滚轮的触发是顺时针旋转,逆时针旋转以及一般都有一个按键,这个跟普通按键一样的。
旋转会让其中两跟引脚的波形发生,这里也说不清是怎么变化,而且我单看那个手册提供的波形我也看不明白,一般我都是直接配合逻辑分析仪来捕获那个波形然后根据波形变化规律去写程序的。
滚轮的规格都差不多,或者说原理差不多,掌握之后面对其他规格的滚轮,代码稍作修改就可以接着用了。
原理跟普通按键检测有点类似,不过是从判断0和1变成判断两根线组合的状态。
程序配置
Wheel.h
#ifndef _WHEEL_H_
#define _WHEEL_H_
typedef struct
{
unsigned char After_Status;
unsigned char Before_Status;
unsigned char Trigger_condition; /* 0x01:顺时针,0xFF:逆时针 */
unsigned char Debounce_Cnt;
}Wheel_Task_T;
extern Wheel_Task_T Wheel_1;
void Wheel_GPIO_Init();
void Wheel_Scan();
#endif
Wheel.h
void Wheel_GPIO_Init()
{
unsigned char i = 0;
if(GPIOA_4_Get_Status() != 0)
i |= 0x01;
if(GPIOA_5_Get_Status() != 0)
i |= 0x02;
Wheel_1.Trigger_condition = 0;
Wheel_1.Debounce_Cnt = 0;
Wheel_1.After_Status = 0;
Wheel_1.Before_Status = i;
GPIOA_4_Control(IO_Input);
GPIOA_4_Pullup(Enable);
GPIOA_5_Control(IO_Input);
GPIOA_5_Pullup(Enable);
}
void Wheel_Scan()
{
unsigned char i = 0;
if(GPIOA_4_Get_Status() != 0)
i |= 0x01;
if(GPIOA_5_Get_Status() != 0)
i |= 0x02;
if(i != Wheel_1.Before_Status)
{
Wheel_1.Before_Status = i;
Wheel_1.Debounce_Cnt = 2;
}
else if(Wheel_1.Debounce_Cnt != 0)
{
Wheel_1.Debounce_Cnt -= 1;
if(Wheel_1.Debounce_Cnt == 0)
{
if((Wheel_1.Before_Status == 1)&&(Wheel_1.After_Status == 3))
{
Trigger_condition = 0x01;
}
else if((Wheel_1.Before_Status == 2)&&(Wheel_1.After_Status == 3))
{
Trigger_condition = 0xFF;
}
Wheel_1.After_Status = Wheel_1.Before_Status;
}
}
}
void Wheel_Handle()
{
if(Trigger_condition == 0x01)
{
Trigger_condition = 0;
GPIOA_6_Control(IO_Output);
GPIOA_6_Toggle();
}
if(Trigger_condition == 0xFF)
{
Trigger_condition = 0;
GPIOA_7_Control(IO_Output);
GPIOA_7_Toggle();
}
}
main.c
if(TB0.FragmentFlag & Fragment_1ms_Mask)
{
TB0.FragmentFlag ^= Fragment_1ms_Mask;
Wheel_Scan();
Wheel_Handle();
}