概述
http://www.ti.com.cn/cn/lit/an/tidu312/tidu312.pdf
http://www.ti.com.cn/cn/lit/an/slua712/slua712.pdf
Designing a UCD3138 Controlled Interleaved PFCBosheng Sun High Performance Isolated
http://www.st.com/content/ccc/resource/technical/document/application_note/group0/9e/cc/b1/4a/5d/c8/4a/64/DM00333800/files/DM00333800.pdf/jcr:content/translations/en.DM00333800.pdf
https://www.st.com/content/ccc/resource/technical/document/application_note/fa/f1/fe/3d/81/1e/47/45/DM00050692.pdf/files/DM00050692.pdf/jcr:content/translations/en.DM00050692.pdf
http://ww1.microchip.com/downloads/en/AppNotes/01106A.pdf
http://www.ti.com/lit/an/slua079/slua079.pdf
http://www.ti.com/lit/an/slua896/slua896.pdf
http://www.ti.com/lit/ml/slyy131/slyy131.pdf
https://www.ti.com/seclit/ml/slup203/slup203.pdf
http://www.rolfes.org/kevin_rolfes_msee_thesis.pdf
https://www.infineon.com/dgdl/APP_XMC4000_PFC_Example_Code_v1_0.exe?fileId=db3a30433fa3001d013fa46cca63035a
https://www.infineon.com/dgdl/APP_XMC4000_PFC_v1_0.pdf?fileId=db3a30433f74fc8b013f7549c9430047
/*******************************************************************************
Copyright (c) 2013, Infineon Technologies AG **
All rights reserved. **
**
Redistribution and use in source and binary forms, with or without **
modification,are permitted provided that the following conditions are met: **
**
*Redistributions of source code must retain the above copyright notice, **
this list of conditions and the following disclaimer. **
*Redistributions in binary form must reproduce the above copyright notice, **
this list of conditions and the following disclaimer in the documentation **
and/or other materials provided with the distribution. **
*Neither the name of the copyright holders nor the names of its contributors **
may be used to endorse or promote products derived from this software without**
specific prior written permission. **
**
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" **
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE **
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE **
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE **
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR **
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF **
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS **
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN **
CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) **
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE **
POSSIBILITY OF SUCH DAMAGE. **
**
To improve the quality of the software, users are encouraged to share **
modifications, enhancements or bug fixes with Infineon Technologies AG **
dave@infineon.com). **
**
********************************************************************************
** **
** **
** PLATFORM : Infineon XMC4000 Series **
** **
** COMPILER : Compiler Independent **
** **
** AUTHOR : Application Engineering **
** **
** MAY BE CHANGED BY USER [yes/no]: Yes **
** **
** MODIFICATION DATE : Jul 01, 2013 **
** **
*******************************************************************************/
/*******************************************************************************
** Author(s) Identity **
********************************************************************************
** **
** Initials Name **
** ---------------------------------------------------------------------------**
** HLM Application Engineering **
*******************************************************************************/
/**
* @file main.c
* @brief Main.c file for PFC operating in CCM, Avg Current Mode Ctrl
*
*/
/*******************************************************************************
** Include Files **
*******************************************************************************/
/* Inclusion of header file */
#include <DAVE3.h> //Declarations from DAVE3 Code Generation (includes SFR declaration)
#include "GPIO.h"
#include "PFC.h"
#include "arm_math.h"
/*******************************************************************************
** Global Constant Definitions **
*******************************************************************************/
#define HIGH_LINE
#define N_VIN 0.166f
#define N_VOUT 0.166f
#define OUTPUTVOLTAGE_REF 400.0f
#define BLOCK_SIZE 1
#define NUM_TAPS 12
__IO uint32_t *ShadowCompareReg;
__IO uint32_t *ShadowTransfer;
__IO uint32_t *ADCResult_Vin;
__IO uint32_t *ADCResult_Vout;
__IO uint32_t *ADCResult_Current;
/*******************************************************************************
** Global Variable Definitions **
*******************************************************************************/
uint16_t uwInductorCurrent;
uint16_t uwOutputVoltage;
uint16_t uwInputVoltage;
uint16_t FIR_DelayCounter;
uint16_t OverVoltageBit;
uint16_t qADCUpperBound;
uint16_t qADCLowerBound;
uint16_t qOverVoltageCount;
uint16_t qUnderVoltageCount;
float fADCUpperBound;
float fADCLowerBound;
uint32_t blockSize = BLOCK_SIZE;
static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];
volatile float fOpAmpOffset;
volatile unsigned long timingdelay;
volatile PFC_Coefs_Type PFC;
arm_pid_instance_f32 PI_Current;
arm_pid_instance_f32 PI_Voltage;
arm_fir_instance_f32 sFIR;
/*******************************************************************************
** Private Constant Definitions **
*******************************************************************************/
const float32_t firCoeffs32[NUM_TAPS] =
{0.0056f, 0.0158f, 0.0467f, 0.0967f, 0.1503f, 0.1850f, 0.1850f, 0.1503f, 0.0967f, 0.0467f, 0.0158f, 0.0056f};
/*******************************************************************************
** Public Function Definitions **
*******************************************************************************/
void Delay100us(unsigned long time);
void PFC_Init(void);
void ControlLoop_Init(void);
void Current_Offset_Measurement(void);
void arm_fir_f32_1(const arm_fir_instance_f32 *S, float32_t *pSrc, float32_t *pDst);
/*******************************************************************************
** **
** FUNCTION : int main(void) **
** **
** DESCRIPTION : This is the main function of the PFC code **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
int main(void)
{
// status_t status; // Declaration of return variable for DAVE3 APIs (toggle comment if required)
// at CLK001 App: Set Back Up Clock Trimming Option to "Backup Clock Factory Calibrated"
DAVE_Init(); // Initialization of DAVE Apps
/* Set system timer to 100us */
SysTick_Config(12000);
/* Change the interrupt setting from Period Match to One Match Interrupt. Take note of the CCU4x/CC4x used */
WR_REG(CCU40_CC40->INTE, CCU4_CC4_INTE_PME_Msk, CCU4_CC4_INTE_PME_Pos, 0);
WR_REG(CCU40_CC40->INTE, CCU4_CC4_INTE_OME_Msk, CCU4_CC4_INTE_OME_Pos, 1);
/* Initialize pointers to corresponding registers */
ADCResult_Current = &ADCCH001_Handle0.ADCGrPtr->RES[ADCCH001_Handle0.kEndResultRegNo];
ADCResult_Vout = &ADCCH001_Handle1.ADCGrPtr->RES[ADCCH001_Handle1.kEndResultRegNo];
ADCResult_Vin = &ADCCH001_Handle2.ADCGrPtr->RES[ADCCH001_Handle2.kEndResultRegNo];
ShadowCompareReg = &PWMSP001_Handle0.CC4yRegsPtr->CRS;
ShadowTransfer = &PWMSP001_Handle0.CC4yKernRegsPtr->GCSS;
/* Initialize ADC Queue */
ADC002_InitializeQueue(&ADC002_Handle0);
/* Set Output Voltage Lower and Higher Boundary for STARTUP OPERATION */
fADCUpperBound = 480.0f / N_VOUT;
fADCLowerBound = 0.0f / N_VOUT;
qADCUpperBound = (uint32_t) fADCUpperBound;
qADCLowerBound = (uint32_t) fADCLowerBound;
/* Set Output Voltage Upper Boundary (Boundary1) and Lower Boundary (Boundary0) */
WR_REG(ADCGROUP001_Handle0.VADCGroupPtr->BOUND, VADC_G_BOUND_BOUNDARY1_Msk, VADC_G_BOUND_BOUNDARY1_Pos, qADCUpperBound);
WR_REG(ADCGROUP001_Handle0.VADCGroupPtr->BOUND, VADC_G_BOUND_BOUNDARY0_Msk, VADC_G_BOUND_BOUNDARY0_Pos, qADCLowerBound);
/* Initialize Current Loop PI controller coefficients AC-DC Converter */
PI_Current.Kp = 0.0f;
PI_Current.Ki = 0.0f;
PI_Current.Kd = 0.0f;
arm_pid_init_f32(&PI_Current, 1);
/* Initialize Voltage Loop PI controller coefficients */
PI_Voltage.Kp = 0.0;
PI_Voltage.Ki = 0.0;
PI_Voltage.Kd = 0.0;
arm_pid_init_f32(&PI_Voltage, 1);
/* Start CCU4 Slices */
PWMSP001_Start(&PWMSP001_Handle0);
PWMSP001_Start(&PWMSP001_Handle1);
/* Delay 500ms to wait for OpAmp output to stabilize */
Delay100us(5000);
/* Measure OpAmp Offset */
Current_Offset_Measurement();
/* Initialize PFC variables */
PFC_Init();
/* Enable Period Match and Compare Match interrupts for Voltage and Current Loop */
NVIC002_EnableIRQ(&NVIC002_Handle0);
NVIC002_EnableIRQ(&NVIC002_Handle1);
/* Delay 50ms to wait for FIR filter to stabilise */
Delay100us(500);
/* Initialize PI controllers coefficients for Voltage and Current Loops */
ControlLoop_Init();
/* Enable Overvoltage Interrupt */
NVIC002_EnableIRQ(&NVIC002_Handle2);
/* Delay until PFC Steady State operation is reached */
Delay100us(5000);
Delay100us(5000);
/* Set Output Voltage Lower and Higher Boundary for STEADY STATE OPERATION */
fADCUpperBound = 450.0f / N_VOUT;
fADCLowerBound = 370.0f / N_VOUT;
qADCUpperBound = (uint32_t) fADCUpperBound;
qADCLowerBound = (uint32_t) fADCLowerBound;
/* Set Output Voltage Upper Boundary (Boundary1) and Lower Boundary (Boundary0) */
WR_REG(ADCGROUP001_Handle0.VADCGroupPtr->BOUND, VADC_G_BOUND_BOUNDARY1_Msk, VADC_G_BOUND_BOUNDARY1_Pos, qADCUpperBound);
WR_REG(ADCGROUP001_Handle0.VADCGroupPtr->BOUND, VADC_G_BOUND_BOUNDARY0_Msk, VADC_G_BOUND_BOUNDARY0_Pos, qADCLowerBound);
while(1)
{
}
return 0;
}
/*******************************************************************************
** **
** FUNCTION : void PeriodMatch_INT(void) **
** **
** DESCRIPTION : This is the Interrupt Service Routine for **
** CCU4 Period Match event. It is used for Current Loop **
** and updating PWM duty cycle. **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void PeriodMatch_INT(void)
{
volatile uint16_t tempInductorCurrent;
/* Read Input Voltage */
PFC.qVin = *ADCResult_Vin;
PFC.fVin = (float)PFC.qVin * PFC.fN_Vin;
/* Read Inductor Current */
tempInductorCurrent = *ADCResult_Current;
PFC.fIpfc = (float)tempInductorCurrent;
PFC.fIpfc = PFC.fIpfc - fOpAmpOffset;
/* Calculate Current Command */
PFC.fCurrentCmdOut = PFC.fVin * PFC.fInvSqr * PFC.fPI_VoltageOut;
/* Current Loop Calculation for AC-DC Converter */
PFC.fPI_CurrentOut = arm_pid_f32(&PI_Current, (PFC.fCurrentCmdOut - PFC.fIpfc));
if (OverVoltageBit == 0)
{
/* Update PWM for Current Control */
*ShadowCompareReg = (uint16_t) (PFC.fPI_CurrentOut);
/* Limit PWM duty cycle */
if(*ShadowCompareReg > PFC.qPWM_Current_MAX)
{
*ShadowCompareReg = PFC.qPWM_Current_MAX;
}
}
else
{
/* Turn off PWM */
*ShadowCompareReg = 0;
}
/* Enable Shadow Transfer for Slice 0 */
*ShadowTransfer = 0x01;
}
/*******************************************************************************
** **
** FUNCTION : void CompareMatch_INT(void) **
** **
** DESCRIPTION : This is the Interrupt Service Routine for **
** CCU4 Compare Match event. It is used for Output Voltage **
** Loop and Feedforward Filter **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void CompareMatch_INT(void)
{
/* Read Output Voltage */
PFC.qVout = *ADCResult_Vout;
PFC.fVout = (float)PFC.qVout * PFC.fN_Vout;
/* Voltage Loop Calculation */
PFC.fPI_VoltageOut = arm_pid_f32(&PI_Voltage, (PFC.fVoltageRef - PFC.fVout));
/* FIR filter */
FIR_DelayCounter--;
while(FIR_DelayCounter == 0)
{
/* FIR Filter */
arm_fir_f32_1(&sFIR, &PFC.fVin, &PFC.fFilterResult);
/* Calculate Inverse Square */
PFC.fInvSqr = 1.0f / (PFC.fFilterResult * PFC.fFilterResult);
FIR_DelayCounter = 40;
}
}
/*******************************************************************************
** **
** FUNCTION : void Overvoltage_INT(void) **
** **
** DESCRIPTION : This is the Interrupt Service Routine for **
** VADC Channel Event Interrupt. It is used as overvoltage **
** handler. **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void Overvoltage_INT(void)
{
/* Upper Boundary Interrupt */
if ((PFC.qVout > qADCUpperBound) && !OverVoltageBit)
{
/* Sample OverVoltage Interrupt occurrence for 500 times (5ms) */
qOverVoltageCount++;
if (qOverVoltageCount > 500)
{
/* Turn On OverVoltage Bit */
OverVoltageBit = 1;
/* Reset PI Controllers */
arm_pid_reset_f32(&PI_Current);
arm_pid_reset_f32(&PI_Voltage);
/* Reset OverVoltage Counter */
qOverVoltageCount = 0;
}
}
/* Lower Boundary Interrupt */
else if ((PFC.qVout < qADCLowerBound) && OverVoltageBit)
{
/* Sample UnderVoltage Interrupt occurrence for 500 times (5ms) */
qUnderVoltageCount++;
if(qUnderVoltageCount > 500)
{
/* Turn Off OverVoltage Bit */
OverVoltageBit = 0;
/* Enable PI Controllers */
ControlLoop_Init();
/* Reset UnderVoltage Counter */
qUnderVoltageCount = 0;
}
}
}
/*******************************************************************************
** **
** FUNCTION : void PFC_Init(void) **
** **
** DESCRIPTION : This function is to initialize PFC parameters and **
** Feedforward Filter **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void PFC_Init(void)
{
/* Initialize FIR Filter */
arm_fir_init_f32(&sFIR, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], blockSize);
/* Assign values to PFC struct */
PFC.fN_Vin = N_VIN;
PFC.fN_Vout = N_VOUT;
PFC.fVoltageRef = OUTPUTVOLTAGE_REF;
FIR_DelayCounter = 40;
/* Determine Maximum Duty Cycle from CCU4 Period Register. In this case it is 80% */
PFC.qPWM_Current_MAX = (PWMSP001_Handle0.CC4yRegsPtr->PRS * 9.6) / 10;
/* Initialize OverVoltage Conditions to 0 during startup */
OverVoltageBit = 0;
qOverVoltageCount = 0;
qUnderVoltageCount = 0;
}
/*******************************************************************************
** **
** FUNCTION : void ControlLoop_Init(void) **
** **
** DESCRIPTION : This function is to initialize Current and Voltage Loop **
** Parameters (Kp and Ki) **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void ControlLoop_Init(void)
{
#ifdef HIGH_LINE
/* Initialize Current Loop PI controller coefficients AC-DC Converter */
PI_Current.Kp = 0.036f/2; /* high line */
PI_Current.Ki = 0.02f/2; /* high line */
PI_Current.Kd = 0.0f;
arm_pid_init_f32(&PI_Current, 1);
/* Initialize Voltage Loop PI controller coefficients */
PI_Voltage.Kp = 0.01f; /* high line */
PI_Voltage.Ki = 0.04f*15; /* high line */
PI_Voltage.Kd = 0.0f;
arm_pid_init_f32(&PI_Voltage, 1);
#else
/* Initialize Current Loop PI controller coefficients AC-DC Converter */
PI_Current.Kp = 0.04/2; /* low line */
PI_Current.Ki = 0.022/10; /* low line */
PI_Current.Kd = 0.0f;
arm_pid_init_f32(&PI_Current, 1);
/* Initialize Voltage Loop PI controller coefficients */
PI_Voltage.Kp = 0.01f/4; /* low line */
PI_Voltage.Ki = 0.04f*10; /* low line */
PI_Voltage.Kd = 0.0f;
arm_pid_init_f32(&PI_Voltage, 1);
#endif
}
/*******************************************************************************
** **
** FUNCTION : void Current_Offset_Measurement(void) **
** **
** DESCRIPTION : This function is to measure the Current Op-Amp Offset **
** in the beginning **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void Current_Offset_Measurement(void)
{
uint16_t MeasurementCount = 0;
uint32_t ulOpAmpOffset = 0;
while (MeasurementCount < 32)
{
/* Read Inductor Current from ADC Result Register */
ADCCH001_GetResult(&ADCCH001_Handle0, &uwInductorCurrent);
/* Accumulate Inductor Current reading for 32 times */
ulOpAmpOffset += (uwInductorCurrent & 0x0FFF);
MeasurementCount++;
}
/* Find the Op-Amp Current Sense average by dividing the accumulated readings */
fOpAmpOffset = (float)ulOpAmpOffset / 32.0;
}
/*******************************************************************************
** **
** FUNCTION : void Delay100us(unsigned long time) **
** **
** DESCRIPTION : This function produces 100us delay time **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void Delay100us(unsigned long time)
{
unsigned long t, m;
timingdelay = time;
for(t = timingdelay; t>0; t--)
{
for(m = 1000; m>0; m--);
}
}
void SysTick_Handler(void)
{
if(timingdelay != 0)
{
timingdelay--;
}
}
/*******************************************************************************
** **
** FUNCTION : void arm_fir_f32_1( , , ) **
** **
** DESCRIPTION : This is Feedfoward Filter function **
** **
** VERSION : 1.0.0 (Initial version) **
** **
** DATE : Jul 01, 2013 **
** **
*******************************************************************************/
void arm_fir_f32_1(const arm_fir_instance_f32 * S, float32_t * pSrc, float32_t * pDst)
{
float32_t *pState = S->pState; /* State pointer */
float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
float32_t *pStateCurnt; /* Points to the current sample of the state */
float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
uint32_t i, tapCnt; /* Loop counters */
float32_t acc0; /* Accumulators */
/* S->pState points to state array which contains previous frame (numTaps - 1) samples */
/* pStateCurnt points to the location where the new input data should be written */
pStateCurnt = &(S->pState[(numTaps - 1u)]);
/* Copy one sample at a time into state buffer */
*pStateCurnt++ = *pSrc++;
/* Set the accumulator to zero */
acc0 = 0.0f;
/* Initialize state pointer */
px = pState;
/* Initialize Coefficient pointer */
pb = (pCoeffs);
i = numTaps;
/* Perform the multiply-accumulates */
do
{
acc0 += *px++ * *pb++;
i--;
} while(i > 0u);
/* The result is store in the destination buffer. */
*pDst++ = acc0;
/* Advance state pointer by 1 for the next sample */
pState = pState + 1;
/* Processing is complete.
** Now copy the last numTaps - 1 samples to the satrt of the state buffer.
** This prepares the state buffer for the next function call. */
/* Points to the start of the state buffer */
pStateCurnt = S->pState;
tapCnt = (numTaps - 1u) >> 2u;
/* copy data */
while(tapCnt > 0u)
{
*pStateCurnt++ = *pState++;
*pStateCurnt++ = *pState++;
*pStateCurnt++ = *pState++;
*pStateCurnt++ = *pState++;
/* Decrement the loop counter */
tapCnt--;
}
/* Calculate remaining number of copies */
tapCnt = (numTaps - 1u) % 0x4u;
/* Copy the remaining q31_t data */
while(tapCnt > 0u)
{
*pStateCurnt++ = *pState++;
/* Decrement the loop counter */
tapCnt--;
}
}
最后
以上就是震动发箍为你收集整理的PFC+LLC实现的全部内容,希望文章能够帮你解决PFC+LLC实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复