Other Parts Discussed in Thread: TMS320F28335
Hi everyone!
I intend to perform FOC on 4 pole three phase motors using TMS320F28335. I am facing problems getting a constant speed. I edited the lab 6 example and included the eQEP.c file and initialized the eQEP registers as follows:
EQep1Regs.QDECCTL.bit.QSRC=00; // QEP quadrature count mode
EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
EQep1Regs.QEPCTL.bit.PCRM=01;
EQep1Regs.QPOSMAX=0xffffffff;
EQep1Regs.QEPCTL.bit.QPEN=1; // QEP enable
In the timer ISR I calculate the velocity as follows:
//Unfiltered
p_new=(unsigned int)EQep1Regs.QPOSCNT;
Pos0 = (p_new*2*pi)/4096.0;
Vel0 = (Pos0-Pos1)/0.0001;
Pos1 = Pos0;
//filtered
FPos0 = (p_new*2*pi)/4096.0;
FVel0 = (FVel1 + g*FPos0 - g*FPos1)/(g*0.0001 + 1);
FPos1 = FPos0;
FVel1 = FVel0;
the sinusoidal angular frequency is 62.8 and I expect the measured speed to be 31.4 rad/s and the interrupt timer frequency is 10KHz.
The problem that I am facing is that I dont get a constant speed. 5 in 10 values are 31.4 and rest are 15 rad/s or 60 rad/s and 1 in 10 is a negative value as well. I tried the 2-3 different filters and with that too I do not get a constant value. With the filters the speed is continuously changing from 20 to 35 rad/s. I am observing at 100ms in the debug window and I get a count of 4096 from the encoder for one complete rotation.
Could you please let me know where I might be going wrong. I also tried with the inbuilt speed measurement code and it too gave similar results.
Thanks,
//
// Lab5_1: TMS320F28335
// (c) Frank Bormann
//
//###########################################################################
//
// FILE: Lab5_1.c
//
// TITLE: DSP28335ControlCARD; Digital Output
// 4 - bit - counter at 4 LEDs LD1(GPIO9), LD2(GPIO11), LD3(GPIO34)
// and LD4 (GPIO49)
// software delay loop; watchdog disabled
// template file for Lab5_1
//###########################################################################
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|======|===============================================
// 3.0 | 02 May 2008 | F.B. | Lab5_1 for F28335;
// 3.1 | 06 Nov 2009 | F.B | Lab5_1 for F28335 and PE revision5
//###########################################################################
#include "DSP2833x_Device.h"
#include "math.h"
// Prototype statements for functions found within this file.
void Gpio_select(void);
void InitSystem(void);
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void InitCpuTimers(void);
interrupt void cpu_timer0_isr(void);
extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);
void Setup_ePWM();
extern void InitEQep1Gpio(void);
float d1=0,d2=0,d3=0,t=0,f=10,i=0;
float p_old=0,Pos0,Pos1,Vel0,Vel1;
unsigned int p_new=0;
float FPos0,FPos1,FVel0,FVel1,g=100;
#define DT 10e-5
#define pi 3.1415926535
//###########################################################################
// main code
//###########################################################################
void main(void)
{
InitSysCtrl();
EALLOW;
SysCtrlRegs.WDCR = 0x00AF;
EDIS;
DINT; // Disable all interrupts
Gpio_select(); // GPIO9,GPIO11,GPIO34 and GPIO49 as output (LEDs @ peripheral explorer)
Setup_ePWM();
InitPieCtrl();
InitPieVectTable();
EALLOW;
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS;
InitCpuTimers();
ConfigCpuTimer(&CpuTimer0, 150, 100);
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
InitEQep1Gpio();
EQep1Regs.QDECCTL.bit.QSRC=00; // QEP quadrature count mode
EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
EQep1Regs.QEPCTL.bit.PCRM=01; // PCRM=00 mode - QPOSCNT reset on index event
EQep1Regs.QEPCTL.bit.QCLM=1; // Latch on unit time out*/
EQep1Regs.QPOSMAX=0xffffffff;
EQep1Regs.QEPCTL.bit.QPEN=1; // QEP enable
IER |= 1;
EINT;
ERTM;
CpuTimer0Regs.TCR.bit.TSS = 0;
while(1)
{
EALLOW;
SysCtrlRegs.WDKEY = 0x55; // service WD #1
EDIS;
}
}
void cpu_timer0_isr()
{
CpuTimer0.InterruptCount=CpuTimer0.InterruptCount+1;
EALLOW;
SysCtrlRegs.WDKEY = 0xAA; // service WD #2
EDIS;
p_new=(unsigned int)EQep1Regs.QPOSCNT; //unsigned
Pos0 = (p_new*2*pi)/4096.0;
Vel0 = (Pos0-Pos1)/0.0001;
Pos1 = Pos0;
FPos0 = (p_new*2*pi)/4096.0;
FVel0 = (FVel1 + g*FPos0 - g*FPos1)/(g*0.0001 + 1);
FPos1 = FPos0;
FVel1 = FVel0;
d1=3600+3600*sin(2*pi*f*t);
d2=3600+3600*sin(2*pi*f*t-(2*pi)/3);
d3=3600+3600*sin(2*pi*f*t+(2*pi)/3);
t=t+DT;
EPwm1Regs.CMPA.half.CMPA = (int) d1;
EPwm2Regs.CMPA.half.CMPA = (int) d2;
EPwm3Regs.CMPA.half.CMPA = (int) d3;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void Gpio_select(void)
{
EALLOW;
GpioCtrlRegs.GPADIR.all = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A active
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // ePWM3A active
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; // ePWM4A active
EDIS;
}
void Setup_ePWM(void)
{
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 1
EPwm1Regs.TBCTL.bit.CTRMODE = 0; //CTRMODE, 00 = count up mode
EPwm1Regs.TBCTL.bit.SYNCOSEL = 3; //SYNCOSEL, 11 = sync-out disabled
EPwm1Regs.TBCTL.bit.PRDLD = 0; // PRDLD, 0 = reload PRD on counter=0
EPwm1Regs.TBCTL.bit.PHSEN = 0x0; //PHSEN, 0 = phase control disabled
EPwm1Regs.TBCTL.bit.FREE_SOFT = 3; //FREE/SOFT, 11 = ignore emulation suspend
EPwm1Regs.TBCTL.bit.SWFSYNC = 0; //SWFSYNC, 0 = no software sync produced
EPwm1Regs.TBPRD = 7500; // 20 KHz - PWM signal
EPwm1Regs.CMPA.half.CMPA = 1875; // set compare value
d1=3750; // initiaze duty value
EPwm1Regs.AQCTLA.all = 0x0012; //Set ePWM high when counter =0 and low when counter = compare value
EPwm1Regs.ETPS.all = 0x100; //SOC on first event
EPwm1Regs.ETSEL.all = 0xA00; // Enable SOC A and start of conversion when counter = period
EPwm2Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 1
EPwm2Regs.TBCTL.bit.CTRMODE = 0; //CTRMODE, 00 = count up mode
EPwm2Regs.TBCTL.bit.SYNCOSEL = 3; //SYNCOSEL, 11 = sync-out disabled
EPwm2Regs.TBCTL.bit.PRDLD = 0; // PRDLD, 0 = reload PRD on counter=0
EPwm2Regs.TBCTL.bit.PHSEN = 0x0; //PHSEN, 0 = phase control disabled
EPwm2Regs.TBCTL.bit.FREE_SOFT = 3; //FREE/SOFT, 11 = ignore emulation suspend
EPwm2Regs.TBCTL.bit.SWFSYNC = 0; //SWFSYNC, 0 = no software sync produced
EPwm2Regs.TBPRD = 7500; // 20 KHz - PWM signal
EPwm2Regs.CMPA.half.CMPA = 1875; // set compare value
d2=3750; // initiaze duty value
EPwm2Regs.AQCTLA.all = 0x0012; //Set ePWM high when counter =0 and low when counter = compare value
EPwm3Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1
EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0; // HSPCLKDIV = 1
//EPwm1Regs.TBCTL.bit.CTRMODE = 2;
EPwm3Regs.TBCTL.bit.CTRMODE = 0; //CTRMODE, 00 = count up mode
EPwm3Regs.TBCTL.bit.SYNCOSEL = 3; //SYNCOSEL, 11 = sync-out disabled
EPwm3Regs.TBCTL.bit.PRDLD = 0; // PRDLD, 0 = reload PRD on counter=0
EPwm3Regs.TBCTL.bit.PHSEN = 0x0; //PHSEN, 0 = phase control disabled
EPwm3Regs.TBCTL.bit.FREE_SOFT = 3; //FREE/SOFT, 11 = ignore emulation suspend
EPwm3Regs.TBCTL.bit.SWFSYNC = 0; //SWFSYNC, 0 = no software sync produced
EPwm3Regs.TBPRD = 7500; // 20 KHz - PWM signal
EPwm3Regs.CMPA.half.CMPA = 1875; // set compare value
d3=3750; // initiaze duty value
EPwm3Regs.AQCTLA.all = 0x0012; //Set ePWM high when counter =0 and low when counter = compare value
}
//===========================================================================
// End of SourceCode.
//===========================================================================