这是旋转编码器的样子:
2.jpg
3.png
编码器工作原理:
像一个方向旋转,比如向左旋转会A先与GND接通然后到B,向右转就是反过来B先与GND导通然后到A。(这里只是做个比喻,实际不一定是这样的,问题不大)
向左转的时序图:
4.png
为了使它工作稳定A和B引脚需要接一个10K左右的上拉电阻。
清楚它的工作原理就可以开始写代码了
先在cubeMX配置(这里只需要配置PC11为A,PA15为B,其他不用管):
5.png

6.png

然后在nvic选项中把对应的中断勾上否则无法进入回调函数(选不同引脚显示是不一样的反正把带EXTI的选项勾上就对了)
7.png
下面就是代码(发生中断会自动进入这条函数不需要调用,放主函数下面就行了)


//声明这些全局变量,使用方法:读取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); //清除中断
}
最后修改:2020 年 06 月 28 日
声明:无闻风博客|版权所有,违者必究|如未注明,均为原创| 转载:转载请注明原文链接