有关磁编码器测速
首先是从速度的计算公式下手,v=ds/dt 那么,提高编码器分辨率和提高时间的分辨率都十分重要。 并且因为转动的时候并非完全平稳的一条速度曲线,为了避免采样速度过快使得ds为太小的数值进而导致数值的不稳定,应该通过以下几种规则限定如何读取速度
开始我想的是应该分为两种模式,ds控制的模式和dt控制的模式 首先是读到ds为0或者接近0的情况,应该延长读取的周期,防止计算的v突变成0 其次是读到ds接近0.5圈的情况,则应该加快采样速度,防止出现超过半圈的计算错误。
但是实际工作中发现还是优先保证ds的数值比较合适,因为保证dt的话,采样率较高可能会造成较大的数据波动,体现起来就是数据毛刺。 举个例子就是ds=5,dt=50us,此时计算v=0.1*3662(编码器系数)=366.2rpm 那么ds稍微变化一些,ds=4,dt=50us,v=292.96rpm,可以看到跨度非常大,变化高达73,这显然是令人不能接受的。
那么根据这个优先保证ds的思想,可以设置一个简单的由P控制的参数 将角度变化量和0.25圈进行对比,通过累加完成控制dt。 然后通过对dt进行限制最大值(最低采样频率)和最小值(最高采样频率)。通过将dt赋给定时器初值,改变定时器计时时间的方式实现速度采样。
以下是有关的代码实现
- long Set_Time_Dat = 0;
- void Timer0_Isr(void) interrupt 1
- {
- u16 Time_Dat;
- TR0 = 0; // 关掉定时器0
- while (_speed_dat_flag)
- ; // 等待flag为0
- _angle_dangle = (_angle_this_dat - _angle_last_dat);
- if (_angle_dangle != 0)
- _speed_dtime = 0;
- _speed_dtime = (_speed_this_time - _speed_last_time);
- if (_angle_dangle < -(Encode_bit_Max / 2))
- _angle_dangle += Encode_bit_Max; // 过零处理
- if (_angle_dangle > (Encode_bit_Max / 2))
- _angle_dangle -= Encode_bit_Max;
- _angle_last_dat = _angle_this_dat;
- _speed_last_time = _speed_this_time;
- Set_Time_Dat += (4096 - abs(_angle_dangle)); // 根据角度差自适应
- if (Set_Time_Dat > 50000)
- Set_Time_Dat = 50000; // 限制最大值
- if (Set_Time_Dat < 250)
- Set_Time_Dat = 250; // 限制最小值
- Time_Dat = (u16)(65536UL - Set_Time_Dat);
- TH0 = (u8)(Time_Dat >> 8);
- TL0 = (u8)Time_Dat;
- TR0 = 1; // 设置完成再开启
- }
复制代码
|