因为MSPM0G3507只有TimerG8有QEI功能,当需要外接多个编码器时,可采用GPIO中断方式实现计数。

一.sysconfig

(1)Basic Config

1.创建一组GPIO,并加入两个引脚进行配置(两个引脚的配置是一样的)

2.将引脚设置为输入模式

3.设置为浮空输入

(2)Interrupt Config

1.使能中断

2.设置为上升沿触发

(3)PinMux

选择要使用的引脚

二.代码

1.初始化

volatile uint32_t gpioA;
volatile int32_t gEncoderCount = 0;
float speed = 0;

int main(void)
{
    
    SYSCFG_DL_init();


    NVIC_EnableIRQ(GPIO_EncoderA_INT_IRQN);//使能外部中断
    

    while (1) 
    {

    }
}

2.编写外部中断服务函数

void GROUP1_IRQHandler(void)
{
    //获取中断信号
    gpioA = DL_GPIO_getEnabledInterruptStatus(GPIOA,
    GPIO_EncoderA_PIN_0_PIN | GPIO_EncoderA_PIN_1_PIN);

    //如果是GPIO_EncoderA_PIN_0_PIN产生的中断
    if((gpioA & GPIO_EncoderA_PIN_0_PIN) == GPIO_EncoderA_PIN_0_PIN)
    {
        //Pin0上升沿,看Pin1的电平,为低电平则判断为反转,高电平判断为正转
        if(!DL_GPIO_readPins(GPIOA,GPIO_EncoderA_PIN_1_PIN))//P1为低电平
        {
            gEncoderCount--;
        }
        else//P1为高电平
        {
            gEncoderCount++;
        }
    }
    
    //类似于Stm32中编码器模式的AB两相都测,可得到2倍的计数
    else if((gpioA & GPIO_EncoderA_PIN_1_PIN) == GPIO_EncoderA_PIN_1_PIN)
    {
        //Pin1上升沿
        if(!DL_GPIO_readPins(GPIOA,GPIO_EncoderA_PIN_0_PIN))//P0为低电平
        {
            gEncoderCount++;
        }
        else//P1为高电平
        {
            gEncoderCount--;
        }
    }
    
    //最后清除中断标志位
    DL_GPIO_clearInterruptStatus(GPIOA, GPIO_EncoderA_PIN_0_PIN|GPIO_EncoderA_PIN_1_PIN);
}

3.获取速度

int main(void)
{
    
    SYSCFG_DL_init();


    NVIC_EnableIRQ(GPIO_EncoderA_INT_IRQN);
    

    while (1) 
    {
        /* 每次获取完计数值后清零,则可获得以执行周期为单位的速度值 */
        speed = gEncoderCount;
        gEncoderCount = 0;
        delay_cycles(320000);
    }
}

Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐