正交编码

Screen

正交编码器

正交编码器(又名双通道增量式编码器),用于将线性移位转换为脉冲信号。通过监控脉冲的数目和两个信号的相对相位,用户可以跟踪旋转位置、旋转方向和速度。另外,第三个通道称为索引信号,可用于对位置计数器进行复位,从而确定绝对位置。

两个信号相位相差90度,这两个信号就称为正交。

工作原理

增量型编码器通过内部光敏接收管将编码器的转向转化为A相和B相脉冲的时序和相位关系。编码器每转还输出一个Z相脉冲以代表零位参考位。

71a50536gw1ewzcnk3emlg20go0900uc

通过A、B输出波形可知每个运动周期的时序为

编码器的中断

编码器的中断实际上就是定时器的中断。也就是说定时器是每隔一定时间加一个数(或减一个数 ),当数到达预设值时就产生中断,而编码器是每一个有效脉冲就加一个数(或减一个数 ),当数到达预设值时就产生中断。若预设值为1000则编码器与定时器中断不同的是,当编码器反转时值到达999产生一次中断,而当编码器正转到达0时同 样产生一次中断。在硬件上这两个中断是没法区分的,这也就造成了有种情况的误判。

想象一下,如果编码器的预设值为1000,当某次我们使得编码器正转产生中断后,立即反转则又该怎么办呢?根据上面的说法,这时候会产生两次一样的中断。 如果在算法上没有处理的话,极有可能认为是行走了两次正向。但实际上并没有。所以这个时候必须结合方向来判断行走的情况(判断方向使用的是DIR寄存器 位)或者在产生中断后读一次count寄存器位(看看是999还是0,以此来判断当前的方向)。只有上一次为正且这一次同样为正,距离才是相加的。

读取编码器的数据一般有三种方式:

① 专用硬件模块

② I/O中断处理

③ 普通I/O读取并处理

从①至③,占用的计算资源依次增大,但通用性也依次增大,本文将讲解第三种读取方式的原理和实现方式。

代码实现

两相数据都发生变化时,无法判定是顺时针或逆时针旋转,于是都假定变化后数据是在 A相跳变时采集的数据。当采样频率足够高时,两相数据同时发生变化的概率很小,这样的计算方式是足够精确的。

用C语言来表示以上表格的含义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
uint8_t state = 0;

void Update(void)
{
// Read new state bits
if (digitalRead(A))
{
state |= 0x02;
}
if (dagitalRead(B))
{
state |= 0x01;
}

switch (state)
{
case 0x01:
case 0x07:
case 0x08:
case 0x0E:
position -= 1;
break;
case 0x02:
case 0x04:
case 0x0B:
case 0x0D:
position += 1;
break;
case 0x03:
case 0x0C:
position -= 2;
break;
case 0x06:
case 0x09:
position += 2;
break;
default:
//case 0x00:
//case 0x05:
//case 0x0A:
//case 0x0F:
//position += 0;
break;
}

// Update the old state
state <<= 2;
// Keep the old state bits and clear other bits
state &= 0x0C;
}

循环调用以上的函数,就可以得到编码器旋转的栅格数,从而计算出旋转速度和距离。

STM32的编码器模式

在STM32中,编码器使用的是定时器接口,通过数据手册可知,定时器1,2,3,4,5和8有编码器的功能,而其他没有。编码器输入信号TI1,TI2经过输入滤波,边沿检测产生TI1FP1,TI2FP2接到编码器模块,通过配置编码器的工作模式,即可以对编码器进行正向/反向计数。

其它

  1. 编码器有个转速上限,超过这个上限是不能正常工作的,这个是硬件的限制,原则上线数越多转速就越低,这点在选型时要注意,编码器的输出一般是开漏的,所以单片机的IO一定要上拉输入状态
  2. 定时器初始化好以后,任何时候CNT寄存器的值就是编码器的位置信息,正转他会加反转他会减这部分是不需要软件干预的,初始化时给的TIM_Period 值应该是码盘整圈的刻度值,在减溢出会自动修正为这个数.加超过此数值就回0
  3. 如果要扩展成多圈计数需要溢出中断,程序上圈计数加减方向位就行了
  4. 每个定时器的输入脚可以通过软件设定滤波
  5. 应用中如果没有绝对位置信号或者初始化完成后还没有收到绝对位置信号前的计数只能是相对计数.收到绝对位置信号后重新修改一次CNT的值就行了.码盘一般都有零位置信号,结合到定时器捕获输入就行.上电以后要往返运动一下找到这个位置
  6. 即便有滤波计数值偶尔也会有出错误的情况,一圈多计一个或少计一个数都是很正常的特别是转速比较高的时候尤其明显,有个绝对位置信号做修正是很有必要的.绝对位置信号不需要一定在零位置点,收到这个信号就将CNT修正为一个固定的数值即可
  7. 开启定时器的输入中断可以达到每个步计数都作处理的效果,但是高速运转的时候你可能处理不过来

参考:STM32——编码器测速原理及STM32编码器模式

0%