Part Number: TMDSCNCD28035ISO
Other Parts Discussed in Thread: TMS320F28035
Tool/software: Code Composer Studio
Hi,
I'm trying to build a motorcontrol using the Piccolo TMS320F28035 Isolated controlCARD.
The motorcontrol only needs the angleposition of the rotor.
Therfor i want to use an encoder and the eQEP-Input of the controlcard.
For the preperation i studied the example "Example_2803xEqep_pos_speed", implement it on the controlcard and it worked well.
For my application i create a new projekt and simplifyte the code of the example.
Cause the velocity is not needed, the interrupt should not based on the unit timer or the pwm but on the eqep.
But it don't work.
I think i did somthing wrong in use of the interrupt cause the Example_2803xEqep_pos_speed worked with my function of POSSPEED_Init(), POSSPEED_Calc(POSSPEED *p) well.
I hope you can help me
void POSSPEED_Init(void)
{
//EQep1Regs.QUPRD=600000; // Unit Timer for 100Hz at 60 MHz SYSCLKOUT
EQep1Regs.QDECCTL.bit.QSRC=00; // QEP quadrature count mode
EQep1Regs.QEPCTL.bit.FREE_SOFT=2; // Emulation Control Bits -> Position counter, Watchdog counter, Unit timer, Capture Timer is unaffected by emulation suspend
EQep1Regs.QEPCTL.bit.PCRM=00; // PCRM=00 mode - QPOSCNT reset on index event
//EQep1Regs.QEPCTL.bit.UTE=1; // Unit Timeout Enable
//EQep1Regs.QEPCTL.bit.QCLM=1; // Latch on unit time out
EQep1Regs.QPOSMAX=0xfff; // eQEP Maximum Position Count Register -> 12 Bit
EQep1Regs.QEPCTL.bit.QPEN=1; // QEP enable
EQep1Regs.QCAPCTL.bit.UPPS=5; // 1/32 for unit position Unit position event prescaler -> UPEVNT = QCLK/32
EQep1Regs.QCAPCTL.bit.CCPS=6; // 1/64 for CAP clock eQEP capture timer clock prescaler -> CAPCLK = SYSCLKOUT/64
EQep1Regs.QCAPCTL.bit.CEN=1; // QEP Capture Enable eQEP capture unit is enabled
}
void POSSPEED_Calc(POSSPEED *p)
{
long tmp;
unsigned int pos16bval;
//**** 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)
{
p->index_sync_flag = 0x00F0;
EQep1Regs.QCLR.bit.IEL=1; // Clear interrupt flag
}
}
__interrupt void prdTick(void)
{
// Position measurement
qep_posspeed.calc(&qep_posspeed);
// Acknowledge this interrupt to receive more interrupts from group 1
EQep1Regs.QCLR.bit.INT = 1; // clear global INT FLAG
EQep1Regs.QEPSTS.bit.UPEVNT = 1; // clear Unit position event
PieCtrlRegs.PIEACK.all = PIEACK_GROUP5;
}
int main(void)
{
InitSysCtrl();
InitGpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.EQEP1_INT= &prdTick;
EDIS;
IER |= M_INT5 ;
PieCtrlRegs.PIEIER5.bit.INTx1 = 1 ;
EINT;
ERTM;
qep_posspeed.init(&qep_posspeed);
for(;;){}
}