找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

一定位一脉冲的EC11旋转编码器最简洁的单片机驱动代码

查看数: 23125 | 评论数: 58 | 收藏 62
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2021-7-2 19:11

正文摘要:

先上代碼為敬             if(!PinA && PinA_O && PinB) {                 Now++;      &nbs ...

回复

ID:879481 发表于 2025-6-4 18:49
有在PIC单片机上使用编码开关的程序代码,小白想借鉴下
ID:983641 发表于 2025-2-15 15:21
相当简洁的代码。需要时间消化。
ID:1143011 发表于 2025-1-16 12:31
bhjyqjs 发表于 2022-2-7 10:49
楼主代码及其精简,不错!
实际上,只检测A引脚的下降沿,由B引脚状态决定加减更高效。
经实验,无漏脉冲 ...

高手啊!
ID:471574 发表于 2024-9-27 08:22
http://www.51hei.com/bbs/dpj-233399-1.html
这个也是很简洁,又新颖的EC11驱动
ID:774081 发表于 2024-9-20 15:54
hewayking 发表于 2024-7-2 17:06
个人做法是a下降沿中断     中断后   判断b高低   确定正反转

试了,很棒!史上最简洁的代码。
ID:119977 发表于 2024-7-2 17:06
个人做法是a下降沿中断     中断后   判断b高低   确定正反转
ID:774081 发表于 2024-1-26 16:36
之前测试很多代码,效果均不理想,表现为正转、反转有误判,从而导致计数不对。我想到的办法是得到方向数据后(比如正转定义为1,反转定义为0),先修正方向,再结合中断和方向二者,决定是否累加或累减计数值。方案是建立一个数组,包括10个元素,用来存储获得的方向,任何时刻记录的是最近十次获得的方向数据,对数组的10个元素进行累加,和超过5时,强制为正方向,反之为负方向。实测效果有所改善,计数值绝不会忽大忽小、重复出现等情况了。遗憾的是如果你反复正转、反转1下,那计数还是会有问题,即不会保持不变。但这种使用场景很少见吧?真要微调,你多转几下,再反过来多转几下就行。有人会说,实际卡顿感与计数反映会不同步吧?理论上讲是这样,但单片机速度很快,实际感觉不到不同步。
ID:430492 发表于 2024-1-19 14:56
要想多快都不丢步(相对哈,快到中断处理都来不及不算哈),必须在中断里来处理。这种中断+轮询判断的方式,依然会丢步的。
ID:1101997 发表于 2024-1-19 14:51
这东西还是需要用状态机来写,只要描述好正常状态迁移的关系,异常状态处理,硬件上消抖不消抖都是可以处理好的。
ID:774081 发表于 2024-1-19 14:17
完美的代码效果应该是转动一下只计数一下,不能多增也不能不增,最重要的是!不论转得多快还是多慢,都如此,那才是好代码!从这个标准来说,我试验了上10款作者自诩为非常不错的代码,均不合格!当然我自己也编不出合格的代码来,一度怀疑是我买的EC11编码器在硬件方面不合格,因为只有上拉电阻。没有消抖电容。但符合这样标准的编码器效果是普遍存在的,比如十几、二十年前的进口功放机,就采用了旋转编码器调整音量,那编码器的使用效果才是我追求的,现在我的一个项目卡在编码器上,怎么都不好用,肯定采用中断来实现,还没找到合适的代码,下一步寄加消抖电容看看谁的代码最理想,再来汇报。
ID:471574 发表于 2023-12-14 17:37
楼主的代码很不错,我这边有另一种算法,也很精简EC11编码器基于运算解码的算法(原创),汇编后大小也基本一样,有一个算法甚至更小
ID:688905 发表于 2023-11-29 16:40
很好的优化方法,学习了!
ID:427868 发表于 2023-11-29 15:01
diyage 发表于 2023-11-25 19:55
我跟你用的一样,但是发现转快了丢码,慢很好

你说的这种情况,确实存在,也不能旋转过快,且在部分EC11上表现明显,即存在挑EC11现象,,后来我尝试将KB对地接的104电容换成105的就改善了,也不挑EC11了,你可试试。
ID:103411 发表于 2023-11-29 14:12
下载学习一下,正准备用这个一定位一脉冲编码器。
ID:1053178 发表于 2023-11-25 19:55
刘佑红 发表于 2023-9-25 15:48
以下是我之前采用拿来主义得到的,只对判断后执行部分稍作修改,应用还不错。
/************************ ...

我跟你用的一样,但是发现转快了丢码,慢很好
ID:378108 发表于 2023-9-28 09:57
  unsigned char key=0;
  static bit nextA;
  if (KA()!=nextA)
    {nextA=KA();
      if (nextA==1)
        {if (KB()==1) key=6;else key=5;}
      else
        {if (KB()==0) key=6;else key=5;}
    }
return key;
ID:378108 发表于 2023-9-28 09:49
haokey 发表于 2021-7-7 12:20
探讨一下,假如我改成这样会怎样:
if(!PinA&&PinB)
{PinA_O= 1;}

你这样是不行的,会重复的加或减
ID:427868 发表于 2023-9-25 15:48
以下是我之前采用拿来主义得到的,只对判断后执行部分稍作修改,应用还不错。
/************************参数设置***************************/
void        canshu()                                //EC11旋转编码器一定位一脉冲
{
        static bit LastA = 0;                 //EC11旋转编码器的A引脚上一次的状态
        static bit LastB = 0;                //EC11旋转编码器的B引脚上一次的状态
               
  if(KA != LastA)                         //判断EC11旋转编码器A引脚是否等于上一次的状态
  {
    if(KA == 0)                                //EC11旋转编码器旋转后,判断KA是否是低电平状态
         {
                if(KB)                         //判断KB引脚当前状态,高电平则为正转
                        {num++;}                                                
                else
                        {num--;}                                                       
         }       
     LastA = KA;                         //更新编码器上一个状态暂存变量
     LastB = KB;                         //更新编码器上一个状态暂存变量
   }
}

现在看来LsaB变量似乎没有用,有空了去掉它试试。对于正反向不同的EC11,我是通过调换num变量的加减方向来解决的。
ID:965189 发表于 2023-9-22 23:34
我用一个外中断,使用正常。
ID:433219 发表于 2023-9-22 19:34
一般方法:先判断跳变(同时触发抖动计时连续判断),再判断另一个io的高低,
ID:161164 发表于 2023-9-22 16:14
herui2128 发表于 2023-9-22 15:41
谢谢楼主分享,我用的STC15W408AS。用楼主的例程,采用两个外部中断来检测脉冲。能正常检测到正转和反转。 ...

用一个外中断即可
  1. uint Delay_XD = 0;
  2. bit Encoder_EN = 1;
  3. void exint0() interrupt 0       //INT0中断入口
  4. {
  5.         if(Encoder_EN)
  6.         {
  7.                 if(!P33)
  8.                 {
  9.                         count1++;
  10.                 }else{
  11.                         count2++;
  12.                 }
  13.                 Encoder_EN = 0;
  14.         }
  15. }
  16. void main()
  17. {
  18.         //your code
  19.         while(1)
  20.         {
  21.                 //your code
  22.                 if(!Encoder_EN)
  23.                 {
  24.                         if(P32)
  25.                         {
  26.                                 if(Delay_XD++>=1000)//按主循环周期调节
  27.                                 {
  28.                                         Delay_XD = 0;
  29.                                         Encoder_EN = 1;
  30.                                 }
  31.                         }else{
  32.                                 Delay_XD = 0;
  33.                         }
  34.                 }
  35.         }
  36. }
复制代码



ID:398219 发表于 2023-9-22 15:41
谢谢楼主分享,我用的STC15W408AS。用楼主的例程,采用两个外部中断来检测脉冲。能正常检测到正转和反转。但是旋转编码器的旋转速度稍微快点,就容易丢脉冲(脉冲速度快了,连成一片了),导致单片机采不到或者误采到B相。求一下速度快点的解决办法。count1和count2是正转和反转的脉冲计数,以后用于计算角度使用。
void exint0() interrupt 0       //INT0中断入口
{       
        if(!P32 && PinA_O && P33)
        {
                count1++;
               
        }       
        PinA_O = P32;
}
//外部中断服务程序1
void exint1() interrupt 2       //INT1中断入口
{
        if(!P33 && PinB_O && P32)
        {
                count2++;
        }
        PinB_O = P33;
}
ID:1064915 发表于 2023-7-1 09:36
hi等你 发表于 2023-6-28 16:05
我就是不用定时器和中断,这个资源用在更重要的地方,只需要判断10和11就行,反转判断01和11.

已 ...

能否共享一下
ID:1085441 发表于 2023-6-30 21:21
微笑的小小 发表于 2022-11-8 17:51
这个代码我在STC15W408AS上调试通过。 为什么在STC8H1K08上不行,就是没有操作EC11旋转编码器,电脑串口     ...

STC15W的引脚默认是准双向口,STC8H的引脚默认是高阻,初始化的时候需要设置为准双向口。
ID:1085441 发表于 2023-6-30 21:18
EC11不需要用延时,放在中断程序中,占用资源很少,用的很稳定。
ID:996773 发表于 2023-6-28 16:05
lkc8210 发表于 2023-6-27 11:30
看到"延时毫秒"和"中断和定时器都不需要"
就知道你还没弄懂



我就是不用定时器和中断,这个资源用在更重要的地方,只需要判断10和11就行,反转判断01和11.

已经成品用了好久了,手感也很好
ID:161164 发表于 2023-6-27 11:30
hi等你 发表于 2023-4-17 10:59
不用这么复杂,只要判断两个脚是11,然后延时毫秒多少。忘了,再判断是不是10,就说明

它旋转了,如果判 ...

看到"延时毫秒"和"中断和定时器都不需要"
就知道你还没弄懂
ID:1085900 发表于 2023-6-26 22:21
hi等你 发表于 2023-4-17 10:59
不用这么复杂,只要判断两个脚是11,然后延时毫秒多少。忘了,再判断是不是10,就说明

它旋转了,如果判 ...

[em17
ID:996773 发表于 2023-4-17 10:59
不用这么复杂,只要判断两个脚是11,然后延时毫秒多少。忘了,再判断是不是10,就说明

它旋转了,如果判断出来是01就是反方向旋转了,中断和定时器都不需要,主程序留在

等待的时候加一丢丢延时再执行就ok了
ID:240452 发表于 2022-11-8 20:55
stc8h默认是高阻
ID:240452 发表于 2022-11-8 20:55
//00准双向  01推挽输出  10高阻输入 11开漏输出高阻输入
P3M1 = B0000_0000;
P3M0 = B1010_0000;

增加这个后就可以了
ID:240452 发表于 2022-11-8 17:51
这个代码我在STC15W408AS上调试通过。 为什么在STC8H1K08上不行,就是没有操作EC11旋转编码器,电脑串口    不断收到数据。                                                                                                                                                                                          
ID:887371 发表于 2022-6-14 15:48
hewayking 发表于 2022-2-16 14:19
个人做法硬件加104电容  一个接外部中断一个接普通IO    中断后读普通IO高低     正转高或低   反转低或高 ...

我也认为这种方法更好。
http://www.51hei.com/bbs/dpj-221520-1.html
这是用十速51mcu做的直流电机定位功能,非常可靠准确,用于EC11要加104电容。
一定要用软件消抖,要增加2个全局bit变量用于存储AB引脚之前的状态,但这样增加了不少mcu开销。
ID:509339 发表于 2022-2-17 14:27
hewayking 发表于 2022-2-16 14:19
个人做法硬件加104电容  一个接外部中断一个接普通IO    中断后读普通IO高低     正转高或低   反转低或高 ...

难打别人不都是这样吗?
ID:119977 发表于 2022-2-16 14:19
个人做法硬件加104电容  一个接外部中断一个接普通IO    中断后读普通IO高低     正转高或低   反转低或高控制++ --      可靠高效无敌  一般人我不告诉他
ID:883031 发表于 2022-2-8 14:40
齿轮传动,小齿轮带大齿轮,用大齿轮带动编码器旋转,即可降低转速
ID:161164 发表于 2022-2-8 13:29
cn_zhx 发表于 2022-2-8 10:18
其实,这里AB数据线产生的是格雷码,如果我们采集时采用判断AB两线的变化,即,A或B来下降沿时,作出4次判 ...

什么是加减速器的方法?
可以详细说说吗?
ID:883031 发表于 2022-2-8 10:18
本帖最后由 cn_zhx 于 2022-2-8 14:43 编辑

其实,这里AB数据线产生的是格雷码,如果我们采集时采用判断AB两线的变化,即,A或B来下降沿时,作出4次判断,可以避免楼上所说的哆嗦,但是,要求采样频率要跟得上,可以采用加减速器的方法,
ID:67925 发表于 2022-2-8 01:32
lkc8210 发表于 2022-1-28 14:03
如果编码器太松就有可能

为什么我知道是因为我以前就是用类似的算法,后来全部换成更复杂的算法了。
看应用,如果误加减影响不大则可以用,否则需要更鲁棒性的算法
ID:161164 发表于 2022-2-7 17:20
bhjyqjs 发表于 2022-2-7 10:49
楼主代码及其精简,不错!
实际上,只检测A引脚的下降沿,由B引脚状态决定加减更高效。
经实验,无漏脉冲 ...

妙啊~

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

Powered by 单片机教程网

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