找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 21785|回复: 10
收起左侧

AB相旋转编码器解码

  [复制链接]
ID:26188 发表于 2015-6-23 14:03 | 显示全部楼层 |阅读模式

    AB相旋转编码器有两根信号脚,为A和B。当编码器旋转时,编码器内部两个开关交替通断,两个开关公共端接电源时,A、B脚输出方波;当A超前(或滞后)B时,为正转,反之为反转。以下是摘抄至小孩子的解码算法,简单高效。
假设函数IS_PIN_A_HIGH()和IS_PIN_B_HIGH()是读取A,B两个引脚的状态
假设有两个外中断INT0和INT1都已经配置为双边沿触发模式,则解码如下:

  • //! 编码计数器
  • static volatile uint32_t s_wQDCounter = 0;
  • ISR(INT0_vect)
  • {
  •     if (IS_PIN_A_HIGH() && IS_PIN_B_HIGH()) {
  •         s_wQDCounter++;
  •     } else {
  •         s_wQDCounter--;
  •     }
  • }
  • ISR(INT1_vect)
  • {
  •     if (IS_PIN_A_HIGH() && IS_PIN_B_HIGH()) {
  •         s_wQDCounter--;
  •     } else {
  •         s_wQDCounter++;
  •     }
  • }



读取全局变量s_wQDCounter的时候别忘记加入中断保护。如果要追求效率,可以将计数器类型修改为uint16_t。

--------------------------
以上就是中断法,可以用引脚电平变化中断来做。上面的代码是4倍频。如果要2倍频,去掉任何一个中断处理程序即可。
如果要单倍频,选择任意一个外中断,并选择只对某个边沿触发即可。

多年测试,稳定可靠~
记住一句口诀:

任意边沿触发模式下,A和B进行电平比较:
对A触发的中断:同加异减
对B触发的中断:同减异加
反之亦然

评分

参与人数 1黑币 +30 收起 理由
世纪21电源 + 30

查看全部评分

回复

使用道具 举报

ID:149451 发表于 2016-11-29 15:44 | 显示全部楼层
初学者想找个完整的C51检测EC11编码器的程序,真不好找。大牛们通常只画“点睛”之笔,搞得我等菜鸟云里雾里的...........能给个完整的学习学习吗?
回复

使用道具 举报

ID:288865 发表于 2018-3-9 17:14 | 显示全部楼层
对啊送福送到家,别藏着掖着的
回复

使用道具 举报

ID:221051 发表于 2020-1-16 21:40 | 显示全部楼层
感谢分享!
回复

使用道具 举报

ID:696335 发表于 2021-1-20 10:49 | 显示全部楼层
w1179benp 发表于 2016-11-29 15:44
初学者想找个完整的C51检测EC11编码器的程序,真不好找。大牛们通常只画“点睛”之笔,搞得我等菜鸟云里雾 ...

现在你是大牛了,,可以分享一下代码吗?是真的难找啊
回复

使用道具 举报

ID:371527 发表于 2021-2-20 20:21 | 显示全部楼层
精炼的编码器程序
回复

使用道具 举报

ID:430492 发表于 2022-4-7 16:43 | 显示全部楼层
楼主思路清晰,代码也很精简,赞一个!!
回复

使用道具 举报

ID:168971 发表于 2023-2-2 09:50 | 显示全部楼层
最近正在琢磨旋转编码器,,,借鉴下楼主的
回复

使用道具 举报

ID:774081 发表于 2024-1-26 14:54 | 显示全部楼层
s_wQDCounter被楼主定义为无符号整型,但是在代码中却使用了--运算符,意味着可能要存储负值,基于此,就可以对楼主的责任心打问号。实测楼主的代码确实不好用,只能说有反应,要说实用,完全不可。另外楼主所述“双边沿触发模式”就是指电平变化触发吧?
回复

使用道具 举报

ID:1109793 发表于 2024-2-4 10:33 | 显示全部楼层
shennognshi 发表于 2024-1-26 14:54
s_wQDCounter被楼主定义为无符号整型,但是在代码中却使用了--运算符,意味着可能要存储负值,基于此,就可 ...

实际上这种中断模式在使用时是极其不可靠的。
回复

使用道具 举报

ID:1109793 发表于 2024-2-4 14:51 | 显示全部楼层
网上找到一种这样的,在定时器中断里面不断的调用,可以试试效果怎样
static uchar temp;
temp <<= 2;
if(sig_a)temp += 2;
if(sig_b)temp += 1;
switch(temp&0x0f){
        case 2:case 4:case 11:case 13:
        counter++;                        //脉冲数增加
        break;
        case 1:case 7:case 8:case 14:
        counter--;                //脉冲数减少
        break;
        case 3:case 6:case 9:case 12:
        break;
        }
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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