注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

俊峰 电子 电脑

伸手摘星,未必如愿,但至少不会弄脏你的手

 
 
 

日志

 
 
关于我

荆门市东宝中学 熊军锋 任教学科:网络管理 擅长的技术:专业开发8位 16位 32位单片机,电脑人机界面一体化控制,工业控制,数控产品及嵌入式系统开发等。 曾经做过的项目:数码发电机,摩托车综合仪表,变频器,打包机控制

网易考拉推荐

旋转编码器解码的工作原理与应用源码  

2010-04-13 16:53:08|  分类: 嵌入式开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

旋转编码器的信号输出有A相,B相,Z相,其中Z为零脉冲,计数模块中不使用。计数模块使用A,B来进行计数。编码器结构以及计数原理如下: 
结构:玻璃码盘,上排为A,下排为B,灰色的不透光,白色的透光。 
编码器转动后经过码盘和光电二极管的作用可以得到如下的波形:

旋转编码器解码的工作原理与应用源码 - dbzxxiong - 俊峰 电子 电脑

上图为编码器的工作原理,图中A相超前B相90度,如果转动方向相反,则A相滞后B相90度。B_A为B&A的组合,若A相超前B相90度设定为正向旋转,则编码器正向转动一个码的距离,B_A变化过程为01-11-10-00。 
根据这个原理计数模块根据B_A变化过程来计数: 
若当前B_A为00状态,下一个状态为01则计数器加1。 
若当前B_A为00状态,下一个状态为10则计数器减1。 
其余状态不符合编码器的工作原理,计数器的值不变。 
此时计数器的结果是编码器实际移动一个码距离的4倍。由于编码器加工精度的原因,这个结果与实际的位置相比,不是非常准确。 
通常的增量式光电编码器产生的周期性的方波信号理论的占空比是1:1,即50%。但是由于码盘加工精度,安装精度等原因的影响,在编码器匀速转动时产生信号的占空比不是1:1,是40%-60%,即信号占空比的误差是10%。 
但是其信号的周期误差,即高电平与低电平时间总和的误差比较小,为1%。所以通常用编码器信号测量速度应该测量信号的整个周期来计算,这样测量的误差才较小。 
只有把计数结果右移两位(除以4),得到的结果才是准确的编码器移动一个码的距离。
/*旋转编码器解码程序
PC4,PC5为左右输入,内部上拉,公共脚接地。
1ms调用一次
//修改:
*/
#define Knob_In_PIN PINC
#define Knob_In_PORT PORTC
#define Knob_In_DDR DDRC

#define Knob_In_L PC4
#define Knob_In_R PC5

//输出结果:0不动作;1左转一格;2右转一格。
enum direct {STOP,LEFT,RIGHT}D_OUT;

const unsigned char direct_left[5] PROGMEM ={3,2,0,1,3};
const unsigned char direct_right[5] PROGMEM ={3,1,0,2,3};

//初始化。
void Knob_Init(void)
{
Knob_In_DDR &= ~((1<<Knob_In_L)|(1<<Knob_In_R)); //输入
Knob_In_PORT |=(1<<Knob_In_L)|(1<<Knob_In_R); //上拉
}

//编码器解码 
void knob_scan(void) 

unsigned char knob_ary[3];
unsigned char knob_count; 
unsigned char knob_value; 
bit knob_update;
   
   knob_value = Knob_In_PIN&((1<<Knob_In_L)|(1<<Knob_In_R)); //取端口C管脚信号 
   knob_value =knob_value>>4;
   
  if(knob_value==knob_ary[0])
  {
    ++knob_count;
    if(knob_count==1)
    {
      knob_ary[2]=knob_ary[1];
      knob_ary[1]=knob_ary[0];
      update=1;
    }
    if(knob_count==0xff) //停留,不转动。
    {
      knob_count=2;
    }
  }
  else
  {
    knob_ary[0]=knob_value;
    knob_count=0;
  }
  //如果转动产生新数据,判断方向。
  //左转为 11 10 00 01 11  3 2 0 1 3
  //右转为 11 01 00 10 11  3 1 0 2 3
  if(update)
  {
    update=0;
    for(i=0;i<4;i++)
    {
      if((knob_ary[2]==pgm_read_byte(direct_left+i))&&(knob_ary[1]==pgm_read_byte(direct_left+i+1)))
      {
        D_OUT=LEFT;
      }
      else if((knob_ary[2]==pgm_read_byte(direct_right+i))&&(knob_ary[1]==pgm_read_byte(direct_right+i+1)))
      {
        D_OUT=RIGHT;
      }
      else D_OUT=STOP;
    }
  }
}

  评论这张
 
阅读(1053)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017