一、简介
两定位一脉冲的EC11稍微复杂一些,转动一格只会输出半个脉冲。静止时,AB触点开关可以是断开的也可以是闭合的。
- 若初始状态时AB都是高电平,转动一格就输出从高电平到低电平的下降沿,随后一直输出低电平。对应于EC11内部AB两个触电开关的动作为断开–>闭合。
- 若初始状态时AB都是低电平,转动一格就输出从低电平到高电平的上升沿,随后一直输出低电平。对应于EC11内部AB两个触点开关的动作为闭合–>断开。
二、特性
有一些质量比较差的EC11会有一些额外的问题要考虑,例如开关的抖动问题,例如转动定位不清晰,静止时AB两个触点都要闭合或者都要断开才对,但是定位点不清晰,转动的角度不到位导致一个触点已经闭合(断开)了,另一个触点却还保持在断开(闭合)。
三、示例代码
sbit EC_B = P0 ^ 0; // 编码器 P0.0 端口
sbit EC_A = P1 ^ 3; // 编码器 P1.3 端口
static uint8_t EC_A_Val = 0, EC_B_Val = 0;
static uint8_t EC_A_old = 0, EC_B_old = 0;
/*********************************************
函数名:EncoderReading
功 能:读取编码器数据
返回值:0--无动作 1--正转 2--反转
作 者:薛建强
时 间:2019/06/11
**********************************************/
uint8_t EncoderReading(void)
{
/*捕获一次*/
EC_A_Val = EC_A;
EC_B_Val = EC_B;
/*************EC_B上升沿*******************/
if (EC_A_Val == EC_A_old && EC_B_Val > EC_B_old)
{
/*重新给旧值赋值*/
EC_B_old = EC_B_Val;
EC_A_old = EC_A_Val;
if (EC_A_Val == 0) //反转
{
return 2;
}
}
/*************EC_B下升沿*******************/
if (EC_A_Val == EC_A_old && EC_B_Val < EC_B_old)
{
/*重新给旧值赋值*/
EC_B_old = EC_B_Val;
EC_A_old = EC_A_Val;
if (EC_A_Val == 1) //反转
{
return 2;
}
}
/*************EC_A上升沿*******************/
if (EC_B_Val == EC_B_old && EC_A_Val > EC_A_old)
{
/*重新给旧值赋值*/
EC_B_old = EC_B_Val;
EC_A_old = EC_A_Val;
if (EC_B_Val == 0) //正转
{
return 1;
}
}
/*************EC_A下升沿*******************/
if (EC_B_Val == EC_B_old && EC_A_Val < EC_A_old)
{
/*重新给旧值赋值*/
EC_B_old = EC_B_Val;
EC_A_old = EC_A_Val;
if (EC_B_Val == 1) //正转
{
return 1;
}
}
return 0;
}
使用方式:
KEY_state = EncoderReading(); //编码器调光度
switch (KEY_state)
{
case 1://正转
break;
case 2://反转
break;
}
四、其他
编码器型号是EC11,带一个微动开关。
它也是常见的一种编码器,旋转一圈,能输出20个脉冲信号。也就是说,你要让编码器输出一个单片机能识别的脉冲,最少要旋转13°。
当然也有输出15个脉冲的型号或者输出更多脉冲的型号,例如EC16。换言之,就是旋转精度不一样。
那么编码器有什么用呢?
如果我们用一个变量cnt来计数,那么当编码器顺时针旋转360°,cnt的值就+20,旋转两圈,cnt 的值就+40。旋转N圈,cnt的值就+20*N。
反之,逆时针旋转N圈,cnt 的值就-20*N。
用手来拧,有些时候比按微动开关要舒服的多,而且可以顺时针和逆时针的快拧和慢拧,更是舒服。
所以呢,鼠标的中间的滚轮,汽车用CD上调整频率和音量的旋钮,用的都是编码器。