STM32F070RB 旋钮编码器 外部中断实现

文章描述了一个使用STM32的GPIO模块实现的编码器检测系统,通过A相的上升/下降沿触发中断,然后在中断中读取并比较B相的电平,判断编码器的转动方向,以消除波形抖动影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PC7: A相

PC9:B相

初始化:

void encoder_io_init(void)
{
    GPIO_InitTypeDef   GPIO_InitStructure;
    __HAL_RCC_GPIOC_CLK_ENABLE();/* Enable GPIOC clock */
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    GPIO_InitStructure.Pull = GPIO_PULLDOWN;
    GPIO_InitStructure.Pin = GPIO_PIN_9 |GPIO_PIN_8;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

    /* Configure PC.7 PC9 pin as input floating */
    GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING_FALLING;//GPIO_MODE_IT_FALLING;//GPIO_MODE_IT_RISING;
    GPIO_InitStructure.Pull = GPIO_PULLDOWN;
    GPIO_InitStructure.Pin = GPIO_PIN_7;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

    /* Enable and set EXTI line 4_15 Interrupt to the lowest priority */
    HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}

外部中断: 

void EXTI4_15_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
}
中断回调函数:

int16_t  B_level, Cnt;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_7)
    {

        if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0 && Cnt==0)//A相下降沿触发第一次中断
        {
            Cnt++;//计数值加一,表示已经触发了第一次中断
            B_level=0;//读取B相电平,若为高电平则B_level置1,反之保持0
            if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9) == 1){
                B_level=1;
            }
        }
        if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 1 && Cnt==1)//A相上升沿触发第二次中断
        {
            Cnt=0;//计数清零
            if(B_level==1 && HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9) == 0){
                g_p7++;//正转
            }
            if(B_level==0 && HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9) == 1){
                g_p9++;//反转
            }
        }

    }

}

注意:A相先判断下降沿

原理:

增加判断正、反转的条件,读取一个周期内的电平变化再进行判断。首先将最小系统板的PB0引脚与A相连接,触发方式选择上升/下降沿触发,用A相的输出信号来触发中断,然后在A相下降沿触发第一次中断后读取B相电平,紧接着A相上升沿触发第二次中断后读取B相电平,结合两次读取到的电平来判断是正转还是反转,这种检测方法和第二种方法的原理相同,即从A相的下降沿触发到上升沿触发期间,若B相电平发生了变化,则判定编码器转动,反之未转动,波形抖动时B相的电平保持不变,能够实现消抖。


### 关于EC11旋转编码器与51单片机结合使用的外部中断程序 对于EC11旋转编码器与51单片机的组合,在实现过程中主要依赖外部中断来捕捉编码器的状态变化。下面提供一段示例代码,该代码展示了如何配置51单片机以响应来自EC11旋转编码器A相和B相信号的变化。 #### 配置说明 - 使用两个外部中断分别监听A相(INT0)和B相(INT1),以便检测旋钮的方向以及增量。 - 当任意一相发生电平跳变时触发相应的中断服务函数,在其中通过判断另一相的状态决定转向方向,并更新位置计数值。 ```c #include <reg51.h> sbit LED = P2^0; // 假设LED连接到P2.0口作为调试指示灯 unsigned char cnt = 0; // A相输入端口中断服务子程序 void ISR_A_Phase() interrupt 0 using 1 { if(P3_2 == 0){ // 如果此时B相为低,则表示顺时针转动 cnt++; LED = ~LED; } } // B相输入端口中断服务子程序 void ISR_B_Phase() interrupt 2 using 1 { if(P3_3 == 1){ // 如果此时A相为高,则表示逆时针转动 cnt--; LED = ~LED; } } void main(){ IT0=1; // 设置下降沿触发方式(INT0) IT1=1; // 设置下降沿触发方式(INT1) EX0=1; // 开启外部中断0(A相) EX1=1; // 开启外部中断1(B相) EA=1; // 总控位开 while(1){ // 主循环内可以加入其他操作逻辑 } } ``` 此段代码实现了基本的功能需求,即利用外部中断机制实时监测EC11旋转编码器的动作情况,并据此调整内部计数器`cnt`的值。每当检测到一次完整的脉冲周期(即从一个状态转换至另一个状态再返回原状的过程),就会相应地增加或减少这个计数器中的数值[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值