eQEP增强型正交编码模块原理介绍及配合MircoE mercury II 4000光栅传感器使用
2015-05-31 09:29
435 查看
1、首先介绍MircoE mercury II 4000光栅传感器串口PIN及对应功能</span>(male D-sub connector)
正交TTL电平(标准为低电平0,高电平1(+5v))
差分信号
由于光栅传感器一般意义上有转动和直线两种:
对于直线光栅来说,一般考虑的是位移信号,相对位移=(当前QPOSCNT的值- 开始时QPOSCNT的值)* 光栅分辨率(count / m);
对于转动光栅来说,一般考虑的是机械角度和电角度,机械角度是空间转过一周的这一般分为两种计算转速的方式
1、在高速时,M测速法:
2、在低速时,T测速法:
{
long tmp;
unsigned int pos16bval,temp1;
_iq Tmp1,newp,oldp;
//**** Position calculation - mechanical and electrical motor angle ****//
p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF; // Motor direction: 0=CCW/reverse, 1=CW/forward
pos16bval=(unsigned int)EQep1Regs.QPOSCNT; // capture position once per QA/QB period
p->theta_raw = pos16bval+ p->cal_angle; // raw theta = current pos. + ang. offset from QA
// The following lines calculate
//p->theta_mech ~= QPOSCNT/mech_scaler [current cnt/(total cnt in 1 rev.)]
// where mech_scaler = 4000 cnts/revolution
tmp = (long) ( (long)p->theta_raw * (long)p->mech_scaler ); // Q0*Q26 = Q26
tmp &= 0x03FFF000;
p->theta_mech = (int)(tmp>>11); // Q26 -> Q15
p->theta_mech &= 0x7FFF;
// The following lines calculate p->elec_mech
p->theta_elec = p->pole_pairs * p->theta_mech; // Q0*Q15 = Q15
p->theta_elec &= 0x7FFF;
// Check an index occurrence
if (EQep1Regs.QFLG.bit.IEL == 1)
{
97d2
p->index_sync_flag = 0x00F0;
EQep1Regs.QCLR.bit.IEL=1; // Clear interrupt flag
}
正交TTL电平(标准为低电平0,高电平1(+5v))
差分信号
由于光栅传感器一般意义上有转动和直线两种:
对于直线光栅来说,一般考虑的是位移信号,相对位移=(当前QPOSCNT的值- 开始时QPOSCNT的值)* 光栅分辨率(count / m);
对于转动光栅来说,一般考虑的是机械角度和电角度,机械角度是空间转过一周的这一般分为两种计算转速的方式
1、在高速时,M测速法:
2、在低速时,T测速法:
</pre>void POSSPEED_Calc(POSSPEED *p)
{
long tmp;
unsigned int pos16bval,temp1;
_iq Tmp1,newp,oldp;
//**** Position calculation - mechanical and electrical motor angle ****//
p->DirectionQep = EQep1Regs.QEPSTS.bit.QDF; // Motor direction: 0=CCW/reverse, 1=CW/forward
pos16bval=(unsigned int)EQep1Regs.QPOSCNT; // capture position once per QA/QB period
p->theta_raw = pos16bval+ p->cal_angle; // raw theta = current pos. + ang. offset from QA
// The following lines calculate
//p->theta_mech ~= QPOSCNT/mech_scaler [current cnt/(total cnt in 1 rev.)]
// where mech_scaler = 4000 cnts/revolution
tmp = (long) ( (long)p->theta_raw * (long)p->mech_scaler ); // Q0*Q26 = Q26
tmp &= 0x03FFF000;
p->theta_mech = (int)(tmp>>11); // Q26 -> Q15
p->theta_mech &= 0x7FFF;
// The following lines calculate p->elec_mech
p->theta_elec = p->pole_pairs * p->theta_mech; // Q0*Q15 = Q15
p->theta_elec &= 0x7FFF;
// Check an index occurrence
if (EQep1Regs.QFLG.bit.IEL == 1)
{
97d2
p->index_sync_flag = 0x00F0;
EQep1Regs.QCLR.bit.IEL=1; // Clear interrupt flag
}
//**** High Speed Calculation using QEP Position counter ****// // Check unit Time out-event for speed calculation: // Unit Timer is configured for 100Hz in INIT function if(EQep1Regs.QFLG.bit.UTO==1) // If unit timeout (one 100Hz period) { /** Differentiator **/ // The following lines calculate position = (x2-x1)/4000 (position in 1 revolution) pos16bval=(unsigned int)EQep1Regs.QPOSLAT; // Latched POSCNT value tmp = (long)((long)pos16bval*(long)p->mech_scaler); // Q0*Q26 = Q26 tmp &= 0x03FFF000; tmp = (int)(tmp>>11); // Q26 -> Q15 tmp &= 0x7FFF; newp=_IQ15toIQ(tmp); oldp=p->oldpos; if (p->DirectionQep==0) // POSCNT is counting down { if (newp>oldp) Tmp1 = - (_IQ(1) - newp + oldp); // x2-x1 should be negative else Tmp1 = newp -oldp; } else if (p->DirectionQep==1) // POSCNT is counting up { if (newp<oldp) Tmp1 = _IQ(1) + newp - oldp; else Tmp1 = newp - oldp; // x2-x1 should be positive } if (Tmp1>_IQ(1)) p->Speed_fr = _IQ(1); else if (Tmp1<_IQ(-1)) p->Speed_fr = _IQ(-1); else p->Speed_fr = Tmp1; // Update the electrical angle p->oldpos = newp; // Change motor speed from pu value to rpm value (Q15 -> Q0) // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q p->SpeedRpm_fr = _IQmpy(p->BaseRpm,p->Speed_fr); //======================================= EQep1Regs.QCLR.bit.UTO=1; // Clear interrupt flag }
//**** Low-speed computation using QEP capture counter ****// if(EQep1Regs.QEPSTS.bit.UPEVNT==1) // Unit position event { if(EQep1Regs.QEPSTS.bit.COEF==0) // No Capture overflow temp1=(unsigned long)EQep1Regs.QCPRDLAT; // temp1 = t2-t1 else // Capture overflow, saturate the result temp1=0xFFFF; p->Speed_pr = _IQdiv(p->SpeedScaler,temp1); // p->Speed_pr = p->SpeedScaler/temp1 Tmp1=p->Speed_pr; if (Tmp1>_IQ(1)) p->Speed_pr = _IQ(1); else p->Speed_pr = Tmp1; // Convert p->Speed_pr to RPM if (p->DirectionQep==0) // Reverse direction = negative p->SpeedRpm_pr = -_IQmpy(p->BaseRpm,p->Speed_pr); // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q else // Forward direction = positive p->SpeedRpm_pr = _IQmpy(p->BaseRpm,p->Speed_pr); // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q EQep1Regs.QEPSTS.all=0x88; // Clear Unit position event flag // Clear overflow error flag } }
相关文章推荐
- JavaScript实现倒计时效果
- 用户 'sa' 登录失败。 (Microsoft SQL Server,错误: 18456)的另一个解决办法
- 【Storm】storm安装、配置、使用以及Storm单词计数程序的实例分析
- Hibernate映射(四)— 一对多
- 将基于Dagger-1开发的项目迁移到Dagger-2中
- hdu 5249 元素插入、删除找中值
- 通过Jenkins并行完成UI的自动化测试
- eclipse调试常用快捷键
- 切换卡TabHost控件的使用
- 12周项目一
- Fedora21下安装 sqlite3
- telnet
- 百度地图API的学习
- 类的默认赋值函数
- TabHost.TabSpec中的标签实现图文左右排(默认上下排)
- 百度地图API的学习
- Unity3d在安卓平台下使用sqlite存储操作数据
- 在windows server 2008上面装chrome driver 出错: cannot find Chrome driver
- 培训感悟
- 软考小结