Other Parts Discussed in Thread: TMS320F28335
Hello all, I am having a problem with the ezDSP using the TI TMS320f28335. I need to eventually use this to switch up to 2000 Amps in a motor and needless to say it needs to be rock solid. I have set up a test program, where I initialize the chip, setting up the ADC and a timer using the ePWM peripheral. I assign it to my interrupt routine and inside of that I have a variable named test that I simply increment. I am watching that variable in a watch window (real time mode with continuous refresh) and sure enough, when I run the program I see it incrementing. I then stop the program and run it again and this time it never gets updated (it just hangs inside my while(1) loop and never enters the interrupt. Sometimes I change a #define variable (that I am currently not using for this particular test) and recompile and that seems to break it. Other times, it will work 10 times in a row, I will enter a space, then backspace, recompile and it will not work. This problem makes no sense to me. Here is some code, if anyone can see a problem I would greatly appreciate it. Thanks again.
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "PIController.h" // Header for PI controller
#include "PWM.h" // Header for PWM update
// Configure which ePWM timer interrupts are enabled at the PIE level:
#define PWM1_INT_ENABLE 1
// Configure ADC
// ADC start parameters
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
#define ADC_CKPS 0x1 // ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
#define ADC_SHCLK 0xf // Sample and Hold width in ADC module periods = 16 ADC clocks
#define RM 59 //Measurement Resistor = 59 ohms
#define IV_RATIO 2000.0//1000 to 1 convertsion from current to volts (LEM SENSOR LA55P) * 2
#define VOLT_OFFSET 0.0
#define VOLTSCALE 45.78754579e-6
interrupt void pwmLoad_isr(void);
PICONTROLLER pi_current_controller = PICONTROLLER_DEFAULTS;
PWMOUT pwm = PWMOUT_DEFAULTS;
//Post Filtered Current Measurements
float current_pre = 0.0;
//Post Filtered Current Measurements
float current_post = 0.0;
//parameter for convex current filter (0<alpha<1)
float alpha = 0.985;
// Define interrupt frequency (5KhZ control frequency)
const float ISR_frequency = 25000.0;
float ISR_period = 1.0; //Initialized in main to 1/ISR_frequency
//Define system clock speed
const float system_frequency = 150000000.0; //150MhZ
float current_ref = 0.0;
int test = 0;
int i;
void main(void){
ISR_period = 1.0 / ISR_frequency;
// Initialize System Control: PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
InitSysCtrl();
// Initialize GPIO for eQEP1
// This function is found in DSP2833x_EQep.c
//InitEQep1Gpio();
// Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// This function is found in the DSP2833x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT = &pwmLoad_isr;
//PieVectTable.TINT0 = &pwmLoad_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Enable CPU INT3 which is connected to EPWM1-6 INT:
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER3.bit.INTx1 = PWM1_INT_ENABLE;
InitAdc(); // Initalize the ADC
// Specific ADC setup
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 0; // 1 Cascaded mode
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x2;
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // pin2
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // pin3
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x4; // pin4
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run
AdcRegs.ADCTRL2.all = 0x2000;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EALLOW;
//Configure pin to drive transistor
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // Use as GPIO
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // Configure as Output
EDIS;
//INITIALIZE CONTROLLER
pi_current_controller.Kp = .1;
pi_current_controller.DeltaTime = ISR_period;
pi_current_controller.Ki = .05;
pi_current_controller.Kc = 0.001;
pi_current_controller.Kd = .005;
pi_current_controller.OutMax = 1; //Limit between zero and one for PWM duty cycle control
pi_current_controller.OutMin = 0;
pi_current_controller.Ref = 0.0;
pi_current_controller.Feedbk = 0.0;
//INITIALIZE PWM
pwm.PeriodClock = system_frequency / (10*ISR_frequency);//10*ISR_frequency; //make PWM 10X faster than control frequency;
pwm.init(&pwm);
for(;;){
//sit and wait for interrupt}
}
}
// Main FOC loop
interrupt void pwmLoad_isr(void)
{
while (AdcRegs.ADCST.bit.INT_SEQ1== 0) {} // Wait for interrupt
//current_pre = ((float)(AdcRegs.ADCRESULT0)*VOLTSCALE);
current_pre = (((float)(AdcRegs.ADCRESULT0)*VOLTSCALE) - VOLT_OFFSET)*IV_RATIO/RM;
current_post = alpha * current_post + (1.0-alpha)*current_pre;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
test++;
current_ref = 1.0; //Set desired current to 1.0 Amps
pi_current_controller.Ref = -1.0*current_ref;
pi_current_controller.Feedbk = -1.0*current_post;
//pi_current_controller.calc(&pi_current_controller);
pi_current_controller.Output=0.1;//manual duty cycle overide for testing
pwm.Da = pi_current_controller.Output;
pwm.Db = 0.0;
pwm.Dc = 0.0;
pwm.update(&pwm);
// Clear INT flag for this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}