我是靠谱客的博主 清秀春天,最近开发中收集的这篇文章主要介绍正交编码器溢出处理1.正交编码器2.正交编码器使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 1.正交编码器
    • 1.1 参数特性
    • 1.2 应用范围
  • 2.正交编码器使用
    • 2.1 溢出问题
    • 2.2 中断模式
    • 2.3 循环模式
      • 延伸



1.正交编码器

  正交编码器一般指的是增量式光栅(磁栅)编码器,通常有三路输出信号,A相、B相、Z相,俗称ABZ编码器。所谓正交,即是A相信号和B相信号相位相差90°,根据AB相位的前后,即可判断旋转机构正转还是反转。Z相信号,是旋转一圈后输出的信号,也称为零点信号。

在这里插入图片描述

正交编码器


1.1 参数特性

  • 线数,旋转一圈的脉冲数,如1024线、2500线、10000线
  • 工作电压,3.3V、5V
  • 差分信号,工业应用,为了增加抗干扰能力,ABZ信号通常以差分信号输出
  • 无Z相信号,一些编码器无Z相信号

1.2 应用范围

  • 与电机结合应用,组成伺服电机,直流电机、交流电机、步进电机等
  • 转速测量
  • 多媒体音量调节
  • 鼠标滚轮
  • 游戏手柄

2.正交编码器使用

  • 使用GPIO模拟,适合低速场合,如鼠标滚轮、多媒体音量调节
  • 专用编码器接口,基本上主流的MCU、MPU都支持,适合高速场合使用

  一般情况下使用专门的编码器接口,即是支持正交计数的定时器,由CPU硬件上实现脉冲计数和方向判断,用户只需从定时器寄存器获取脉冲计数和方向,相比使用GPIO模拟效率和精度高。定时器接口还支持边缘采集,可以实现2倍频、4倍频信号;例如5000线编码器,通过4倍频后,单圈实现20000脉冲,最低识别精度为360/20000°。

在这里插入图片描述

STM32编码器接口定时器计数

2.1 溢出问题

  正交编码器接口定时器计数,与定时器位数密切关联;通常定时器有8位、6位、32位;目前主流ARM处理定时器以16位为主,高端处理器支持32位。对于8位计数器,溢出大小为2^8=255;16位计数器溢出大小为2 ^16=65535;32位计数器溢出大小为2 ^32=4294967294。


  以50000线编码为例,经过4倍频后,单圈为20000脉冲;如果是8位计数器,单圈则溢出78次;16位计数器,3圈后溢出。对于高速场景,是不允许的。

  • 如果使能溢出中断,则中断频率过高,影响CPU其他任务
  • 如果未使能中断,CPU运算能力需要在单圈溢出前获取计数值

  以主流16位定时器为例,分别实现以上两个方式溢出处理。


2.2 中断模式

  如果速度不高,或者中断频率容忍度在设计范围,不影响其他任务的正常执行,则可以开启溢出中断,增加一个圈数计算变量,实现起来是非常方便的。实现步骤如下:

  • 初始正交编码器接口,复位计数值为0
  • 重新溢出中断,正转时圈数值减1,反转时圈数加1
  • 实际位置脉冲值=圈数编码器线数4+当前计数值(未满一圈)

伪代码

int64_t count = 0;

/* init encoder timer  */

/* reset encoder timer count */

/* IRQ handler */
void irq_handler(void)
{
	if (direct == CCW)
	{
		count--;
	}
	else
	{
		count++;
	}
}

/* read real pos */
int64_t read_real_pos(void)
{
	int64_t pos= 0;

	temp = count*(2^16 + 1) + (int64_t)__HAL_TIM_GET_COUNTER(&timer);
	return pos;
}

  注意有符号数运算,初始值为0;正转时易于理解。对于反正:初始值计数为0,翻转值65530,产生溢出中断一次,实际值为-6553636+65530 = -6。



2.3 循环模式

  对于高速场景,高频中断占用大量CPU资源,导致其他任务未能及时执行,这是不允许的。定时器计数溢出后归零,在未开启溢出中断时,用户无法感知溢出多少次。因此,我们只需保证处理周期内最多允许一次溢出,处理周期依赖于实际软件复杂度、编码器线数、最大转速。先上伪代码。


#define MAX_COUNT (50000*4)
#define TURN_COUNT (MAX_COUNT/2)	

int64_t pos_fun(void)
{
	static int64_t last_pos = 0;
	int64_t temp_pos = 0;
	int64_t real_pos = 0;
	int64_t current_pos = timer_read_pos();
		
	temp_pos = current_pos - last_pos;
	if (temp_pos >= MAX_COUNT)
	{
	    temp_pos -= TURN_COUNT;
	}
	else if (temp_pos < -MAX_COUNT)
	{
	    temp_pos += TURN_COUNT;
	}

	last_pos = current_pos;
	real_pos += temp_pos;
		
	return real_pos;
}

实现原理:

  • MAX_COUNT 为单圈计数值
  • TURN_COUNT 为一个计算临界值,通常取单圈数值的一半
  • 处理时,当前计数值与上一次值比较,如果差值大于TURN_COUNT ,说明发生反转溢出,则减去单圈值;如果差值小于-TURN_COUNT ,说明发生正转溢出,则加上单圈值
  • 处理周期,取决于软件设计和最大转速,确保这个周期内最多发生一次溢出

延伸

  实质上,该方式也适用于一些绝对式编码器场景;如单圈绝对式编码器,该类编码器以数字接口(SSI、CAN、BISS、并口)输出位置信息,最大支持记录一圈的绝对位置,超出单圈位置后归零。

最后

以上就是清秀春天为你收集整理的正交编码器溢出处理1.正交编码器2.正交编码器使用的全部内容,希望文章能够帮你解决正交编码器溢出处理1.正交编码器2.正交编码器使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部