This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello Sir/Madam,
I am trying to write on " EQep1Regs.QCLR.bit.IEL", but unable to write.
With below lines
if (lsw==0) {
EQep1Regs.QPOSCNT=0; // Reset position cnt.
EQep1Regs.QCLR.bit.IEL = 1;
}
It makes the POSCNT = 0, when lsw = 0, but doesn't write on EQepRegs. I am not able to understand what i am missing to initialize.
The motor works perfectly fine when lsw = 1 or 2.
I am using PWM interrupt 1, 2, 3 for generation of PWM signals and PWM4 for interrupt for control logic. There are no other interrupts in my code. I have modified "HVPM_Sensored.c" according to my requirement (in terms of generation of PWM signals, rest is same as the original).
Thanking you in advance.
EQep1Regs.QCLR.bit.IEL = 1 will just clear the IEL flag in the QFLG register. The bits in QCLR are labeled as "R=0/W=1" in the manual, meaning they always read zero which is why you didn't see the value change.
You are correct that EQep1Regs.QEPCTL.bit.IEL is the correct place to configure the index latch settings. It doesn't really have anything to do with the EQep1Regs.QFLG.bit.IEL bit though. It just determines when QPOSILAT has the position counter value latched into it.
If you cause a rising edge on the index pin, do you see QFLG get set? Or if you're trying to just force the flag to go high, there's a QFRC register for that? I'm not sure I understand what you're trying to do with the index flag. Could you elaborate?
Whitney
Thank you sir for your reply.
I understood about QCLR.
I am trying to Calibrate encoder as mentioned in "HVPM_sensored" example of development kits. I am working on 28379D and "EQep1Regs.QFLG.bit.IEL" does not set to 1, and hence I am not able to obtain "qep1.CalibratedAngle".
Note: I am not using HVPM_sensored file, rather I am trying to understand the same and implement in 28379D.
Thanks in advance.
Dear sir , As you mentioned Using QFRC I am able to set "EQep1Regs.QFLG.bit.IEL" to 1. But, the QPOSCNT value is not latching inside " QPOSILAT" register. But, I can see in watch window "EQep1Regs.QEPCTL.bit.IEL" as 1. how is that possisble?
In the initialization, qep1.CalibratedAngle = 1000 ;
but after the flag sets to 1, it goes to 0 as QPOSILAT has 0 value.
I suspect QFRC just sets the flag--I don't think it has the same behavior as a true index event on the index pin, so I'm not very surprised it doesn't cause the latch.
Do you have something connected on the index pin that is toggling it? Have you confirmed that your GPIO configuration that selects which pin functions as the index pin is correct?
Whitney
Hi
yes I get the point that QFRC will not work as true index event.
1. There 5 output pins (connected)of encoder of motor model EMJ-04APB22. So, all of them together I have connected to QEPA of 28379D.
So, I do not think anything toggling.
2. As I mentioned earlier, when I close loop, speed and current both, motor works fine, but without calibrated angle.
To calibrate the angle, I want the Index event latch interrupt flag to set.
3. Another thing I tried to use "Eqep_pos_speed.c" example without making any changes in it. when I rotate motor, Index event latch interrupt flag does not set.
Below are my GPIO settings.
void InitEQep1Gpio(void) { EALLOW; // // Disable internal pull-up for the selected output pins // for reduced power consumption // Pull-ups can be enabled or disabled by the user. GpioCtrlRegs.GPAPUD.bit.GPIO20 = 1; // Disable pull-up on GPIO20 (EQEP1A) GpioCtrlRegs.GPAPUD.bit.GPIO21 = 1; // Disable pull-up on GPIO21 (EQEP1B) // GpioCtrlRegs.GPAPUD.bit.GPIO22 = 1; // Disable pull-up on GPIO22 (EQEP1S) GpioCtrlRegs.GPAPUD.bit.GPIO23 = 1; // Disable pull-up on GPIO23 (EQEP1I) // // Synchronize inputs to SYSCLK // Synchronization can be enabled or disabled by the user. // Comment out other unwanted lines. // GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0; // Sync GPIO20 to SYSCLK (EQEP1A) GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0; // Sync GPIO21 to SYSCLK (EQEP1B) // GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 0; // Sync GPIO22 to SYSCLK (EQEP1S) GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 0; // Sync GPIO23 to SYSCLK (EQEP1I) // // Configure EQEP-1 pins using GPIO regs // This specifies which of the possible GPIO pins will be EQEP1 functional // pins. GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1; // Configure GPIO20 as EQEP1A GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1; // Configure GPIO21 as EQEP1B // GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1; // Configure GPIO22 as EQEP1S GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1; // Configure GPIO23 as EQEP1I EDIS; }
// ------------------------------------------------------------------------------ // Detect calibration angle (optional) and call the QEP module // ------------------------------------------------------------------------------ EQep1Regs.QEPCTL.bit.IEL = 1; if (lsw==0) {EQep1Regs.QPOSCNT=0; EQep1Regs.QCLR.bit.IEL = 1;} // Reset position cnt. if ((EQep1Regs.QFLG.bit.IEL==1) && Init_IFlag==0) // Check the first index occurrence {qep1.CalibratedAngle= EQep1Regs.QPOSILAT; Init_IFlag++;} // Keep the latched position if (lsw!=0) QEP_MACRO(1,qep1);
Thank you sir for your prompt reply.
To avoid the doubt of index pulse if it exists or not, I used another DSP of my colleague " Docking-stn EMU-USB" and build the example " HVPM_sensored", flag sets perfectly. so that means Index event exist. Also, I checked with oscilloscope that
Also I am using same settings and code of HVPM_Sensored, then why not in 28379D ?
I did not have QEPCTL.IEL configured before, but after you mentioned I tried to configured inside interrupt as below, but still Index event latch interrupt flag did not set.
what is your suggestion about this " Another thing I tried to use "Eqep_pos_speed.c" example without making any changes in it. when I rotate motor, Index event latch interrupt flag does not set for 28379D" ?
Thank you for suggestiong of GPIO, I will take care of it.
I am using TMSF28379D LaunchPad. There exist an index pulse and also A, B, QPOSCNT is increasing as expected, so other pins are working fine. I also tried to write on GPIO as per your suggesttion.
The below is my control logic, which is same as HVPM_sensored example. I tried to change " QEP_MACRO(1,qep1)" to " QEP_MACRO(2,qep1)", but compiler gives me an error of " subscript out of range". So, I could not test QEPB of 28379D.
__interrupt void epwm4_isr(void) { EPwm4TimerIntCount++; // ------------------------------------------------------------------------------ // Connect inputs of the RMP module and call the ramp control macro // ------------------------------------------------------------------------------ if(lsw==0)rc1.TargetValue = 0; else rc1.TargetValue = SpeedRef; RC_MACRO(rc1) // ------------------------------------------------------------------------------ // Connect inputs of the RAMP GEN module and call the ramp generator macro // ------------------------------------------------------------------------------ rg1.Freq = rc1.SetpointValue; RG_MACRO(rg1) //=================== current measurement============================// AdcaRegs.ADCSOCFRC1.all = 0x000F; //phase a current AdccRegs.ADCSOCFRC1.all = 0x000F; //phase c current clarke1.As = _IQmpy2(_IQ12toIQ(AdcaResultRegs.ADCRESULT0)-offsetA); // Phase A curr. clarke1.Cs = _IQmpy2(_IQ12toIQ(AdccResultRegs.ADCRESULT0)-offsetC); // Phase C curr. CLARKE_MACRO(clarke1) // ------------------------------------------------------------------------------ // Connect inputs of the PARK module and call the park trans. macro // ------------------------------------------------------------------------------ park1.Alpha = clarke1.Alpha; park1.Beta = clarke1.Beta; if(lsw==0) park1.Angle = 0; else if(lsw==1) park1.Angle = rg1.Out; else park1.Angle = qep1.ElecTheta;//;qep_posspeed.theta_elec park1.Sine = _IQsinPU(park1.Angle); park1.Cosine = _IQcosPU(park1.Angle); PARK_MACRO(park1) Theta = _IQtoF(qep1.ElecTheta); // x= sin(Theta) ; // ------------------------------------------------------------------------------ // Connect inputs of the PI module and call the PID speed controller macro // ------------------------------------------------------------------------------ if (SpeedLoopCount==SpeedLoopPrescaler) { pi_spd.Ref = rc1.SetpointValue; pi_spd.Fbk = speed1.Speed; //qep_posspeed.Speed_pr; PI_MACRO(pi_spd); SpeedLoopCount=1; } else SpeedLoopCount++; if(lsw!=2) {pi_spd.ui=0; pi_spd.i1=0;} SPEED = _IQtoF(pi_spd.Out); // ------------------------------------------------------------------------------ // Connect inputs of the PI module and call the PID IQ controller macro // ------------------------------------------------------------------------------ if(lsw==0) pi_iq.Ref = 0; else if(lsw==1) pi_iq.Ref = IqRef; else pi_iq.Ref = pi_spd.Out; pi_iq.Fbk = park1.Qs; PI_MACRO(pi_iq) i_q = _IQtoF(pi_iq.Out); // ------------------------------------------------------------------------------ // Connect inputs of the PI module and call the PID ID controller macro // ------------------------------------------------------------------------------ if(lsw==0) pi_id.Ref = _IQ(0.05); else pi_id.Ref = IdRef; pi_id.Fbk = park1.Ds; PI_MACRO(pi_id) i_d = _IQtoF(pi_id.Out); // ------------------------------------------------------------------------------ // Connect inputs of the INV_PARK module and call the inverse park trans. macro // ------------------------------------------------------------------------------ ipark1.Ds = pi_id.Out; ipark1.Qs = pi_iq.Out; ipark1.Sine=park1.Sine; ipark1.Cosine=park1.Cosine; IPARK_MACRO(ipark1) // ------------------------------------------------------------------------------ // Detect calibration angle (optional) and call the QEP module // ------------------------------------------------------------------------------ if (lsw==0) {EQep1Regs.QPOSCNT=0; EQep1Regs.QCLR.bit.IEL = 1;} // Reset position cnt. if ((EQep1Regs.QFLG.bit.IEL==1) && Init_IFlag==0) // Check the first index occurrence {qep1.CalibratedAngle= EQep1Regs.QPOSILAT; Init_IFlag++;} // Keep the latched position if (lsw!=0) QEP_MACRO(1,qep1); // ------------------------------------------------------------------------------ // Connect inputs of the SPEED_FR module and call the speed calculation macro // ------------------------------------------------------------------------------ speed1.ElecTheta = _IQ24toIQ((int32)qep1.ElecTheta); speed1.DirectionQep = (int32)(qep1.DirectionQep); SPEED_FR_MACRO(speed1) // ------------------------------------------------------------------------------ // Connect inputs of the SVGEN_DQ module and call the space-vector gen. macro // ------------------------------------------------------------------------------ svgen1.Ualpha = ipark1.Alpha; svgen1.Ubeta = ipark1.Beta; SVGENDQ_MACRO(svgen1) // ------------------------------------------------------------------------------ // Connect inputs of the PWM_DRV module and call the PWM signal generation macro // ------------------------------------------------------------------------------ Ta = _IQtoF(svgen1.Ta); Tb = _IQtoF(svgen1.Tb); Tc = _IQtoF(svgen1.Tc); EPwm1Regs.CMPA.bit.CMPA = (Uint16)(((Ta/2)+0.5)*EPwm1Regs.TBPRD); EPwm2Regs.CMPA.bit.CMPA = (Uint16)(((Tb/2)+0.5)*EPwm2Regs.TBPRD); EPwm3Regs.CMPA.bit.CMPA = (Uint16)(((Tc/2)+0.5)*EPwm3Regs.TBPRD); // EQep1Regs.QFRC.bit.IEL = 1; if (EPwm4TimerIntCount>=5000) { offsetA= _IQmpy(K1,offsetA)+_IQmpy(K2,_IQ12toIQ(AdcaResultRegs.ADCRESULT0)); //Phase A offset // offsetB= _IQmpy(K1,offsetB)+_IQmpy(K2,_IQ12toIQ(AdcResult.ADCRESULT2)); //Phase B offset offsetC= _IQmpy(K1,offsetC)+_IQmpy(K2,_IQ12toIQ(AdccResultRegs.ADCRESULT0)); //Phase C offset } EPwm4Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; }
I do not understand, if there is a problem with interrupt priority or what else to check. Because, I am using PWM4 as an interrupt for control logic.
Thanks
-Vidhi
Find the table of EQEP addresses into which QEP_MACRO indexes and see if it has EQep2Regs in it (I found it my Ctrl+Clicking on QEP_MACRO and then again on *eQEP). If it doesn't, try adding it. Then you should be able to do QEP_MACRO(2,qep1) without the warning.
// Used to indirectly access eQEP module volatile struct EQEP_REGS *eQEP[] = { &EQep1Regs, &EQep1Regs, &EQep2Regs };
Whitney