Dear team:
1, Is there a more detailed comment on the following code?
long tmp; unsigned int pos16bval,temp1; _iq Tmp1,newp,oldp; 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;
2, I use the f28335 chip. Do I need to calculate the angle feedback with the incremental encoder, as in the Q format of the official documents?
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
}
p->theta_mech / p->theta_elec is angle feedback, Q15 format, I only need to interrupt every call, and then > > 15 / or ÷ 32768 (the 15th power of 2) is the real data?
p->SpeedRpm_fr = _IQmpy(p->BaseRpm,p->Speed_fr); The result here is in Q0 format. Can I use it directly?
Best Regards