simulation of the Buck closedloop with PI controller

Help to look at the following code of the ADC module settings, as well as the back of the voltage control code where there is a problem, the code can not realize the PI control please help you to solve it!

After running, it

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#include "DSP2833x_Device.h" /* DSP2833x Headerfile Include File */
#include "DSP2833x_Examples.h" /* DSP2833x Examples Include File */
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include <math.h>
#define BUFFER_LENGTH 4096
#define CURRENT_SCALE_FACTOR 0.00054
#define VOLTAGE_SCALE_FACTOR 0.0405
#define VREF 3.3 //Reference voltage for the ADC
#define SYSTEM_CLOCK 200E6 // 200MHz
#define TBCLK 100E6 // 100MHz
#define PWM_CARRIER 100E3 // 100kHz
// Global variable for this example
Uint16 Sample1=0, Sample2=0; // 실제 Sensing이 된 ADC 변수
Uint16 ADC_cnt=0, ADC_cnt2=0, ADC_data0=0, ADC_data1=0, ADC_flag=0; // ADC Calibaraion를 위한 변수 설정
float32 I_osum=0., I_oavg=0.;
Uint16 Fil_cnt=0;
Uint16 I_Fil=0, I_inFil=0;
Uint16 Runflag=0, Trip_cnt=0; //여러 제어Mode 및 OpenLoop가 가능하도록 설정. Runflag 값을 변경하여 동작을 다음과 같이 설정 할 수 있다.
// 0 : 평상시(동작안함), 1 : 투스위치 Openloop Test,
// 2 : 투스위치 VoltageControl, 3 : 스위치 1개 Openloop Test, 4 : 디지털 제어
Uint16 EPwm1IsrTicker = 0;
Uint16 BackTicker;
Uint16 AdcisrTicker; // ADC 인터럽트 서비스 루틴 호출 횟수 계수(S/W카운터)
Uint16 VoltageTicker;
float32 Adc_Result;
float32 AdcOffset;
float64 V_o=0., offset_0=0., I_o=0., offset_1=0.; // ADC Calibaraion 및 출력전압 센싱값 변수 설정
float32 V_err=0., V_ref=0; // PI제어를 위한 오차 및 출력전압 Reference
float32 Kv_pi =0., V_pterm=0., V_iterm=0. ; // PI제어기의 P제어기 수행후 값(V_pterm),
float32 V_in_REF=0;
float32 Anti_Err=0;
float32 IntegV_err=0;
float32 Integerr=0;
float32 Antierr=0;
// I제어기 수행 후 값 (V_iterm), 두 값을 더한 최종 출력값 (V_pi)
float32 K_p1=0, K_i1=0, K_a1=0; // Voltage Control의 게인
float32 Io_f=0., Vo_f=0.; // 전류 Filter 변수 설정
float32 test_value=0.;
float32 out_sat=0.0;
float32 out_pi=0.0;
float32 PwmDutyRatio;
float32 FallingEdgeDelay;
float32 RisingEdgeDelay;
float32 DBPer=0.0;
/*★*/
float32 I_err=0., I_ref=0.4; // PI제어를 위한 오차 및 입력 전류 Reference
float32 Ki_pi =0., I_pterm=0., I_iterm=0.; // PI제어기의 P제어기 수행후 값(V_pterm), I제어기 수행후 값 (V_iterm), 두 값을 더한 최종 출력값 (V_pi)
float32 K_p2=4.0, K_i2=100.0; // Current Control의 게인
float32 PwmDutyRatioA = 0.0;
////////////////////////////inverter
// Global variables used in inverter
void epwm1module(void); // epwm1module 함수 불러오기
void epwm2module(void); // epwm2module 함수 불러오기
void epwm3module(void); // epwm3module 함수 불러오기
interrupt void epwm1isr(void); // Interrupt 불러오기(epwm1isr)
interrupt void ADCIsr(void); //Interrupt ADC
void main(void)
{
InitSysCtrl();
InitEPwmGpio();
DINT;
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT = &epwm1isr; // PIE Vector Table 설정
PieVectTable.EPWM2_INT = &epwm1isr;
PieVectTable.EPWM3_INT = &epwm1isr;
PieVectTable.ADCINT = &epwm1isr;
PieVectTable.EPWM1_TZINT = &epwm1isr;
PieVectTable.EPWM2_TZINT = &epwm1isr;
EDIS;
InitAdc();
AdcRegs.ADCREFSEL.bit.REF_SEL = 0;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; // ADCCLK = HSPCLK/(ADCCLKPS*2)/(CPS+1)
// ADC 주기 설정 Code
AdcRegs.ADCTRL1.bit.CPS = 0; // ADCCLK = 100MHz/(1*2)/(0+1) = 50MHz
// ADC 주기 설정 Code
AdcRegs.ADCTRL1.bit.ACQ_PS = 15; // 샘플/홀드 사이클 = ACQ_PS + 1 = 16 (ADCCLK기준)
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 샘플링 모드 선택 (0:순차 샘플링 Sequence, 1:동시 샘플링 Simultaneous)
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 시퀀스 모드 설정: 직렬 시퀀스 모드 (0:병렬 모드, 1:직렬 모드)
AdcRegs.ADCTRL1.bit.SUSMOD=0; // 시작점을 EPWM과 동기화
AdcRegs.ADCMAXCONV.all = 0x1; // ADC를 사용할 개수
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // ADC 순서 설정
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // ADC 순서 설정
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // ePWM_SOCA로 ADC 시퀀스 시동
EPwm3Regs.ETSEL.bit.SOCAEN = 1; // EPWM 3번에 동기화 신호 Enable
EPwm3Regs.ETSEL.bit.SOCASEL = 2; // SOCA의 동기화 시점을 PRD와 동일하게 설정
EPwm3Regs.ETPS.bit.SOCAPRD = 1; // SOCA의 동기화 횟수를 EPWM과 동일하게 설정
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Carrier 파형을 Up 으로 설정
EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0; // EPWM3번의 CLK 분주
EPwm3Regs.TBCTL.bit.CLKDIV = 0; // EPWM3번의 CLK 분주
EPwm3Regs.TBPRD = (TBCLK/PWM_CARRIER)-1; // (100MHz/100KHz)-1 = 999 𝑇_𝑃𝑊𝑀=2∗𝑇𝐵𝑃𝑅𝐷∗ 𝑇_𝑇𝐵𝐶𝐿𝐾
EPwm3Regs.TBCTR = 0x0000; // 초기 Counter Clear
// PIE의 ADC 인터럽트 활성화
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // PIE 인터럽트(ADCINT) 활성화
IER |= M_INT1; // CPU 인터럽트(INT1) 활성화
PieCtrlRegs.PIEIER2.bit.INTx1 = 1;
PieCtrlRegs.PIEIER2.bit.INTx2 = 1; // TZ int2
IER |= M_INT2; // CPU 인터럽트(INT1) 활성화
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
epwm1module();
epwm2module();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
// Enable CPU INT3 which is connected to EPWM1-3 INT:
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
IER |= M_INT3;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
BackTicker = 0;
for(;;)
{
BackTicker++;
}
}
// DC_DC
void epwm1module(void)
{
/* Setup Counter Mode and Clock */
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count 방식 설정 (Up방식으로)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // EPWM Clock 설정
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // EPWM Clock 설정
/* Setup Phase */
EPwm1Regs.TBPHS.half.TBPHS = 0; // 위상을 얼만큼 이동시키는지 설정
EPwm1Regs.TBCTL.bit.PHSEN = 0; // 위상을 이동 시킬지 말지를 결정 (0:Disable , 1:Enable)
// Setup Period (Carrier Frequency)
EPwm1Regs.TBPRD = (TBCLK/PWM_CARRIER)-1; // Set Timer Period, (100MHz/100KHz)-1 = 999
EPwm1Regs.TBCTR = 0; // Clear Counter
/* Set Compare Value */
EPwm1Regs.CMPA.half.CMPA = 0; // 비교기의 +레퍼런스 설정 (초기조건 - 0으로 설정)
/* Setup shadowing */
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Shadow 레지스터에서 로드하는 시점을 설정
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 시점을 설정 (카운터가 Zero일 경우 동기화), 위상을 사용하지 않아 크게 의미가 없는 코드
/* Set actions */
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm1Regs.AQCTLA.bit.ZRO=AQ_SET; // Carrier가 zero일때 high신호로
/* Set Dead-time */
EPwm1Regs.DBCTL.bit.IN_MODE = 0;
EPwm1Regs.DBCTL.bit.OUT_MODE = 0;
EPwm1Regs.DBCTL.bit.POLSEL = 0;
EPwm1Regs.DBFED = 1; // Falling Deadtime 설정
EPwm1Regs.DBRED = 1; // Rising Deadtime 설정
/* Set Interrupts */
EPwm1Regs.ETSEL.bit.INTSEL = 1; // EPWM 인터럽트 옵션 - CTR이 PRD일때 동기화
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event EPwm1Regs.
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA 이벤트 트리거 Enable
EPwm1Regs.ETSEL.bit.SOCASEL = 2; // SCCA 트리거 조건 : 카운터 주기 일치 시 (읽는 시점이라고 생각하시면 됩니다)
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // SOCA 이벤트 분주 설정 : 트리거 조건 한번 마다 (샘플링을 EPWM주파수에 동기화를 시켰다고 보시면 됩니다.)
EALLOW;
EDIS;
}
void epwm2module()
{
/* Setup Counter Mode and Clock */
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count 방식 설정 (Up방식으로)
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // EPWM Clock 설정
EPwm2Regs.TBCTL.bit.CLKDIV = 0; // EPWM Clock 설정
/* Setup Phase */
EPwm2Regs.TBPHS.half.TBPHS = 0; // 위상을 얼만큼 이동시키는지 설정
EPwm2Regs.TBCTL.bit.PHSEN = 0; // 위상을 이동 시킬지 말지를 결정 (0:Disable , 1:Enable)
// Setup Period (Carrier Frequency)
EPwm2Regs.TBPRD = (TBCLK/PWM_CARRIER)-1; // Set Timer Period, (100MHz/100KHz)-1 = 999
EPwm2Regs.TBCTR = 0; // Clear Counter
/* Set Compare Value */
EPwm2Regs.CMPA.half.CMPA = 0; // 비교기의 +레퍼런스 설정 (초기조건 - 0으로 설정)
/* Setup shadowing */
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Shadow 레지스터에서 로드하는 시점을 설정
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 시점을 설정 (카운터가 Zero일 경우 동기화), 위상을 사용하지 않아 크게 의미가 없는 코드
/* Set actions */
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm2Regs.AQCTLA.bit.ZRO=AQ_SET; // Carrier가 zero일때 high신호로
/* Set Dead-time */
EPwm2Regs.DBCTL.bit.IN_MODE = 0;
EPwm2Regs.DBCTL.bit.OUT_MODE = 0;
EPwm2Regs.DBCTL.bit.POLSEL = 0;
EPwm2Regs.DBFED = 1; // Falling Deadtime 설정
EPwm2Regs.DBRED = 1; // Rising Deadtime 설정
}
interrupt void epwm1isr(void)
{
EPwm1IsrTicker++;
if (PwmDutyRatioA >= 0.8)
{
PwmDutyRatioA = 0.8;
}
EPwm1Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA;
EPwm2Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA;
EPwm1Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
interrupt void Adcisr(void)
{
if(AdcisrTicker==10)
{
AdcOffset = ((3.3 * (float32)(AdcRegs.ADCRESULT0)) / 4096); //Offset value before startup
}
AdcisrTicker++;
if (AdcisrTicker > 10000)
AdcisrTicker = 11;
Adc_Result = ((3.3 * (float32)(AdcRegs.ADCRESULT0) / 4096) - AdcOffset) * 10;
}
void voltageController(void) // Voltage Control Mode
{
////////////// Deadtime 설정 ///////////////
EPwm1Regs.DBCTL.bit.IN_MODE = 0; // EPWMxA is the source for both falling-edge & rising-edge delay
EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // Dead-band is fully enabled for both rising-edge delay on EPWMxA and falling-edge delay on EPWMxB
EPwm1Regs.DBCTL.bit.POLSEL = 2; // Active High Complementary (AHC). EPWMxB is inverted
EPwm2Regs.DBCTL.bit.IN_MODE = 0; // EPWMxA is the source for both falling-edge & rising-edge delay
EPwm2Regs.DBCTL.bit.OUT_MODE = 3; // Dead-band is fully enabled for both rising-edge delay on EPWMxA and falling-edge delay on EPWMxB
EPwm2Regs.DBCTL.bit.POLSEL = 2; // Active High Complementary (AHC). EPWMxB is inverted
////////////// PI 제어기 설정 /////////////////
if(Adc_Result<4.0)
{
PwmDutyRatio=0.416;
return;
}
V_err=V_ref-Adc_Result;
Antierr=V_err-K_a1*(out_pi-out_sat);
Integerr +=K_i1*Antierr;
out_pi=Integerr + K_p1*V_err;
if(out_pi>0.8)
out_sat=0.8;
else if(out_pi<0.1)
out_sat=0.1;
else
out_sat=out_pi;
PwmDutyRatio=out_sat;
VoltageTicker++;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 High신호로
EPwm1Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA; // 비교기와 최종 레퍼런스 비교
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 High신호로
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm2Regs.CMPA.half.CMPA = (EPwm2Regs.TBPRD + 1) * PwmDutyRatioA; // 비교기와 최종 레퍼런스 비교
}
</code>
<code>#include "DSP2833x_Device.h" /* DSP2833x Headerfile Include File */ #include "DSP2833x_Examples.h" /* DSP2833x Examples Include File */ #include "DSP28x_Project.h" // Device Headerfile and Examples Include File #include <math.h> #define BUFFER_LENGTH 4096 #define CURRENT_SCALE_FACTOR 0.00054 #define VOLTAGE_SCALE_FACTOR 0.0405 #define VREF 3.3 //Reference voltage for the ADC #define SYSTEM_CLOCK 200E6 // 200MHz #define TBCLK 100E6 // 100MHz #define PWM_CARRIER 100E3 // 100kHz // Global variable for this example Uint16 Sample1=0, Sample2=0; // 실제 Sensing이 된 ADC 변수 Uint16 ADC_cnt=0, ADC_cnt2=0, ADC_data0=0, ADC_data1=0, ADC_flag=0; // ADC Calibaraion를 위한 변수 설정 float32 I_osum=0., I_oavg=0.; Uint16 Fil_cnt=0; Uint16 I_Fil=0, I_inFil=0; Uint16 Runflag=0, Trip_cnt=0; //여러 제어Mode 및 OpenLoop가 가능하도록 설정. Runflag 값을 변경하여 동작을 다음과 같이 설정 할 수 있다. // 0 : 평상시(동작안함), 1 : 투스위치 Openloop Test, // 2 : 투스위치 VoltageControl, 3 : 스위치 1개 Openloop Test, 4 : 디지털 제어 Uint16 EPwm1IsrTicker = 0; Uint16 BackTicker; Uint16 AdcisrTicker; // ADC 인터럽트 서비스 루틴 호출 횟수 계수(S/W카운터) Uint16 VoltageTicker; float32 Adc_Result; float32 AdcOffset; float64 V_o=0., offset_0=0., I_o=0., offset_1=0.; // ADC Calibaraion 및 출력전압 센싱값 변수 설정 float32 V_err=0., V_ref=0; // PI제어를 위한 오차 및 출력전압 Reference float32 Kv_pi =0., V_pterm=0., V_iterm=0. ; // PI제어기의 P제어기 수행후 값(V_pterm), float32 V_in_REF=0; float32 Anti_Err=0; float32 IntegV_err=0; float32 Integerr=0; float32 Antierr=0; // I제어기 수행 후 값 (V_iterm), 두 값을 더한 최종 출력값 (V_pi) float32 K_p1=0, K_i1=0, K_a1=0; // Voltage Control의 게인 float32 Io_f=0., Vo_f=0.; // 전류 Filter 변수 설정 float32 test_value=0.; float32 out_sat=0.0; float32 out_pi=0.0; float32 PwmDutyRatio; float32 FallingEdgeDelay; float32 RisingEdgeDelay; float32 DBPer=0.0; /*★*/ float32 I_err=0., I_ref=0.4; // PI제어를 위한 오차 및 입력 전류 Reference float32 Ki_pi =0., I_pterm=0., I_iterm=0.; // PI제어기의 P제어기 수행후 값(V_pterm), I제어기 수행후 값 (V_iterm), 두 값을 더한 최종 출력값 (V_pi) float32 K_p2=4.0, K_i2=100.0; // Current Control의 게인 float32 PwmDutyRatioA = 0.0; ////////////////////////////inverter // Global variables used in inverter void epwm1module(void); // epwm1module 함수 불러오기 void epwm2module(void); // epwm2module 함수 불러오기 void epwm3module(void); // epwm3module 함수 불러오기 interrupt void epwm1isr(void); // Interrupt 불러오기(epwm1isr) interrupt void ADCIsr(void); //Interrupt ADC void main(void) { InitSysCtrl(); InitEPwmGpio(); DINT; InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.EPWM1_INT = &epwm1isr; // PIE Vector Table 설정 PieVectTable.EPWM2_INT = &epwm1isr; PieVectTable.EPWM3_INT = &epwm1isr; PieVectTable.ADCINT = &epwm1isr; PieVectTable.EPWM1_TZINT = &epwm1isr; PieVectTable.EPWM2_TZINT = &epwm1isr; EDIS; InitAdc(); AdcRegs.ADCREFSEL.bit.REF_SEL = 0; AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; // ADCCLK = HSPCLK/(ADCCLKPS*2)/(CPS+1) // ADC 주기 설정 Code AdcRegs.ADCTRL1.bit.CPS = 0; // ADCCLK = 100MHz/(1*2)/(0+1) = 50MHz // ADC 주기 설정 Code AdcRegs.ADCTRL1.bit.ACQ_PS = 15; // 샘플/홀드 사이클 = ACQ_PS + 1 = 16 (ADCCLK기준) AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 샘플링 모드 선택 (0:순차 샘플링 Sequence, 1:동시 샘플링 Simultaneous) AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 시퀀스 모드 설정: 직렬 시퀀스 모드 (0:병렬 모드, 1:직렬 모드) AdcRegs.ADCTRL1.bit.SUSMOD=0; // 시작점을 EPWM과 동기화 AdcRegs.ADCMAXCONV.all = 0x1; // ADC를 사용할 개수 AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // ADC 순서 설정 AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // ADC 순서 설정 AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // ePWM_SOCA로 ADC 시퀀스 시동 EPwm3Regs.ETSEL.bit.SOCAEN = 1; // EPWM 3번에 동기화 신호 Enable EPwm3Regs.ETSEL.bit.SOCASEL = 2; // SOCA의 동기화 시점을 PRD와 동일하게 설정 EPwm3Regs.ETPS.bit.SOCAPRD = 1; // SOCA의 동기화 횟수를 EPWM과 동일하게 설정 EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Carrier 파형을 Up 으로 설정 EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0; // EPWM3번의 CLK 분주 EPwm3Regs.TBCTL.bit.CLKDIV = 0; // EPWM3번의 CLK 분주 EPwm3Regs.TBPRD = (TBCLK/PWM_CARRIER)-1; // (100MHz/100KHz)-1 = 999 𝑇_𝑃𝑊𝑀=2∗𝑇𝐵𝑃𝑅𝐷∗ 𝑇_𝑇𝐵𝐶𝐿𝐾 EPwm3Regs.TBCTR = 0x0000; // 초기 Counter Clear // PIE의 ADC 인터럽트 활성화 PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // PIE 인터럽트(ADCINT) 활성화 IER |= M_INT1; // CPU 인터럽트(INT1) 활성화 PieCtrlRegs.PIEIER2.bit.INTx1 = 1; PieCtrlRegs.PIEIER2.bit.INTx2 = 1; // TZ int2 IER |= M_INT2; // CPU 인터럽트(INT1) 활성화 EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; epwm1module(); epwm2module(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3 // Enable CPU INT3 which is connected to EPWM1-3 INT: PieCtrlRegs.PIEIER3.bit.INTx1 = 1; PieCtrlRegs.PIEIER3.bit.INTx2 = 1; PieCtrlRegs.PIEIER3.bit.INTx3 = 1; IER |= M_INT3; // Enable global Interrupts and higher priority real-time debug events: EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM BackTicker = 0; for(;;) { BackTicker++; } } // DC_DC void epwm1module(void) { /* Setup Counter Mode and Clock */ EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count 방식 설정 (Up방식으로) EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // EPWM Clock 설정 EPwm1Regs.TBCTL.bit.CLKDIV = 0; // EPWM Clock 설정 /* Setup Phase */ EPwm1Regs.TBPHS.half.TBPHS = 0; // 위상을 얼만큼 이동시키는지 설정 EPwm1Regs.TBCTL.bit.PHSEN = 0; // 위상을 이동 시킬지 말지를 결정 (0:Disable , 1:Enable) // Setup Period (Carrier Frequency) EPwm1Regs.TBPRD = (TBCLK/PWM_CARRIER)-1; // Set Timer Period, (100MHz/100KHz)-1 = 999 EPwm1Regs.TBCTR = 0; // Clear Counter /* Set Compare Value */ EPwm1Regs.CMPA.half.CMPA = 0; // 비교기의 +레퍼런스 설정 (초기조건 - 0으로 설정) /* Setup shadowing */ EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정 EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정 EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Shadow 레지스터에서 로드하는 시점을 설정 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 시점을 설정 (카운터가 Zero일 경우 동기화), 위상을 사용하지 않아 크게 의미가 없는 코드 /* Set actions */ EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로 EPwm1Regs.AQCTLA.bit.ZRO=AQ_SET; // Carrier가 zero일때 high신호로 /* Set Dead-time */ EPwm1Regs.DBCTL.bit.IN_MODE = 0; EPwm1Regs.DBCTL.bit.OUT_MODE = 0; EPwm1Regs.DBCTL.bit.POLSEL = 0; EPwm1Regs.DBFED = 1; // Falling Deadtime 설정 EPwm1Regs.DBRED = 1; // Rising Deadtime 설정 /* Set Interrupts */ EPwm1Regs.ETSEL.bit.INTSEL = 1; // EPWM 인터럽트 옵션 - CTR이 PRD일때 동기화 EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event EPwm1Regs. EPwm1Regs.ETSEL.bit.SOCAEN = 1; // SOCA 이벤트 트리거 Enable EPwm1Regs.ETSEL.bit.SOCASEL = 2; // SCCA 트리거 조건 : 카운터 주기 일치 시 (읽는 시점이라고 생각하시면 됩니다) EPwm1Regs.ETPS.bit.SOCAPRD = 1; // SOCA 이벤트 분주 설정 : 트리거 조건 한번 마다 (샘플링을 EPWM주파수에 동기화를 시켰다고 보시면 됩니다.) EALLOW; EDIS; } void epwm2module() { /* Setup Counter Mode and Clock */ EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count 방식 설정 (Up방식으로) EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // EPWM Clock 설정 EPwm2Regs.TBCTL.bit.CLKDIV = 0; // EPWM Clock 설정 /* Setup Phase */ EPwm2Regs.TBPHS.half.TBPHS = 0; // 위상을 얼만큼 이동시키는지 설정 EPwm2Regs.TBCTL.bit.PHSEN = 0; // 위상을 이동 시킬지 말지를 결정 (0:Disable , 1:Enable) // Setup Period (Carrier Frequency) EPwm2Regs.TBPRD = (TBCLK/PWM_CARRIER)-1; // Set Timer Period, (100MHz/100KHz)-1 = 999 EPwm2Regs.TBCTR = 0; // Clear Counter /* Set Compare Value */ EPwm2Regs.CMPA.half.CMPA = 0; // 비교기의 +레퍼런스 설정 (초기조건 - 0으로 설정) /* Setup shadowing */ EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정 EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정 EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Shadow 레지스터에서 로드하는 시점을 설정 EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 시점을 설정 (카운터가 Zero일 경우 동기화), 위상을 사용하지 않아 크게 의미가 없는 코드 /* Set actions */ EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로 EPwm2Regs.AQCTLA.bit.ZRO=AQ_SET; // Carrier가 zero일때 high신호로 /* Set Dead-time */ EPwm2Regs.DBCTL.bit.IN_MODE = 0; EPwm2Regs.DBCTL.bit.OUT_MODE = 0; EPwm2Regs.DBCTL.bit.POLSEL = 0; EPwm2Regs.DBFED = 1; // Falling Deadtime 설정 EPwm2Regs.DBRED = 1; // Rising Deadtime 설정 } interrupt void epwm1isr(void) { EPwm1IsrTicker++; if (PwmDutyRatioA >= 0.8) { PwmDutyRatioA = 0.8; } EPwm1Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA; EPwm2Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA; EPwm1Regs.ETCLR.bit.INT = 1; PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; } interrupt void Adcisr(void) { if(AdcisrTicker==10) { AdcOffset = ((3.3 * (float32)(AdcRegs.ADCRESULT0)) / 4096); //Offset value before startup } AdcisrTicker++; if (AdcisrTicker > 10000) AdcisrTicker = 11; Adc_Result = ((3.3 * (float32)(AdcRegs.ADCRESULT0) / 4096) - AdcOffset) * 10; } void voltageController(void) // Voltage Control Mode { ////////////// Deadtime 설정 /////////////// EPwm1Regs.DBCTL.bit.IN_MODE = 0; // EPWMxA is the source for both falling-edge & rising-edge delay EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // Dead-band is fully enabled for both rising-edge delay on EPWMxA and falling-edge delay on EPWMxB EPwm1Regs.DBCTL.bit.POLSEL = 2; // Active High Complementary (AHC). EPWMxB is inverted EPwm2Regs.DBCTL.bit.IN_MODE = 0; // EPWMxA is the source for both falling-edge & rising-edge delay EPwm2Regs.DBCTL.bit.OUT_MODE = 3; // Dead-band is fully enabled for both rising-edge delay on EPWMxA and falling-edge delay on EPWMxB EPwm2Regs.DBCTL.bit.POLSEL = 2; // Active High Complementary (AHC). EPWMxB is inverted ////////////// PI 제어기 설정 ///////////////// if(Adc_Result<4.0) { PwmDutyRatio=0.416; return; } V_err=V_ref-Adc_Result; Antierr=V_err-K_a1*(out_pi-out_sat); Integerr +=K_i1*Antierr; out_pi=Integerr + K_p1*V_err; if(out_pi>0.8) out_sat=0.8; else if(out_pi<0.1) out_sat=0.1; else out_sat=out_pi; PwmDutyRatio=out_sat; VoltageTicker++; EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로 EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 High신호로 EPwm1Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA; // 비교기와 최종 레퍼런스 비교 EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 High신호로 EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로 EPwm2Regs.CMPA.half.CMPA = (EPwm2Regs.TBPRD + 1) * PwmDutyRatioA; // 비교기와 최종 레퍼런스 비교 } </code>
#include "DSP2833x_Device.h"        /* DSP2833x Headerfile Include File */
#include "DSP2833x_Examples.h"      /* DSP2833x Examples Include File */
#include "DSP28x_Project.h"    // Device Headerfile and Examples Include File
#include <math.h>
#define BUFFER_LENGTH   4096
#define CURRENT_SCALE_FACTOR  0.00054
#define VOLTAGE_SCALE_FACTOR  0.0405
#define VREF            3.3        //Reference voltage for the ADC
#define   SYSTEM_CLOCK      200E6   // 200MHz
#define   TBCLK            100E6   // 100MHz
#define   PWM_CARRIER         100E3   // 100kHz

// Global variable for this example
Uint16 Sample1=0, Sample2=0;                                            // 실제 Sensing이 된 ADC 변수
Uint16 ADC_cnt=0, ADC_cnt2=0, ADC_data0=0, ADC_data1=0, ADC_flag=0;     // ADC Calibaraion를 위한 변수 설정
float32 I_osum=0., I_oavg=0.;
Uint16 Fil_cnt=0;
Uint16 I_Fil=0, I_inFil=0;
Uint16 Runflag=0, Trip_cnt=0;       //여러 제어Mode 및 OpenLoop가 가능하도록 설정. Runflag 값을 변경하여 동작을 다음과 같이 설정 할 수 있다.
                                    // 0 : 평상시(동작안함), 1 : 투스위치 Openloop Test,
                                    // 2 : 투스위치 VoltageControl, 3 : 스위치 1개 Openloop Test, 4 : 디지털 제어
Uint16 EPwm1IsrTicker = 0;
Uint16  BackTicker;
Uint16  AdcisrTicker;               // ADC 인터럽트 서비스 루틴 호출 횟수 계수(S/W카운터)
Uint16  VoltageTicker;
float32 Adc_Result;
float32 AdcOffset;
float64 V_o=0., offset_0=0., I_o=0., offset_1=0.;   // ADC Calibaraion 및 출력전압 센싱값 변수 설정
float32 V_err=0., V_ref=0;                        // PI제어를 위한 오차 및 출력전압 Reference
float32 Kv_pi =0., V_pterm=0., V_iterm=0. ;          // PI제어기의 P제어기 수행후 값(V_pterm),
float32 V_in_REF=0;
float32 Anti_Err=0;
float32 IntegV_err=0;
float32 Integerr=0;
float32 Antierr=0;
                                                    // I제어기 수행 후 값 (V_iterm), 두 값을 더한 최종 출력값 (V_pi)
float32 K_p1=0, K_i1=0, K_a1=0; // Voltage Control의 게인
float32 Io_f=0., Vo_f=0.;   // 전류 Filter 변수 설정
float32 test_value=0.;
float32 out_sat=0.0;
float32 out_pi=0.0;
float32 PwmDutyRatio;
float32 FallingEdgeDelay;
float32 RisingEdgeDelay;
float32 DBPer=0.0;


/*★*/
float32 I_err=0., I_ref=0.4;                // PI제어를 위한 오차 및 입력 전류 Reference
float32 Ki_pi =0., I_pterm=0., I_iterm=0.;   // PI제어기의 P제어기 수행후 값(V_pterm), I제어기 수행후 값 (V_iterm), 두 값을 더한 최종 출력값 (V_pi)
float32 K_p2=4.0, K_i2=100.0;                 // Current Control의 게인

float32 PwmDutyRatioA = 0.0;


////////////////////////////inverter
// Global variables used in inverter



void epwm1module(void);     // epwm1module 함수 불러오기
void epwm2module(void);     // epwm2module 함수 불러오기
void epwm3module(void);     // epwm3module 함수 불러오기
interrupt void epwm1isr(void);  // Interrupt 불러오기(epwm1isr)
interrupt void ADCIsr(void);    //Interrupt ADC

void main(void)
{
    InitSysCtrl();
   InitEPwmGpio();

   DINT;

   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

   InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
      EALLOW;  // This is needed to write to EALLOW protected registers
      PieVectTable.EPWM1_INT = &epwm1isr;   // PIE Vector Table 설정
      PieVectTable.EPWM2_INT = &epwm1isr;
      PieVectTable.EPWM3_INT = &epwm1isr;
      PieVectTable.ADCINT = &epwm1isr;
      PieVectTable.EPWM1_TZINT = &epwm1isr;
      PieVectTable.EPWM2_TZINT = &epwm1isr;

      EDIS;

        InitAdc();
AdcRegs.ADCREFSEL.bit.REF_SEL = 0;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1;   // ADCCLK = HSPCLK/(ADCCLKPS*2)/(CPS+1)
// ADC 주기 설정 Code
AdcRegs.ADCTRL1.bit.CPS = 0;        // ADCCLK = 100MHz/(1*2)/(0+1) = 50MHz
// ADC 주기 설정 Code
AdcRegs.ADCTRL1.bit.ACQ_PS = 15;    // 샘플/홀드 사이클 = ACQ_PS + 1 = 16 (ADCCLK기준)
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;  // 샘플링 모드 선택 (0:순차 샘플링 Sequence, 1:동시 샘플링 Simultaneous)
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;   // 시퀀스 모드 설정: 직렬 시퀀스 모드 (0:병렬 모드, 1:직렬 모드)
AdcRegs.ADCTRL1.bit.SUSMOD=0;       // 시작점을 EPWM과 동기화
AdcRegs.ADCMAXCONV.all = 0x1;       // ADC를 사용할 개수
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;  // ADC 순서 설정
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;  // ADC 순서 설정

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // ePWM_SOCA로 ADC 시퀀스 시동
EPwm3Regs.ETSEL.bit.SOCAEN = 1;         // EPWM 3번에 동기화 신호 Enable
EPwm3Regs.ETSEL.bit.SOCASEL = 2;        // SOCA의 동기화 시점을 PRD와 동일하게 설정
EPwm3Regs.ETPS.bit.SOCAPRD = 1;         // SOCA의 동기화 횟수를 EPWM과 동일하게 설정
EPwm3Regs.TBCTL.bit.CTRMODE =  TB_COUNT_UP; // Carrier 파형을 Up 으로 설정
EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0;  // EPWM3번의 CLK 분주
EPwm3Regs.TBCTL.bit.CLKDIV = 0;     // EPWM3번의 CLK 분주
EPwm3Regs.TBPRD = (TBCLK/PWM_CARRIER)-1;               // (100MHz/100KHz)-1 = 999 𝑇_𝑃𝑊𝑀=2∗𝑇𝐵𝑃𝑅𝐷∗ 𝑇_𝑇𝐵𝐶𝐿𝐾
EPwm3Regs.TBCTR = 0x0000;           // 초기 Counter Clear
// PIE의 ADC 인터럽트 활성화
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;  // PIE 인터럽트(ADCINT) 활성화
        IER |= M_INT1;              // CPU 인터럽트(INT1)  활성화
        PieCtrlRegs.PIEIER2.bit.INTx1 = 1;
        PieCtrlRegs.PIEIER2.bit.INTx2 = 1;  // TZ int2
        IER |= M_INT2;      // CPU 인터럽트(INT1)  활성화
      EALLOW;
      SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
      EDIS;

      epwm1module();
      epwm2module();

      EALLOW;
      SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
      EDIS;

      // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
      // Enable CPU INT3 which is connected to EPWM1-3 INT:
      PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
      PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
      PieCtrlRegs.PIEIER3.bit.INTx3 = 1;

      IER |= M_INT3;

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

         BackTicker = 0;
         for(;;)
         {
             BackTicker++;
         }
}
// DC_DC
void epwm1module(void)
{
/* Setup Counter Mode and Clock */
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;  // Count 방식 설정 (Up방식으로)
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;              // EPWM Clock 설정
EPwm1Regs.TBCTL.bit.CLKDIV = 0;                 // EPWM Clock 설정

/* Setup Phase */
EPwm1Regs.TBPHS.half.TBPHS = 0; // 위상을 얼만큼 이동시키는지 설정
EPwm1Regs.TBCTL.bit.PHSEN = 0;  // 위상을 이동 시킬지 말지를 결정 (0:Disable , 1:Enable)

// Setup Period (Carrier Frequency)
EPwm1Regs.TBPRD = (TBCLK/PWM_CARRIER)-1;   // Set Timer Period, (100MHz/100KHz)-1 = 999
EPwm1Regs.TBCTR = 0;                  // Clear Counter

/* Set Compare Value */
EPwm1Regs.CMPA.half.CMPA =  0;   // 비교기의 +레퍼런스 설정 (초기조건 - 0으로 설정)

/* Setup shadowing */
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;      // 원신호를 보호해주는 Shadow 레지스터 설정
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;   // Shadow 레지스터에서 로드하는 시점을 설정
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 시점을 설정 (카운터가 Zero일 경우 동기화), 위상을 사용하지 않아 크게 의미가 없는 코드

/* Set actions */
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm1Regs.AQCTLA.bit.ZRO=AQ_SET;    // Carrier가 zero일때  high신호로

/* Set Dead-time */
EPwm1Regs.DBCTL.bit.IN_MODE = 0;
EPwm1Regs.DBCTL.bit.OUT_MODE = 0;
EPwm1Regs.DBCTL.bit.POLSEL = 0;

EPwm1Regs.DBFED = 1;    // Falling Deadtime 설정
EPwm1Regs.DBRED = 1;    // Rising Deadtime 설정

/* Set Interrupts */
EPwm1Regs.ETSEL.bit.INTSEL = 1; // EPWM 인터럽트 옵션 - CTR이 PRD일때 동기화
EPwm1Regs.ETSEL.bit.INTEN = 1;  // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event    EPwm1Regs.

EPwm1Regs.ETSEL.bit.SOCAEN = 1;   // SOCA 이벤트 트리거 Enable
EPwm1Regs.ETSEL.bit.SOCASEL = 2;  // SCCA 트리거 조건 : 카운터 주기 일치 시 (읽는 시점이라고 생각하시면 됩니다)
EPwm1Regs.ETPS.bit.SOCAPRD = 1;   // SOCA 이벤트 분주 설정 : 트리거 조건 한번 마다 (샘플링을 EPWM주파수에 동기화를 시켰다고 보시면 됩니다.)
EALLOW;
EDIS;
}

void epwm2module()
{
    /* Setup Counter Mode and Clock */
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;  // Count 방식 설정 (Up방식으로)
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0;              // EPWM Clock 설정
    EPwm2Regs.TBCTL.bit.CLKDIV = 0;                 // EPWM Clock 설정

    /* Setup Phase */
    EPwm2Regs.TBPHS.half.TBPHS = 0; // 위상을 얼만큼 이동시키는지 설정
    EPwm2Regs.TBCTL.bit.PHSEN = 0;  // 위상을 이동 시킬지 말지를 결정 (0:Disable , 1:Enable)

    // Setup Period (Carrier Frequency)
    EPwm2Regs.TBPRD = (TBCLK/PWM_CARRIER)-1;   // Set Timer Period, (100MHz/100KHz)-1 = 999
    EPwm2Regs.TBCTR = 0;                  // Clear Counter

    /* Set Compare Value */
    EPwm2Regs.CMPA.half.CMPA =  0;   // 비교기의 +레퍼런스 설정 (초기조건 - 0으로 설정)

    /* Setup shadowing */
    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;      // 원신호를 보호해주는 Shadow 레지스터 설정
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 원신호를 보호해주는 Shadow 레지스터 설정
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;   // Shadow 레지스터에서 로드하는 시점을 설정
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 동기화 시점을 설정 (카운터가 Zero일 경우 동기화), 위상을 사용하지 않아 크게 의미가 없는 코드

    /* Set actions */
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
    EPwm2Regs.AQCTLA.bit.ZRO=AQ_SET;    // Carrier가 zero일때  high신호로

    /* Set Dead-time */
    EPwm2Regs.DBCTL.bit.IN_MODE = 0;
    EPwm2Regs.DBCTL.bit.OUT_MODE = 0;
    EPwm2Regs.DBCTL.bit.POLSEL = 0;

    EPwm2Regs.DBFED = 1;    // Falling Deadtime 설정
    EPwm2Regs.DBRED = 1;    // Rising Deadtime 설정
}

interrupt void epwm1isr(void)
{
    EPwm1IsrTicker++;

    if (PwmDutyRatioA >= 0.8)
    {
        PwmDutyRatioA = 0.8;
    }

    EPwm1Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA;
    EPwm2Regs.CMPA.half.CMPA = (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA;

    EPwm1Regs.ETCLR.bit.INT = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}

interrupt void Adcisr(void)
{
    if(AdcisrTicker==10)
    {
        AdcOffset = ((3.3 * (float32)(AdcRegs.ADCRESULT0)) / 4096);     //Offset value before startup
    }

    AdcisrTicker++;

    if (AdcisrTicker > 10000)
        AdcisrTicker = 11;

        Adc_Result = ((3.3 * (float32)(AdcRegs.ADCRESULT0) / 4096) - AdcOffset) * 10;

}
void voltageController(void)     // Voltage Control Mode
{
////////////// Deadtime 설정 ///////////////
EPwm1Regs.DBCTL.bit.IN_MODE = 0;    // EPWMxA is the source for both falling-edge & rising-edge delay
EPwm1Regs.DBCTL.bit.OUT_MODE = 3;   // Dead-band is fully enabled for both rising-edge delay on EPWMxA and falling-edge delay on EPWMxB
EPwm1Regs.DBCTL.bit.POLSEL = 2;     // Active High Complementary (AHC). EPWMxB is inverted

EPwm2Regs.DBCTL.bit.IN_MODE = 0;    // EPWMxA is the source for both falling-edge & rising-edge delay
EPwm2Regs.DBCTL.bit.OUT_MODE = 3;   // Dead-band is fully enabled for both rising-edge delay on EPWMxA and falling-edge delay on EPWMxB
EPwm2Regs.DBCTL.bit.POLSEL = 2;     // Active High Complementary (AHC). EPWMxB is inverted

    ////////////// PI 제어기 설정 /////////////////
    if(Adc_Result<4.0)
    {
        PwmDutyRatio=0.416;
        return;
    }
    V_err=V_ref-Adc_Result;                 
    Antierr=V_err-K_a1*(out_pi-out_sat);
    Integerr +=K_i1*Antierr;
    out_pi=Integerr + K_p1*V_err;



    if(out_pi>0.8)
        out_sat=0.8;
    else if(out_pi<0.1)
        out_sat=0.1;
    else
        out_sat=out_pi;
    PwmDutyRatio=out_sat;
    VoltageTicker++;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;    // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;      // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 High신호로
EPwm1Regs.CMPA.half.CMPA =  (EPwm1Regs.TBPRD + 1) * PwmDutyRatioA;        // 비교기와 최종 레퍼런스 비교
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;      // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 High신호로
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;    // Carrier가 올라가면서 레퍼런스와 만나는 지점에서 Low신호로
EPwm2Regs.CMPA.half.CMPA = (EPwm2Regs.TBPRD + 1) * PwmDutyRatioA;        // 비교기와 최종 레퍼런스 비교
}

can realize PI control, voltage control mode, and can output the control result on the SC450 control board.

New contributor

Xingyi Li is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật