功能是利用单片机外部中断判断编码器A相上升沿、下降沿时B相状态,避免编码器方向转换时少计数。
这是写的第一版
void INT0_ISR_Handler (void) interrupt INT0_VECTOR //进中断时已经清除标志
{
static u8 count = 0;
static bit b_flag; //
if(Enc_A == 0 && count == 0) //编码器A相低电平,计数为零
{
b_flag = 0; //标志位为0,转动方向标志位
if(Enc_B) //B相为高
b_flag = 1; //转动方向
count = 1; //A相脉冲下降沿
}
if(Enc_A == 1 && count == 1) //A相脉冲上升并且完整一个脉冲
{
if(Enc_B == 0 && b_flag == 1) //
{
cnt_a--;
}
if(Enc_B && b_flag == 0)
{
cnt_a++;
}
count = 0;
}
}
这是优化后的,通过将编码器状态和计数器封装到结构体中,我们可以更加便捷地管理编码器状态,并且在中断服务程序中也更容易理解代码的逻辑。
//2023-6-14优化 ,用枚举类型定义编码器状态
enum EncoderState
{
ENC_LOW,
ENC_FALLING_EDGE,
ENC_HIGH,
ENC_RISING_EDGE
};
//2023-6-14优化 ,将编码器的A相和B相状态封装成一个结构体
struct Encoder
{
enum EncoderState A;
enum EncoderState B;
int count;
};
void INT0_ISR_Handler(void) interrupt INT0_VECTOR //进中断时已经清除标志
{
static struct Encoder encoder;
static enum EncoderState lastA = ENC_HIGH;
// 读取A相和B相状态
encoder.A = Enc_A ? ENC_HIGH : ENC_LOW;
encoder.B = Enc_B ? ENC_HIGH : ENC_LOW;
// 判断编码器状态变化
if (lastA == ENC_LOW && encoder.A == ENC_HIGH) // A相上升沿
{
if (encoder.B == ENC_LOW) // 正转方向
{
encoder.count++;
}
else if (encoder.B == ENC_HIGH) // 反转方向
{
encoder.count--;
}
}
// 更新状态
lastA = encoder.A;
}