具有 ASEK动态链接库谐波线性化功能的先进编程算法

具有 ASEK动态链接库谐波线性化功能的先进编程算法

下载 PDF版

作者:罗伯特·贝特,
亚博棋牌游戏Allegro微系统有限责任公司

介绍

无论是工业自动化和机器人技术,还是电动助力转向和电机位置传感,许多应用都需要监测旋转轴(以轴上或离轴排列形式)的角度。

在设计中使用磁体时,磁场输入在整个旋转范围很可能不均匀,它存在固有误差。这些磁场输入误差会导致系统内的测量误差。线性化能减少这些输入误差。

A1332A1335可采用的谐波线性化能以最多 15种修正谐波的形式应用线性化,利用快速傅立叶变换 (快速傅立叶变换)可确定它们的相位和振幅,根据磁体在角度传感器 集成电路周围的一次旋转产生的数据可完成 快速傅立叶变换通过使用 快板提供的软件计算系数,并对片内 电可擦可编程只读存储器进行编程,可使用这种技术。本应用说明介绍了,当 快板提供的软件不够灵活或要使用定制软件时,客户能使用的功能和处理流程。

编程要求

所有软件都是在使用 .NET 4.0的 Microsoft Visual Studio 2010环境下开发的。请为您要使用的器件下载命令库 (C#/.NET)并添加到其所含的 3.个 动态链接库的项目参考中。

收集数据

首先,关闭所有后线性化算法处理;这包括零点偏移、后线性化旋转 (RO)短行程反转 (四)和旋转晶片位元 (RD)预线性化调节可保持开启,如 学位设置、IIR过滤器 (FI)和预线性化旋转 (LR)

沿角度增加的位置移动编码器。如果角度传感器 集成电路的输出未相应增大,可设置 LR位元以反转角度传感器 集成电路输出的反向,或在校准时沿反方向转动编码器,在此情况下,可能需要设置后线性化旋转位元 (RO)参阅《A1332/A1335》编程参考》了解更多详情。

最佳收集方法是按间距相等的步数旋转目标,这样产生的数据点数量就是 2.的幂数。通常,32或 64个间距均匀的数据点就足够了。如果不能实现,可收集数据点,然后必须按下节介绍的方法预处理数据。

另一种收集所需数据点的方法是多次旋转目标,然后按预定义的间隔收集数据。当收集到足够的数据点覆盖目标的整个旋转范围时,接下来必须按下节介绍的方法预处理数据。

预处理数据

如果收集的数据点数量不是 2.的幂数,或者收集的数据点间距不等,必须调整数据点数组的长度并/或使它们间距相等。要对数据执行此操作,可调用 ResizePointArray例程。

参数 x是编码器数值的数组,参数 Y是在该编码器数值中收集的器件读数。参数 新闻化是重新调整的数组大小。如果参数 x设置为空,则假设已按从 0开始至 360结束的相等间距收集数值 Y如果参数 x不是空,则需要在调整数组大小前,为输入数组排序。

double[]ResizePointArray(double[]x,double[]y,int newSize)

此例程会在输入数组上执行三次样条插值,以采用所需的数据点数量,生成间距相等的数组。

初始处理

数据收集完毕,并形成长度为 2.的幂数的数组后,就可以计算谐波系数了。要计算谐波系数,可调用 计算谐波线性系数例程。

谐波效率[]计算谐波线性系数(双[]点,输出布尔点错误)

其输入是已收集的角度数组。此例程会执行 FFT并会返回系数数组和一个警告标记。当一个或多个输入角比例程计算的角度大 20度时,需要设置点误差警告标记。

以一个包含 8.个输入项的数组为例,例程计算的角度应为 [0, 45, 90, 135, 180, 225, 270, 315]。如果输入数组是 [0, 45, 90, 135, 180, 204, 270, 315],则例程会设置 点错误因为第 6.个输入项的误差超过 20度。

选择谐波

当所有谐波系数已计算完毕后,必须选择所需的谐波。通常,计算例程生成的谐波数量会超过器件能支持的谐波数量,所以,必须选择一些算法以选择相关的谐波。

使用谐波的数量还取决于所用的器件种类和功能。A1332的谐波最大数量是 15,但如果使用最大值,一些可编程的功能会使用默认值,如短行程设置和特定的 I2C与 SPI设置。不使用默认值时,这些可编程功能的谐波最大数量是 9.A1335的谐波最大数量是 11,但要达到此数量,一些可编程功能会使用默认值,如短行程设置。不使用默认值时,这些可编程功能的谐波最大数量是 8.

最简单的算法是按照所需的谐波数量选择第一个谐波。这种方法很简单,它选择的谐波不会对输出产生显著的影响。

快板A1335的示例编程器目前使用的算法是选择振幅大于 0.3的谐波。需要注意的是,当前软件的一个限制是在所选谐波之间只能跳过 4.个谐波。如果跳过的谐波超过 4.个,还需要选择最后一个选定谐波和所需谐波之间的所有谐波。

器件编程

谐波选择完毕后,可调用例程 生成谐波线性化设备值生成要写入器件的数值。

谐波设备值[]生成谐波线性化设备值(谐波效率[]系数)

谐波系数传递到此例程中,它会返回器件编程所需的一组数值。此例程抛出的唯一异常是在所选系数之间跳过 4.个以上谐波系数的情形。

要对器件进行谐波线性化编程,必须设置 HL标记,必须将 哈鲁马克斯字段设置为要使用的系数数量,同时必须编写 谐波相位和 谐波振幅字段。

代码实例

使用制度;
使用快板;

名称空间协调ClineArizationExample
{
公共类HarmonicClineArizationExample
{
公共和谐ClineArizationExample()
{
}

公共void程序协调化(字符串文件路径、ASEK asekProgrammer)
{
尝试
{
协调效率[]hc;
bool pointError=false;
双[]点=空;
string fieldBuffer=File.ReadAllText(文件路径);
弦线;
ListencoderReadings=新列表();
Listdeviceradings=新列表();

// 1.1 收集数据
// 从文本文件中读取角度。忽略空白行或以 a#打头的行。
如果(!string.IsNullOrEmpty(fieldBuffer))
{
使用(StringReader sr=新StringReader(fieldBuffer))
{
而((line=sr.ReadLine())!=null)
{
line=line.Trim();
if(string.IsNullOrEmpty(line)| | line.StartsWith(“#”)
{
继续;
}

// 每行可采用 2.种格式中的 1.种。
// 首行包含编码器角度,其次是逗号隔开的器件角度 (22.125,23.543)
// 或只有器件角度 (23.543)
// 如果角度的间距不等,则两个数值都需要。
string[]value=line.Split(',');

如果(值.Length>1)
{
双编码器=Convert.ToDouble(值[0]);
而(编码器>=360.0)
{
编码器-=360.0;
}
而(编码器<0.0)
{
编码器+=360.0;
}
encoderReadings.Add(编码器);
Add(Convert.ToDouble(值[1]);
}
其他的
{
Add(Convert.ToDouble(值[0]);
}
}
}

// 1.2 预处理数据
如果(!powerOfTwo(deviceradings.Count()))
{
// 如果数据点数量差一个,只删除最后一个,
if(powerOfTwo(deviceradings.Count()-1))
{
deviceReadings.RemoveAt(deviceReadings.Count()-1);
points=deviceReadings.ToArray();
}
其他的
{
// 否则应计算所需的样本数量。
// 如果样本数量小于 64,
// 可四舍五入至最接近 2.的幂数的数值,否则应向下取整数。
int-desiredSamples=8;
while(desiredSamples{
所需样本*=2;
}

if(deviceReadings.Count()>64)
{
所需样本/=2;
}

// 如果没有编码器读数,可假设器件读数的间距相等。
如果 (encoderReadings.Count()!=deviceReadings.Count())
{
// 将角度列表转换为数组,然后调整其长度。
points=((IHarmonicLinearization)asekProgrammer).ResizePointArray(null,deviceReadings.ToArray(),desiredSamples);
}
其他的
{
// 将角度列表转换为数组,然后调整其长度。
点=((IHarmonicLinearization)asekProgrammer).调整点阵列(encoderReadings.ToArray(),deviceReadings.ToArray(),desiredSamples);
}
}
}
其他的
{
// 将角度列表转换为数组
points=deviceReadings.ToArray();
}

// 1.3 初始处理
// 通过数据点数组计算系数。
hc=((i谐波线性化)asekProgrammer)。计算谐波线性系数(点,输出点误差);

// 当一个或多个入射角比例程的计算结果大 20度时,就会出现数据点误差。
// 以包含 8.个数值的数组为例 [0, 45, 90, 135, 180, 204, 270, 315],计算例程会为
// 第 6.个输入项发放警告标记,因为它应该接近 225。
if(点错误)
{
MessageBox.Show(“其中一个入射角比预期值大 20度。");
}

// 1.4 选择谐波
// 一组谐波系数计算完毕后,需要选择系数。计算例程
//返回的系数数量通常会超过器件能支持的系数数量,因此需要
// 需要使用一些限制系数数量的方法。可以先选出前 8.个,也可使用其他方法。
int numberOfHarmonicComponents=hc.长度;
int numberOfSelectedHarmonicComponents=0;
int lastHarmonicComponentSelected=0;
int MaxHarmonicComponentSelected=8;//在影响器件的其他功能前,可使用谐波的最大数量

// 就此例而言,选择前 8.个振幅超过 0.3的谐波。
对于(int index=0;index{
如果((hc[指数]。振幅>0.3)和&(选择的谐波分量数<选择的最大谐波分量))
{
// 如果要选择的谐波和选择的最后一个谐波
// 之间的谐波数量大于 4.还需要
// 选择它们之间的一些谐波。
int skip=索引-选择的LastHarmonicComponent;
如果(跳过>4)
{
// 确保要选择的谐波数量
// 不超过所需的谐波数量。
int numberNeeded=跳过/4;
如果((NumberNeed+numberOfSelectedHarmonicComponents)<=MaxHarmonicComponents已选定)
{
对于(int-jndex=1;jndex<=numberneed;++jndex)
{
hc[jndex].select=true;
++所选谐波分量的数量;
}
hc[index].select=true;
++所选谐波分量的数量;
}
其他的
{
// 代码在选择所需的谐波时,超过
// 所选系数的最大数量,因此它会停止选择。
打破
}
}
其他的
{
hc[index].select=true;
++所选谐波分量的数量;
}
lastHarmonicComponentSelected=索引;
}
}

// 如果未选择谐波,可选择前 8.个。
if(numberOfSelectedHarmonicComponents==0)
{
对于(int i=0;(i{
hc[i]。选择=true;
++所选谐波分量的数量;
}
}

// 1.5 器件编程
// 生成需要写入 电可擦可编程只读存储器的数值。
HarmonicDeviceValues[]eepromValues=((iHarmonicLinealization)作为一个程序)。生成HarmonicLinealizationDeviceValues(hc);

// 确保器件通电
asekProgrammer.SetVcc(5.0);

// 确保写入器件的 eeprom这需要使 SRAM具备可写性,并关停处理器
((ISRAMWriteAccessMode)asekProgrammer.SetSRAMWriteAccessMode();
((IPProcessorMode)asekProgrammer.SetProcessorIdle();

// 在 电可擦可编程只读存储器中开启谐波线性化
((IRegisterAccess)asekProgrammer).WritePartialRegister(MemoryAccessType.extended,0x306,1,15,15);//HL=1

// 设置要使用的谐波数量
((IRegisterAccess)asekProgrammer).WritePartialRegister(MemoryAccessType.extended,0x309,eepromValues.Length,19,16);//HAR_MAX=谐波数量

//对于谐波
对于(uint index=0;index{
uint寄存器值=(uint)((eepromValues[index]。相位<<12)和0x0FFF000)+
((eepromValues[index].advance<<10)和0x0C000)+
(EEPROM值[索引]。振幅&0x03FF));
((IRegisterAccess)asekProgrammer).WriterRegister(MemoryAccessType.extended,0x30C+索引,registerValue);//谐波相位、ADV和谐波振幅
}

// 关闭电源,然后再接通,确保器件使用新的线性化数值。
asekProgrammer.SetVccOff();
asekProgrammer.SetVcc(5.0);
}
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}
}

私有bool powerOfTwo(int值)
{
int log2n点=0;
int j=数值;

而((j>0)和((j&1)==0))//计算输入值的对数底数 2.
{
log2npoints++;
j>>=1;
}

如果((值<2)| |(值!=(1<{
返回false;
}

返回true;
}
}
}

角度输入文件的格式

此文件包含一个角度值列表。如果有两个数值被逗号隔开,则第一个数值是编码器角度,第二个数值是器件角度。行可以是空白的,如果它们以 # 打头,则可将其视为注释。

角度输入文件实例:

329.59
354.81
6.832
13.566
17.592
20.228
22.638
24.638
25.956
27.454
28.77
30.054
30.966

包含两列时:

0,123
22.5,145.5
45,168
67.5,190.5
90,213
112.5,235.5
135,258
157.5,280.5
180,303
202.5,325.5
225,348
247.5,10.5
270,33
292.5,55.5
315,78
337.5,100.5