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.

how to calculate 2P2Z reference (IrefNetBus)

dear all,

I need to set the reference so that i get 80% duty cycle in the first phase. then i set the reference to 0 so that i get 0% duty cycle. But i do not understand how to calculate & set the reference.

i found that the output never falls completely to zero.

Can anybody tell how to calculate the reference to get proper duty cycle.

my code:

//_IQn(A)=A*(2^n)
//eg. if A=800, then IQ14(A)=(2^14)*800=16384*800=13107200
//DSP2803x_Headers_nonBIOS.cmd

//====================================================================================include file
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include <string.h>
#include <stdint.h>

#include "DSP2803x_EPwm_defines.h"
#include "DPlib.h"
#include "IQmathLib.h"
#include "Weldcntlr_Settings.h"

//=====================================
#define dead_angle_us 10

//====================================================================================variable definition

//--------------------------------------------------------------------------------------
// C address variables for use with ASM module terminals
long AdcNetBus[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // used as consecutive addresses for ADC_Rslts
long IrefNetBus1=0,IrefNetBus2=0; // used as address for Iref1
long UoutNetBus1=0,UoutNetBus2=0; // used as address for Uout1

#pragma DATA_SECTION(CNTL_2P2Z_CoefStruct1, "CNTL_2P2Z_Coef");
#pragma DATA_SECTION(CNTL_2P2Z_CoefStruct2, "CNTL_2P2Z_Coef");

struct CNTL_2P2Z_CoefStruct CNTL_2P2Z_CoefStruct1;
struct CNTL_2P2Z_CoefStruct CNTL_2P2Z_CoefStruct2;

// ADC configuration variables
int ChSel[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int TrigSel[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ACQPS[16]={6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6};

//---------------------------------------------------------------------------
// Used to indirectly access all EPWM modules
volatile struct EPWM_REGS *ePWM[] =
{ &EPwm1Regs, //intentional: (ePWM[0] not used)
&EPwm1Regs,
&EPwm2Regs,
&EPwm3Regs,
&EPwm4Regs
};

long Iset1=0,Iset2=0; // Control loop 1 target
int16 Gui_Iset1=0,Gui_Iset2=0; //Q15

// Boost channel 1 2P2Z Control loop gains
long Pgain1=50; //50
long Igain1=1; //
long Dgain1=20; //

//Scaling Constants (values found via spreadsheet; exact value calibrated per board)
int16 K_Vin=19439; // 0.593 in Q15
int16 K_Vout=20452; // 0.625 in Q15
int16 iK_Iset=24824; //24824; // 1.515 in Q14
int16 K_Iout=21627; // 0.660 in Q15

// These are defined by the linker (see F2808.cmd)
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadSize;
extern Uint16 RamfuncsRunStart;

//====================================================================================DPLIB pointer definition
extern long *ADCDRV_1ch_Rlt1;
extern long *ADCDRV_1ch_Rlt2;

extern long *CNTL_2P2Z_Ref1, *CNTL_2P2Z_Fdbk1, *CNTL_2P2Z_Out1;
extern long *CNTL_2P2Z_Coef1;

extern long *CNTL_2P2Z_Ref2, *CNTL_2P2Z_Fdbk2, *CNTL_2P2Z_Out2;
extern long *CNTL_2P2Z_Coef2;

extern long *PWMDRV_ComplPairDB_Duty1;
extern long *PWMDRV_ComplPairDB_Duty2;

// Voltage terminal pointers
extern long *ADCDRV_1ch_Rlt9;
extern long *ADCDRV_1ch_Rlt10;
extern long *ADCDRV_1ch_Rlt11;
extern long *ADCDRV_1ch_Rlt12;

//====================================================================================function definition
// ---------------------------------- USER -----------------------------------------
void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntChSel, int mode);
void PWM_ComplPairDB_CNF(int16 n, int16 period, int16 mode, int16 phase);
void PWM_ComplPairDB_UpdateDB (int16 n, int16 DbRed, int16 DbFed);


//======================================================================
void main(void)
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// DeviceInit(); // Device Life support & GPIO
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2803x_SysCtrl.c file.
InitSysCtrl();

EALLOW;
//-------------------------------------------------output
GpioCtrlRegs.GPADIR.bit.GPIO0=1;
GpioCtrlRegs.GPADIR.bit.GPIO1=1;
GpioCtrlRegs.GPADIR.bit.GPIO2=1;
GpioCtrlRegs.GPADIR.bit.GPIO3=1;

GpioCtrlRegs.GPAMUX1.bit.GPIO0=1; //ePWM selected
GpioCtrlRegs.GPAMUX1.bit.GPIO1=1; //ePWM selected
GpioCtrlRegs.GPAMUX1.bit.GPIO2=1; //ePWM selected
GpioCtrlRegs.GPAMUX1.bit.GPIO3=1; //ePWM selected

//-------------------------------------------------
EDIS;

DINT;

InitPieCtrl();

IER = 0x0000;
IFR = 0x0000;

InitPieVectTable();


memcpy((uint16_t *)&RamfuncsRunStart,(uint16_t *)&RamfuncsLoadStart, (unsigned long)&RamfuncsLoadSize);

InitFlash();


// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM


//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Step 5. User specific code,
// Only used if running from FLASH
// Note that the variable FLASH is defined by the build configuration
// #ifdef FLASH
// Copy time critical code and Flash setup code to RAM
// The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
// symbols are created by the linker. Refer to the linker files.
// memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
//InitFlash(); // Call the flash wrapper init function
// #endif //(FLASH)
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// ---------------------------------- USER -----------------------------------------
// 2 pole / 2 Zero compensator coefficients (B2, B1, B0, A2, A1) are mapped to the
// simpler 3 coefficients P, I, D to allow for trial & error intuitive tuning via
// CCS WatchWindow or GUI Sliders. Note: User can modify if needed and assign full
// set of 5 coef.

// Boost channel 1 2P2Z Coefficient init
CNTL_2P2Z_CoefStruct1.b2 = _IQ16(Dgain1);
CNTL_2P2Z_CoefStruct1.b1 = _IQ16(Igain1 - Pgain1 - Dgain1);
CNTL_2P2Z_CoefStruct1.b0 = _IQ16(Pgain1 + Igain1 + Dgain1);
CNTL_2P2Z_CoefStruct1.a2 = _IQ26(0.0);
CNTL_2P2Z_CoefStruct1.a1 = _IQ26(1.0);
CNTL_2P2Z_CoefStruct1.max = _IQ14(DMAX);
CNTL_2P2Z_CoefStruct1.min = _IQ14(DMIN);

// Boost channel 2 2P2Z Coefficient init
CNTL_2P2Z_CoefStruct2.b2 = _IQ16(Dgain1);
CNTL_2P2Z_CoefStruct2.b1 = _IQ16(Igain1 - Pgain1 - Dgain1);
CNTL_2P2Z_CoefStruct2.b0 = _IQ16(Pgain1 + Igain1 + Dgain1);
CNTL_2P2Z_CoefStruct2.a2 = _IQ26(0.0);
CNTL_2P2Z_CoefStruct2.a1 = _IQ26(1.0);
CNTL_2P2Z_CoefStruct2.max = _IQ14(DMAX);
CNTL_2P2Z_CoefStruct2.min = _IQ14(DMIN);


//==================================================================================
// INCREMENTAL BUILD OPTIONS - NOTE: select via ProjectSettings.h
//==================================================================================

// ---------------------------------- USER -----------------------------------------
#define prd 1200 // 1200 Period count = 50 KHz @ 60 MHz
//#define prd 600 // 600 Period count = 100 KHz @ 60 MHz
//#define prd 300 // 300 Period count = 200 KHz @ 60 MHz
//#define prd 200 // 200 Period count = 300 KHz @ 60 MHz
//#define prd 150 // 150 Period count = 400 KHz @ 60 MHz

#define Iout1R AdcResult.ADCRESULT1 //Q12
#define Vout1R AdcResult.ADCRESULT9 //Q12
#define Iout2R AdcResult.ADCRESULT2 //Q12
#define Vout2R AdcResult.ADCRESULT10 //Q12
#define VinR AdcResult.ADCRESULT12 //Q12

// ADC Channel Selection
ChSel[0] = 2; // Dummy read for first sample bug //ADCINA2
// ChSel[1] = 1; // A2 - Iout1 - blue //ADCINA1
ChSel[1] = 2; // A2 - Iout1 - blue //ADCINA2
ChSel[2] = 1; // A2 - Iout1 - blue //ADCINA1

// ADC Trigger Selection
TrigSel[0] = ADCTRIG_EPWM1_SOCA; // ePWM1, ADCSOCA //ADCTRIG5 – ePWM1, ADCSOCA
// TrigSel[1] = ADCTRIG_EPWM2_SOCA; // ePWM2, ADCSOCA //ADCTRIG7 – ePWM2, ADCSOCA
TrigSel[1] = ADCTRIG_EPWM1_SOCA; // ePWM1, ADCSOCA //ADCTRIG5 – ePWM1, ADCSOCA
TrigSel[2] = ADCTRIG_EPWM2_SOCA; // ePWM2, ADCSOCA //ADCTRIG7 – ePWM2, ADCSOCA

//adc2 will be triggered by EPWM1_SOCA & EPWM2_SOCA signal

// void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntChSel, int mode)
ADC_SOC_CNF(ChSel, TrigSel, ACQPS, 16, 0);

// void PWM_ComplPairDB_CNF(int16 n, int16 period, int16 mode, int16 phase)
PWM_ComplPairDB_CNF(1, prd, 1, 0);
PWM_ComplPairDB_CNF(2, prd, 0, 0);

// void PWM_ComplPairDB_UpdateDB(int16 n, int16 dbRED, int16 dbFED)
PWM_ComplPairDB_UpdateDB(1,5,4);
PWM_ComplPairDB_UpdateDB(2,5,4);

// Configure ePWMs to generate ADC SOC pulses
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable ePWM1 SOCA pulse
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_PRD; // SOCA from ePWM1 Zero event
EPwm1Regs.ETPS.bit.SOCAPRD = ET_3RD; // Trigger ePWM1 SOCA on every 3rd event

// Configure ePWMs to generate ADC SOC pulses
EPwm2Regs.ETSEL.bit.SOCAEN = 1; // Enable ePWM2 SOCA pulse
EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_PRD; // SOCA from ePWM1 Zero event
EPwm2Regs.ETPS.bit.SOCAPRD = ET_3RD; // Trigger ePWM1 SOCA on every 3rd event

DPL_Init(); // DPL ASM ISR init

//----------------------------------------------------------------------// Closed-Loop Current
// Lib Module connection to "nets"
//----------------------------------------

// Boost 1 connections
CNTL_2P2Z_Ref1 = &IrefNetBus1; // point to Iref1
ADCDRV_1ch_Rlt1 = &AdcNetBus[1];
CNTL_2P2Z_Fdbk1 = &AdcNetBus[1]; // point to Iout1
CNTL_2P2Z_Coef1 = &CNTL_2P2Z_CoefStruct1.b2; // point to first coeff of 1st loop
CNTL_2P2Z_Out1 = &UoutNetBus1; // point to 2P2Z Uout1
PWMDRV_ComplPairDB_Duty1 = &UoutNetBus1;

// Boost 2 connections
CNTL_2P2Z_Ref2 = &IrefNetBus2; // point to Iref1
ADCDRV_1ch_Rlt2 = &AdcNetBus[2];
CNTL_2P2Z_Fdbk2 = &AdcNetBus[2]; // point to Iout1
CNTL_2P2Z_Coef2 = &CNTL_2P2Z_CoefStruct2.b2; // point to first coeff of 1st loop
CNTL_2P2Z_Out2 = &UoutNetBus2; // point to 2P2Z Uout1
PWMDRV_ComplPairDB_Duty2 = &UoutNetBus2;

// Voltage connections
ADCDRV_1ch_Rlt9 = &AdcNetBus[9];
ADCDRV_1ch_Rlt10 = &AdcNetBus[10];
ADCDRV_1ch_Rlt11 = &AdcNetBus[11];
ADCDRV_1ch_Rlt12 = &AdcNetBus[12];

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//=================================================================================
// INTERRUPT & ISR INITIALISATION (best to run this section after other initialisation)
//=================================================================================
EALLOW;
PieVectTable.EPWM1_INT = &DPL_ISR; // Map Interrupt
PieVectTable.EPWM2_INT = &DPL_ISR; // Map Interrupt

PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // Enable EPWM1 int in PIE group 3
PieCtrlRegs.PIEIER3.bit.INTx2 = 1;

// Configure ISR trigger
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // INT on Period event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // Generate ISR INT on every 3rd event

// Configure ISR trigger
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // INT on Period event
EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate ISR INT on every 3rd event

// Enable Peripheral, global Ints and higher priority real-time debug events:
IER |= M_INT3; // Enable CPU INT3 connected to EPWM1-6 INTs:

EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

//configure one shot s/w force TRIP ZONE
EPwm1Regs.TZSEL.bit.OSHT1=TZ_ENABLE;
EPwm1Regs.TZCTL.bit.TZA=TZ_FORCE_LO;

EPwm2Regs.TZSEL.bit.OSHT1=TZ_ENABLE;
EPwm2Regs.TZCTL.bit.TZA=TZ_FORCE_LO;

EDIS;


//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while(1){

Gui_Iset1 =8000;
Iset1 = ((long)Gui_Iset1*(long)iK_Iset) >> 5;
Gui_Iset2 =8000;
Iset2 = ((long)Gui_Iset2*(long)iK_Iset) >> 5;
IrefNetBus1 = Iset1;
IrefNetBus2 = Iset2;

DELAY_US(2000000);

Gui_Iset1 =0;
Iset1 = ((long)Gui_Iset1*(long)iK_Iset) >> 5;
Gui_Iset2 =0;
Iset2 = ((long)Gui_Iset2*(long)iK_Iset) >> 5;
IrefNetBus1 = Iset1;
IrefNetBus2 = Iset2;

DELAY_US(2000000);

}

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}