找回密码
 立即注册
查看: 270|回复: 6

求助旋转编码器实现程序

[复制链接]

48

主题

87

回帖

907

积分

高级会员

积分
907
发表于 2026-9-8 18:33:25 | 显示全部楼层 |阅读模式
求助旋转编码器实现程序,我试了几个编码器程序都十分不理想,我现在使用的是STC32G12K128单片机,我现在AB接的是P33、P36,准备用双中断,刚开始还好用了几天口,就出现跳码现象,用豆包提供的几个程序不知为什么豆包成功,求助各位老师提供一个验证比较理想的程序,谢谢
回复

使用道具 举报 送花

已绑定手机

11

主题

484

回帖

1362

积分

金牌会员

积分
1362
发表于 2026-9-8 20:06:01 | 显示全部楼层
旋转编码器编程非常简单,以EC11编码器为例:
无标题.jpg


旋转编码器A接 P3.2 INT0
旋转编码器B接任意IO
当P3.2下降沿触发中断立即读编码器B判断旋转方向
旋转编码器A、B接有硬件消抖,无需软件消抖
//INT0外部中断服务函数
void INT0_Isr() interrupt 0
{
        if(Encoder_B)count++;         //正转
        else count--;                    //反转               
}


回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25428
发表于 2026-9-9 00:13:06 | 显示全部楼层
截图202609090013016270.jpg
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25428
发表于 2026-9-9 00:13:43 | 显示全部楼层

现在我已经获得了非常全面的信息。让我来整理回答。

根据我的理解,用户只是提供了一个论坛帖子的链接让我查看。这个论坛帖子是关于STC32G12K128单片机上使用旋转编码器(EC11)出现跳码问题的求助帖。

让我综合分析已有信息,给用户一个完整的技术分析和解决方案。


我仔细阅读了你提供的论坛帖子链接(TID 25526),这是国芯人工智能技术交流社区关于旋转编码器实现程序的求助帖。下面我作为STC FAE工程师给你完整的分析。


一、帖子内容摘要

楼主问题:

  • 使用 STC32G12K128 单片机
  • 旋转编码器AB相接 P3.3、P3.6
  • 尝试双中断方式,刚开始正常,用了几天后出现跳码现象
  • 用其他AI工具提供的程序效果不佳,寻求验证过的可靠方案

论坛回复(wul*):**

建议编码器A接P3.2(INT0),B接任意IO,用下降沿中断立即读B判断方向,且编码器需有硬件消抖。


二、问题根因分析

你提到的"双中断+用了几天出现跳码",通常由以下因素导致:

  1. 机械抖动:旋转编码器(如EC11)旋转时触点抖动会产生大量毛刺,如果中断触发过密,会在一个编码脉冲上重复计数。
  2. 两个I/O口各自独立中断:P3.3(INT1)和P3.6(INT2)分别触发中断,两个中断可能在编码器状态切换的临界时刻竞争/重入,导致方向判断错误。
  3. 缺少输入滤波/去抖:STC32G的I/O口中断虽然有上升/下降沿配置,但本身没有硬件去抖。编码器信号若不经过RC硬件消抖,软件上又没做滤波,就极易跳码。
  4. 中断响应时间过长:在中断里做较多运算会丢掉编码器的快速脉冲。

三、推荐方案

针对你的应用,我给你两种可靠方案:

方案一:硬件正交编码器模式(最推荐)

STC32G12K128 的 PWMA 高级PWM定时器原生支持正交编码器接口模式,硬件自动处理方向判断和计数,无需软件去抖、无需中断竞争,这是最稳定可靠的方案。

根据《STC32G系列手册》第「26 16位高级PWM定时器,支持正交编码」章节,配置编码器接口模式的关键步骤如下:

// 正交编码器模式示例(PWMA定时器)
// 编码器A相接PWMA_TI1,编码器B相接PWMA_TI2
#include "stc32g.h"
#include "intrins.h"

void main(void)
{
    unsigned char enc_cnt_h, enc_cnt_l;
  
    EAXFR = 1;          // 使能访问XFR
    CKCON = 0x00;       // 外部数据总线速度最快
    WTST = 0x00;        // 程序代码等待参数最快
  
    // 配置PWMA编码器输入引脚为I/O输入模式
    // 具体引脚映射取决于PWMA_PS寄存器的设置
    // 默认PWMA_PS=0x00时,PWM通道在P1端口
  
    PWMA_ENO = 0x00;        // 关闭PWM输出,配置为输入
    PWMA_PS = 0x00;         // 00:PWM at P1
    PWMA_PSCRH = 0x00;      // 预分频寄存器高
    PWMA_PSCRL = 0x00;      // 预分频寄存器低
  
    PWMA_CCMR1 = 0x21;      // 通道1配置为输入,接编码器,滤波器4时钟
    PWMA_CCMR2 = 0x21;      // 通道2配置为输入,接编码器,滤波器4时钟
  
    PWMA_SMCR = 0x03;       // 编码器模式3(TI1和TI2双边沿计数)
  
    PWMA_CCER1 = 0x55;      // 配置通道使能和极性
    PWMA_CCER2 = 0x55;      // 配置通道使能和极性
  
    PWMA_IER = 0x02;        // 使能PWMA中断
    PWMA_CR1 |= 0x01;       // 使能计数器
  
    EA = 1;
  
    while (1)
    {
        // 周期读取计数器值
        enc_cnt_h = PWMA_CCR1H;
        enc_cnt_l = PWMA_CCR1L;
        // 使用enc_cnt_h/enc_cnt_l得到当前编码器位置
    }
}

// PWMA中断服务函数
void PWMA_ISR() interrupt 26
{
    if (PWMA_SR1 & 0x02)
    {
        PWMA_SR1 &= ~0x02;   // 清除中断标志
    }
}

注意: 使用PWMA正交编码器模式时,需要确认编码器A/B信号映射到PWMA的TI1/TI2输入引脚上。你可以通过查阅STC32G管脚图确认对应的引脚。

方案二:外部中断 + 软件状态机去抖(移植性更好)

如果你更习惯用外部中断方式,建议使用单边沿中断 + 状态机判断,避免两个中断竞争:

  • 编码器A相接 P3.2(INT0),用下降沿触发
  • 编码器B相接任意普通I/O口(如P3.4),不用中断
  • 在INT0中断中读B相电平判断方向
#include "stc32g.h"
#include "intrins.h"

volatile int encoder_count = 0;   // 编码器计数值
volatile unsigned char enc_dir = 0;

void main(void)
{
    unsigned char last_a;
  
    // 确保P3M0/P3M1配置为准双向
    P3M1 = 0x00;
    P3M0 = 0x00;
  
    // INT0下降沿触发
    IT0 = 1;        // INT0下降沿触发
    EX0 = 1;        // 使能INT0中断
  
    EA = 1;
  
    last_a = P32;   // 保存初始状态
  
    while (1)
    {
        // 主循环处理编码器计数
        // encoder_count 在中断中更新
    }
}

// INT0中断服务函数(外部中断0)
void INT0_ISR() interrupt 0
{
    // 在P3.2下降沿时读取B相判断方向
    if (P34)        // B相为高 -> 正转
    {
        encoder_count++;
    }
    else            // B相为低 -> 反转
    {
        encoder_count--;
    }
}

重要提示:此方案依赖编码器自身的硬件消抖(如RC滤波)。如果编码器没有硬件消抖,建议在硬件上添加RC滤波电路(典型值为10kΩ电阻+0.1μF电容),或在软件中做简单的去抖处理。


四、跳码问题排查建议

根据你的描述"用了几天后出现跳码",建议按以下顺序排查:

排查项 说明
硬件消抖 编码器A/B相是否接入RC滤波?没有的话务必加
引脚配置 编码器输入的I/O口配置为准双向或高阻输入,避免内部上拉影响
中断配置 确认IT0/IT1/IT2的中断触发方式与编码器信号匹配
供电稳定性 编码器供电与MCU是否共地?电源纹波是否过大?
长线干扰 编码器与MCU之间连线过长时,考虑增加隔离/滤波

如需我进一步针对你的具体电路给出更精确的配置代码,请告诉我:

  1. 你的编码器型号(EC11?还是其他?)
  2. 编码器A/B相分别接在哪两个引脚
  3. 是否有硬件RC消抖电路
  4. 你期望的计数精度(1倍/2倍/4倍频)

我可以根据你的实际情况,给出完全量身定制且经过验证的代码方案。


信息来源:

  • 论坛帖子TID 25526(回复内容为论坛用户建议)
  • 《STC32G系列手册》第「26 16位高级PWM定时器,支持正交编码」章节
  • 《STC32G系列手册》第「14 中断系统」章节
  • 《STC32G系列手册》第「15 普通I/O口均可中断,不是传统外部中断」章节
  • 《STC32G系列手册》第「4 STC32G系列选型简介」章节(管脚图)

🔍 搜索 "STC8H 单片机 例程 下载"

⏱️ 查找用时 29.9s | 总回答用时 47.9s

回复

使用道具 举报 送花

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-9-9 21:50:17 | 显示全部楼层
神*** 发表于 2026-9-9 00:13
现在我已经获得了非常全面的信息。让我来整理回答。
根据我的理解,用户只是提供了一个论坛帖子的链接让我 ...

刚开始正交编码法不行,使用中断判断另一个的高低电平就可以,我让豆包分析,它其中说了一条可能是并联的电容大的问题,将AB两相并联电容103,更换为102正交编码就可以,效果还可以,不知使用时间久了怎么样,我原来是用一个中断判断高低电平,最后用两个中断,新的可以,编码器磨损了,效果就不好,看看正交编码的这个怎么样,非常感谢你的详细的指导,祝你您工作顺利,身体健康,谢谢

点评

担心编码器用旧不可靠可以往编码器滴注缝纫机机油防触点氧化,可保持数年不丢码。  发表于 2026-9-10 07:29
回复

使用道具 举报 送花

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-9-9 21:52:41 | 显示全部楼层
wul*** 发表于 2026-9-8 20:06
旋转编码器编程非常简单,以EC11编码器为例:

谢谢你的回答,祝您身体健康、万事如意
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-7 14:37 , Processed in 0.073164 second(s), 74 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表