Hello,
why we call Raw ADC result is a Q12 number(28027)?
is it just because it 12 ADC bit converter?
I am learning Qmath and can understand it, but can't get why Raw ADC result is a Q12 number?
thank you,
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.
Hello,
why we call Raw ADC result is a Q12 number(28027)?
is it just because it 12 ADC bit converter?
I am learning Qmath and can understand it, but can't get why Raw ADC result is a Q12 number?
thank you,
//----------------------------------------------------------------------------------
// FILE: HVPSFB-Main.C
//
// Description: Peak current mode control of a phase shifted full bridge
//
// Version: 1.0
//
// Target: TMS320F2802x(PiccoloA)
//
//----------------------------------------------------------------------------------
// Copyright Texas Instruments � 2004-2009
//----------------------------------------------------------------------------------
// Revision History:
//----------------------------------------------------------------------------------
// Date | Description / Status
//----------------------------------------------------------------------------------
// 18 Apr 2011 - Peak Current Mode Controlled Phase Shifted Full bridge (HN)
//----------------------------------------------------------------------------------
//
// PLEASE READ - Useful notes about this Project
// Although this project is made up of several files, the most important ones are:
// "{ProjectName}-Main.C" - this file
// - Application Initialization, Peripheral config,
// - Application management
// - Slower background code loops and Task scheduling
// "{ProjectName}-DevInit_F28xxx.C
// - Device Initialization, e.g. Clock, PLL, WD, GPIO mapping
// - Peripheral clock enables
// - DevInit file will differ per each F28xxx device series, e.g. F280x, F2833x,
// "{ProjectName}-DPL-ISR.asm
// - Assembly level library Macros and any cycle critical functions are found here
// "{ProjectName}-Settings.h"
// - Global defines (settings) project selections are found here
// - This file is referenced by both C and ASM files.
// Code is made up of sections, e.g. "FUNCTION PROTOTYPES", "VARIABLE DECLARATIONS" ,..etc
// each section has FRAMEWORK and USER areas.
// FRAMEWORK areas provide useful ready made "infrastructure" code which for the most part
// does not need modification, e.g. Task scheduling, ISR call, GUI interface support,...etc
// USER areas have functional example code which can be modified by USER to fit their appl.
//
// Code can be compiled with various build options (Incremental Builds IBx), these
// options are selected in file "{ProjectName}-Settings.h". Note: "Rebuild All" compile
// tool bar button must be used if this file is modified.
//----------------------------------------------------------------------------------
#include "HVPSFB-Settings.h"
#include "PeripheralHeaderIncludes.h"
#include "DSP2802x_EPWM_defines.h"
#include "DPlib.h"
#include "IQmathLib.h"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// FUNCTION PROTOTYPES
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void DeviceInit(void);
#ifdef FLASH
void InitFlash();
#endif
void MemCopy();
void DeviceInit(void);
void SCIA_Init();
void SerialHostComms();
void InitFlash();
interrupt void ISR_Temp(void);
//---------------------------------------------------------------
// System Defines
//---------------------------------------------------------------
#define PWM_PRD (60000/200) // Period count = 300 corresponding to 100 KHz @ 60 MHz (Up-Down count mode)
#define CP_MIN_THRESHOLD 25600 // 400W = 400*2^6
#define CP_HI_THRESHOLD 26880 // 420W = 420*2^6
#define CP_MID_THRESHOLD 26240 // 410W = 410*2^6
#define CC_MIN_THRESHOLD 4480 // 35A = 35*2^7
#define CC_HI_THRESHOLD 4864 // 38A = 38*2^7
#define CC_MID_THRESHOLD 4608 // 36A = 36*2^7
#define UV_THRESHOLD 8192 // 8V = 8*2^10
//-------------------------------- DPLIB --------------------------------------------
void PWMDRV_PSFB_PCMC_CNF(int16 n, int16 period, int16 SR_Enable, int16 Comp2_Prot);
void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntChSel, int mode);
extern void DacDrvCnf(int16 n, int16 DACval, int16 DACsrc, int16 RAMPsrc, int16 Slope_initial);
// -------------------------------- FRAMEWORK --------------------------------------
// State Machine function prototypes
//----------------------------------------------------------------------------------
// Alpha states
void A0(void); //state A0
void B0(void); //state B0
void C0(void); //state C0
// A branch states
void A1(void); //state A1
void A2(void); //state A2
void A3(void); //state A3
void A4(void); //state A4
// B branch states
void B1(void); //state B1
void B2(void); //state B2
void B3(void); //state B3
void B4(void); //state B4
// C branch states
void C1(void); //state C1
void C2(void); //state C2
void C3(void); //state C3
void C4(void); //state C4
// Variable declarations
void (*Alpha_State_Ptr)(void); // Base States pointer
void (*A_Task_Ptr)(void); // State pointer A branch
void (*B_Task_Ptr)(void); // State pointer B branch
void (*C_Task_Ptr)(void); // State pointer C branch
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// VARIABLE DECLARATIONS - GENERAL
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// -------------------------------- FRAMEWORK --------------------------------------
int16 VTimer0[4]; // Virtual Timers slaved of CPU Timer 0 (A events)
int16 VTimer1[4]; // Virtual Timers slaved of CPU Timer 1 (B events)
int16 VTimer2[4]; // Virtual Timers slaved of CPU Timer 2 (C events)
int16 SerialCommsTimer;
int16 CommsOKflg;
extern Uint16 *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
// Used for ADC Configuration
int ChSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ACQPS[16] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};
int TrigSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// ---------------------------------- USER -----------------------------------------
// ---------------------------- DPLIB Net Pointers ---------------------------------
// Declare net pointers that are used to connect the DP Lib Macros here
// ADCDRV_4ch
extern volatile long *ADCDRV_4ch_RltPtrA;
extern volatile long *ADCDRV_4ch_RltPtrB;
extern volatile long *ADCDRV_4ch_RltPtrC;
extern volatile long *ADCDRV_4ch_RltPtrD;
// ADCDRV_1ch
extern volatile long *ADCDRV_1ch_Rlt2; // Instance #1
extern volatile long *ADCDRV_1ch_Rlt3; // Instance #2
extern volatile long *ADCDRV_1ch_Rlt9; // Instance #3
extern volatile long *CNTL_2P2Z_Ref1, *CNTL_2P2Z_Out1, *CNTL_2P2Z_Fdbk1;
extern volatile long *CNTL_2P2Z_Ref2, *CNTL_2P2Z_Out2, *CNTL_2P2Z_Fdbk2;
extern volatile long *CNTL_2P2Z_Coef1, *CNTL_2P2Z_Coef2;
// DACRAMPDRV
extern volatile long *DACDRV_RAMP_In1;
// ---------------------------- DPLIB Variables ---------------------------------
// Declare the net variables being used by the DP Lib Macro here
volatile long Adc_VavgBus[5]; // Used as consecutive addresses for ADC Vout conversion results
#pragma DATA_SECTION(Adc_VavgBus, "ADCDRV_4ch_Section"); // Output terminal 1
volatile long Adc_Ifb, Adc_Vfbin, Adc_Iout;
volatile long Vref = 0; // FB Set Voltage
volatile long Iref = 0; // FB Current Loop Command
volatile long Vfb_slew_temp = 0; // Temp variable: used only if implementing
// slew rate control in the slower state machine
volatile long VfbSetSlewed = 4187136; // Slewed set point for the FB voltage loop - start from 4V
volatile long VfbSlewRate = 25600; // FB Slew rate adjustment
int16 phase, dbAtoP_leg = 20, dbPtoA_leg = 20; // FB Phase command and Dead band
// adjust for the right and left legs
int16 Slope = 40, SR_mode = 2, SR_old=2;
int16 No_2p2z = 0; // Used to disable 2P2Z execution when control loop coefficients are being changed
int16 trig_up = 74, trig_dwn = (PWM_PRD-68); // Used to trigger ISR in Up-Count and Down-Count
int16 range = 0, auto_DB = 1; // Used to adjust DB based on load conditions
int16 input_good = 0, start_flag = 0; // Used for soft-start ad shut-down
int16 SR_DB = -3; // Used to adjust SR timing if needed
int16 sub_adj = 0; // Used to compensate for offsets in Iout reading
int16 Fault_isr = 0, CC_flag = 0, CP_flag = 0; // Fault ISR counter, flags to keep track of constant current and constant power operations
int16 CP_adjust1=2, CP_adjust = 2; // Used to implement constant power algorithm
int16 UV_Shutdown = 0; // Under voltage shutdown flag
int16 CC_Enable = 0, CP_Enable = 0; // CC and CP function enable
int16 CC_Enable_safe = 0, CP_Enable_safe = 0;
volatile long Avg_Vout = 0, Avg_tmp = 0; // Used for calculating average of output voltage over one switching cycle (8x oversampling)
int16 Iout_prev = 0, Iout_diff = 0; // Used for fast dead-band adjustment for big load transients
int16 Auto_Run = 1; // Stand-alone operation
#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;
long Pgain, Igain, Dgain, Dmax;
int16 Ipri_trip = 16925; // Programmable overcurrent shut-down level via on-chip comparator and DAC
int16 Pgain_Gui = 648, Igain_Gui = 64, Dgain_Gui = 0; // PID gains for the voltage loop (Values can be controlled from CCS or GUI)
int16 b2_Gui=0, b1_Gui=-10945, b0_Gui=12412, a2_Gui=0, a1_Gui=1024, a0_Gui; // 2P2Z coefficients for the voltage loop (Values can be controlled directly from CCS or from GUI by poles and zeroes placement)
int16 pid2p2z_Gui= 1, coeff_change = 1; // Flag for switching between PID and poles and zeroes based coeffiefients, Flag to indicate change of coefficients
// System Flags
int16 FaultFlg; // Fault flag set on over current or output undervoltage conditions
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// VARIABLE DECLARATIONS - CCS WatchWindow / GUI support
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// -------------------------------- FRAMEWORK --------------------------------------
//GUI support variables
// sets a limit on the amount of external GUI controls - increase as necessary
int16 *varSetTxtList[64]; //64 textbox controlled variables
int16 *varSetBtnList[16]; //16 button controlled variables
int16 *varSetSldrList[16]; //16 slider controlled variables
int16 *varGetList[16]; //16 variables sendable to GUI
int16 *arrayGetList[16]; //16 arrays sendable to GUI
// ---------------------------------- USER -----------------------------------------
// Monitor ("Get") // Display as:
int16 Gui_Vfbin; // Q5
int16 Gui_Ifb; // Q12
int16 Gui_Vfbout; // Q10
int16 Gui_Iout; // Q7
int16 Gui_VfbSet = 1024; // Q10
int16 Gui_IfbSet = 614; // Q12 -- Build 1 Only - 0.15A
int16 Gui_Pout = 0; // Q6
//Scaling Constants (values found via spreadsheet)
int16 K_Vfbin; // Q15
int16 K_Ifb; // Q15
int16 K_Vfbout; // Q15
int16 K_Iout; // Q15
int16 iK_Ifb; // Q14
int16 iK_Vfbout; // Q14
// Variables for background support only (no need to access)
int16 i; // common use incrementer
int16 HistPtr, temp_Scratch;
int16 temp_ChNum, temp_Iout;
int16 Vset[NumChannels+1]; // Per Unit (Q15)
int16 Vmargin[NumChannels+1]; // Per Unit (Q15)
// History arrays are used for Running Average calculation (boxcar filter)
// Used for CCS display and GUI only, not part of control loop processing
int16 Hist_Vfbin[HistorySize];
int16 Hist_Ifb[HistorySize];
int16 Hist_Vfbout[HistorySize];
int16 Hist_Iout[HistorySize];
int16 Mytimer1 = 0;//harry
int16 BlueLedToggle = 0;//harry
void main(void)
{
//=================================================================================
// INITIALISATION - General
//=================================================================================
//-------------------------------- FRAMEWORK --------------------------------------
DeviceInit(); // Device Life support & GPIO
SCIA_Init(); // Initalize the Serial Comms A peripheral
// Only used if running from FLASH
#ifdef FLASH
// Copy time critical code and Flash setup code to RAM
// The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
// symbols are created by the linker. Refer to the linker files.
MemCopy((Uint16*)&RamfuncsLoadStart, (Uint16*)&RamfuncsLoadEnd, (Uint16*)&RamfuncsRunStart);
// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
InitFlash(); // Call the flash wrapper init function
#endif //(FLASH)
// Timing sync for background loops
// Timer period definitions found in PeripheralHeaderIncludes.h
CpuTimer0Regs.PRD.all = mSec2; // A tasks
CpuTimer1Regs.PRD.all = mSec5; // B tasks
CpuTimer2Regs.PRD.all = mSec0_5; // C tasks
// Tasks State-machine init
Alpha_State_Ptr = &A0;
A_Task_Ptr = &A1;
B_Task_Ptr = &B1;
C_Task_Ptr = &C1;
VTimer0[0] = 0;
VTimer1[0] = 0; VTimer1[1] = 0;
VTimer2[0] = 0;
CommsOKflg = 0;
HistPtr = 0;
// ---------------------------------- USER -----------------------------------------
//Configure Scaling Constants
K_Vfbin = 21555; // 0.6578 in Q15 (see excel spreadsheet)
K_Ifb = 27755; // 0.8470 in Q15 (see excel spreadsheet)
K_Vfbout = 16411; // 0.5008 in Q15 (see excel spreadsheet)
K_Iout = 17974; // 0.5485 in Q15 (see excel spreadsheet)
iK_Ifb = 19343; // 1.1806 in Q14 (see excel spreadsheet)
iK_Vfbout = 32714; // 1.9967 in Q14 (see excel spreadsheet)
//=================================================================================
// INITIALISATION - GUI connections
//=================================================================================
// Use this section only if you plan to "Instrument" your application using the
// Microsoft C# freeware GUI Template provided by TI
//"Set" variables
//---------------------------------------
// assign GUI variable Textboxes to desired "setable" parameter addresses
varSetTxtList[0] = &Slope; // Q0
varSetTxtList[1] = &Ipri_trip; // Q15
varSetTxtList[2] = &dbAtoP_leg; // Q15
varSetTxtList[3] = &dbPtoA_leg; // Q15
varSetTxtList[4] = &sub_adj; // Q15
varSetTxtList[5] = &b0_Gui; // I5Q10
varSetTxtList[6] = &b1_Gui; // I5Q10
varSetTxtList[7] = &b2_Gui; // I5Q10
varSetTxtList[8] = &a0_Gui; // I5Q10
varSetTxtList[9] = &a1_Gui; // I5Q10
varSetTxtList[10] = &a2_Gui; // I5Q10
varSetTxtList[11] = &coeff_change; // Q0
varSetTxtList[12] = &SR_mode; // Q0
// assign GUI Buttons to desired flag addresses
varSetBtnList[0] = &auto_DB;
varSetBtnList[1] = &pid2p2z_Gui;
varSetBtnList[2] = &CC_Enable;
varSetBtnList[3] = &CP_Enable;
varSetSldrList[0] = &Gui_VfbSet; // Q10
varSetSldrList[1] = &Pgain_Gui; // Q26/67108
varSetSldrList[2] = &Igain_Gui; // Q26/67108
varSetSldrList[3] = &Dgain_Gui; // Q26/67108
varGetList[0] = &Gui_Vfbout; // Q10
varGetList[1] = &Gui_Vfbin; // Q5
varGetList[2] = &Gui_Ifb; // Q12
varGetList[3] = &Gui_Iout; // Q9
varGetList[4] = &FaultFlg; //
varGetList[5] = &dbAtoP_leg; //
varGetList[6] = &dbPtoA_leg; //
varGetList[7] = &SR_mode; //
varGetList[8] = &Gui_Pout; //
varGetList[9] = &CC_flag; //
varGetList[10] = &CP_flag; //
varGetList[11] = &UV_Shutdown; //
//---------------------------------------------------------------------------
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Incremental build options via Module connections to system Nets.
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
//==================================================================================
// INCREMENTAL BUILD OPTIONS - NOTE: select via ProjectSettings.h
//==================================================================================
// ---------------------------------- USER -----------------------------------------
//==============================================================================
#if (INCR_BUILD == 1) // CMC check with constant I command + ADC feedback
//=============================================================
#define Vfb_outR AdcResult.ADCRESULT1 //
#define IfbR AdcResult.ADCRESULT2 //
#define Vfb_inR AdcResult.ADCRESULT3 //
#define IoutR AdcResult.ADCRESULT9 //
// Channel Selection for Cascaded Sequencer
ChSel[0] = 0; // A0 - O/P Voltage - Dummy
ChSel[1] = 0; //B // A0 - O/P Voltage
ChSel[2] = 2; // A2 - Transformer Primary Current
ChSel[3] = 9; // B1 - I/P Voltage
ChSel[4] = 0; //C // A0 - O/P Voltage
ChSel[5] = 0; // A0 - O/P Voltage - Dummy
ChSel[6] = 0; //A // A0 - O/P Voltage
ChSel[7] = 0; // A0 - O/P Voltage - Dummy
ChSel[8] = 0; //D // A0 - O/P Voltage
// ChSel[9] = 11; // B3 - Iout1
ChSel[9] = 12; // B4 - Iout2
TrigSel[0] = ADCTRIG_EPWM3_SOCA; // O/P Voltage sampling triggered by EPWM3 SOCA - Dummy
TrigSel[1] = ADCTRIG_EPWM3_SOCA; //B // O/P Voltage sampling triggered by EPWM3 SOCA
TrigSel[2] = ADCTRIG_EPWM3_SOCA; // Transformer Primary Current sampling triggered by EPWM3 SOCA
TrigSel[3] = ADCTRIG_EPWM3_SOCA; // I/P Voltage sampling triggered by EPWM3 SOCA
TrigSel[4] = ADCTRIG_EPWM3_SOCA; //C // O/P Voltage sampling triggered by EPWM3 SOCA
TrigSel[5] = ADCTRIG_EPWM1_SOCA; // O/P Voltage sampling triggered by EPWM1 SOCA at CTR = ZRO or PRD - Dummy
TrigSel[6] = ADCTRIG_EPWM1_SOCA; //A // O/P Voltage sampling triggered by EPWM1 SOCA at CTR = ZRO or PRD
TrigSel[7] = ADCTRIG_EPWM3_SOCB; // O/P Voltage sampling triggered by EPWM3 SOCB at CMPB3 - Dummy
TrigSel[8] = ADCTRIG_EPWM3_SOCB; //D // O/P Voltage sampling triggered by EPWM3 SOCB at CMPB3
TrigSel[9] = ADCTRIG_EPWM2_SOCA; // Iout triggered by EPWM2 SOCA
EALLOW;
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 9; // SOC0-8 are high priority
EDIS;
PWMDRV_PSFB_PCMC_CNF(1, PWM_PRD, 1, 1); // ePWM1 and ePWM2, Period=PWM_PRD, SR_Enable=1, Comp2_Prot=1
ADC_SOC_CNF(ChSel,TrigSel,ACQPS, 16, 0);// ACQPS=8, No ADC channel triggers an interrupt IntChSel > 15,
// Mode= Start/Stop (0)
DPL_Init(); // ASM ISR init
DacDrvCnf(1, 1280, 1, 2, Slope); // Comp1, DACval = 1280(Initial), Slope compensation is used,
// Ramp is PWM3 Synced, Initial Slope
// Lib Module connection to "nets"
//----------------------------------------
// ADC feedback connections
ADCDRV_4ch_RltPtrA = &Adc_VavgBus[1];
ADCDRV_4ch_RltPtrB = &Adc_VavgBus[2];
ADCDRV_4ch_RltPtrC = &Adc_VavgBus[3];
ADCDRV_4ch_RltPtrD = &Adc_VavgBus[4];
ADCDRV_1ch_Rlt2 = &Adc_Ifb;
ADCDRV_1ch_Rlt3 = &Adc_Vfbin;
ADCDRV_1ch_Rlt9 = &Adc_Iout;
// DAC connections
DACDRV_RAMP_In1 = &Iref; // Controls the DAC reference voltage
#endif // (INCR_BUILD == 1)
//==============================================================================
#if (INCR_BUILD == 2) // // Closed loop: CMC + Voltage loop + Slope Comp
//=============================================================
#define Vfb_outR AdcResult.ADCRESULT1 //
#define IfbR AdcResult.ADCRESULT2 //
#define Vfb_inR AdcResult.ADCRESULT3 //
#define IoutR AdcResult.ADCRESULT9 //
// Channel Selection for Cascaded Sequencer
ChSel[0] = 0; // A0 - O/P Voltage - Dummy
ChSel[1] = 0; //B // A0 - O/P Voltage
ChSel[2] = 2; // A2 - Transformer Primary Current
ChSel[3] = 9; // B1 - I/P Voltage
ChSel[4] = 0; //C // A0 - O/P Voltage
ChSel[5] = 0; // A0 - O/P Voltage - Dummy
ChSel[6] = 0; //A // A0 - O/P Voltage
ChSel[7] = 0; // A0 - O/P Voltage - Dummy
ChSel[8] = 0; //D // A0 - O/P Voltage
// ChSel[9] = 11; // B3 - Iout1
ChSel[9] = 12; // B4 - Iout2
TrigSel[0] = ADCTRIG_EPWM3_SOCA; // O/P Voltage sampling triggered by EPWM3 SOCA - Dummy
TrigSel[1] = ADCTRIG_EPWM3_SOCA; //B // O/P Voltage sampling triggered by EPWM3 SOCA
TrigSel[2] = ADCTRIG_EPWM3_SOCA; // Transformer Primary Current sampling triggered by EPWM3 SOCA
TrigSel[3] = ADCTRIG_EPWM3_SOCA; // I/P Voltage sampling triggered by EPWM3 SOCA
TrigSel[4] = ADCTRIG_EPWM3_SOCA; //C // O/P Voltage sampling triggered by EPWM3 SOCA
TrigSel[5] = ADCTRIG_EPWM1_SOCA; // O/P Voltage sampling triggered by EPWM1 SOCA triggered at CTR = ZRO or PRD - Dummy
TrigSel[6] = ADCTRIG_EPWM1_SOCA; //A // O/P Voltage sampling triggered by EPWM1 SOCA triggered at CTR = ZRO or PRD
TrigSel[7] = ADCTRIG_EPWM3_SOCB; // O/P Voltage sampling triggered by EPWM3 SOCB triggered at CMPB3 - Dummy
TrigSel[8] = ADCTRIG_EPWM3_SOCB; //D // O/P Voltage sampling triggered by EPWM3 SOCB triggered at CMPB3
TrigSel[9] = ADCTRIG_EPWM2_SOCA; // Iout triggered by EPWM2 SOCA
// ADC channel conversion priority
EALLOW;
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 9; // SOC0-8 are high priority
EDIS;
// Configure PWM1 and PWM2 with TBPRD of 300 clock cycles
PWMDRV_PSFB_PCMC_CNF(1, PWM_PRD, 1, 1); // ePWM1 and ePWM2, Period=PWM_PRD, SR_Enable=1, Comp2_Prot=1
ADC_SOC_CNF(ChSel,TrigSel,ACQPS, 16, 0);// ACQPS=8, No ADC channel triggers an interrupt IntChSel > 15, Mode= Start/Stop (0)
// Digital Power (DP) library initialisation
DPL_Init();
// Configure Comparator and DAC for peak current mode operation with internal ramp for slope compensation
DacDrvCnf(1, 1280, 1, 2, Slope); // Comp1, DACval = 1280(Initial), Slope compensation is used, Ramp is PWM3 Synced, Initial Slope
// Lib Module connection to "nets"
//----------------------------------------
// ADC feedback connections
ADCDRV_4ch_RltPtrA = &Adc_VavgBus[1];
ADCDRV_4ch_RltPtrB = &Adc_VavgBus[2];
ADCDRV_4ch_RltPtrC = &Adc_VavgBus[3];
ADCDRV_4ch_RltPtrD = &Adc_VavgBus[4];
ADCDRV_1ch_Rlt2 = &Adc_Ifb;
ADCDRV_1ch_Rlt3 = &Adc_Vfbin;
ADCDRV_1ch_Rlt9 = &Adc_Iout;
// 2P2Z connections for the outer Voltage Loop
CNTL_2P2Z_Ref1 = &VfbSetSlewed; // Slewed Voltage command
CNTL_2P2Z_Out1 = &Iref; // Reference command to the current loop
CNTL_2P2Z_Fdbk1 = &Avg_Vout; // Avg. FB O/P Voltage feedback
CNTL_2P2Z_Coef1 = &CNTL_2P2Z_CoefStruct1.b2; // point to first coeff.
// DAC connections
DACDRV_RAMP_In1 = &Iref; // Controls the DAC reference voltage
// Coefficients for Outer Voltage Loop
// PID coefficients & Clamping (Q26)
Dmax = _IQ24(0.25);
Pgain = _IQ26(0.6479916);
Igain = _IQ26(0.06399917);
Dgain = _IQ26(0.0);
// Coefficient init --- Coeeficient values in Q26
// Use IQ Maths to generate floating point values for the CLA
CNTL_2P2Z_CoefStruct1.b2 = Dgain; // B2
CNTL_2P2Z_CoefStruct1.b1 = (Igain-Pgain-Dgain-Dgain); // B1
CNTL_2P2Z_CoefStruct1.b0 = (Pgain + Igain + Dgain); // B0
CNTL_2P2Z_CoefStruct1.a2 = 0.0; // A2 = 0
CNTL_2P2Z_CoefStruct1.a1 = _IQ26(1.0); // A1 = 1
CNTL_2P2Z_CoefStruct1.max = Dmax; //Clamp Hi
CNTL_2P2Z_CoefStruct1.min = _IQ24(0.0); //Clamp Min
#endif // (INCR_BUILD == 2)
// Configure Comparator2 and DAC for over current protection
DacDrvCnf(2, Ipri_trip, 0, 2, 0); // Comp2, DACval = Ipri_trip, DAC Source is DACval, Ramp Source = don't care, Slope = don't care
FaultFlg = 0;
EPwm1Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip
EPwm2Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // 0=GPIO, 1=EPWM1A, 2=Resv, 3=Resv
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // 0=GPIO, 1=EPWM1B, 2=SPISIMO-D, 3=Resv
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // 0=GPIO, 1=EPWM2A, 2=Resv, 3=Resv
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // 0=GPIO, 1=EPWM2B, 2=SPISOMI-D, 3=Resv
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1; // 0=GPIO, 1=EPWM4A, 2=SYNCI, 3=SYNCO
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1; // 0=GPIO, 1=EPWM4B, 2=SPISTE-D, 3=ECAP2
//All enabled ePWM module clocks are started with the first rising edge of TBCLK aligned
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
//=================================================================================
// INTERRUPT & ISR INITIALISATION (best to run this section after other initialisation)
//=================================================================================
//Also Set the appropriate # define's in the {ProjectName}-Settings.h
//to enable interrupt management in the ISR
EALLOW;
PieVectTable.EPWM1_INT = &DPL_ISR; // Map Interrupt
EDIS;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // PIE level enable, Grp3 / Int1
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA; // INT on CMPA event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT every event
// Enable Peripheral, global Ints and higher priority real-time debug events:
IER |= M_INT3;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// EALLOW;
// Backgound Loop
for(;;)
{
// State machine entry & exit point
//===========================================================
(*Alpha_State_Ptr)(); // jump to an Alpha state (A0,B0,...)
//===========================================================
// Fast dead-band adjustment for large load transients
Iout_diff = IoutR - Iout_prev;
if (Iout_diff>292 || Iout_diff<(-292)) //12-bit ADC result corresponding to a change of 10A on Iout ~ 292d
C1();
Iout_prev = IoutR;
}
} //END MAIN CODE
//=================================================================================
// STATE-MACHINE SEQUENCING AND SYNCRONIZATION
//=================================================================================
//--------------------------------- FRAMEWORK -------------------------------------
void A0(void)
{
// loop rate synchronizer for A-tasks
if(CpuTimer0Regs.TCR.bit.TIF == 1)
{
CpuTimer0Regs.TCR.bit.TIF = 1; // clear flag
//-----------------------------------------------------------
(*A_Task_Ptr)(); // jump to an A Task (A1,A2,A3,...)
//-----------------------------------------------------------
if (Mytimer1 == 500)
{
Mytimer1 = 0;
BlueLedToggle = 1;
}
else Mytimer1++;
VTimer0[0]++; // virtual timer 0, instance 0 (spare)
}
Alpha_State_Ptr = &B0; // Comment out to allow only A tasks
}
void B0(void)
{
// loop rate synchronizer for B-tasks
if(CpuTimer1Regs.TCR.bit.TIF == 1)
{
CpuTimer1Regs.TCR.bit.TIF = 1; // clear flag
//-----------------------------------------------------------
(*B_Task_Ptr)(); // jump to a B Task (B1,B2,B3,...)
//-----------------------------------------------------------
VTimer1[0]++; // virtual timer 1, instance 0
VTimer1[1]++; // virtual timer 1, instance 1 (used by DSP280xx_SciCommsGui.c)
}
Alpha_State_Ptr = &C0; // Allow C state tasks
}
void C0(void)
{
// loop rate synchronizer for C-tasks
if(CpuTimer2Regs.TCR.bit.TIF == 1)
{
CpuTimer2Regs.TCR.bit.TIF = 1; // clear flag
//-----------------------------------------------------------
(*C_Task_Ptr)(); // jump to a C Task (C1,C2,C3,...)
//-----------------------------------------------------------
VTimer2[0]++; //virtual timer 2, instance 0 (spare)
}
Alpha_State_Ptr = &A0; // Back to State A0
}
//=================================================================================
// A - TASKS
//=================================================================================
//--------------------------------------------------------
void A1(void) // Control Coefficient re-calculations
//=====================================================================
{
// Fault management
if (CC_flag == 1 || CP_flag == 1)
{
if (Gui_Vfbout < UV_THRESHOLD) // If output voltage < UV threshold when operating in CC or CP mode - then Shutdown
{
EALLOW;
EPwm1Regs.TZFRC.bit.OST = 1;
EDIS;
UV_Shutdown = 1;
}
}
if ( (*ePWM[1]).TZFLG.bit.OST == 1 )
{
FaultFlg = 1;
DINT; // Disable Global interrupt
EALLOW;
PieVectTable.EPWM1_INT = &ISR_Temp; // Temporary Interrupt to service pending interrupts
EPwm1Regs.ETSEL.bit.INTEN = 0; //Disable interrupt at the peripheral level
EINT; // Enable Global interrupt INTM
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP"); // Wait 5 cycles for any pending interrupts to be serviced
DINT; // Disable Global interrupt
PieVectTable.EPWM1_INT = &DPL_ISR; // Interrupt re-mapped
// EDIS;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0; // PIE level Disable, Grp3 / Int1
PieCtrlRegs.PIEIFR3.bit.INTx1 = 0; // Clear IFR register
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
EINT; // Enable Global interrupt INTM
EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Initial Config
EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
EPwm4Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Initial Config
EPwm4Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
EPwm2Regs.TZFRC.bit.OST = 1; // Initial Config
EPwm4Regs.TZFRC.bit.OST = 1;
EDIS;
}
else FaultFlg = 0;
Pgain = Pgain_Gui*67108; // Q26
Igain = Igain_Gui*67108; // Q26
Dgain = Dgain_Gui*67108; // Q26
if (coeff_change == 1)
{
No_2p2z = 1; // Used to disable 2P2Z execution when coefficients are being changed
if (pid2p2z_Gui == 0)
{
// Voltage loop coefficient update
CNTL_2P2Z_CoefStruct1.b2 = Dgain; // B2
CNTL_2P2Z_CoefStruct1.b1 = (Igain - Pgain - Dgain - Dgain); // B1
CNTL_2P2Z_CoefStruct1.b0 = (Pgain + Igain + Dgain); // B0
CNTL_2P2Z_CoefStruct1.a2 = 0.0; // A2 = 0
CNTL_2P2Z_CoefStruct1.a1 = _IQ26(1.0); // A1 = 1
// CNTL_2P2Z_CoefStruct1.max =Dmax; //Clamp Hi
// CNTL_2P2Z_CoefStruct1.min =_IQ24(0.0); //Clamp Min
}
else
{
CNTL_2P2Z_CoefStruct1.b2 = b2_Gui*65536; // B2 - I5Q10 scaled to I5Q26
CNTL_2P2Z_CoefStruct1.b1 = b1_Gui*65536; // B1
CNTL_2P2Z_CoefStruct1.b0 = b0_Gui*65536; // B0
CNTL_2P2Z_CoefStruct1.a2 = a2_Gui*65536; // A2
CNTL_2P2Z_CoefStruct1.a1 = a1_Gui*65536; // A1
// CNTL_2P2Z_CoefStruct1.max =Dmax; //Clamp Hi
// CNTL_2P2Z_CoefStruct1.min =_IQ24(0.0); //Clamp Min
}
No_2p2z = 0;
coeff_change = 0;
}
EALLOW;
Comp2Regs.DACVAL.bit.DACVAL = ((Ipri_trip)>>5); // DAC Value is in Q10
Comp1Regs.RAMPDECVAL_SHDW = Slope;
EDIS;
//-------------------
A_Task_Ptr = &A2;
//-------------------
}
//=====================================================================
void A2(void) // Slew Rate, SCI GUI
//-----------------------------------------------------------------
{
// This is an example code for implementing the slew rate control in
// a slower state machine instead of implementing it in the ISR.
// VfbSlewRate should be set as a positive value
Vfb_slew_temp = Vref - VfbSetSlewed;
if (Vfb_slew_temp >= VfbSlewRate) // Positive Command
{
VfbSetSlewed = VfbSetSlewed + VfbSlewRate;
}
else
{
if ((-1)*(Vfb_slew_temp) >= VfbSlewRate) // Negative Command
{
VfbSetSlewed = VfbSetSlewed - VfbSlewRate;
}
}
SerialHostComms();
//-------------------
A_Task_Ptr = &A3; // To make task A3 active, change &A1 to &A3
//-------------------
}
//=======================================================================
void A3(void) // SPARE (not active)
//=======================================================================
{
if (BlueLedToggle == 1)//Mytimer1==500)
{
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
Mytimer1=0;
BlueLedToggle = 0;
}
//-----------------
A_Task_Ptr = &A1; // To make task A4 active, change &A1 to &A4
//-----------------
}
/*
//=======================================================================
void A3(void) // SPARE (not active)
//=======================================================================
{
//-----------------
A_Task_Ptr = &A1; // To make task A4 active, change &A1 to &A4
//-----------------
}
//=====================================================================
void A4(void) // SPARE (not active)
//=====================================================================
{
//-----------------
A_Task_Ptr = &A1; // After Task A4, start over with task A1
//-----------------
}*/
//%%%%%%%%%%%%%%% B-Tasks: %%%%%%%%%%%%%%%%%%%%%%%%%
//=====================================================================
void B1(void) // Voltage and Current Dashboard measurements
//=====================================================================
{
// Voltage measurement calculated by:
// Gui_Vfbin = VfbinAvg * K_Vfbin, where VfbinAvg = sum of 8 Vfb_inR samples
// Gui_Vfbout = VfboutAvg * K_Vfbout, where VfboutAvg = sum of 8 Vfb_outR samples
HistPtr++;
if (HistPtr >= 8) HistPtr = 0;
// BoxCar Averages - Input Raw samples into History arrays
//----------------------------------------------------------------
Hist_Vfbin[HistPtr] = Vfb_inR; // Raw ADC result (Q12)
temp_Scratch=0;
for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Vfbin[i]; // Q12 * 8 = Q15
Gui_Vfbin = ( (long) temp_Scratch * (long) K_Vfbin ) >> 15; // (Q15 * Q15)>>15 = Q15
// BoxCar Averages - Input Raw samples into History arrays
//----------------------------------------------------------------
Hist_Vfbout[HistPtr] = Vfb_outR; // Raw ADC result (Q12)
temp_Scratch=0;
for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Vfbout[i]; // Q12 * 8 = Q15
Gui_Vfbout = ( (long) temp_Scratch * (long) K_Vfbout ) >> 15; // (Q15 * Q15)>>15 = Q15
// Voltage Meas
//----------------------------------------------------------------
// view following variables in Watch Window as:
// Gui_Vfbin = Q5
// Gui_Vfbout = Q10
// Current measurement calculated by:
// Gui_Ifb = IfbAvg * K_Ifb, where IfbAvg = sum of 8 IfbR samples
//BoxCar Averages - Input Raw samples into History arrays
Hist_Ifb[HistPtr] = IfbR; // Raw ADC result (Q12)
temp_Scratch=0;
for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Ifb[i]; // Q12 * 8 = Q15
Gui_Ifb = ( (long) temp_Scratch * (long) K_Ifb ) >> 15; // (Q15 * Q15)>>15 = Q15
Hist_Iout[HistPtr] = IoutR; // Raw ADC result (Q12)
temp_Scratch=0;
for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Iout[i]; // Q12 * 8 = Q15
temp_Scratch = ( ((long) temp_Scratch * (long) K_Iout ) >> 15) - sub_adj; // (Q15 * Q15)>>15 = Q15 (Offset Adjust)
if (temp_Scratch < 0) temp_Scratch = 0;
Gui_Iout = temp_Scratch;
// Current Meas
//----------------------------------------------------------------
// view following variables in Watch Window as:
// Gui_Ifb = Q12
// Voltage setting calculated by:
// Vref = Gui_VfbSet * iK_Vfbout, where iK_Vfbout = 1/K_Vfbout (i.e. inverse K_Vfbout)
// view and set following variable in Watch Window as:
// Gui_VfbSet = Q10 (Used as Q15 below)
Vref = ( (long) Gui_VfbSet * (long) iK_Vfbout ) >> 5; // (Q15 * Q14) >> 5 = Q24
#if (INCR_BUILD == 1)
// Current setting calculated by:
// Iref = Gui_IfbSet * iK_Ifb, where iK_Ifb = 1/K_Ifb (i.e. inverse K_Ifb)
// view and set following variable in Watch Window as:
// Gui_IfbSet = Q12 (Used as Q15 below)
if (Gui_IfbSet < 614) // Gui_IfbSet >= 0.15A
Gui_IfbSet = 614;
Iref = ( (long) Gui_IfbSet * (long) iK_Ifb ) >> 5; // (Q15 * Q14) >> 5 = Q24
#endif
B_Task_Ptr = &B1;
//-----------------
}
/*
//=====================================================================
void B2(void) // SPARE
//=====================================================================
{
//-----------------
B_Task_Ptr = &B1;
//-----------------
}
//=====================================================================
void B3(void) // SPARE (not active)
//=====================================================================
{
//-----------------
B_Task_Ptr = &B1;
//-----------------
}
//=====================================================================
void B4(void) // SPARE (not active)
//=====================================================================
{
//-----------------
B_Task_Ptr = &B1;
//-----------------
}
*/
//%%%%%%%%%%%%%%% C-Tasks: %%%%%%%%%%%%%%%%%%%%%%%%%
//=====================================================================
//=====================================================================
void C1(void)
//=====================================================================
{
if (auto_DB == 1)
{
switch (range)
{
case 0:
if (Gui_Iout < 640) // 5A
{
/* if (dbAtoP_leg<36) dbAtoP_leg++;
else
{
if (dbAtoP_leg>36) dbAtoP_leg--;
}
if (dbPtoA_leg<44) dbPtoA_leg++;
else
{
if (dbPtoA_leg>44) dbPtoA_leg--;
}*/
dbAtoP_leg = 36;
dbPtoA_leg = 44;
range = 0;
}
else range = 1;
break;
case 1:
if (Gui_Iout > 512 && Gui_Iout < 1024) // 4A & 8A
{
/* if (dbAtoP_leg<32) dbAtoP_leg++;
else
{
if (dbAtoP_leg>32) dbAtoP_leg--;
}
if (dbPtoA_leg<42) dbPtoA_leg++;
else
{
if (dbPtoA_leg>42) dbPtoA_leg--;
}*/
dbAtoP_leg = 32;
dbPtoA_leg = 42;
range = 1;
}
else
{
if (Gui_Iout > 1023) range = 2;
else range = 0;
}
break;
case 2:
if (Gui_Iout > 896 && Gui_Iout < 1408) // 7A & 11A
{
/* if (dbAtoP_leg<27) dbAtoP_leg++;
else
{
if (dbAtoP_leg>27) dbAtoP_leg--;
}
if (dbPtoA_leg<22) dbPtoA_leg++;
else
{
if (dbPtoA_leg>22) dbPtoA_leg--;
}*/
dbAtoP_leg = 27;
dbPtoA_leg = 22;
range = 2;
}
else
{
if (Gui_Iout > 1407) range = 3;
else range = 0;
}
break;
case 3:
if (Gui_Iout > 1280 && Gui_Iout < 1792) // 10A & 14A
{
/* if (dbAtoP_leg<22) dbAtoP_leg++;
else
{
if (dbAtoP_leg>22) dbAtoP_leg--;
}
if (dbPtoA_leg<22) dbPtoA_leg++;
else
{
if (dbPtoA_leg>22) dbPtoA_leg--;
}*/
dbAtoP_leg = 22;
dbPtoA_leg = 22;
range = 3;
}
else
{
if (Gui_Iout > 1791) range = 4;
else range = 0;
}
break;
case 4:
if (Gui_Iout > 1664 && Gui_Iout < 2176) // 13A & 17A
{
/* if (dbAtoP_leg<20) dbAtoP_leg++;
else
{
if (dbAtoP_leg>20) dbAtoP_leg--;
}
if (dbPtoA_leg<21) dbPtoA_leg++;
else
{
if (dbPtoA_leg>21) dbPtoA_leg--;
}*/
dbAtoP_leg = 20;
dbPtoA_leg = 21;
range = 4;
}
else
{
if (Gui_Iout > 2175) range = 5;
else range = 0;
}
break;
case 5:
if (Gui_Iout > 2048 && Gui_Iout < 2560) // 16A & 20A
{
/* if (dbAtoP_leg<20) dbAtoP_leg++;
else
{
if (dbAtoP_leg>20) dbAtoP_leg--;
}
if (dbPtoA_leg<18) dbPtoA_leg++;
else
{
if (dbPtoA_leg>18) dbPtoA_leg--;
}*/
dbAtoP_leg = 20;
dbPtoA_leg = 18;
range = 5;
}
else
{
if (Gui_Iout > 2559) range = 6;
else range = 0;
}
break;
case 6:
if (Gui_Iout > 2432 && Gui_Iout < 2944) // 19A & 23A
{
/* if (dbAtoP_leg<18) dbAtoP_leg++;
else
{
if (dbAtoP_leg>18) dbAtoP_leg--;
}
if (dbPtoA_leg<18) dbPtoA_leg++;
else
{
if (dbPtoA_leg>18) dbPtoA_leg--;
}*/
dbAtoP_leg = 18;
dbPtoA_leg = 18;
range = 6;
}
else
{
if (Gui_Iout > 2943) range = 7;
else range = 0;
}
break;
case 7:
if (Gui_Iout > 2816 && Gui_Iout < 3328) // 22A & 26A
{
/* if (dbAtoP_leg<18) dbAtoP_leg++;
else
{
if (dbAtoP_leg>18) dbAtoP_leg--;
}
if (dbPtoA_leg<14) dbPtoA_leg++;
else
{
if (dbPtoA_leg>14) dbPtoA_leg--;
}*/
dbAtoP_leg = 18;
dbPtoA_leg = 14;
range = 7;
}
else
{
if (Gui_Iout > 3327) range = 8;
else range = 0;
}
break;
case 8:
if (Gui_Iout > 3200 && Gui_Iout < 4096) // 25A & 32A
{
/* if (dbAtoP_leg<16) dbAtoP_leg++;
else
{
if (dbAtoP_leg>16) dbAtoP_leg--;
}
if (dbPtoA_leg<14) dbPtoA_leg++;
else
{
if (dbPtoA_leg>14) dbPtoA_leg--;
}*/
dbAtoP_leg = 16;
dbPtoA_leg = 14;
range = 8;
}
else
{
if (Gui_Iout > 4095) range = 9;
else range = 0;
}
break;
case 9:
if (Gui_Iout > 3968 && Gui_Iout < 4864) // 31A & 38A
{
/* if (dbAtoP_leg<15) dbAtoP_leg++;
else
{
if (dbAtoP_leg>15) dbAtoP_leg--;
}
if (dbPtoA_leg<13) dbPtoA_leg++;
else
{
if (dbPtoA_leg>13) dbPtoA_leg--;
}*/
dbAtoP_leg = 15;
dbPtoA_leg = 13;
range = 9;
}
else
{
if (Gui_Iout > 4863) range = 10;
else range = 0;
}
break;
case 10:
if (Gui_Iout > 4736 && Gui_Iout < 5632) // 37A & 44A
{
/* if (dbAtoP_leg<14) dbAtoP_leg++;
else
{
if (dbAtoP_leg>14) dbAtoP_leg--;
}
if (dbPtoA_leg<12) dbPtoA_leg++;
else
{
if (dbPtoA_leg>12) dbPtoA_leg--;
}*/
dbAtoP_leg = 14;
dbPtoA_leg = 12;
range = 10;
}
else
{
if (Gui_Iout > 5631) range = 11;
else range = 0;
}
break;
case 11:
if (Gui_Iout > 5504) // 43A
{
/* if (dbAtoP_leg<12) dbAtoP_leg++;
else
{
if (dbAtoP_leg>12) dbAtoP_leg--;
}
if (dbPtoA_leg<12) dbPtoA_leg++;
else
{
if (dbPtoA_leg>12) dbPtoA_leg--;
}*/
dbAtoP_leg = 12;
dbPtoA_leg = 12;
range = 11;
}
else range = 0;
break;
}
}
EPwm1Regs.DBRED = dbPtoA_leg;
EPwm1Regs.DBFED = dbPtoA_leg;
if(Auto_Run == 1)
//-----------------
C_Task_Ptr = &C2;
//-----------------
else
//-----------------
C_Task_Ptr = &C1;
//-----------------
}
//=====================================================================
void C2(void) // SPARE (not active)
//=====================================================================
{
if (Gui_Vfbin > 11200 && Gui_Vfbin < 13440) // 350<Vfbin<420
{
if (input_good >= 100) // Input has been good for 100*(C2 task execution rate)
{
if (start_flag == 0)
{
VfbSetSlewed = 2093568; // Start ramping up from 2V (Q24)
Gui_VfbSet = 12.2*1024; // Desired Output * 2^10
start_flag = 1;
}
}
else
{
input_good++;
if (input_good == 80)
{
EPwm1Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip
EPwm2Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip
EPwm4Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip
}
}
}
else
{
input_good = 0;
Gui_VfbSet = 2*1024; //2V
Dmax = _IQ24(0.25);
CNTL_2P2Z_CoefStruct1.max = Dmax;
start_flag = 0;
}
Gui_Pout = ((long)(Gui_Iout) * (long)(Gui_Vfbout))>>11; // Q7*Q10>>11. Gui_Pout in Q6
if (start_flag == 1)
{
if (Gui_Iout > CC_MIN_THRESHOLD && CC_Enable == 1)
{
if (Gui_Iout > CC_HI_THRESHOLD) // Too high - needs faster response
{
Dmax = (Dmax<=_IQ24(0.1))?_IQ24(0.1):(Dmax - _IQ24(0.0003)); //Clamp Dmax to a minimum of 0.1
CNTL_2P2Z_CoefStruct1.max = Dmax;
}
else
{
if (Gui_Iout > CC_MID_THRESHOLD)
{
Dmax = (Dmax<=_IQ24(0.1))?_IQ24(0.1):(Dmax - _IQ24(0.0001)); //Clamp Dmax to a minimum of 0.1
CNTL_2P2Z_CoefStruct1.max = Dmax;
}
}
CC_flag = 1;
CP_flag = 0;
}
else
{
if (Dmax < _IQ24(0.734375))
{
Dmax = Dmax + _IQ24(0.01);
CNTL_2P2Z_CoefStruct1.max = Dmax;
}
else
{
Dmax = _IQ24(0.734375);
CNTL_2P2Z_CoefStruct1.max = Dmax;
}
CC_flag = 0;
}
if (CP_Enable == 1)
{
if (Gui_Pout > CP_MIN_THRESHOLD)
{
if (Gui_Pout > CP_HI_THRESHOLD)
Gui_VfbSet = (Gui_VfbSet>8192)?(Gui_VfbSet - CP_adjust*4):8192; // Reduce Vout command at a faster rate. Clamped to 8192 i.e. 8V
else
{
if (Gui_Pout > CP_MID_THRESHOLD)
Gui_VfbSet = (Gui_VfbSet>8192)?(Gui_VfbSet - CP_adjust):8192; // Reduce Vout command. Clamped to 8192 i.e. 8V
}
CP_flag = (CC_flag==1)?0:1;
}
else
{
if (CC_flag == 0)
Gui_VfbSet = (Gui_VfbSet<12492)?(Gui_VfbSet + CP_adjust1):12492; // Increase Vout command slowly. Clamp Max to 12.2V
CP_flag = 0;
}
}
else
{
Gui_VfbSet = 12.2*1024;
CP_flag = 0;
}
}
else // start_flag = 0. FB is disabled, re-intialise Dmax to a low value
{
Dmax = _IQ24(0.25);
CNTL_2P2Z_CoefStruct1.max = Dmax;
}
//-----------------
C_Task_Ptr = &C1;
//-----------------
}
/*
//=====================================================================
void C2(void) // SPARE (not active)
//=====================================================================
{
//-----------------
C_Task_Ptr = &C1;
//-----------------
}*/
interrupt void ISR_Temp(void)
{
Fault_isr++;
asm(" IRET"); // Return from interrupt
}
it is in B1 task of the Main.c in HVPSFB kit, whichi is attached to this post. I also pasted the related and highlited below: Thank you,
void B1(void) // Voltage and Current Dashboard measurements
//===================================================================== { // Voltage measurement calculated by: // Gui_Vfbin = VfbinAvg * K_Vfbin, where VfbinAvg = sum of 8 Vfb_inR samples // Gui_Vfbout = VfboutAvg * K_Vfbout, where VfboutAvg = sum of 8 Vfb_outR samples HistPtr++; if (HistPtr >= 8) HistPtr = 0;
// BoxCar Averages - Input Raw samples into History arrays //---------------------------------------------------------------- Hist_Vfbin[HistPtr] = Vfb_inR; // Raw ADC result (Q12)
temp_Scratch=0; for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Vfbin[i]; // Q12 * 8 = Q15
Gui_Vfbin = ( ( long) temp_Scratch * (long) K_Vfbin ) >> 15; // (Q15 * Q15)>>15 = Q15
// BoxCar Averages - Input Raw samples into History arrays //---------------------------------------------------------------- Hist_Vfbout[HistPtr] = Vfb_outR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Vfbout[i]; // Q12 * 8 = Q15
Gui_Vfbout = ( ( long) temp_Scratch * (long) K_Vfbout ) >> 15; // (Q15 * Q15)>>15 = Q15
// Voltage Meas //---------------------------------------------------------------- // view following variables in Watch Window as: // Gui_Vfbin = Q5 // Gui_Vfbout = Q10 // Current measurement calculated by: // Gui_Ifb = IfbAvg * K_Ifb, where IfbAvg = sum of 8 IfbR samples //BoxCar Averages - Input Raw samples into History arrays Hist_Ifb[HistPtr] = IfbR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Ifb[i]; // Q12 * 8 = Q15
Gui_Ifb = ( ( long) temp_Scratch * (long) K_Ifb ) >> 15; // (Q15 * Q15)>>15 = Q15
Hist_Iout[HistPtr] = IoutR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i<HistorySize; i++) temp_Scratch = temp_Scratch + Hist_Iout[i]; // Q12 * 8 = Q15
temp_Scratch = ( (( long) temp_Scratch * (long) K_Iout ) >> 15) - sub_adj; // (Q15 * Q15)>>15 = Q15 (Offset Adjust)
if (temp_Scratch < 0) temp_Scratch = 0;
Gui_Iout = temp_Scratch; // Current Meas //---------------------------------------------------------------- // view following variables in Watch Window as: // Gui_Ifb = Q12 // Voltage setting calculated by: // Vref = Gui_VfbSet * iK_Vfbout, where iK_Vfbout = 1/K_Vfbout (i.e. inverse K_Vfbout) // view and set following variable in Watch Window as: // Gui_VfbSet = Q10 (Used as Q15 below) Vref = ( ( long) Gui_VfbSet * (long) iK_Vfbout ) >> 5; // (Q15 * Q14) >> 5 = Q24
#if (INCR_BUILD == 1)
// Current setting calculated by: // Iref = Gui_IfbSet * iK_Ifb, where iK_Ifb = 1/K_Ifb (i.e. inverse K_Ifb) // view and set following variable in Watch Window as: // Gui_IfbSet = Q12 (Used as Q15 below) if (Gui_IfbSet < 614) // Gui_IfbSet >= 0.15A
Gui_IfbSet = 614; Iref = ( ( long) Gui_IfbSet * (long) iK_Ifb ) >> 5; // (Q15 * Q14) >> 5 = Q24
#endif
B_Task_Ptr = &B1; //----------------- }
If I interpret this correctly, by calling the ADC result "Q12" it treats the conversion result essentially as a percentage of the ADC full scale range. Instead of thinking of the ADC conversion as in the range of 0 to 4095, you can think of it as in the range 0 to 1. This does not require any conversion of the result, just treating the result differently.
Let me know if that helps.
thanks a lot.
after reading your explanation, I kind of understand it.
thank you,