大家好、下午好、
我有一个有关 TI 太阳能微型逆变器开发套件的超级问题。 我的嵌入式编程技能扩展到一个大学课程、实现非常基本的功能。 我 不是100%确定如何执行第6.1.3.1节第5和6号、内容如下:5.运行偏移校准例程以计算 PV 电流和电网的 ADC 输入通道上的模拟偏移。 6.为控制循环使用的50KHz ISR 配置中断,为后台任务配置1KHz ISR。 选择1KHz ISR 时、50Hz ISR 可中断1KHz ISR。
是否有一个演示或一个如何解释我需要对给定代码执行的确切操作? 我使用过 MPLAB IDE、但从未使用过 Code Composer。 我担心、通过添加或更改代码、如果文件实际编译和编译、我可能会损坏电路板或其中一个组件。 非常感谢您的帮助。 下面是.c 文件和开发套件用户指南的链接。
//----------------------------------------------------------------------------------
// FILE: SolarMicroInv_F2803x-Main.C
//
// Description: Solar MicroInverter Project
//
// Version: 1.0
//
// Target: TMS320F2803x(PiccoloB),
//
//----------------------------------------------------------------------------------
// Copyright Texas Instruments
2004-2013
//----------------------------------------------------------------------------------
// Revision History:
//----------------------------------------------------------------------------------
// Date | Description / Status
//----------------------------------------------------------------------------------
// June 26 2013 : (Manish Bhardwaj, Shamim Choudhury)
//----------------------------------------------------------------------------------
//
// 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}-Settings.h"
// - Global defines (settings) project selections are found here
// - This file is referenced by both C and ASM files.
// "{ProjectName}-Includes.h"
// - Include file used by project are defined in this file
//
// 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 "SolarMicroInv-Includes.h"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// FUNCTION PROTOTYPES
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Add prototypes of functions being used in the project here
void DeviceInit(void);
#ifdef FLASH
void InitFlash();
#endif
void MemCopy();
#ifdef FLASH
#pragma CODE_SECTION(Inv_ISR,"ramfuncs");
#pragma CODE_SECTION(OneKhzISR,"ramfuncs");
#endif
//This is the control loop ISR run at 50Khz
interrupt void Inv_ISR(void);
//This is 1 Khz ISR slaved off CPU timer 2,
interrupt void OneKhzISR();
void InitECapture();
void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntChSel, int mode);
void PWM_1ch_UpDwnCnt_CNF(int16 n, Uint16 period, int16 mode, int16 phase);
void PWM_MicroInvLineClamp_CNF(int n,int period,int deadband_rising,int deadband_falling);
// -------------------------------- FRAMEWORK --------------------------------------
// State Machine function prototypes
//----------------------------------------------------------------------------------
// Alpha states
void A0(void); //state A0
void B0(void); //state B0
// 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
// 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
//----------------------------------------------------------------------------------
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// VARIABLE DECLARATIONS - GENERAL
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// -------------------------------- FRAMEWORK --------------------------------------
int16 VTimer0[4]; // Virtual Timers slaved off CPU Timer 0
int16 VTimer1[4]; // Virtual Timers slaved off CPU Timer 1
// Used for running BackGround in flash, and ISR in RAM
extern Uint32 *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
extern Uint32 *IQfuncsLoadStart, *IQfuncsLoadEnd, *IQfuncsRunStart;
// Used for ADC Configuration
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] = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
//---------------------------------------------------------------------------
// Used to indirectly access all EPWM modules
volatile struct EPWM_REGS *ePWM[] = {
&EPwm1Regs, //intentional: (ePWM[0] not used)
&EPwm1Regs, &EPwm2Regs, &EPwm3Regs, &EPwm4Regs, &EPwm5Regs, &EPwm6Regs,
&EPwm7Regs, };
// Used to indirectly access all Comparator modules
volatile struct COMP_REGS *Comp[] = { &Comp1Regs,//intentional: (Comp[0] not used)
&Comp1Regs, &Comp2Regs, &Comp3Regs };
// ---------------------------------- USER -----------------------------------------
//-----------------------------Inverter & DC-DC Control Loop Variables -------------
// String to describe the state of the PV Inverter
char cPV_State[40];
// Solar Library Objects
// RAMP to generate forced angle when grid is not present
RAMPGEN_IQ rgen1;
// CNTL 3p3z for inverter current control
#pragma DATA_SECTION(cntl3p3z_InvI_vars,"cntl_var_RAM")
#pragma DATA_SECTION(cntl3p3z_InvI_coeff,"cntl_coeff_RAM")
CNTL_3P3Z_IQ_VARS cntl3p3z_InvI_vars;
CNTL_3P3Z_IQ_COEFFS cntl3p3z_InvI_coeff;
// CNTL 2p2z for flyback current control
#pragma DATA_SECTION(cntl2p2z_DCDCI_vars,"cntl_var_RAM")
#pragma DATA_SECTION(cntl2p2z_DCDCI_coeff,"cntl_coeff_RAM")
CNTL_2P2Z_IQ_VARS cntl2p2z_DCDCI_vars;
CNTL_2P2Z_IQ_COEFFS cntl2p2z_DCDCI_coeff;
// CNTL PI for bus control
CNTL_PI_IQ cntlPI_BusInv;
int16 UpdateCoef;
long Pgain_BusInv, Dgain_BusInv, Igain_BusInv, Dmax_BusInv;
// SPLL Objects of two types for grid angle lock
SPLL_1ph_IQ spll1;
SPLL_1ph_SOGI_IQ spll2;
float c2, c1;
long Phase_Jump, Phase_Jump_Trig;
// Sine analyzer block for RMS Volt, Curr and Power measurements
SINEANALYZER_DIFF_wPWR_IQ sine_mains;
// notch filter objects for filtering bus voltage, pv current and voltage sense signals
#pragma DATA_SECTION(Bus_Volt_notch,"cntl_var_RAM")
#pragma DATA_SECTION(PV_volt_notch,"cntl_var_RAM")
#pragma DATA_SECTION(PV_cur_notch,"cntl_var_RAM")
#pragma DATA_SECTION( notch_TwiceGridFreq,"cntl_coeff_RAM")
NOTCH_COEFF_IQ notch_TwiceGridFreq;
NOTCH_VARS_IQ Bus_Volt_notch,PV_volt_notch,PV_cur_notch;
// MPPT object for flyback current reference selection
MPPT_INCC_I_IQ mppt_incc_I1;
int16 MPPT_slew;
int16 Run_MPPT;
int16 MPPT_ENABLE;
// Datalogger to plot variables
#if INCR_BUILD==1 || INCR_BUILD==2
DLOG_4CH_IQ dlog1;
int16 DBUFF1[100], DBUFF2[100], DBUFF3[100], DBUFF4[100];
int16 D_val1, D_val2, D_val3, D_val4;
#endif
//TODO
// Inverter and Flyback Variables
_iq24 inv_meas_cur_inst, inv_meas_vol_inst, vbus_meas_inst, vbus_meas_avg ;
// reference variable Inverter
_iq24 InvModIndex, inv_Iset, inv_ref_cur_inst, inv_bus_ref;
// Measure Values DC-DC Stage
long pv_meas_cur_inst,pv_meas_vol_inst,pv_meas_cur_avg, pv_meas_vol_avg;
// Reference Values DC-DC Stage
long pv_ref_cur_inst, pv_ref_cur_mppt, pv_ref_cur_fixed;
// Measurement Offsets
_iq24 offset_165, offset_GridCurrent, PV_SenseVolt_Offset, PV_SenseCurr_Offset,DC_Bus_Offset;
//Offset filter coefficient K1: 0.05/(T+0.05);
_iq K1 = _IQ(0.998);
//Offset filter coefficient K2: T/(T+0.05)
_iq K2 = _IQ(0.001999);
int16 OffsetCalCounter;
// Duty variables for flyback and inverter (per unit and compare register values)
_iq24 duty_flyback_pu, duty_inv_pu;
long duty_inv, duty_flyback;
// Duty for which the inverter is not switched around zero
int16 DontSwitchZeroLimit;
// Flags for clearing trips and closing the loops and the Relay
int16 CloseIloopInv, ClearInvTrip,CloseFlybackLoop, ClearFlyBackTrip, RlyConnect;
// Flags for detecting ZCD
_iq24 InvSine, InvSine_prev;
int16 ZCDDetect;
// State Machine Variable
enum PVInverterStates {
Idle = 0,
CheckGrid = 1,
CheckPV = 2,
MonitorDCBus = 3,
EnableMPPT = 4,
PVInverterActive = 5,
ResetState1 = 6,
ResetState2 = 7,
FaultState=8
};
enum PVInverterStates PVInverterState = Idle;
enum PVInverterStates PVInverterState_Old= Idle;
int16 SlewState4;
int32 SlewClrInvTrip;
// Value that is emperically tested to make sure the relay connect happens at ZCD
// This accounts for any delay in the relay connection from the time the GPIO is triggered high
long RlyConnectVal;
// DC Bus voltage values where the state machine is triggered to connect relay,
// start the invetrter and flag faults
volatile long inv_bus_rly_connect, inv_bus_start_volt, inv_bus_UV, inv_bus_OV;
//detecting faults
enum Faults {
NoFault = 0,
OverVoltageDCBus = 1,
UnderVoltageDCBus = 2,
OverVoltageGrid = 3,
UnderVoltageGrid = 4,
OverCurrentFlag = 5
};
enum Faults FaultFlag = NoFault;
int16 BusOverVoltageTrip, BusUnderVoltageTrip,OverCurrent;
Uint16 Gui_InvStart;
Uint16 Gui_InvStop;
// Measuring AC signal
long ACFreq_SysTicks;
volatile float AC_Freq;
volatile _iq24 ACFreq;
_iq24 ACFreq2;
volatile int UF_Flag, OF_Flag, UV_Flag, OV_Flag;
volatile long GRID_MAX_VRMS, GRID_MIN_VRMS;
volatile long GRID_MIN_FREQ, GRID_MAX_FREQ;
int Grid_Freq = GRID_FREQ;
long ECAP_TimerMaxVal;
volatile long inv_emavg_vol;
// Stand Alone Flash Image Instrumentation
// GPIO toggles for different states
int16 LedBlinkCnt1, LedBlinkCnt2;
int16 timer1;
// Display Values
// Monitor ("Get") // Display as:
int32 Gui_Vbus; //Q20
int32 Gui_Vpv; //Q20
int32 Gui_Ipv; //Q20
int32 Gui_GridFreq; //Q20
int32 Gui_Prms; //Q6
int32 Gui_Irms; //Q12
long Gui_Vrms; //Q6
int32 Gui_Vavg;
int Gui_MPPTEnable;
long IRMS, VRMS, PRMS;
long K_Irms, K_Vrms, K_Prms, K_Vpv, K_Ipv;
// The following declarations are required in order to use the SFO
// library functions:
int MEP_ScaleFactor; // Global variable used by the SFO library
// Result can be used for all HRPWM channels
// This variable is also copied to HRMSTEP
// register by SFO() function.
int status;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// MAIN CODE - starts here
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void main(void) {
//=================================================================================
// INITIALISATION - General
//=================================================================================
// The DeviceInit() configures the clocks and pin mux registers
// The function is declared in {ProjectName}-DevInit_F2803/2x.c,
// Please ensure/edit that all the desired components pin muxes
// are configured properly that clocks for the peripherals used
// are enabled, for example the individual PWM clock must be enabled
// along with the Time Base Clock
DeviceInit(); // Device Life support & GPIO
//-------------------------------- FRAMEWORK --------------------------------------
// Only used if running from FLASH
// Note that the variable FLASH is defined by the compiler with -d 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(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
MemCopy(&IQfuncsLoadStart, &IQfuncsLoadEnd, &IQfuncsRunStart);
// 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 = mSec5; // A tasks
CpuTimer1Regs.PRD.all = mSec50; // B tasks
// Configure CPU-Timer 2 to interrupt every second:
// 60MHz CPU Freq, Period (in uSeconds)
// Configure CPU Timer interrupt for 1KHz interrupt
ConfigCpuTimer(&CpuTimer2, 60, 1000);
CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
// Tasks State-machine init
Alpha_State_Ptr = &A0;
A_Task_Ptr = &A1;
B_Task_Ptr = &B1;
VTimer0[0] = 0;
VTimer1[0] = 0;
LedBlinkCnt1 = 5;
LedBlinkCnt2 = 5;
//==================================================================================
// INCREMENTAL BUILD OPTIONS - NOTE: selected via {ProjectName-Settings.h
//==================================================================================
// ---------------------------------- USER -----------------------------------------
//TODO PWM Configuration
/************* PWM Configuration **************************/
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable clocks for EPWM
// 50Khz at 60Mhz device = > 60*1000/50 =1200,
PWM_MicroInvLineClamp_CNF(1, (CPU_FREQ/(INV_FREQ)), INV_DEADBAND,
INV_DEADBAND);
// Put DC-DC PWM configuration here
PWM_1ch_UpDwnCnt_CNF(3, (CPU_FREQ / (FLYBACK_FREQ)), 0,
(CPU_FREQ / (FLYBACK_FREQ * 2)) - 2);
// PWM 4 configured only to verify the blanking pulse for over current trips
// PWM_1ch_UpDwnCnt_CNF(4, (CPU_FREQ / (FLYBACK_FREQ)), 0,
// (CPU_FREQ / (FLYBACK_FREQ * 2)) - 2);
//
// EPwm4Regs.TBPHS.half.TBPHS=EPwm4Regs.TBPHS.half.TBPHS-2;
//
// EPwm4Regs.AQCTLA.bit.CAD=AQ_SET;
// EPwm4Regs.AQCTLA.bit.CBU=AQ_CLEAR;
// EPwm4Regs.AQCTLA.bit.CAU=AQ_NO_ACTION;
//
// EPwm4Regs.CMPA.half.CMPA=0;
// EPwm4Regs.CMPB=0;
// Add the dead band configuration for PWM3
EALLOW;
EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; /* Rising Delay on 1A & Falling Delay on 1B*/
EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; /* Active high complementary mode (EPWMxA is inverted)*/
EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL; /* 1A for Rising& Falling*/
EPwm3Regs.DBRED = FLYBACK_DEADBAND_RED; /* Delay at Rising edge*/
EPwm3Regs.DBFED = FLYBACK_DEADBAND_FED; /* Delay at Falling edge*/
EDIS;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK
// Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
// MEP_ScaleFactor/HRMSTEP must be filled with calibrated value in order // for the module to work
status = SFO_INCOMPLETE;
while (status == SFO_INCOMPLETE) { // Call until complete
status = SFO();
}
if (status != SFO_ERROR) { // IF SFO() is complete with no errors
EALLOW;
EPwm1Regs.HRMSTEP = MEP_ScaleFactor;
EDIS;
}
if (status == SFO_ERROR) {
while (1)
; // SFO function returns 2 if an error occurs
// The code would loop here for infinity if it // returns an error
}
/************ PWM Configuration END **********************/
/****************** ADC Configuration *******************/
//TODO ADC Configuration
#define IPV_FB AdcResult.ADCRESULT1
#define VPV_FB AdcResult.ADCRESULT2
#define VBUS_FB AdcResult.ADCRESULT3
#define IINV_FB AdcResult.ADCRESULT5
#define VAC_FB AdcResult.ADCRESULT6
#define VREF165_FB AdcResult.ADCRESULT7
#define V0_5_REF AdcResult.ADCRESULT8
//Map channel to ADC Pin
// the dummy reads are to account for first sample issue in Rev 0 silicon
// Please refer to the Errata and the datasheet, this would be fixed in later versions of the silicon
// EPWM 3 SOC Signals
ChSel[0] = 6; // Dummy read for first
ChSel[1] = 6; // A6 - IPV, A2 - IP1 Sen - CT
ChSel[2] = 11; // B3 - VPV
//ChSel[3] = 14; // B6 - VBOOST in Rev 1 PCB
ChSel[3] = 4; // A4 - VBOOST in Rev 2 PCB
// EPWM 1 SOC Signals
ChSel[4] = 1; // A1 - IGRID
ChSel[5] = 1; // A1 - IGRID
ChSel[6] = 9; // B1 - VGRID
ChSel[7] = 7; // A7 - Ref_1.65V
ChSel[8] = 5; // A5 - Ref_0.5V
ChSel[9] = 8; // B0 - LEM Current Reference Output
//ChSel[10] = 0; // A0 - PLC
// Select Trigger Event
TrigSel[0] = ADCTRIG_EPWM3_SOCA;
TrigSel[1] = ADCTRIG_EPWM3_SOCA;
TrigSel[2] = ADCTRIG_EPWM3_SOCA;
TrigSel[3] = ADCTRIG_EPWM2_SOCA;
TrigSel[4] = ADCTRIG_EPWM2_SOCA;
TrigSel[5] = ADCTRIG_EPWM2_SOCA;
TrigSel[6] = ADCTRIG_EPWM2_SOCA;
TrigSel[7] = ADCTRIG_EPWM2_SOCA;
TrigSel[8] = ADCTRIG_EPWM2_SOCA;
//TrigSel[9]= ADCTRIG_EPWM2_SOCA;
//TrigSel[10]= ADCTRIG_EPWM2_SOCA;
// use auto clr ADC int flag mode=2
// end of conversion of inverter current triggers ADC INT 1
ADC_SOC_CNF(ChSel, TrigSel, ACQPS, 5, 2);
// Configure the PWM to issue appropriate Start of Conversion for the ADC
// DC-DC Flyback
EPwm3Regs.ETSEL.bit.SOCAEN = 1; /* Enable SOC on A group*/
EPwm3Regs.ETSEL.bit.SOCASEL = ET_CTRD_CMPB; /* Select SOC from counter at ctr = 0*/
EPwm3Regs.ETPS.bit.SOCAPRD = ET_1ST; /* Generate pulse on 1st even*/
EPwm3Regs.ETSEL.bit.SOCAEN = 1; /* Enable SOC on A group*/
EPwm3Regs.CMPB = 12;
// DC-AC Inverter
// Note: SOCA is configured by the PWM CNF macro
// but we ovewirte it to make the adc sampling centered
EPwm2Regs.ETSEL.bit.SOCAEN = 1;
EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTRD_CMPB;
EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;
EPwm2Regs.ETSEL.bit.SOCAEN = 1;
EPwm2Regs.CMPB = 70; // EPWM 2 is phase shifter by 50 i.e. when EPWM1 Ctr is zero then EPWM2 Ctr is 52
// The we take 8 cycles to sample + 6 cycles to covert the first dummy
// and add half the ADC sample width =? 52+8+6+4
/************ ADC Configuration END **********************/
/************ ECAP Init **********************************/
InitECapture();
/************ ECAP Init END ******************************/
/************ Control Variable Initialization ************/
//TODO Solar Library Module Initialization
// Initialize the net variables
//RAMPGEN
RAMPGEN_IQ_init(&rgen1);
rgen1.Freq = _IQ24(GRID_FREQ);
rgen1.StepAngleMax = _IQ24(1.0/INV_FREQ);
//CNTL3P3Z Inverter Current Loop
CNTL_3P3Z_IQ_VARS_init(&cntl3p3z_InvI_vars);
CNTL_3P3Z_IQ_COEFFS_init(&cntl3p3z_InvI_coeff);
cntl3p3z_InvI_coeff.Coeff_A1 = _IQ24(1.584);
cntl3p3z_InvI_coeff.Coeff_A2 = _IQ24(-0.6978);
cntl3p3z_InvI_coeff.Coeff_A3 = _IQ24(0.1137);
cntl3p3z_InvI_coeff.Coeff_B0 = _IQ24(0.2866);
cntl3p3z_InvI_coeff.Coeff_B1 = _IQ24(-0.3173);
cntl3p3z_InvI_coeff.Coeff_B2 = _IQ24(0.3338);
cntl3p3z_InvI_coeff.Coeff_B3 = _IQ24(-0.2616);
cntl3p3z_InvI_coeff.Max = _IQ24(0.95);
cntl3p3z_InvI_coeff.Min = _IQ24(-0.95);
//CNTL2P2Z Flyback DCDC Current Loop
CNTL_2P2Z_IQ_VARS_init(&cntl2p2z_DCDCI_vars);
CNTL_2P2Z_IQ_COEFFS_init(&cntl2p2z_DCDCI_coeff);
cntl2p2z_DCDCI_coeff.Coeff_A1 = _IQ24(1.0); // A1 = 1
cntl2p2z_DCDCI_coeff.Coeff_A2 = 0.0; // A2 = 0
cntl2p2z_DCDCI_coeff.Coeff_B0 = _IQ24(0.0917); // B0
cntl2p2z_DCDCI_coeff.Coeff_B1 = _IQ24(-0.07138); // B1
cntl2p2z_DCDCI_coeff.Coeff_B2 = _IQ24(0.0); // B2
cntl2p2z_DCDCI_coeff.Max = _IQ24(0.8);
cntl2p2z_DCDCI_coeff.Min = _IQ24(0.0);
cntl2p2z_DCDCI_coeff.IMin = _IQ24(-0.05);
//CNTL PI Inverter Bus Voltage Regulation Loop
Dmax_BusInv = _IQ24(0.80);
Pgain_BusInv = _IQ24(1.0);
Igain_BusInv = _IQ24(0.001);
CNTL_PI_IQ_init(&cntlPI_BusInv);
cntlPI_BusInv.Kp = Pgain_BusInv;
cntlPI_BusInv.Ki = Igain_BusInv;
cntlPI_BusInv.Umax = Dmax_BusInv;
cntlPI_BusInv.Umin = _IQ(0.025);
// MPPT
MPPT_INCC_I_IQ_init(&mppt_incc_I1);
mppt_incc_I1.IpvH = _IQ24(0.000);
mppt_incc_I1.IpvL = _IQ24(0.000);
mppt_incc_I1.VpvH = _IQ24(0.000);
mppt_incc_I1.VpvL = _IQ24(0.000);
mppt_incc_I1.MaxI = _IQ24(0.5);
mppt_incc_I1.MinI = _IQ24(0.0);
mppt_incc_I1.Stepsize = _IQ24(0.005);
mppt_incc_I1.mppt_first = 1;
mppt_incc_I1.mppt_enable = 1;
mppt_incc_I1.StepFirst = _IQ24(0.01);
// SPLL 1ph Notch Filter Method intialization
SPLL_1ph_IQ_init(GRID_FREQ, _IQ21((float)(1.0/ISR_FREQUENCY)), &spll1);
spll1.lpf_coeff.B0_lf = _IQ21(B0_LPF);
spll1.lpf_coeff.B1_lf = _IQ21(B1_LPF);
spll1.lpf_coeff.A1_lf = _IQ21(A1_LPF);
c1 = 0.1;
c2 = 0.00001;
SPLL_1ph_IQ_notch_coeff_update(((float) (1.0 / ISR_FREQUENCY)),
(float) (2 * PI * GRID_FREQ * 2), (float) c2, (float) c1, &spll1);
//SPLL 1ph SOGI Method initialization
SPLL_1ph_SOGI_IQ_init(GRID_FREQ, _IQ23((float)(1.0/ISR_FREQUENCY)), &spll2);
spll2.lpf_coeff.B0_lf = _IQ23(B0_LPF);
spll2.lpf_coeff.B1_lf = _IQ23(B1_LPF);
spll2.lpf_coeff.A1_lf = _IQ23(A1_LPF);
SPLL_1ph_SOGI_IQ_coeff_update(((float) (1.0 / ISR_FREQUENCY)),
(float) (2 * PI * GRID_FREQ), &spll2);
// NOTCH COEFF update for measurement filtering
NOTCH_FLTR_IQ_VARS_init(&Bus_Volt_notch);
NOTCH_FLTR_IQ_VARS_init(&PV_volt_notch);
NOTCH_FLTR_IQ_VARS_init(&PV_cur_notch);
NOTCH_FLTR_IQ_COEFF_Update(((float)(1.0/ISR_FREQUENCY)), (float)(2*PI*GRID_FREQ*2),(float)c2,(float)c1, ¬ch_TwiceGridFreq);
//sine analyzer initialization
SINEANALYZER_DIFF_wPWR_IQ_init(&sine_mains);
sine_mains.Vin = 0;
sine_mains.Iin = 0;
sine_mains.SampleFreq = _IQ15(1000.0);
sine_mains.Threshold = _IQ15(0.1);
sine_mains.nsamplesMax=1000/UNIVERSAL_GRID_MIN_FREQ;
sine_mains.nsamplesMin=1000/UNIVERSAL_GRID_MAX_FREQ;
// Initialize DATALOG module
#if INCR_BUILD==1 || INCR_BUILD==2
dlog1.input_ptr1 = &D_val1;
dlog1.input_ptr2 = &D_val2;
dlog1.input_ptr3 = &D_val3; // spll.Out logged in buff3
dlog1.input_ptr4 = &D_val4; // ramp_sin logged in buff4
dlog1.output_ptr1 = DBUFF1;
dlog1.output_ptr2 = DBUFF2;
dlog1.output_ptr3 = DBUFF3;
dlog1.output_ptr4 = DBUFF4;
dlog1.prev_value = 0;
dlog1.trig_value = _IQ15(0.1);
dlog1.status = 0;
dlog1.pre_scalar = 10;
dlog1.skip_count = 0;
dlog1.size = 100;
dlog1.count = 0;
#endif
//Variable initialization
// inverter measurement
inv_meas_cur_inst=0;
inv_meas_vol_inst=0;
vbus_meas_inst=0;
vbus_meas_avg=0;
// reference variable Inverter
InvModIndex=0;
inv_Iset=0;
inv_ref_cur_inst=0;
inv_bus_ref = DC_BUS_REF_60HZ;
// Measure Values DC-DC Stage
pv_meas_cur_inst=0;
pv_meas_vol_inst=0;
pv_meas_cur_avg=0;
pv_meas_vol_avg=0;
// Reference Values DC-DC Stage
pv_ref_cur_inst=0;
pv_ref_cur_mppt=0;
pv_ref_cur_fixed = _IQ24(0.15);
// Measurement Offsets
offset_GridCurrent = OFFSET_GRIDCURRENT_MEAS;
PV_SenseVolt_Offset = OFFSET_PV_SENSEVOLT_MEAS;
PV_SenseCurr_Offset = OFFSET_PV_SENSECURR_MEAS;
DC_Bus_Offset=OFFSET_DC_BUS_MEAS;
offset_165=0;
// Duty variables for flyback and inverter (per unit and compare register values)
duty_flyback_pu=0;
duty_inv_pu=0;;
duty_inv=0;
duty_flyback=0;
// Duty for which the inverter is not switched around zero
DontSwitchZeroLimit = 15;
// Flags for clearing trips and closing the loops and the Relay
CloseIloopInv=0;
ClearInvTrip=0;
CloseFlybackLoop=0;
ClearFlyBackTrip=0;
RlyConnect=0;
// Flags for detecting ZCD
InvSine=0;
InvSine_prev=0;
ZCDDetect=0;
PVInverterState = Idle;
PVInverterState_Old= Idle;
SlewState4=0;
SlewClrInvTrip=0;
// Value that is emperically tested to make sure the relay connect happens at ZCD
// This accounts for any delay in the relay connection from the time the GPIO is triggered high
RlyConnectVal = _IQ24(0.55);
// DC Bus voltage values where the state machine is triggered to connect relay,
// start the invetrter and flag faults
inv_bus_rly_connect = DC_BUS_RELAY_CONNECT_VOLT_60HZ;
inv_bus_start_volt = DC_BUS_INV_START_VOLT_60HZ;
inv_bus_UV = DC_BUS_UNDERVOLTAGE_LIMIT_60HZ;
inv_bus_OV = DC_BUS_OVERVOLTAGE_LIMIT_60HZ;
FaultFlag = NoFault;
BusOverVoltageTrip = 0;
BusUnderVoltageTrip = 0;
OverCurrent=0;
Gui_InvStart=0;
Gui_InvStop=0;
// Measuring AC signal
ACFreq_SysTicks=0;
AC_Freq=0;
ACFreq=0;
ACFreq2=0;
UF_Flag=0;
OF_Flag=0;
UV_Flag=0;
OV_Flag=0;
GRID_MIN_FREQ = UNIVERSAL_GRID_MIN_FREQ;
GRID_MAX_FREQ = UNIVERSAL_GRID_MAX_FREQ;
GRID_MIN_VRMS = UNIVERSAL_GRID_MIN_VRMS;
GRID_MAX_VRMS = UNIVERSAL_GRID_MAX_VRMS;
Grid_Freq = GRID_FREQ;
ECAP_TimerMaxVal = (CPU_FREQ / CAP_MIN_FREQ_MEAS) >> 1; // Where 40 is the lowest frequency measured by ECAP module
inv_emavg_vol=0;
// Gui Variables
Gui_Vbus=0;
Gui_Vpv=0;
Gui_Ipv=0;
Gui_GridFreq=0; //Q20
Gui_Prms=0; //Q6
Gui_Irms=0; //Q12
Gui_Vrms=0; //Q6
Gui_MPPTEnable=1;
Gui_Vavg=0;
K_Vrms = 26803; //K_Vrms=(418/511)*32767 = 26803, //RMS voltage is viewed as a Q6 number
K_Irms = 28671; //K_Irms=(7/8)*32767 = 28671, //Current is viewed as a Q12 number
K_Prms = 187624;//K_Prms=(7*418/511)*32767 = 187624, //Power is viewed as a Q6 number
K_Vpv = 17732; //K_Vpv=(138/255)*32767= 17732, // Panel Voltage is viewed as Q8
K_Ipv = 30719;//K_Ipv=(15/16)*32767=30719 // Panel Current is viewed in Q11 number
UpdateCoef = 0;
MPPT_ENABLE = 0;
Run_MPPT = 0;
MPPT_slew = 0;
strcpy(cPV_State,"Idle");
/************ Control Variable Initialization END *********/
/********* Protection Mechanisms *****************/
//TODO Protection Code
EALLOW;
// Cycle by cycle interrupt for CPU halt trip
EPwm1Regs.TZSEL.bit.CBC6 = 0x1;
EPwm2Regs.TZSEL.bit.CBC6 = 0x1;
EPwm3Regs.TZSEL.bit.CBC6 = 0x1;
// Adding one shot trip for over-current protection on the inverter TZ2
EPwm1Regs.TZSEL.bit.OSHT2 = 0x1;
EPwm2Regs.TZSEL.bit.OSHT2 = 0x1;
// Adding one shot trip for over current of the flyback stage but avoid the <1% duty condition using blanking
// First enable the COMP3
Comp3Regs.COMPCTL.bit.COMPDACEN =0x1;
Comp3Regs.COMPCTL.bit.SYNCSEL =0x0; // asynchronous version of the COMP signal is passed to the EPWM/GPIO module
Comp3Regs.COMPCTL.bit.CMPINV =0x0; // Output of the comparator is passed directly
Comp3Regs.COMPCTL.bit.COMPSOURCE =0x0; // inverting input of the comparator is connected to the internal DAC
Comp3Regs.DACVAL.bit.DACVAL =700; // set DAC input to peak trip point ~10 Amps, full scale is 15Amps
AdcRegs.COMPHYSTCTL.bit.COMP1_HYST_DISABLE = 0x1;
//Select COMP3 as one shot trip
EPwm3Regs.DCTRIPSEL.bit.DCAHCOMPSEL=DC_COMP3OUT ;
EPwm3Regs.TZDCSEL.bit.DCAEVT1=TZ_DCAH_HI;
EPwm3Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT_FLT ;
EPwm3Regs.DCACTL.bit.EVT1FRCSYNCSEL=DC_EVT_ASYNC;
EPwm3Regs.TZSEL.bit.DCAEVT1=0x1;
//Add blanking to avoid conditions where the over current trip generates <1% duty cycle
EPwm3Regs.DCFCTL.bit.BLANKE=DC_BLANK_ENABLE; // Blanking window is enabled
EPwm3Regs.DCFCTL.bit.BLANKINV=DC_BLANK_NOTINV; // Blanking window is not inverted
EPwm3Regs.DCFCTL.bit.SRCSEL=DC_SRC_DCAEVT1; //DCAEVT1
EPwm3Regs.DCFCTL.bit.PULSESEL=DC_PULSESEL_PRD; // apply offset from TBCTR=TBPRD
EPwm3Regs.DCFOFFSET=59;
EPwm3Regs.DCFWINDOW=255;
// What do we want the OST/CBC events to do?
// TZA events can force EPWMxA
// TZB events can force EPWMxB
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
//clear any spurious trips
EPwm1Regs.TZCLR.bit.OST = 1;
EPwm2Regs.TZCLR.bit.OST = 1;
EPwm3Regs.TZCLR.bit.OST = 1;
// Force a trip event on all the PWM modules for safety
EPwm1Regs.TZFRC.bit.OST = 0x1;
EPwm2Regs.TZFRC.bit.OST = 0x1;
EPwm3Regs.TZFRC.bit.OST = 0x1;
EDIS;
/********* Protection Mechanism END *****************/
/********* Run Calibration for offset in grid and panel current ******/
//TODO Run Calibration Task
OffsetCalCounter=0;
offset_GridCurrent=0;
PV_SenseCurr_Offset=0;
while(OffsetCalCounter<5000)
{
if(AdcRegs.ADCINTFLG.bit.ADCINT1==1)
{
PV_SenseCurr_Offset= _IQmpy(K1,PV_SenseCurr_Offset)+_IQmpy(K2,_IQ12toIQ(IPV_FB));
offset_GridCurrent=_IQmpy(K1,offset_GridCurrent)+_IQmpy(K2,_IQ12toIQ(IINV_FB));
OffsetCalCounter++;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Clear ADCINT1 flag
}
}
/********* INTERRUPTS & ISR INITIALIZATION ***********/
// (best to run this section after other initialization)
// Set up C28x Interrupt
EALLOW;
PieVectTable.ADCINT1 = &Inv_ISR; // Inverter Control Interrupt
PieVectTable.TINT2 = &OneKhzISR; // 1kHz interrupt from CPU timer 2
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable ADCINT1 in PIE group 1
//ADC interrupt already enabled by ADC SOC Cnf
IER |= M_INT1; // Enable CPU INT1 for ADCINT1,ADCINT2,ADCINT9,TripZone
IER |= M_INT14; // CPU timer 2 is connected to CPU INT 14
EINT;
// Enable Global interrupt INTM
ERTM;
// Enable Global realtime interrupt DBGM
EDIS;
/************** BACKGROUND ********************/
//--------------------------------- FRAMEWORK -------------------------------------
for (;;) //infinite loop
{
// State machine entry & exit point
//===========================================================
(*Alpha_State_Ptr)(); // jump to an Alpha state (A0,B0,...)
//===========================================================
}
} //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,...)
//-----------------------------------------------------------
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 (spare)
}
Alpha_State_Ptr = &A0; // Allow C state tasks
}
//=================================================================================
// A - TASKS
//=================================================================================
//--------------------------------------------------------
void A1(void)
//--------------------------------------------------------
{
if(PVInverterState_Old!=PVInverterState)
{
switch(PVInverterState)
{
case Idle: strcpy(cPV_State,"Idle");
break;
case CheckGrid: strcpy(cPV_State,"CheckGrid");
break;
case CheckPV: strcpy(cPV_State,"CheckPV");
break;
case MonitorDCBus: strcpy(cPV_State,"MonitorDCBus");
break;
case EnableMPPT: strcpy(cPV_State,"EnableMPPT");
break;
case PVInverterActive: strcpy(cPV_State,"PVInverterActive");
break;
case ResetState1: strcpy(cPV_State,"ResetState1");
break;
case ResetState2: strcpy(cPV_State,"ResetState2");
break;
case FaultState:if(FaultFlag==OverVoltageDCBus)
strcpy(cPV_State,"FaultState: DC Bus Over Voltage");
else if (FaultFlag==UnderVoltageDCBus)
strcpy(cPV_State,"FaultState: DC Bus Under Voltage");
else if (FaultFlag==OverVoltageGrid)
strcpy(cPV_State,"FaultState: Over Voltage Grid");
else if (FaultFlag==UnderVoltageGrid)
strcpy(cPV_State,"FaultState: Under Voltage Grid");
else if (FaultFlag==OverCurrentFlag)
strcpy(cPV_State,"FaultState: Grid Current Over");
else
strcpy(cPV_State,"FaultState");
break;
}
}
PVInverterState_Old=PVInverterState;
if(PVInverterState==Idle)
Gui_GridFreq=ACFreq<<16;
else
Gui_GridFreq=(long)(spll2.fo)>>3;
//-------------------
//the next time CpuTimer0 'counter' reaches Period value go to A2
A_Task_Ptr = &A2;
//-------------------
}
//--------------------------------------------------------
void A2(void) // Connect Disconnect
//-----------------------------------------------------------------
{
#if(INCR_BUILD==1)||(INCR_BUILD==2)
if(RlyConnect==1)
{
GpioDataRegs.GPASET.bit.GPIO22=1;
}
else
{
GpioDataRegs.GPACLEAR.bit.GPIO22=1;
}
#endif
//-------------------
//the next time CpuTimer0 'counter' reaches Period value go to A1
A_Task_Ptr = &A3;
//-------------------
}
//--------------------------------------------------------
void A3(void)
//-----------------------------------------
{
//-----------------
//the next time CpuTimer0 'counter' reaches Period value go to A1
A_Task_Ptr = &A4;
//-----------------
}
//--------------------------------------------------------
void A4(void) // Spare
//--------------------------------------------------------
{
//-----------------
//the next time CpuTimer0 'counter' reaches Period value go to A1
A_Task_Ptr = &A1;
//-----------------
}
//=================================================================================
// B - TASKS
//=================================================================================
//----------------------------------------
void B1(void)
//----------------------------------------
{
if (UpdateCoef == 1) {
UpdateCoef = 0;
//SPLL_1ph_IQ_notch_coeff_update(((float)(1.0/ISR_FREQUENCY)), (float)(2*PI*GRID_FREQ*2),c2,c1, &spll1);
}
//-----------------
//the next time CpuTimer1 'counter' reaches Period value go to B2
B_Task_Ptr = &B2;
//-----------------
}
//----------------------------------------
void B2(void) // Blink LED on the control CArd
//----------------------------------------
{
// Toggle LD3 on control card to show execution of code
if (LedBlinkCnt1 == 0) {
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;//turn on/off LD3 on the controlCARD
LedBlinkCnt1 = 4;
} else
LedBlinkCnt1--;
//-----------------
//the next time CpuTimer1 'counter' reaches Period value go to B3
B_Task_Ptr = &B3;
//-----------------
}
//----------------------------------------
void B3(void) // State Machine, Enable Disable Loops, User Controls
//----------------------------------------
{
#if ((INCR_BUILD == 1))
if (ClearInvTrip==1)
{
EALLOW;
EPwm1Regs.TZCLR.bit.OST=0x1;
EPwm2Regs.TZCLR.bit.OST=0x1;
EDIS;
ClearInvTrip=0;
}
#endif
#if ((INCR_BUILD==1)||(INCR_BUILD==2))
if (ClearFlyBackTrip==1)
{
EALLOW;
EPwm3Regs.TZCLR.bit.OST=0x1;
EDIS;
ClearFlyBackTrip=0;
}
#endif
//-----------------
//the next time CpuTimer1 'counter' reaches Period value go to B4
B_Task_Ptr = &B1;
//-----------------
}
// ISR for inverter
interrupt void Inv_ISR() {
/*************************************************/
/************ Inverter Code *********************/
/*************************************************/
//-------------------------------------------------------------------
// Inverter Current and Voltage Measurements
//-------------------------------------------------------------------
// TODO Inverter ISR
offset_165 = ((int32) VREF165_FB) << 12;
vbus_meas_inst = (((long)VBUS_FB<<12)-DC_Bus_Offset);
inv_meas_vol_inst = ((long) (((long) VAC_FB << 12) - offset_165)) << 1;
inv_meas_cur_inst = (((int32) IINV_FB << 12) - offset_GridCurrent) << 1;
//-----------------------------------------------------------------------------------------
#if (INCR_BUILD == 1 ) // Open Loop Check
//-----------------------------------------------------------------------------------------
// Run the ramp ctl to generate the forced sine angle for open loop test of the inverter
RAMPGEN_IQ_MACRO(rgen1);
if(Phase_Jump==1)
{
rgen1.Angle+=_IQ24(0.25);
if(rgen1.Angle>_IQ24(1.0))
rgen1.Angle=rgen1.Angle-_IQ24(1.0);
rgen1.Out=rgen1.Angle;
Phase_Jump=0;
if(Phase_Jump_Trig==0)
Phase_Jump_Trig=_IQ24(1.0);
else
Phase_Jump_Trig=0;
}
// Use the angle value to compute the sine value
InvSine = _IQsinPU(rgen1.Out);
//NOTCH PLL
/*spll1.AC_input=(long)InvSine>>3; // Q24 to Q21
SPLL_1ph_IQ_MACRO(spll1);*/
//SOGI PLL
spll2.u[0]=(long)InvSine>>1;
SPLL_1ph_SOGI_IQ_MACRO(spll2);
// inverter duty value
duty_inv_pu=_IQ24mpy(InvSine,InvModIndex);
#endif // (INCR_BUILD == 1)
//-----------------------------------------------------------------------------------------
#if (INCR_BUILD == 2) //Closed Current Loop Inverter with forced/internal sine angle
//-----------------------------------------------------------------------------------------
#if (GRID_CONNECT==1)
// Run the SPLL and compute the inverter sine value
spll2.u[0]=(long)inv_meas_vol_inst>>1;// shift from Q24 to Q23
SPLL_1ph_SOGI_IQ_MACRO(spll2);
InvSine=spll2.sin<<1;// shift from Q23 to Q24
#else
// Run the ramp ctl to generate the forced sine angle for open loop test of the inverter
RAMPGEN_IQ_MACRO(rgen1);
// Use the angle value to compute the sine value
InvSine = _IQsinPU(rgen1.Out);
#endif
if((InvSine_prev<=_IQ24(0.00))&&(InvSine>_IQ24(0.00)))
ZCDDetect=1;
else
ZCDDetect=0;
if (ClearInvTrip==1 && ZCDDetect==1)
{
EALLOW;
EPwm1Regs.TZCLR.bit.OST=0x1;
EPwm2Regs.TZCLR.bit.OST=0x1;
EDIS;
ClearInvTrip=0;
CloseIloopInv=1;
}
inv_ref_cur_inst = _IQ24mpy(inv_Iset, InvSine);
if(CloseIloopInv==1)
{
cntl3p3z_InvI_vars.Ref=inv_ref_cur_inst;
cntl3p3z_InvI_vars.Fdbk=inv_meas_cur_inst;
CNTL_3P3Z_IQ_ASM(&cntl3p3z_InvI_coeff,&cntl3p3z_InvI_vars);
duty_inv_pu=_IQ24div((cntl3p3z_InvI_vars.Out+inv_meas_vol_inst),vbus_meas_inst);
duty_inv_pu= (duty_inv_pu>_IQ24(1.0))?_IQ24(1.0):duty_inv_pu;
duty_inv_pu= (duty_inv_pu<_IQ24(-1.0))?_IQ24(-1.0):duty_inv_pu;
}
else
{
duty_inv_pu=0;
}
#endif
//-----------------------------------------------------------------------------------------
#if (INCR_BUILD == 3 ) //Grid Connected Test
//-----------------------------------------------------------------------------------------
#if (GRID_CONNECT==1)
// Run the SPLL and compute the inverter sine value
spll2.u[0]=(long)inv_meas_vol_inst>>1;// shift from Q24 to Q23
SPLL_1ph_SOGI_IQ_MACRO(spll2);
InvSine=spll2.sin<<1;// shift from Q23 to Q24
#else
// Run the ramp ctl to generate the forced sine angle for open loop test of the inverter
RAMPGEN_IQ_MACRO(rgen1);
// Use the angle value to compute the sine value
InvSine = _IQsinPU(rgen1.Out);
#endif
if((InvSine_prev<=_IQ24(0.00))&&(InvSine>_IQ24(0.00)))
{
ZCDDetect=1;
if(MPPT_slew==0)
{
if(MPPT_ENABLE==1)
{
Run_MPPT=1;
}
MPPT_slew=10;
}
else
MPPT_slew--;
}
else
{
ZCDDetect=0;
}
if((InvSine_prev<=RlyConnectVal)&&(InvSine>RlyConnectVal))
{
if(RlyConnect==1)
{
RlyConnect=0;
GpioDataRegs.GPASET.bit.GPIO22=1;
}
}
InvSine_prev=InvSine;
if ( ClearInvTrip==1 && ZCDDetect==1 )
{
EALLOW;
EPwm1Regs.TZCLR.bit.OST=0x1;
EPwm2Regs.TZCLR.bit.OST=0x1;
EDIS;
ClearInvTrip=0;
CloseIloopInv=1;
}
if(CloseIloopInv==1)
{
cntlPI_BusInv.Ref =Bus_Volt_notch.Out;
cntlPI_BusInv.Fbk =inv_bus_ref;
CNTL_PI_IQ_MACRO(cntlPI_BusInv)
inv_Iset=cntlPI_BusInv.Out;
inv_ref_cur_inst = _IQ24mpy(inv_Iset, InvSine);
cntl3p3z_InvI_vars.Ref=inv_ref_cur_inst;
cntl3p3z_InvI_vars.Fdbk=inv_meas_cur_inst;
CNTL_3P3Z_IQ_ASM(&cntl3p3z_InvI_coeff,&cntl3p3z_InvI_vars);
duty_inv_pu=_IQ24div((cntl3p3z_InvI_vars.Out+inv_meas_vol_inst),vbus_meas_inst);
duty_inv_pu= (duty_inv_pu>_IQ24(1.0))?_IQ24(1.0):duty_inv_pu;
duty_inv_pu= (duty_inv_pu<_IQ24(-1.0))?_IQ24(-1.0):duty_inv_pu;
}
#endif // (INCR_BUILD == 3)
//--------------------------------------------------------------------------------
// PWM Driver for the inverter
//--------------------------------------------------------------------------------
duty_inv = _IQ24mpy((long)(INV_PWM_PERIOD),_IQ24abs(duty_inv_pu));
if (duty_inv < DontSwitchZeroLimit) {
if (duty_inv_pu > 0) {
EPwm1Regs.CMPA.half.CMPA = 0;
EPwm1Regs.CMPB = 0;
EPwm2Regs.CMPA.half.CMPA = INV_PWM_PERIOD;
} else {
EPwm1Regs.CMPB = 0;
EPwm1Regs.CMPA.half.CMPA = 0;
EPwm2Regs.CMPA.half.CMPA = 0;
}
} else {
if (duty_inv_pu > 0) {
EPwm1Regs.CMPA.half.CMPA = duty_inv;
EPwm1Regs.CMPB = 0;
EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPRD;
} else {
EPwm1Regs.CMPA.half.CMPA = 0;
EPwm1Regs.CMPB = duty_inv;
EPwm2Regs.CMPA.half.CMPA = 0;
}
}
/*************************************************/
/************ fly back Code **********************/
/*************************************************/
//TODO Fly Back ISR
//-------------------------------------------------------------------
// PV Current and Voltage
//-------------------------------------------------------------------
pv_meas_cur_inst = _IQsat((((long)IPV_FB<<12)- PV_SenseCurr_Offset),_IQ24(1.0),_IQ24(0.0));
//pv_meas_cur_inst=_IQsat((((long)IPV_FB<<12)- ((long)V0_5_REF<<12)),_IQ24(1.0),_IQ24(0.0)); // use this when using CT
pv_meas_vol_inst = _IQsat((((long)VPV_FB<<12)-PV_SenseVolt_Offset),_IQ24(1.0),_IQ24(0.0));
pv_meas_cur_inst=(pv_meas_cur_inst>0)?pv_meas_cur_inst:0;
//-----------------------------------------------------------------------------------------
#if (INCR_BUILD == 1 ) // Open Loop Check
//-----------------------------------------------------------------------------------------
// flyback duty value
#endif // (INCR_BUILD == 1)
//-----------------------------------------------------------------------------------------
#if (INCR_BUILD == 2) //Closed Current Loop Flyback
//-----------------------------------------------------------------------------------------
cntl2p2z_DCDCI_vars.Ref=pv_ref_cur_inst;
cntl2p2z_DCDCI_vars.Fdbk=pv_meas_cur_inst;
CNTL_2P2Z_IQ_ASM(&cntl2p2z_DCDCI_coeff,&cntl2p2z_DCDCI_vars);
duty_flyback_pu=cntl2p2z_DCDCI_vars.Out;
#endif // (INCR_BUILD == 2)
//-----------------------------------------------------------------------------------------
#if (INCR_BUILD == 3) //Closed Current Loop Fly back
//-----------------------------------------------------------------------------------------
if(CloseFlybackLoop==1)
{
cntl2p2z_DCDCI_vars.Ref=pv_ref_cur_inst; //cntl2p2z_DCDCV_vars.Out;
cntl2p2z_DCDCI_vars.Fdbk=pv_meas_cur_inst;
CNTL_2P2Z_IQ_ASM(&cntl2p2z_DCDCI_coeff,&cntl2p2z_DCDCI_vars);
// fly back duty value
duty_flyback_pu=cntl2p2z_DCDCI_vars.Out;
}
#endif // (INCR_BUILD == 2)
//--------------------------------------------------------------------------------
// PWM Driver for fly back DC-DC
//--------------------------------------------------------------------------------
duty_flyback =(_IQ22mpy((int32)(FLYBACK_PWM_PERIOD)<<22,(int32)duty_flyback_pu>>2))>> 6;
if (duty_flyback > _IQ16(25))
EPwm3Regs.CMPA.all = duty_flyback;
else
EPwm3Regs.CMPA.all = 0;
//--------------------------------------------------------------------------------
// Moving Average for MPPT and Notch Filters
//--------------------------------------------------------------------------------
Bus_Volt_notch.In=vbus_meas_inst;
NOTCH_FLTR_IQ_ASM(&Bus_Volt_notch,¬ch_TwiceGridFreq);
PV_volt_notch.In=pv_meas_vol_inst;
NOTCH_FLTR_IQ_ASM(&PV_volt_notch,¬ch_TwiceGridFreq);
PV_cur_notch.In=pv_meas_cur_inst;
NOTCH_FLTR_IQ_ASM(&PV_cur_notch,¬ch_TwiceGridFreq);
MATH_EMAVG2_IQ_MACRO(Bus_Volt_notch.Out, vbus_meas_avg, _IQ(0.0005));
MATH_EMAVG2_IQ_MACRO(PV_cur_notch.Out, pv_meas_cur_avg, _IQ(0.0005));
pv_meas_cur_avg=(pv_meas_cur_avg>0)?pv_meas_cur_avg:0;
MATH_EMAVG2_IQ_MACRO(PV_volt_notch.Out, pv_meas_vol_avg, _IQ(0.0005));
pv_meas_vol_avg=(pv_meas_vol_avg>0)?pv_meas_vol_avg:0;
// ------------------------------------------------------------------------------
// Connect inputs of the Datalogger module
// ------------------------------------------------------------------------------
#if INCR_BUILD==1
// First two DBUFF check SPLL operations
D_val1 = (int16)_IQtoIQ15(InvSine);
D_val2 = (int16)_IQtoIQ15(spll2.sin<<1);
// Next two check Vac and Iac measurement
D_val3 = (int16)_IQtoIQ15(inv_meas_cur_inst);
D_val4 = (int16)_IQtoIQ15(inv_meas_vol_inst);
DLOG_4CH_IQ_MACRO(dlog1);
#endif
#if INCR_BUILD==2
#if GRID_CONNECT==1
D_val1 = (int16)_IQtoIQ15(inv_meas_vol_inst);
D_val2 = (int16)_IQtoIQ15(InvSine);
#else
D_val1 = (int16)_IQtoIQ15(InvSine);
D_val2 = (int16)_IQtoIQ15(inv_meas_vol_inst);
#endif
D_val3 = (int16)_IQtoIQ15(inv_meas_cur_inst);
D_val4 = (int16)_IQtoIQ15(inv_ref_cur_inst);
DLOG_4CH_IQ_MACRO(dlog1);
#endif
//-------------------------------------------------------------------
// Acknowledge interrupt
//-------------------------------------------------------------------
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Must acknowledge the PIE group
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Clear ADCINT1 flag
//-------------------------------------------------------------------
return;
}
// One KHz ISR
interrupt void OneKhzISR() {
// Let the inv_ISR interrupt this routine
EINT;
//TODO State Machine
#if (INCR_BUILD == 3)
// Inverter State ==0 , Idle state, wait for the inverter start command
// Inverter State ==1 , Check if grid is present
// Inverter State ==2 , Check if sufficient panel voltage is available
// Inverter State ==3 , Check if dc bus is enough to feed power into the grid
// Inverter State ==4 , wait for stop command, Check if dc bus goes into under volatage condition
// Inverter State ==5 , if stop, trip all PWM's, shut down MPPT and return to state 0, reset all values
switch(PVInverterState)
{
case Idle:
// Wait for the command to start the inverter
if(Gui_InvStart==1)
{
PVInverterState=CheckGrid;
Gui_InvStart=0;
}
break;
case CheckGrid:
// once the inverter command is issued check if the grid is present
// once identified re -initailize the VRMS and FREQ limit for that grid range
// also modify the PLL coefficients for the grid frequency
#if(GRID_CONNECT==1)
if(OV_Flag==0&&UV_Flag==0&&UF_Flag==0&&OF_Flag==0)
{
if(_IQ4abs((ACFreq-_IQ4(50.0)))<_IQ4(GRID_OVER_UNDER_FREQ_LIMIT))
{
PVInverterState=CheckPV;
Grid_Freq=50;
GRID_MIN_FREQ=Grid_Freq-GRID_OVER_UNDER_FREQ_LIMIT;
GRID_MAX_FREQ=Grid_Freq+GRID_OVER_UNDER_FREQ_LIMIT;
GRID_MIN_VRMS=220-GRID_OVER_UNDER_VRMS_LIMIT;
GRID_MAX_VRMS=220+GRID_OVER_UNDER_VRMS_LIMIT;
// SPLL 1ph Notch Filter Method intialization
SPLL_1ph_IQ_init(Grid_Freq,_IQ21((float)(1.0/ISR_FREQUENCY)),&spll1);
spll1.lpf_coeff.B0_lf=B0_LPF;
spll1.lpf_coeff.B1_lf=B1_LPF;
spll1.lpf_coeff.A1_lf=A1_LPF;
c1=0.1;
c2=0.00001;
SPLL_1ph_IQ_notch_coeff_update(((float)(1.0/ISR_FREQUENCY)), (float)(2*PI*Grid_Freq*2),(float)c2,(float)c1, &spll1);
NOTCH_FLTR_IQ_COEFF_Update(((float)(1.0/ISR_FREQUENCY)), (float)(2*PI*Grid_Freq*2),(float)c2,(float)c1, ¬ch_TwiceGridFreq);
//SPLL 1ph SOGI Method initialization
SPLL_1ph_SOGI_IQ_init(Grid_Freq,_IQ23((float)(1.0/ISR_FREQUENCY)),&spll2);
spll2.lpf_coeff.B0_lf=_IQ23(166.877556);
spll2.lpf_coeff.B1_lf=_IQ23(-166.322444);
spll2.lpf_coeff.A1_lf=_IQ23(-1.0);
SPLL_1ph_SOGI_IQ_coeff_update(((float)(1.0/ISR_FREQUENCY)),(float)(2*PI*Grid_Freq),&spll2);
inv_bus_ref=DC_BUS_REF_50HZ;
inv_bus_rly_connect= DC_BUS_RELAY_CONNECT_VOLT_50HZ;
inv_bus_start_volt=DC_BUS_INV_START_VOLT_50HZ;
inv_bus_UV=DC_BUS_UNDERVOLTAGE_LIMIT_50HZ;
inv_bus_OV=DC_BUS_OVERVOLTAGE_LIMIT_50HZ;
cntlPI_BusInv.Umin =_IQ(0.015);
SlewClrInvTrip=10;
}
else if(_IQ4abs((ACFreq-_IQ4(60.0)))<_IQ4(GRID_OVER_UNDER_FREQ_LIMIT))
{
PVInverterState=CheckPV;
Grid_Freq=60;
GRID_MIN_FREQ=Grid_Freq-GRID_OVER_UNDER_FREQ_LIMIT;
GRID_MAX_FREQ=Grid_Freq+GRID_OVER_UNDER_FREQ_LIMIT;
GRID_MIN_VRMS=110-GRID_OVER_UNDER_VRMS_LIMIT;
GRID_MAX_VRMS=110+GRID_OVER_UNDER_VRMS_LIMIT;
// SPLL 1ph Notch Filter Method intialization
SPLL_1ph_IQ_init(Grid_Freq,_IQ21((float)(1.0/ISR_FREQUENCY)),&spll1);
spll1.lpf_coeff.B0_lf=B0_LPF;
spll1.lpf_coeff.B1_lf=B1_LPF;
spll1.lpf_coeff.A1_lf=A1_LPF;
c1=0.1;
c2=0.00001;
SPLL_1ph_IQ_notch_coeff_update(((float)(1.0/ISR_FREQUENCY)), (float)(2*PI*Grid_Freq*2),(float)c2,(float)c1, &spll1);
NOTCH_FLTR_IQ_COEFF_Update(((float)(1.0/ISR_FREQUENCY)), (float)(2*PI*Grid_Freq*2),(float)c2,(float)c1, ¬ch_TwiceGridFreq);
//SPLL 1ph SOGI Method initialization
SPLL_1ph_SOGI_IQ_init(Grid_Freq,_IQ23((float)(1.0/ISR_FREQUENCY)),&spll2);
spll2.lpf_coeff.B0_lf=_IQ23(166.877556);
spll2.lpf_coeff.B1_lf=_IQ23(-166.322444);
spll2.lpf_coeff.A1_lf=_IQ23(-1.0);
SPLL_1ph_SOGI_IQ_coeff_update(((float)(1.0/ISR_FREQUENCY)),(float)(2*PI*Grid_Freq),&spll2);
inv_bus_ref=DC_BUS_REF_60HZ;
inv_bus_rly_connect= DC_BUS_RELAY_CONNECT_VOLT_60HZ;
inv_bus_start_volt=DC_BUS_INV_START_VOLT_60HZ;
inv_bus_UV=DC_BUS_UNDERVOLTAGE_LIMIT_60HZ;
inv_bus_OV=DC_BUS_OVERVOLTAGE_LIMIT_60HZ;
cntlPI_BusInv.Umin =_IQ(0.025);
SlewClrInvTrip=10;
}
}
#else
PVInverterState=CheckPV;
#endif
if(Gui_InvStop==1)
{
PVInverterState=Idle;
Gui_InvStop=0;
}
break;
case CheckPV:
// AC is present, check if PV is present
if(Gui_InvStop==1)
{
PVInverterState=ResetState1; // go to the re-initalization state, this logs any fault conditions as well
Gui_InvStop=0;
}
if(Gui_Vpv>VPV_MIN)
{
// sufficient PV voltage is present
// Clear Fly Back Trip and monitor DC BUs
PVInverterState=MonitorDCBus;
EALLOW;
EPwm3Regs.TZCLR.bit.OST=0x1;
CloseFlybackLoop=1;
EDIS;
pv_ref_cur_inst=_IQ24(0.1);
pv_ref_cur_fixed=_IQ24(0.15);
}
break;
case MonitorDCBus:
// Flyback is pumping current into the DC Bus
// Monitor the DC Bus Value
#if(GRID_CONNECT==1)
if(UV_Flag==1||OV_Flag==1) //UF_Flag==1||||OF_Flag==1
{
Gui_InvStop=1;
}
#endif
if(vbus_meas_inst>inv_bus_OV) // Check for Over Voltage Condition
{
BusOverVoltageTrip=1;
Gui_InvStop=1;
}
if(Gui_InvStop==1)
{
PVInverterState=ResetState1; // go to the re-initalization state
Gui_InvStop=0;
}
if(vbus_meas_inst>inv_bus_rly_connect)
{
RlyConnect=1;
}
// Check if DC Bus is greater than DC_BUS_INV_START_VOLT
// Also Check if the Relay has been connected
// As currently the inverter is off this will happen quickly
if(vbus_meas_inst>inv_bus_start_volt && GpioDataRegs.GPADAT.bit.GPIO22==1)
{
SlewClrInvTrip--;
if(SlewClrInvTrip==0)
{
PVInverterState=EnableMPPT;
// Take inverter out of reset
ClearInvTrip=1;
}
}
SlewState4=250;
break;
case EnableMPPT:
// Wait Before enabling MPPT
SlewState4--;
if(SlewState4==0)
{
PVInverterState=PVInverterActive;
//Enable MPPT
MPPT_ENABLE=1;
mppt_incc_I1.mppt_first=1;
mppt_incc_I1.mppt_enable=1;
}
// check for under voltage
if(vbus_meas_inst<inv_bus_UV)
{
BusUnderVoltageTrip=1;
Gui_InvStop=1;
}
// Check for Over Voltage Condition
if(vbus_meas_inst>inv_bus_OV)
{
BusOverVoltageTrip=1;
Gui_InvStop=1;
}
#if(GRID_CONNECT==1)
if(UV_Flag==1||OV_Flag==1) //UF_Flag==1||||OF_Flag==1
{
Gui_InvStop=1;
}
#endif
if(Gui_InvStop==1)
{
PVInverterState=ResetState1; // go to the re-initalization state
Gui_InvStop=0;
}
break;
case PVInverterActive:
//Inverter is Fully Active Now
// Check for Faults or Stop Command
#if(GRID_CONNECT==1)
if(UV_Flag==1||OV_Flag==1) //||OF_Flag==1UF_Flag==1||
{
Gui_InvStop=1;
}
#endif
// check for under voltage
if(vbus_meas_inst<inv_bus_UV)
{
BusUnderVoltageTrip=1;
Gui_InvStop=1;
}
// Check for Over Voltage Condition
if(vbus_meas_inst>inv_bus_OV)
{
BusOverVoltageTrip=1;
Gui_InvStop=1;
}
if(Gui_InvStop==1)
{
PVInverterState=ResetState1; // go to the re-initalization state
Gui_InvStop=0;
}
break;
case ResetState1:
#if(GRID_CONNECT==1)
/*if(UF_Flag==1)
{
FaultFlag=1;
Gui_InvStop=1;
}
else if (OF_Flag==1)
{
FaultFlag=2;
Gui_InvStop=1;
}
*/
if(UV_Flag==1)
{
FaultFlag=UnderVoltageGrid;
}
else if(OV_Flag==1)
{
FaultFlag=OverVoltageGrid;
}
else if(BusUnderVoltageTrip==1)
{
FaultFlag=UnderVoltageDCBus;
}
else if(BusOverVoltageTrip==1)
{
FaultFlag=OverVoltageDCBus;
}
#endif
// Run the reset sequence
// Fist disable MPPT and set the ref current command to zero
// This is done to make sure the flyback does not see <10% duty when tripping
MPPT_ENABLE=0;
mppt_incc_I1.mppt_first=1;
mppt_incc_I1.mppt_enable=0;
pv_ref_cur_inst=_IQ24(0.0);
// zero the buffer values, this makes sure the DC-DC Flyback stage shuts down fast
//DINT;
// CNTL_2P2Z_IQ_C_VAR_INIT(cntl2p2z_DCDCI_vars);
//EINT;
duty_flyback=0;
duty_flyback_pu=0;
CloseFlybackLoop=0;
PVInverterState=ResetState2;
break;
case ResetState2:
//Disconnect relay
GpioDataRegs.GPACLEAR.bit.GPIO22=1;
// by now the CMPA value should be zero
if(EPwm3Regs.CMPA.half.CMPA==0)
{
// Trip the PWM for the inverter
// software force the trip of inverter and flyback
EALLOW;
EPwm1Regs.TZFRC.bit.OST=0x1;
EPwm2Regs.TZFRC.bit.OST=0x1;
EPwm3Regs.TZFRC.bit.OST=0x1;
EPwm1Regs.CMPA.half.CMPA=0;
EPwm1Regs.CMPB=0;
EPwm2Regs.CMPA.half.CMPA=0;
EPwm3Regs.CMPA.half.CMPA=0;
EDIS;
duty_inv_pu=0;
duty_inv=0;
inv_Iset=0;
CloseIloopInv=0;
#if (GRID_CONNECT==1)
if(FaultFlag==0)
PVInverterState=Idle;
else
PVInverterState=FaultState;
#else
PVInverterState=Idle;
#endif
CNTL_2P2Z_IQ_VARS_init(&cntl2p2z_DCDCI_vars);
CNTL_3P3Z_IQ_VARS_init(&cntl3p3z_InvI_vars);
cntlPI_BusInv.up=0;
cntlPI_BusInv.ui=0;
cntlPI_BusInv.v1=0;
cntlPI_BusInv.i1=0;
cntlPI_BusInv.up=0;
cntlPI_BusInv.w1=0;
}
break;
default:
break;
}
#endif
//TODO AC Measurements
//---------------------------------------------------------------------
// Grid Frequency Measurements
//---------------------------------------------------------------------
ACFreq_SysTicks = (ECap1Regs.CAP1 + ECap1Regs.CAP2 + ECap1Regs.CAP3
+ ECap1Regs.CAP4) << 3;
ACFreq = _IQ4div(_IQ4(CPU_FREQ), ACFreq_SysTicks);
if (ECap1Regs.TSCTR > ECAP_TimerMaxVal
|| (ECap1Regs.CAP1 > ECAP_TimerMaxVal)
|| (ECap1Regs.CAP2 > ECAP_TimerMaxVal)
|| (ECap1Regs.CAP3 > ECAP_TimerMaxVal)) {
ACFreq_SysTicks = 0;
ACFreq = 0;
}
if (ACFreq < _IQ4(GRID_MIN_FREQ))
UF_Flag = 1;
else
UF_Flag = 0;
if (ACFreq > _IQ4(GRID_MAX_FREQ))
OF_Flag = 1;
else
OF_Flag = 0;
MATH_EMAVG2_IQ_MACRO((_IQ24abs(inv_meas_vol_inst)), inv_emavg_vol,
_IQ24(0.0003));
Gui_Vavg = _IQ16mpy((int32)inv_emavg_vol>>8,_IQ16(AC_PEAK_SENSE));
if (Gui_Vavg < _IQ16(GRID_MIN_VRMS))
UV_Flag = 1;
else
UV_Flag = 0;
if (Gui_Vavg > _IQ16(GRID_MAX_VRMS))
OV_Flag = 1;
else
OV_Flag = 0;
if (UF_Flag == 0 && Gui_Vavg > _IQ16(40.0)) {
//Calculate RMS input voltage and input frequency
sine_mains.Iin = inv_meas_cur_inst >> 9;
sine_mains.Vin = inv_meas_vol_inst >> 9;
SINEANALYZER_DIFF_wPWR_IQ_MACRO(sine_mains);
VRMS = (sine_mains.Vrms) << 9;// Convert sine_mainsV.Vrms from Q15 to Q24 and save as VrectRMS
IRMS = (sine_mains.Irms) << 9;// Convert sine_mainsV.Irms from Q15 to Q24 and save as IrectRMS
PRMS = (sine_mains.Prms) << 9;// Convert sine_mainsV.Prms from Q15 to Q24 and save as PinRMS
Gui_Prms = (sine_mains.Prms * K_Prms) >> 15;
Gui_Irms = (sine_mains.Irms * K_Irms) >> 15;
Gui_Vrms = (sine_mains.Vrms * K_Vrms) >> 15;
/*if(Gui_Vrms<_IQ6(GRID_MIN_VRMS))
UV_Flag=1;
else
UV_Flag=0;
if(Gui_Vrms>_IQ6(GRID_MAX_VRMS))
OV_Flag=1;
else
OV_Flag=0;
*/
} else {
VRMS = 0;// Convert sine_mainsV.Vrms from Q15 to Q24 and save as VrectRMS
IRMS = 0;// Convert sine_mainsV.Irms from Q15 to Q24 and save as IrectRMS
PRMS = 0;// Convert sine_mainsV.Prms from Q15 to Q24 and save as PinRMS
Gui_Prms = 0;
Gui_Irms = 0;
Gui_Vrms = 0;
SINEANALYZER_DIFF_wPWR_IQ_init(&sine_mains);
sine_mains.Vin = 0;
sine_mains.Iin = 0;
sine_mains.SampleFreq = _IQ15(1000.0);
sine_mains.Threshold = _IQ15(0.1);
sine_mains.nsamplesMax=1000/UNIVERSAL_GRID_MIN_FREQ;
sine_mains.nsamplesMin=1000/UNIVERSAL_GRID_MAX_FREQ;
}
Gui_Vpv = _IQ20mpy(pv_meas_vol_avg>>4,_IQ20(PV_VOL_SENSE_MAX));
Gui_Ipv = _IQ20mpy(pv_meas_cur_avg>>4,_IQ20(PV_CURR_SENSE_MAX));
Gui_Vbus = _IQ20mpy(vbus_meas_avg>>4,_IQ20(VBUS_VOL_SENSE_MAX));
//Freq_Vin = sine_mainsV.SigFreq;// Q15
//VrmsReal = _IQ15mpy (KvInv, sine_mainsV.Vrms);
//Gui_PinRMS = (sine_mainsV.Prms*K_Prms) >> 15;//Q15*Q15 >> 15 = Q15, When no calibration is used
// if((sine_mainsV.Prms>123)&&(sine_mainsV.Prms <= 858)){ //Max Power used for normalization is 19.8*405.2=8022.96W.//
// //So 210W = 210/8022.96 *32767 = 858 in Q15 format//
// // 30W = 30/8022.96 *32767 = 123 in Q15 format//
// Gui_PinRMS = (((sine_mainsV.Prms*slope_Pcorr) >> 15)- offset_Pcorr);//Q15*Q15 >> 15 = Q15,
// //apply calibration between 30W and 210W
// }
// else{
// Gui_PinRMS = (sine_mainsV.Prms*K_Prms) >> 15;//Q15*Q15 >> 15 = Q15, apply zero calibration
// }
//
//
// Gui_PinRMS_16 = (int16)(Gui_PinRMS);
//TODO MPPT Task
#if INCR_BUILD==2
if(MPPT_ENABLE==1)
{
if(MPPT_slew==0)
{
Run_MPPT=1;
MPPT_slew=100;
}
else
MPPT_slew--;
}
#endif
if (Run_MPPT == 1) {
Run_MPPT = 0;
// MPPT routine
mppt_incc_I1.Ipv =pv_meas_cur_avg; //IpvRead;
mppt_incc_I1.Vpv =pv_meas_vol_avg; //VpvRead;
MPPT_INCC_I_IQ_MACRO(mppt_incc_I1);
pv_ref_cur_mppt = mppt_incc_I1.ImppOut;
#if(MPPT==1)
if(Gui_MPPTEnable==1)
pv_ref_cur_inst=pv_ref_cur_mppt;
else
pv_ref_cur_inst=pv_ref_cur_fixed;
#else
pv_ref_cur_inst = pv_ref_cur_fixed;
#endif
}
if (EPwm1Regs.TZFLG.bit.OST == 1 && RlyConnect == 1
&& PVInverterState >= 4) {
OverCurrent = 1;
} else if (EPwm1Regs.TZFLG.bit.OST == 0) {
OverCurrent = 0;
}
}
/**********************************************************/
/********************** ECAP INIT *************************/
/**********************************************************/
void InitECapture() {
ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // Operation in Continuous Mode
ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // Wrap after 4 events
ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP2POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CAP3POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP4POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // Difference operation
ECap1Regs.ECCTL2.bit.SYNCI_EN = 0; // Enable sync in
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter
//ECap1Regs.ECCTL2.bit.REARM = 1; // arm one-shot
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
// ECap1Regs.ECEINT.bit.CEVT4 = 1; // 4 events = interrupt
}