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.
Tool/software:
I have used the example file of device support> 379dx> possspeed.c. which uses the header " F28x_Project.h ". Basically combining my code with posssped.
The calculations are for a 2 pole,1500 rpm,1024 PPR motor calculated the Example_possspeed.h file is changed according to this:
100V CCS graph (large spikes):
So i can easily remove the possibility of DAC fault.
The sensors are all off so no ADC problem.
If i use a separate board for testing the ADC there is not ripple only if i control it in this board it has spikes (within 200Hz FFT).
The V/F code seems correct otherwise it would not work under low voltage as well.
I have tried closed loop Current control with RL load which works good so probably this is just an encoder/speed code problem issue.
The fascinating thing is Using V/F in another system and just transferring the encoder value has no problem at any rate.
So already as it can be seen in the main.c file the rate of calling the epwm9_isr function modified but to no luck.
In my testing it is probably the QUPRD problem or something else like rate etc (which i cannot seem to find because these spikes only exist inside the board measuring it through another board doesn't have ripples at all)
Any suggestions regarding this matter would be highly appreciated.
For ease i have attached all the 3 changed files here
//########################################################################### // // FILE: Example_posspeed.c // // TITLE: Pos/speed measurement using EQEP peripheral // // DESCRIPTION: // // This file includes the EQEP initialization and position and speed // calculation functions called by Eqep_posspeed.c. The position and speed // calculation steps performed by POSSPEED_Calc() at SYSCLKOUT = 200 MHz are // described below: // // 1. This program calculates: **theta_mech** // // theta_mech = QPOSCNT/mech_Scaler = QPOSCNT/4000, where 4000 is the number // of counts in 1 revolution. // (4000/4 = 1000 line/rev. quadrature encoder) // // 2. This program calculates: **theta_elec** // // theta_elec = (# pole pairs) * theta_mech = 2*QPOSCNT/4000 // // 3. This program calculates: **SpeedRpm_fr** // // SpeedRpm_fr = [(x2-x1)/4000]/T - Equation 1 // Note (x2-x1) = difference in number of QPOSCNT counts. Dividing (x2-x1) // by 4000 gives position relative to Index in one revolution. // If base RPM = 6000 rpm: 6000 rpm = [(x2-x1)/4000]/10ms - Equation 2 // = [(x2-x1)/4000]/(.01s*1 min/60 sec) // = [(x2-x1)/4000]/(1/6000) min // max (x2-x1) = 4000 counts, or 1 revolution in 10 ms // // // If both sides of Equation 2 are divided by 6000 rpm, then: // 1 = [(x2-x1)/4000] rev./[(1/6000) min * 6000rpm] // Because (x2-x1) must be <4000 (max) for QPOSCNT increment, // (x2-x1)/4000 < 1 for CW rotation // And because (x2-x1) must be >-4000 for QPOSCNT decrement, // (x2-x1)/4000>-1 for CCW rotation // speed_fr = [(x2-x1)/4000]/[(1/6000) min * 6000rpm] // = (x2-x1)/4000 - Equation 3 // // To convert speed_fr to RPM, multiply Equation 3 by 6000 rpm // SpeedRpm_fr = 6000rpm *(x2-x1)/4000 - Final Equation // // 2. **min rpm ** = selected at 10 rpm based on CCPS prescaler options // available (128 is greatest) // // 3. **SpeedRpm_pr** // SpeedRpm_pr = X/(t2-t1) - Equation 4 // where X = QCAPCTL [UPPS]/4000 rev. (position relative to Index in // 1 revolution) // If max/base speed = 6000 rpm: // 6000 = (32/4000)/[(t2-t1)/(200MHz/64)] // where 32 = QCAPCTL [UPPS] (Unit timeout - once every 32 edges) // 32/4000 = position in 1 revolution (position as a fraction // of 1 revolution) // t2-t1/(200MHz/64), t2-t1= # of QCAPCLK cycles, and // QCAPCLK cycle = 1/(200MHz/64) // = QCPRDLAT // // So: 6000 rpm = [32(200MHz/64)*60s/min]/[4000(t2-t1)] // t2-t1 = [32(200MHz/64)*60s/min]/(4000*6000rpm) - Equation 5 // = 250 CAPCLK cycles = maximum (t2-t1) = SpeedScaler // // Divide both sides by (t2-t1), and: // 1 = 32/(t2-t1) = [32(200MHz/64)*60 s/min]/(4000*6000rpm)]/(t2-t1) // Because (t2-t1) must be < 250 for QPOSCNT increment: // 250/(t2-t1) < 1 for CW rotation // And because (t2-t1) must be >-250 for QPOSCNT decrement: // 250/(t2-t1)> -1 for CCW rotation // // eed_pr = 250/(t2-t1) // or [32(200MHz/64)*60 s/min]/(4000*6000rpm)]/(t2-t1) - Equation 6 // // To convert speed_pr to RPM: // Multiply Equation 6 by 6000rpm: // SpeedRpm_fr = 6000rpm * [32(200MHz/64)*60 s/min]/[4000*6000rpm*(t2-t1)] // = [32(200MHz/64)*60 s/min]/[4000*(t2-t1)] // or [(32/4000)rev * 60 s/min]/[(t2-t1)(QCPRDLAT)]-Final Equation // // More detailed calculation results can be found in the Example_freqcal.xls // spreadsheet included in the example folder. // // This file contains source for the posspeed module // //########################################################################### // // $Release Date: $ // $Copyright: // Copyright (C) 2013-2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### // // Included Files // #include "F28x_Project.h" #include "Example_posspeed.h" // // POSSPEED_Init - Initialize EQEP1 configuration // void POSSPEED_Init(void) { EQep1Regs.QUPRD = 100; // Unit Timer for 100Hz at 200 MHz //CHANGED here//10,000 maybe//at 10 time // SYSCLKOUT EQep1Regs.QDECCTL.bit.QSRC = 00; // QEP quadrature count mode EQep1Regs.QEPCTL.bit.FREE_SOFT = 2; 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 = 0xffffffff; EQep1Regs.QEPCTL.bit.QPEN = 1; // QEP enable EQep1Regs.QCAPCTL.bit.UPPS = 5; // 1/32 for unit position EQep1Regs.QCAPCTL.bit.CCPS = 6; // 1/64 for CAP clock EQep1Regs.QCAPCTL.bit.CEN = 1; // QEP Capture Enable } // // POSSPEED_Calc - Perform the position calculations // void POSSPEED_Calc(POSSPEED *p) { long tmp; unsigned int pos16bval,temp1; _iq Tmp1,newp,oldp; // // 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 } // // High Speed Calculation using QEP Position counter // // Check unit Time out-event for speed calculation: // Unit Timer is configured for 100Hz in INIT function // 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 } // // Low-speed computation using QEP capture counter // if(EQep1Regs.QEPSTS.bit.UPEVNT == 1) // Unit position event { if(EQep1Regs.QEPSTS.bit.COEF == 0) // No Capture overflow { temp1 = (unsigned long)EQep1Regs.QCPRDLAT; // temp1 = t2-t1 } else // Capture overflow, saturate the result { temp1 = 0xFFFF; } // // p->Speed_pr = p->SpeedScaler/temp1 // p->Speed_pr = _IQdiv(p->SpeedScaler,temp1); Tmp1 = p->Speed_pr; if (Tmp1>_IQ(1)) { p->Speed_pr = _IQ(1); } else { p->Speed_pr = Tmp1; } // // Convert p->Speed_pr to RPM // if(p->DirectionQep == 0) // Reverse direction = negative { // // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q // p->SpeedRpm_pr = -_IQmpy(p->BaseRpm,p->Speed_pr); } else // Forward direction = positive { // // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q // p->SpeedRpm_pr = _IQmpy(p->BaseRpm,p->Speed_pr); } EQep1Regs.QEPSTS.all = 0x88; // Clear Unit position event flag // Clear overflow error flag } } // // End of file //
//########################################################################### // // FILE: Example_posspeed.h // // TITLE: Pos/speed measurement using EQEP peripheral // // DESCRIPTION: // // Header file containing data type and object definitions and // initializers. // //########################################################################### // // $Release Date: $ // $Copyright: // Copyright (C) 2013-2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### #ifndef __POSSPEED__ #define __POSSPEED__ // // Included Files // #include "IQmathLib.h" // // Defines // #define POSSPEED_DEFAULTS {0x0, 0x0,0x0,0x0,0x0,16383,2,0,0x0,\ 488,0,1500,0,\ 0,0,0,\ (void (*)(long))POSSPEED_Init,\ (void (*)(long))POSSPEED_Calc } ////5768 // Globals // typedef struct {int theta_elec; // Output: Motor Electrical angle (Q15) int theta_mech; // Output: Motor Mechanical Angle (Q15) int DirectionQep; // Output: Motor rotation direction (Q0) int QEP_cnt_idx; // Variable: Encoder counter index (Q0) int theta_raw; // Variable: Raw angle from Timer 2 (Q0) int mech_scaler; // Parameter: 0.9999/total count, total// JUST TOOK AS 1024 ticks // count = 4000 (Q26) int pole_pairs; // Parameter: Number of pole pairs (Q0) // 5 pole pairs int cal_angle; // Parameter: Raw angular offset // between encoder and phase a (Q0) int index_sync_flag; // Output: Index sync status (Q0) Uint32 SpeedScaler; // Parameter : Scaler converting 1/N // cycles to a GLOBAL_Q speed (Q0) - // independently with global Q _iq Speed_pr; // Output : speed in per-unit Uint32 BaseRpm; // Parameter : Scaler converting// 2000 rpm base speed set // GLOBAL_Q speed to rpm (Q0) speed - // independently with global Q int32 SpeedRpm_pr; // Output : speed in r.p.m. (Q0) - // independently with global Q _iq oldpos; // Input: Electrical angle (pu) _iq Speed_fr; // Output : speed in per-unit int32 SpeedRpm_fr; // Output : Speed in rpm (Q0) - // independently with global Q void (*init)(); // Pointer to the init funcion void (*calc)(); // Pointer to the calc funtion } POSSPEED; typedef POSSPEED *POSSPEED_handle; // // Function Prototypes // void POSSPEED_Init(void); void POSSPEED_Calc(POSSPEED_handle); #endif // __POSSPEED__ // // End of file //
// V/F for induction (LAST TESTED AT 100V just ok beyound 100 too much ripple in speed) // Included Files #include "F28x_Project.h" #include "Example_posspeed.h" #include <math.h> // // Globals // POSSPEED qep_posspeed=POSSPEED_DEFAULTS; Uint16 Interrupt_Count = 0; //DEFINE ALL CONSTANTS HERE #define EPWM1_TIMER_TBPRD 5000 // Period register for epwm 2-8 (5 kHz) #define EPWM9_TIMER_TBPRD 5000 // Period register for epwm9 - code is written here (10 kHz) #define DACRATE 1250 #define PI 3.1415926536 #define PI2 6.28318530718 #define inv_PI2 0.15915494309 //1/(2*PI) //ADC-RELATED VARIABLES volatile Uint16 bufferFull; volatile float ADC_VSENSE_GAIN=1; volatile float ADC_ISENSE_GAIN=1; //DAC-RELATED VARIABLES volatile float DAC_GAIN = 0.1, DAC_OFFSET = 5.; volatile int scope = 0; //START YOUR OWN VARIABLES HERE #define Ts 0.0001 // = 1/10000 volatile float D = 0.5; //LPF COEFFICIENTS //float LPF_curr_num[3] = {3.9129232e-5, 7.8258464e-5, 3.9129232e-5}; //this is 2nd-order LPF with damping factor = 0.707 and fc = 100 Hz. //float LPF_curr_den[3] = {1, -1.9822318, 0.98238832}; float LPF_curr_num[3] = {0.013231365, 0.026462729, 0.013231365}; float LPF_curr_den[3] = {1, -1.6493092, 0.70223464}; float LPF_volt_num[3] = {0.013231365, 0.026462729, 0.013231365}; //this is 2nd-order LPF with damping factor = 0.707 and fc = 2000 Hz. float LPF_volt_den[3] = {1, -1.6493092, 0.70223464}; float test = 50; volatile float Imax = 10; volatile float Vmax = 400; //VOLTAGE, CURRENT, AND POWER float VDC1=0., VDC2=0., VDC3=0., VDC4=0.; float IDC1=0., IDC2=0., IDC3=0., IDC4=0.; float VDC1_arr[3], VDC2_arr[3], VDC3_arr[3], VDC4_arr[3]; //store the values in arrays for LPF float VDC1_LPF=0., VDC2_LPF=0., VDC3_LPF=0., VDC4_LPF=0.; //values after LPF float VDC1_LPF_arr[3], VDC2_LPF_arr[3], VDC3_LPF_arr[3], VDC4_LPF_arr[3]; float IDC1_arr[3], IDC2_arr[3], IDC3_arr[3], IDC4_arr[3]; //store the values in arrays for LPF float IDC1_LPF=0., IDC2_LPF=0., IDC3_LPF=0., IDC4_LPF=0.; //values after LPF float IDC1_LPF_arr[3], IDC2_LPF_arr[3], IDC3_LPF_arr[3], IDC4_LPF_arr[3]; float VDC_list[4] = {0,0,0,0}, IDC_list[4] = {0,0,0,0}; float PDC1 = 0., PDC2 = 0., PDC3 = 0., PDC4 = 0.; float PDC_list[4] = {0,0,0,0}; float PIN = 0., PO = 0.; volatile float PDC1_TEST = 0., PDC2_TEST = 0., PDC3_TEST = 0., PDC4_TEST = 0.; volatile float P_DAC_SCALE = 0.0002; volatile float Pscale = 1500; //VOLTAGE CONTROLLER VARIABLES volatile float KP_VDC = 0.0005, KI_VDC = 0.05; volatile float VDC_ref_set = 30., VDC_ref = 30.; float error_VDC4=0., error_VDC4_integ=0., ctrl_VDC4=0.; float error_VDC3=0., error_VDC3_integ=0., ctrl_VDC3=0.; float error_VDC2=0., error_VDC2_integ=0., ctrl_VDC2=0.; //POWER CONTROLLER VARIABLES volatile float KP_PDC = 0.0005, KI_PDC = 0.005; volatile float PDC1_ref=0., PDC1_ref_set; volatile float Const_P = 0.5; float PDC2_ref; float error_PDC2=0., error_PDC2_integ=0., ctrl_PDC2=0.; //DECOUPLER float inv_J11=0., inv_J12=0., inv_J13=0.; //inverse Jacobi matrix float inv_J21=0., inv_J22=0., inv_J23=0.; float inv_J31=0., inv_J32=0., inv_J33=0.; float D12_deco, D13_deco, D14_deco; //PHASE SHIFT ANGLES #define Dmax 0.25 #define Dmin -0.25 volatile float D12=0., D13=0., D14=0.; volatile float D23=0., D24=0., D34=0.; int duty_flag=0; volatile float Duty1 = 0.5, Duty2 = 0.5, Duty3 = 0.5, Duty4 = 0.5; volatile float DD12 = 0.1, DD13 = 0.105, DD14 = 0.1; volatile float DD23 = 0., DD24 = 0., DD34 = 0.; //changed code for inverter static double angle_gen=0,m1 = 0.1,FREQ=60; static double Vrefa=0,Vrefb=0,Vrefc=0,Vrefx=0,Vrefy=0,Vrefz =0; static double Vrefa_PWM=0,Vrefb_PWM=0,Vrefc_PWM=0,Vrefx_PWM=0,Vrefy_PWM=0,Vrefz_PWM=0; static int DAC = 6; float gain = 1; static double offsetA=0 , offsetB=0; //FOC PMSM static double Theta_PM=0,Mechanical_PM=0; static double Ia_inv=0,Ib_inv=0,Ic_inv=0; static double Idse = 0, Iqse = 0; static double Wrpm_nofilter = 0, Wrad=0, COS_ANGLE_PM=0, SIN_ANGLE_PM=0,Wrad_print=0; static double Ide=0,Iqe=0; static double Wrpm_ref_PM=0,W_SET=100; static int CLK_Count=0,SEC1=0; //controllers static int count_sp_pm=0,speed_loop=0; static double Wrpm_PM_anti=0,Wrpm_PM_error=0,Wrpm_PM_integ=0,Wrpm_PM_m_out=0,Wrpm_PM_out=0,Wrad_PM=0; static double Ide_Inv_ref=0,Ide_Inv_error=0,Ide_Inv_anti=0,Ide_Inv_integ=0,Ide_Inv_m_out=0,Ide_Inv_out=0; static double Iqe_Inv_ref=0,Iqe_Inv_error=0,Iqe_Inv_anti=0,Iqe_Inv_integ=0,Iqe_Inv_m_out=0,Iqe_Inv_out=0; static double Vdse=0,Vqse=0,Va=0,Vb=0,Vc=0; static double inv_sp = 0, inv_curr = 0, Wrpm_PM_Kp=0, Wrpm_PM_Ki=0, Ide_Inv_Ki=0, Ide_Inv_Kp=0,Iqe_Inv_Ki=0,Iqe_Inv_Kp=0;// gains static double VDC_div = 0; static double Rr = 1.808,Wsl=0; //V/F induction:- static double Wrpm_in=100, Tsamp = 0.0001; static double Va_VF =0,Vb_VF=0,Vc_VF=0; static int VF = 1; static float f_vf_ref=0., f_vf=0., v_vf=0., theta_vf=0.; float a, d, q; float Speed_arr[3]; //store the values in arrays for LPF float Speed_LPF=0.; //values after LPF float Speed_LPF_arr[3]; float Speed_num[3] = {3.9129232e-5, 7.8258464e-5, 3.9129232e-5}; //this is 2nd-order LPF with damping factor = 0.707 and fc = 100 Hz. float Speed_den[3] = {1, -1.9822318, 0.98238832}; static double KP_SP = 0.001, KI_SP = 0.05; static double KP = 1, KI = 100; int Speed_Loop=0,count = 0; //FUNCTION PROTOTYPES & INTERRUPTS void InitEPwmExample(void); void ConfigureADC(void); void SetupADCEpwm(void); void initEpwm();//added from QEP void error(void); __interrupt void prdTick(void);//added from QEP __interrupt void epwm2_isr(void); __interrupt void epwm3_isr(void); __interrupt void epwm4_isr(void); __interrupt void epwm5_isr(void); __interrupt void epwm6_isr(void); __interrupt void epwm7_isr(void); __interrupt void epwm8_isr(void); __interrupt void epwm9_isr(void); __interrupt void adc_isr(void); //Main void main(void) { // Initialize System Control: InitSysCtrl(); // Initialize GPIO: InitGpio(); GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 2); //GPIO30 - CANRXA GPIO_SetupPinMux(12, GPIO_MUX_CPU1, 2); //GPIO31 - CANTXA GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC); GPIO_SetupPinOptions(12, GPIO_OUTPUT, GPIO_PUSHPULL); // Initialize the PIE control registers to their default state. 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). InitPieVectTable(); // enable PWMs CpuSysRegs.PCLKCR2.bit.EPWM1=1; CpuSysRegs.PCLKCR2.bit.EPWM2=1; CpuSysRegs.PCLKCR2.bit.EPWM3=1; CpuSysRegs.PCLKCR2.bit.EPWM4=1; CpuSysRegs.PCLKCR2.bit.EPWM5=1; CpuSysRegs.PCLKCR2.bit.EPWM6=1; CpuSysRegs.PCLKCR2.bit.EPWM7=1; CpuSysRegs.PCLKCR2.bit.EPWM8=1; CpuSysRegs.PCLKCR2.bit.EPWM9=1; InitEQep1Gpio(); //Initialize EPWM GPIOs // InitEPwm1Gpio(); InitEPwm2Gpio(); InitEPwm3Gpio(); InitEPwm4Gpio(); InitEPwm5Gpio(); InitEPwm6Gpio(); InitEPwm7Gpio(); InitEPwm8Gpio(); InitEPwm9Gpio(); // Step 3. Clear all interrupts and initialize PIE vector table: //DINT; EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output simulates Index signal GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Normally low EDIS; EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.EPWM1_INT = &prdTick; PieVectTable.EPWM2_INT = &epwm2_isr; PieVectTable.EPWM3_INT = &epwm3_isr; PieVectTable.EPWM4_INT = &epwm4_isr; PieVectTable.EPWM5_INT = &epwm5_isr; PieVectTable.EPWM6_INT = &epwm6_isr; PieVectTable.EPWM7_INT = &epwm7_isr; PieVectTable.EPWM8_INT = &epwm8_isr; PieVectTable.EPWM9_INT = &epwm9_isr; PieVectTable.ADCA1_INT = &adc_isr; EDIS; // This is needed to disable write to EALLOW protected registers // For this example, only initialize the ePWM EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; // initEpwm();//added for EQEP InitEPwmExample(); ConfigureADC(); SetupADCEpwm(); EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; // Enable CPU INT3 which is connected to EPWM1-3 INT: IER |= M_INT3; // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3 PieCtrlRegs.PIEIER3.bit.INTx1 = 1; PieCtrlRegs.PIEIER3.bit.INTx2 = 1; PieCtrlRegs.PIEIER3.bit.INTx3 = 1; PieCtrlRegs.PIEIER3.bit.INTx4 = 1; PieCtrlRegs.PIEIER3.bit.INTx5 = 1; PieCtrlRegs.PIEIER3.bit.INTx6 = 1; PieCtrlRegs.PIEIER3.bit.INTx7 = 1; PieCtrlRegs.PIEIER3.bit.INTx8 = 1; PieCtrlRegs.PIEIER3.bit.INTx9 = 1; PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //ADC EALLOW; GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0; GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 0; GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0; GpioCtrlRegs.GPDMUX2.bit.GPIO124 = 0; GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1; GpioCtrlRegs.GPBDIR.bit.GPIO58 = 1; GpioCtrlRegs.GPADIR.bit.GPIO26 = 1; GpioCtrlRegs.GPDDIR.bit.GPIO124 = 1; EDIS; // Enable global Interrupts and higher priority real-time debug events: EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM qep_posspeed.init(&qep_posspeed); for(;;) { //start ePWM EPwm9Regs.ETSEL.bit.SOCAEN = 1; //enable SOCA EPwm9Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up down count mode //wait while ePWM causes ADC conversions, which then cause interrupts, //which fill the results buffer, eventually setting the bufferFull //flag while(!bufferFull); bufferFull = 0; //clear the buffer full flag //stop ePWM EPwm9Regs.ETSEL.bit.SOCAEN = 0; //disable SOCA EPwm9Regs.TBCTL.bit.CTRMODE = 3; //freeze counter } } //epwm9_isr -- PUT THE CODE HERE __interrupt void epwm9_isr(void) { count++; if (count>=1) { qep_posspeed.calc(&qep_posspeed); count=0; } Mechanical_PM = qep_posspeed.theta_mech*0.00003051851;// range is 0 to 1 // 1/(2^15)=0.00003051851 //theta way 2(actual encoder theta) Theta_PM = qep_posspeed.theta_elec*0.00003051851;//range is 0 to 1// (1/2^15)=0.00003051851 Speed_arr[0] = qep_posspeed.SpeedRpm_pr; // Speed_LPF_arr[0] = Speed_num[0]*Speed_arr[0] + Speed_num[1]*Speed_arr[1] + Speed_num[2]*Speed_arr[2] - Speed_den[1]*Speed_LPF_arr[1] - Speed_den[2]*Speed_LPF_arr[2]; // Speed_LPF = Speed_LPF_arr[0]; //filtered current // Speed_arr[2] = Speed_arr[1]; // Speed_arr[1] = Speed_arr[0]; // Speed_LPF_arr[2] = Speed_LPF_arr[1]; // Speed_LPF_arr[1] = Speed_LPF_arr[0]; // // Wrpm_nofilter = Speed_LPF; if(VF==1) { f_vf_ref = Wrpm_in/1500.*50.; if(f_vf > f_vf_ref) f_vf -= 3.5*Ts; else f_vf += 3.5*Ts; if(f_vf > 50.) f_vf = 50.; v_vf = PI2 * f_vf*0.47; //for Leroy Motor rated 0.47 a = theta_vf + PI2*f_vf*Ts; theta_vf = a + ((a > PI) ? -PI2 : (a < -PI) ? PI2 : 0.); d = v_vf*cos(theta_vf); q = v_vf*sin(theta_vf); Va_VF = d ; Vb_VF = -0.5*(d - (1.732050807)*q); Vc_VF = -(Va_VF + Vb_VF) ; Vrefa = Va_VF/100;//100V dc link Vrefb = Vb_VF/100;//100V dc link Vrefc = Vc_VF/100;//100V dc link } Vrefa_PWM = (Vrefa+1)*0.5; Vrefb_PWM = (Vrefb+1)*0.5; Vrefc_PWM = (Vrefc+1)*0.5; EPwm2Regs.CMPA.bit.CMPA = Vrefa_PWM*EPWM1_TIMER_TBPRD; // Set compare A value EPwm2Regs.CMPB.bit.CMPB = Vrefb_PWM*EPWM1_TIMER_TBPRD; // Set compare B value EPwm3Regs.CMPA.bit.CMPA = Vrefc_PWM*EPWM1_TIMER_TBPRD; // Set compare A value //EPwm3Regs.CMPB.bit.CMPB = test*EPWM1_TIMER_TBPRD; // Set compare B value //EPwm4Regs.CMPA.bit.CMPA = Vrefx_PWM*EPWM1_TIMER_TBPRD; // Set compare A value //EPwm4Regs.CMPB.bit.CMPB = test*EPWM1_TIMER_TBPRD; // Set compare B value //EPwm5Regs.CMPA.bit.CMPA = Vrefy_PWM*EPWM1_TIMER_TBPRD; // Set compare A value //EPwm5Regs.CMPB.bit.CMPB = test*EPWM1_TIMER_TBPRD; // Set compare B value //EPwm6Regs.CMPA.bit.CMPA = Vrefz_PWM*EPWM1_TIMER_TBPRD; // Set compare A value //EPwm6Regs.CMPB.bit.CMPB = test*EPWM1_TIMER_TBPRD; // Set compare B value if (DAC==1){ EPwm7Regs.CMPA.bit.CMPA = Iqe_Inv_ref*0.1*DACRATE; // (3)//Max = 3.1665 for all ADCs EPwm7Regs.CMPB.bit.CMPB = Iqe*0.1*DACRATE; // (4) EPwm8Regs.CMPA.bit.CMPA = Ide_Inv_ref*0.1*DACRATE; // (1) 0 to 3.1665 MAX voltage ALL or 0 to TBPRD,MAX CURRENT = 25A suppose,offset by +25 EPwm8Regs.CMPB.bit.CMPB = Ide*0.1*DACRATE; // (2) 0 to 3.1665 MAX voltage ALL or 0 to TBPRD } if (DAC==2){ EPwm7Regs.CMPA.bit.CMPA = (IDC1_LPF+10)*0.05*DACRATE; // 10A peak EPwm7Regs.CMPB.bit.CMPB = (IDC2_LPF+10)*0.05*DACRATE; // 10A peak EPwm8Regs.CMPA.bit.CMPA = (IDC1+10)*0.05*DACRATE; // Set compare A value EPwm8Regs.CMPB.bit.CMPB = (IDC2+10)*0.05*DACRATE; // Set compare B value } if (DAC==3){ EPwm7Regs.CMPA.bit.CMPA = Vrefa_PWM*DACRATE; // Set compare A value EPwm7Regs.CMPB.bit.CMPB = Vrefb_PWM*DACRATE; // Set compare B value EPwm8Regs.CMPA.bit.CMPA = Vrefc_PWM*DACRATE; // Set compare A value EPwm8Regs.CMPB.bit.CMPB = ((angle_gen*0.31830988618)+1)*0.5*DACRATE; // Set compare B value } if (DAC==4){ EPwm7Regs.CMPA.bit.CMPA = Theta_PM*DACRATE; // Set compare A value EPwm7Regs.CMPB.bit.CMPB = Mechanical_PM*DACRATE; // Set compare B value EPwm8Regs.CMPA.bit.CMPA = Vrefz_PWM*DACRATE; // Set compare A value EPwm8Regs.CMPB.bit.CMPB = ((angle_gen*0.31830988618)+1)*0.5*DACRATE; // Set compare B value } if (DAC==5){ EPwm7Regs.CMPA.bit.CMPA = Wrpm_ref_PM*0.002*DACRATE; // Set compare A value EPwm7Regs.CMPB.bit.CMPB = qep_posspeed.SpeedRpm_pr*0.002*DACRATE; // Set compare B value EPwm8Regs.CMPA.bit.CMPA = Speed_LPF*0.002*DACRATE; // Set compare A value EPwm8Regs.CMPB.bit.CMPB = qep_posspeed.SpeedRpm_pr*0.002*DACRATE; // Set compare B value } if (DAC==6){ EPwm7Regs.CMPA.bit.CMPA = Wrpm_in;//*0.002*DACRATE; // Set compare A value EPwm7Regs.CMPB.bit.CMPB = qep_posspeed.SpeedRpm_pr;//*0.002*DACRATE; // Set compare B value EPwm8Regs.CMPA.bit.CMPA = 0;//*0.002*DACRATE; // Set compare A value EPwm8Regs.CMPB.bit.CMPB = 0;//*0.002*DACRATE; // Set compare B value } // // Clear INT flag for this timer // EPwm9Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } // // epwm1_isr - EPWM1 ISR // __interrupt void epwm1_isr(void) { // // 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; } __interrupt void epwm2_isr(void) { // // Clear INT flag for this timer // EPwm2Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm3_isr(void) { // // Clear INT flag for this timer // EPwm3Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm4_isr(void) { // // Clear INT flag for this timer // EPwm4Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm5_isr(void) { // // Clear INT flag for this timer // EPwm5Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm6_isr(void) { // // Clear INT flag for this timer // EPwm6Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm7_isr(void) { // // Clear INT flag for this timer // EPwm7Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void epwm8_isr(void) { // sendCANMessage(CAN_TX_MSG_OBJ); // // // // // Get the receive message // // //// getCANMessage(CAN_RX_MSG_OBJ); // // // // // Now wait 1 second before continuing // // // DELAY_US(1000000); // // // // // Ensure the received data matches the transmitted data // // //// if((ucTXMsgData[0] != ucRXMsgData[0]) || //// (ucTXMsgData[1] != ucRXMsgData[1]) || //// (ucTXMsgData[2] != ucRXMsgData[2]) || //// (ucTXMsgData[3] != ucRXMsgData[3])) //// { //// errFlag++; //// asm(" ESTOP0"); //// } //// else //// { //// // //// // Increment successful message count //// // //// msgCount++; //// } // // // // // // Increment the value in the transmitted message data. // // // ucTXMsgData[0] += 0x1; // ucTXMsgData[1] += 0x1; // ucTXMsgData[2] += 0x1; // ucTXMsgData[3] += 0x1; // // // // // Reset data if exceeds a byte // // // if(ucTXMsgData[0] > 0xFF) // { // ucTXMsgData[0] = 0; // } // if(ucTXMsgData[1] > 0xFF) // { // ucTXMsgData[1] = 0; // } // if(ucTXMsgData[2] > 0xFF) // { // ucTXMsgData[2] = 0; // } // if(ucTXMsgData[3] > 0xFF) // { // ucTXMsgData[3] = 0; // } // // Clear INT flag for this timer // EPwm8Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } __interrupt void adc_isr(void) { AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //clear INT3 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear INT1 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //clear INT1 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT2 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear INT2 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //clear INT3 flag // // Check if overflow has occurred // if(1 == AdcaRegs.ADCINTOVF.bit.ADCINT1) { AdcaRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //clear INT1 overflow flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag } if(1 == AdcaRegs.ADCINTOVF.bit.ADCINT2) { AdcaRegs.ADCINTOVFCLR.bit.ADCINT2 = 1; //clear INT1 overflow flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear INT1 flag } if(1 == AdcaRegs.ADCINTOVF.bit.ADCINT3) { AdcaRegs.ADCINTOVFCLR.bit.ADCINT3 = 1; //clear INT1 overflow flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //clear INT1 flag } if(1 == AdcbRegs.ADCINTOVF.bit.ADCINT1) { AdcbRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //clear INT1 overflow flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag } if(1 == AdcbRegs.ADCINTOVF.bit.ADCINT2) { AdcbRegs.ADCINTOVFCLR.bit.ADCINT2 = 1; //clear INT1 overflow flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear INT1 flag } if(1 == AdcbRegs.ADCINTOVF.bit.ADCINT3) { AdcbRegs.ADCINTOVFCLR.bit.ADCINT3 = 1; //clear INT1 overflow flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //clear INT1 flag } if(1 == AdccRegs.ADCINTOVF.bit.ADCINT1) { AdccRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //clear INT1 overflow flag AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag } if(1 == AdccRegs.ADCINTOVF.bit.ADCINT2) { AdccRegs.ADCINTOVFCLR.bit.ADCINT2 = 1; //clear INT1 overflow flag AdccRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear INT1 flag } if(1 == AdccRegs.ADCINTOVF.bit.ADCINT3) { AdccRegs.ADCINTOVFCLR.bit.ADCINT3 = 1; //clear INT1 overflow flag AdccRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //clear INT1 flag } PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } // InitEPwmExample - Initialize EPWM configuration void InitEPwmExample() { //EPWM-1-FOR QEP //EPWM-2 EPwm2Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm2Regs.TBCTR = 0x0000; // Clear counter EPwm2Regs.CMPA.bit.CMPA = 0.5*EPWM1_TIMER_TBPRD; // Set compare A value EPwm2Regs.CMPB.bit.CMPB = 0.5*EPWM1_TIMER_TBPRD; // Set Compare B value EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //Time-base counter equal to zero (TBCTR = 0x00) EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, EPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm2Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-3 EPwm3Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs EPwm3Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm3Regs.TBCTR = 0x0000; // Clear counter EPwm3Regs.CMPA.bit.CMPA = 0.5*EPWM1_TIMER_TBPRD; // Set compare A value EPwm3Regs.CMPB.bit.CMPB = 0.5*EPWM1_TIMER_TBPRD; // Set Compare B value EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm3Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //Time-base counter equal to zero (TBCTR = 0x00) EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm3Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, EPwm3Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1B on event B, up EPwm3Regs.AQCTLB.bit.CAD = AQ_SET; // Clear PWM1B on event B, EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm3Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm3Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-4 EPwm4Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs EPwm4Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm4Regs.TBCTR = 0x0000; // Clear counter EPwm4Regs.CMPA.bit.CMPA = 0.5*EPWM1_TIMER_TBPRD; // Set compare A value EPwm4Regs.CMPB.bit.CMPB = 0.5*EPWM1_TIMER_TBPRD; // Set Compare B value EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm4Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //Time-base counter equal to zero (TBCTR = 0x00) EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm4Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up EPwm4Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, EPwm4Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1B on event B, up EPwm4Regs.AQCTLB.bit.CAD = AQ_SET; // Clear PWM1B on event B, // EPwm4Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event // EPwm4Regs.ETSEL.bit.INTEN = 1; // Enable INT // EPwm4Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-5 EPwm5Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs EPwm5Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm5Regs.TBCTR = 0x0000; // Clear counter EPwm5Regs.CMPA.bit.CMPA = 0.5*EPWM1_TIMER_TBPRD; // Set compare A value EPwm5Regs.CMPB.bit.CMPB = 0.5*EPWM1_TIMER_TBPRD; // Set Compare B value EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm5Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm5Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up EPwm5Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, EPwm5Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1B on event B, up EPwm5Regs.AQCTLB.bit.CAD = AQ_SET; // Clear PWM1B on event B, // EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event // EPwm5Regs.ETSEL.bit.INTEN = 1; // Enable INT // EPwm5Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-6 EPwm6Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs EPwm6Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm6Regs.TBCTR = 0x0000; // Clear counter EPwm6Regs.CMPA.bit.CMPA = 0.5*EPWM1_TIMER_TBPRD; // Set compare A value EPwm6Regs.CMPB.bit.CMPB = 0.5*EPWM1_TIMER_TBPRD; // Set Compare B value EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up EPwm6Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, EPwm6Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1B on event B, up EPwm6Regs.AQCTLB.bit.CAD = AQ_SET; // Clear PWM1B on event B, // // EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event // EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT // EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-7 EPwm7Regs.TBPRD = DACRATE; // Set timer period 801 TBCLKs EPwm7Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm7Regs.TBCTR = 0x0000; // Clear counter //EPwm7Regs.CMPA.bit.CMPA = EPwm7_MIN_CMPA; // Set compare A value //EPwm7Regs.CMPB.bit.CMPB = EPwm7_MAX_CMPB; // Set Compare B value EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm7Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm7Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on event A, up EPwm7Regs.AQCTLA.bit.CAD = AQ_SET; // Clear PWM1A on event A, EPwm7Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM1B on event B, up EPwm7Regs.AQCTLB.bit.CBD = AQ_SET; // Clear PWM1B on event B, EPwm7Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm7Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm7Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-8 EPwm8Regs.TBPRD = DACRATE; // Set timer period 801 TBCLKs EPwm8Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm8Regs.TBCTR = 0x0000; // Clear counter //EPwm8Regs.CMPA.bit.CMPA = EPwm8_MIN_CMPA; // Set compare A value //EPwm8Regs.CMPB.bit.CMPB = EPwm8_MAX_CMPB; // Set Compare B value EPwm8Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down EPwm8Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm8Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm8Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm8Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm8Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm8Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm8Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm8Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on event A, up EPwm8Regs.AQCTLA.bit.CAD = AQ_SET; // Clear PWM1A on event A, EPwm8Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM1B on event B, up EPwm8Regs.AQCTLB.bit.CBD = AQ_SET; // Clear PWM1B on event B, EPwm8Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm8Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm8Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event //EPWM-9 EPwm9Regs.TBPRD = EPWM9_TIMER_TBPRD; EPwm9Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm9Regs.TBCTR = 0x0000; // Clear counter EPwm9Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; EPwm9Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm9Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm9Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm9Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm9Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm9Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero EPwm9Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm9Regs.CMPA.bit.CMPA = 0.5*EPWM9_TIMER_TBPRD; // EPwm9Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on event A, up // EPwm9Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, // EPwm9Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on event B, up // EPwm9Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, EPwm9Regs.ETSEL.bit.INTSEL = 4; // Select INT on Zero event EPwm9Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm9Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event EPwm9Regs.ETSEL.bit.SOCAEN = 0; // Disable SOC on A group EPwm9Regs.ETSEL.bit.SOCASEL = 4; // Select SOC on up-count EPwm9Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event } // ConfigureADC - Write ADC configurations and power up ADC A, B, and C void ConfigureADC(void) { EALLOW; // //write configurations // AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdccRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // //Set pulse positions to late // AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1; // //power up the ADC // AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1; AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1; // //delay for 1ms to allow ADC time to power up // DELAY_US(1000); EDIS; } // SetupADCEpwm - Setup ADC EPWM acquisition window - use ePWM8 void SetupADCEpwm(void) { Uint16 acqps; // // Determine minimum acquisition window (in SYSCLKS) based on resolution // if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION) { acqps = 14; //75ns } else //resolution is 16-bit { acqps = 63; //320ns } if(ADC_RESOLUTION_12BIT == AdcbRegs.ADCCTL2.bit.RESOLUTION) { acqps = 14; //75ns } else //resolution is 16-bit { acqps = 63; //320ns } if(ADC_RESOLUTION_12BIT == AdccRegs.ADCCTL2.bit.RESOLUTION) { acqps = 14; //75ns } else //resolution is 16-bit { acqps = 63; //320ns } // //Select the channels to convert and end of conversion flag // EALLOW; AdcaRegs.ADCSOC14CTL.bit.CHSEL = 14; //SOC14 will convert pin A14 AdcaRegs.ADCSOC14CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC14CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 14; //end of SOC14 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared AdccRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC3 will convert pin C3 AdccRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCSOC3CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdccRegs.ADCINTSEL3N4.bit.INT3SEL = 3; //end of SOC3 will set INT3 flag AdccRegs.ADCINTSEL3N4.bit.INT3E = 1; //enable INT3 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //make sure INT3 flag is cleared AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC3 will convert pin B3 AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcbRegs.ADCSOC3CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcbRegs.ADCINTSEL3N4.bit.INT3SEL = 3; //end of SOC3 will set INT3 flag AdcbRegs.ADCINTSEL3N4.bit.INT3E = 1; //enable INT3 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //make sure INT3 flag is cleared AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC3 will convert pin A3 AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL3N4.bit.INT3SEL = 3; //end of SOC3 will set INT3 flag AdcaRegs.ADCINTSEL3N4.bit.INT3E = 1; //enable INT3 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT3 = 1; //make sure INT3 flag is cleared AdccRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC2 will convert pin A2 AdccRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCSOC2CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdccRegs.ADCINTSEL1N2.bit.INT2SEL = 2; //end of SOC2 will set INT2 flag AdccRegs.ADCINTSEL1N2.bit.INT2E = 1; //enable INT2 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //make sure INT2 flag is cleared AdcbRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC2 will convert pin B2 AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcbRegs.ADCSOC2CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcbRegs.ADCINTSEL1N2.bit.INT2SEL = 2; //end of SOC2 will set INT2 flag AdcbRegs.ADCINTSEL1N2.bit.INT2E = 1; //enable INT2 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //make sure INT2 flag is cleared AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2; //SOC2 will convert pin A2 AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 2; //end of SOC2 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0 will convert pin A0 AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared AdcaRegs.ADCSOC15CTL.bit.CHSEL = 15; //SOC15 will convert pin A15 AdcaRegs.ADCSOC15CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC15CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 15; //end of SOC15 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared AdccRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin C5 AdccRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCSOC5CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 5; //end of SOC5 will set INT2 flag AdccRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT2 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT2 flag is cleared AdcbRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin B5 AdcbRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcbRegs.ADCSOC5CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 5; //end of SOC5 will set INT2 flag AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT2 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT2 flag is cleared AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5; //SOC5 will convert pin A5 AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 5; //end of SOC5 will set INT2 flag AdcaRegs.ADCINTSEL1N2.bit.INT2E = 1; //enable INT2 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //make sure INT2 flag is cleared AdccRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC4 will convert pin C4 AdccRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCSOC4CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 4; //end of SOC4 will set INT2 flag AdccRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT2 flag AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT2 flag is cleared AdcbRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC4 will convert pin B4 AdcbRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcbRegs.ADCSOC4CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 4; //end of SOC4 will set INT2 flag AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT2 flag AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT2 flag is cleared AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4; //SOC4 will convert pin B4 AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 4; //end of SOC4 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT2 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT2 flag is cleared AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1 will convert pin A1 AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 21; //trigger on ePWM8 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1; //end of SOC1 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT2 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT2 flag is cleared EDIS; } // // prdTick - EPWM1 Interrupts once every 4 QCLK counts (one period) // __interrupt void prdTick(void) { // GpioDataRegs.GPATOGGLE.bit.GPIO26 = 1; // Uint16 i; // // // // // Position and Speed measurement // // // // // // // // Control loop code for position control & Speed control // // // Interrupt_Count++; // // // // // Every 1000 __interrupts(4000 QCLK counts or 1 rev.) // // // if (Interrupt_Count==1000) // { // EALLOW; // GpioDataRegs.GPASET.bit.GPIO4 = 1; // Pulse Index signal (1 pulse/rev.) // for (i=0; i<700; i++) // { // } // GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Interrupt_Count = 0; // Reset count // EDIS; // } // // Acknowledge this __interrupt to receive more __interrupts from group 1 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; EPwm1Regs.ETCLR.bit.INT=1; } void error()//CHANGE REQUIRED { EPwm2Regs.CMPA.bit.CMPA = 0*EPWM1_TIMER_TBPRD; // Set compare A value EPwm2Regs.CMPB.bit.CMPB = 0*EPWM1_TIMER_TBPRD; // Set compare B value EPwm3Regs.CMPA.bit.CMPA = 0*EPWM1_TIMER_TBPRD; // Set compare A value EPwm3Regs.CMPB.bit.CMPB = 0*EPWM1_TIMER_TBPRD; // Set compare B value EPwm4Regs.CMPA.bit.CMPA = 0*EPWM1_TIMER_TBPRD; // Set compare A value EPwm4Regs.CMPB.bit.CMPB = 0*EPWM1_TIMER_TBPRD; // Set compare B value EPwm5Regs.CMPA.bit.CMPA = 0*EPWM1_TIMER_TBPRD; // Set compare A value EPwm5Regs.CMPB.bit.CMPB = 0*EPWM1_TIMER_TBPRD; // Set compare B value EPwm6Regs.CMPA.bit.CMPA = 0*EPWM1_TIMER_TBPRD; // Set compare A value EPwm6Regs.CMPB.bit.CMPB = 0*EPWM1_TIMER_TBPRD; // Set compare B value for(;;){} } // // End of file // //END OF FILE
Hi Syed,
I see you're testing on the launchpad, In the following screenshot, what are each channel that is being shown below?
Best,
Ryan Ma
Hello Ryan,
In here C1(red) represents the reference RPM signal and C2(pink) represents " qep_posspeed.SpeedRpm_pr" (measured rpm). rest 2 are not measured.
as can be seen here in the main.c file (line 390):
if (DAC==5){
EPwm7Regs.CMPA.bit.CMPA = Wrpm_ref_PM*0.002*DACRATE; // Set compare A value
EPwm7Regs.CMPB.bit.CMPB = qep_posspeed.SpeedRpm_pr*0.002*DACRATE; // Set compare B value
The other two seperate CCS graphs are for "qep_posspeed.SpeedRpm_pr"
Hi SYED,
What does your current setup look like? I'm still unsure on why would increasing the voltage from 60vDC to 100Vdc cause noise on the input?
Best,
Ryan Ma
Hello Ryan,
The current setup is just a variable transformer-->diode rectifier-->inverter to motor.
It seems strange to me as well.
The thing i suspect is something regarding the rates.
like how do i choose QUPRD value
and at what rate should i call this "qep_posspeed.calc(&qep_posspeed);" to update the values
because changing these results in low or higher spike in the measured speed
Hi Syed,
Could you try the following lab and see if you view the same results?
https://dev.ti.com/tirex/explore/node?node=A__AQrUNT9kEosYkSfiQv8.gQ__C28X-ACADEMY__1sbHxUB__LATEST
Best,
Ryan Ma