背景:
在学习STM32F103的中断时,用到旋转编码器,需要通过旋转编码器输出的DO信号,获取旋转的刻度和方向。
前提知识:
使用中断需要RCC使能GPIO外设口及AFIO口、初始化GPIO、中断引脚AFIO选择配置、EXTI外部中断配置、NVIC嵌套中断向量控制器配置。
信号从输入线进入到边沿检测电路、或门、请求挂起、至NVIC中断控制器
旋转编码器电路
正文
旋转编码器通过特殊码盘结构,将旋转转化为正交信号,其中顺时针旋转A信号比B信号超前90°;逆时针B信号比A信号超前90°。
在上图顺时针方向C.W行, 图2,A超前B90°,如果外部中断信号触发模式为上升沿触发,则在第2条竖线处代表A已经发生上升沿中断信号,且此时A端子为高电平且B端子为高电平;如果外部中断信号触发模式为下降沿触发,则第3条竖线处代表A已经发生了下降沿中断信号,且此时A端子为低电平且B端子为低电平。
在上图逆时针方向C.C.W行, 图2,B超前A90°,如果外部中断信号触发模式为上升沿触发,则在第2条竖线处,在B发生上升沿中断信号后,A端子和B端子都是高电平;如果外部中断信号触发模式为下降沿触发,则在第3条竖线处,A端子和B端子都处于低电平。
注意: 我在编码时,发现如果不同时读取Pin0和Pin1口,将会发现调节显示数值不变。因为在A端子信号发生后,编码器值+1,但是B端子信号会在随后的90°相位的时间点再次触发中断,此时编码器值-1,就会导致数据不变。因此需要同时检测A、B两个端子电平,避免两个中断信号相互干扰。
代码如下:
// 指定外部中断线为下降沿触发
// EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
// 下降沿模式, 因此A和B端子都应该在下降沿模式时电平为低电平.void EXTI0_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line0) == SET){// 上升沿触发, B0if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0){if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)Encoder_Count++;}EXTI_ClearITPendingBit(EXTI_Line0);}
}void EXTI1_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line1) == SET){if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0){if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)Encoder_Count--;}EXTI_ClearITPendingBit(EXTI_Line1);}
}
参考:
STM32入门教程-2023版 细致讲解 中文字幕P12