用STC8H单片机外部中断实现增量式编码器完整计数

功能是利用单片机外部中断判断编码器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;
    
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老赵aaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值