OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8724|回复: 10

旋转编码器怎么使用啊

[复制链接]

28

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
243
金钱
243
注册时间
2015-12-26
在线时间
34 小时
发表于 2016-3-7 17:51:08 | 显示全部楼层 |阅读模式
5金钱
旋转编码器我看见上面有A,B,Z三相,都改怎么使用啊,求指导啊,最好有代码展示!

最佳答案

查看完整内容[请看2#楼]

Z是一圈脉输一个脉冲,一般用作初始状态或复位用, AB是两面路相差90度占空比50%的方波, 用于计数和方向识别 /********************************************************************************************* 函数名:记数器中断处理函数(51单片机定时器读取方式,软件4倍频) 调 用:无 参 数:无 返回值:无 结 果:完成编码器的采集工作,记录编码器的位置状态 sbit BianMa_A = P2^0; // ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-3-7 17:51:09 | 显示全部楼层
本帖最后由 likunxue 于 2016-3-7 21:21 编辑

Z是一圈脉输一个脉冲,一般用作初始状态或复位用,
AB是两面路相差90度占空比50%的方波, 用于计数和方向识别

/*********************************************************************************************
函数名:记数器中断处理函数(51单片机定时器读取方式,软件4倍频
调  用:无
参  数:无
返回值:无
结  果:完成编码器的采集工作,记录编码器的位置状态
sbit BianMa_A  = P2^0;                    //编码器A相输出脉冲线
sbit BianMa_B  = P2^1;                    //编码器B机输出脉冲线
signed long   data WeiZhiJiShuQi  = 0;    //光电编码器位置计数器
/**********************************************************************************************/
void name(void) interrupt 1
     {
     static u16 led_stut = 13706;    //工作指示灯闪乐时间为0.5秒(静态变量)
     static u8 ShuChuZhuangTai = 0;  //AB信号状态寄存器(静态变量)
     unsigned char k,Cal;
     Cal = P2&0x03;//取得当前光电编码器输入状态值
     if(Cal != ShuChuZhuangTai)
       {
       k = (ShuChuZhuangTai << 2 )+ Cal;//得到4倍频编码输入状态值
       switch(k)
             {
             case 0x07:WeiZhiJiShuQi++;break;
             case 0x0E:WeiZhiJiShuQi++;break;
             case 0x08:WeiZhiJiShuQi++;break;
             case 0x01:WeiZhiJiShuQi++;break;
             case 0x0D:WeiZhiJiShuQi--;break;
             case 0x04:WeiZhiJiShuQi--;break;
             case 0x02:WeiZhiJiShuQi--;break;
             case 0x0B:WeiZhiJiShuQi--;break;
             }
       ShuChuZhuangTai = Cal; //输入状态存副本
       }
     if(led_stut != 0)led_stut --;
     else{
         led_stut = 13706;
         LED =~ LED; //工作指示灯取反
         }
     }


以下是STM32F103系列芯片硬件编码器接器的实现方法
#define ENCODER_PERIOD          (u16)40000      //编码器溢出重装值(这个值自已定义,最大不能超过 65535)
#define COUNTER_RESET           0u                  //编码器初值

#define CONSTER_BYTE            (s32)(CONSTER_DAT + TIM3->CNT)              //当前转子机械坐标
extern  vs32 CONSTER_DAT;        //编码器计数器在原子哥的寄存器版本下实现 增加一个宏定义
#define BIT_ADM(addr,bitnum)     MEM_ADDR(BITBAND(((u32)&(addr)),(bitnum)))     //按位操作寄存器
读取编码器的值    X = CONSTER_BYTE ;
/*******************************************************************************************
函 数 名: 定时器3编码器模式初始化函数
调    用: TIM3_BMQMS_Init(u8 remap)
参    数: reamap 复用功能重映像 00,01,11 如果参数错误,则采用00参数
反 回 值: 无
说    明: 初始化编码器的AB信号接于 CH1,CH2上 四倍频输出
          如果计数脉冲小于+- 32768 则可以不需要中断处理,初始化计数器初值为32769
          取值时  Cnt = TIM3->CNT - 32768 就行了
********************************************************************************************/  
void TIM3_BMQMS_Init(u8 remap)
     {            
     switch(remap)//IO接器重映像处理
           {
           case 2: { //TM3_REMAP[1,0] = 10
                   RCC->APB2ENR |= 1<< 0;       //开启辅助功能时钟
                   BIT_ADM(AFIO->MAPR,11) = 1;  //高电平   
                   BIT_ADM(AFIO->MAPR,10) = 0;  //高电平  
                   RCC->APB2ENR |= 1<<3;        //使能PORTB时钟     
                   GPIOB->CRL &= 0xFF00FFFF;    //PB4,PB5
                   GPIOB->CRL |= 0x00440000;    //浮空输入                     
                   }break;
           case 3: {//TM3_REMAP[1,0] = 11
                   RCC->APB2ENR |= 1<< 0;       //开启辅助功能时钟
                   BIT_ADM(AFIO->MAPR,11) = 1;  //高电平   
                   BIT_ADM(AFIO->MAPR,10) = 1;  //高电平
                   RCC->APB2ENR |= 1<<4;        //使能PORTC时钟     
                   GPIOC->CRL &= 0x00FFFFFF;    //PC6,PC7
                   GPIOC->CRL |= 0x44000000;    //浮空输入  
                   }break;
           default:{////TM3_REMAP[1,0] = 00
                   RCC->APB2ENR |= 1<<2;        //使能PORTA时钟     
                   GPIOA->CRL &= 0x00FFFFFF;    //PA6,PA7
                   GPIOA->CRL |= 0x44000000;    //浮空输入  
                   }break;           
           }
     BIT_ADM(RCC->APB1ENR,1)  = 1; //TIM3时钟使能         
     BIT_ADM(RCC->APB1RSTR,1) = 1; //复位TIM3定时器,使之进入初始状态
     BIT_ADM(RCC->APB1RSTR,1) = 0; //结束复位      
     TIM3->ARR = ENCODER_PERIOD-1; //设定计数器自动重装值                                 
     TIM3->PSC = 0;                //预分频器,不分频
     BIT_ADM(TIM3->CR1,7) = 1;     //定时器ARPE充许         
     BIT_ADM(TIM3->CR1,  8) = 0;   //选择时钟分频:不分频(在输入捕获中止参数无效)
     BIT_ADM(TIM3->CR1,  9) = 0;        
     BIT_ADM(TIM3->CR1,  5) = 0;   //选择计数模式:边沿对齐模式  
     BIT_ADM(TIM3->CR1,  6) = 0;      
     BIT_ADM(TIM3->CR1,  4) = 0;   //计数器向上计数      
     BIT_ADM(TIM3->CCMR1,8) = 1;   //CC2S='01' IC2FP2映射到TI2
     BIT_ADM(TIM3->CCMR1,9) = 0;
     BIT_ADM(TIM3->CCMR1,0) = 1;   //CC1S='01' IC1FP1映射到TI1
     BIT_ADM(TIM3->CCMR1,1) = 0;   
     BIT_ADM(TIM3->CCER ,1) = 0;   //CC1P='0'IC1FP1不反相,IC1FP1=TI1   
     BIT_ADM(TIM3->CCER ,5) = 0;   //CC2P='0'IC2FP2不反相,IC2FP2=TI2
     //输入捕获1滤波器     
     BIT_ADM(TIM3->CCMR1,4) = 0;   //IC1F='1000'(可能影响采集响应速度)
     BIT_ADM(TIM3->CCMR1,5) = 1;
     BIT_ADM(TIM3->CCMR1,6) = 0;
     BIT_ADM(TIM3->CCMR1,7) = 0;
     //编码器模式3 (四倍频的输出)
     BIT_ADM(TIM3->SMCR, 0) = 1;   //SMS='011' 所有的输入均在上升沿和下降沿有效
     BIT_ADM(TIM3->SMCR, 1) = 1;
     BIT_ADM(TIM3->SMCR, 2) = 0;
     TIM3->CNT = COUNTER_RESET;    //计数器的初值
     CONSTER_DAT = COUNTER_RESET;  //清零中断计数累加器的值为初始值
     BIT_ADM(TIM3->DIER, 0) = 1;   //允许定时器更新中断   
     MY_NVIC_Init(0,0,TIM3_IRQn,4);//抢占0,子优先级0,组4 设定时器3更新中断为最高级别中断
     BIT_ADM(TIM3->CR1,0) = 1;     //开编码器
     }   
/*******************************************************************************************
函 数 名: 定时器3中断函数
调    用: 无
参    数: 无
反 回 值: 无(这里在编码器模式中CPU唯于需要处理的函数)
*******************************************************************************************/  
void TIM3_IRQHandler(void)
     {         
     if(BIT_ADM(TIM3->SR,0) == 1) //溢出中断     
       {
       BIT_ADM(TIM3->SR,0) = 0; //清除中断标志位   
       if(BIT_ADM(TIM3->CR1,4) == 1)CONSTER_DAT -= ENCODER_PERIOD;
       else{
           CONSTER_DAT += ENCODER_PERIOD;   
           }     
       }                                      
     }








回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-7 21:29:40 | 显示全部楼层
likunxue 发表于 2016-3-7 21:03
Z是一圈脉输一个脉冲,一般用作初始状态或复位用,
AB是两面路相差90度占空比50%的方波, 用于计数和方向 ...

反对,
Z相的频率是A或B相的1/2

http://www.openedv.com/forum.php ... 2&fromuid=29476
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-3-7 21:44:45 | 显示全部楼层
本帖最后由 likunxue 于 2016-3-7 21:47 编辑
xkwy 发表于 2016-3-7 21:29
反对,
Z相的频率是A或B相的1/2

谢谢提醒,
我说的是一圈输出一个脉冲, 我手上的编码器Z就只一圈输出一个脉冲, 其它的我到是没有注意到!
“Z相的频率是A或B相的1/2”  你的意思是如果同时计数A B,Z, 哪AB如果输出50个,Z哪一路就会输出 25个脉冲? 或是如指 Z输出的脉冲宽度?  
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-7 22:30:08 | 显示全部楼层
likunxue 发表于 2016-3-7 21:44
谢谢提醒,
我说的是一圈输出一个脉冲, 我手上的编码器Z就只一圈输出一个脉冲, 其它的我到是没有注意 ...

你看我给你链接的图没?
我的编码器是E6B2,那个图是从数据手册截取的,
500线编码器,主轴旋转一圈,A、B相输出500个方波,Z相250个方波
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-3-7 23:26:30 | 显示全部楼层
本帖最后由 likunxue 于 2016-3-8 00:47 编辑
xkwy 发表于 2016-3-7 22:30
你看我给你链接的图没?
我的编码器是E6B2,那个图是从数据手册截取的,
500线编码器,主轴旋转一圈,A ...

我们不争这个问题了, 算我错了吧, 但你实测了没有呢? 还有你乍知1楼用的编码器就是你说的E6B2编码器呢! 我看了你发的图了, 从图上我无法得知到低一圈Z输出几个脉冲,图只的提示了, Z信号与AB相信号的输出的脉冲起始时间

DSK.png
V.png



我说的只代表我的关点, 因为我用过的编码器Z相是一圈一个脉冲, 我用在步进电机闭环驱动上Z相信号只用来做电机转一圈的校对用!
这两张图是从网上收到的,从上面也只体现出Z相是一圈输出一个脉冲.
因为无法实测你说的哪个E6B2 所以我们别争了!!!!!!!!!!!




N9CRJ9Z(ORELI_C%Q83WSH8.png




回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-8 13:35:48 | 显示全部楼层
likunxue 发表于 2016-3-7 23:26
我们不争这个问题了, 算我错了吧, 但你实测了没有呢? 还有你乍知1楼用的编码器就是你说的E6B2编码器呢!  ...

好的,让他自己检测吧
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2013-10-29
在线时间
5 小时
发表于 2016-3-8 13:39:25 | 显示全部楼层
请看我的帖子。。
回复

使用道具 举报

28

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
243
金钱
243
注册时间
2015-12-26
在线时间
34 小时
 楼主| 发表于 2016-3-17 14:59:10 | 显示全部楼层
非常感谢大家的帮助!
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-3-18 01:18:32 | 显示全部楼层
我一直在等你的回复,这么长时间了,我还以为是我回答错了!  
回复

使用道具 举报

28

主题

70

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
243
金钱
243
注册时间
2015-12-26
在线时间
34 小时
 楼主| 发表于 2016-3-24 18:00:12 | 显示全部楼层
likunxue 发表于 2016-3-18 01:18
我一直在等你的回复,这么长时间了,我还以为是我回答错了!

最近比较忙一直没有去看帖子!谢谢啦!
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 00:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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