这是旋转编码器的样子:
编码器工作原理:
像一个方向旋转,比如向左旋转会A先与GND接通然后到B,向右转就是反过来B先与GND导通然后到A。(这里只是做个比喻,实际不一定是这样的,问题不大)
向左转的时序图:
为了使它工作稳定A和B引脚需要接一个10K左右的上拉电阻。
清楚它的工作原理就可以开始写代码了
先在cubeMX配置(这里只需要配置PC11为A,PA15为B,其他不用管):
然后在nvic选项中把对应的中断勾上否则无法进入回调函数(选不同引脚显示是不一样的反正把带EXTI的选项勾上就对了)
下面就是代码(发生中断会自动进入这条函数不需要调用,放主函数下面就行了)
//声明这些全局变量,使用方法:读取bmq_flag,如果这个变量为0就是编码器没动作
//如果是1,说明向左转了,再读取bmq_go_int,这个变量是转的步数(脉冲数)
//如果是2,说明向右转了,再读取bmq_go_int,这个变量是转的步数(脉冲数)
//读完以后需要对变量清零 bmq_flag=0;bmq_go_int=0;
char bmq_flag; //0 nothink . 1 L . 2 R
int bmq_go_int;
long bmq_old_time;
char bmq_lr; //0 l . 1 r
void HAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin)
{
#definewx 40 //两个脉冲之间的延时,用于识别是新的动作还是连续的脉冲
switch(GPIO_Pin) //识别中断引脚
{
case GPIO_PIN_11: //A被拉低
if(HAL_GetTick()<(bmq_old_time+wx))//如果距离上一个脉冲的时间很短说明在连续旋转
{
if(bmq_lr==1)
{
if(bmq_flag!=1)
{
bmq_flag=2;
bmq_go_int=0;
}
bmq_go_int+=1;
}
}else
{
bmq_lr=0;
}
bmq_old_time=HAL_GetTick();
break;
case GPIO_PIN_15:
if(HAL_GetTick()<(bmq_old_time+wx))
{
if(bmq_lr==0)
{
if(bmq_flag!=2)
{
bmq_flag=1;
bmq_go_int=0;
}
bmq_go_int+=1;
}
}else
{
bmq_lr=1;
}
bmq_old_time=HAL_GetTick();
break;
default:
break;
}
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); //清除中断
}