搜索
bottom↓
回复: 1

大家帮我看下我这款数字PFC电源,电流环不起作用

[复制链接]

出0入0汤圆

发表于 2016-9-27 15:05:47 | 显示全部楼层 |阅读模式
#include "P33ep32mc202.h"
/** CONFIGURATION **************************************************/
_FGS(0xff);//写保护关闭
_FOSCSEL(0xfb);//双速振荡器启动使能 PWM锁定 带PLL的主振荡器
_FOSC(0xdd);//禁止时钟切换 外设引脚多次配置 SOC2数字IO XT晶振模式
_FWDT(0x7f);//看门狗禁止
_FPOR(0xff);//I2C1被映射到SAD1/SCL1引脚 欠压复位_
_FICD(0x03);//禁止JTAG 通过PGEC1 PGED1通讯
void initAdc1(void);
void Delayus(unsigned int);
int  i, j;
unsigned char flag;
float DC_BUSSENSE,DC_DAT;
int PFC_CURRENT;
float ACV_SENSE;
int ADCValues[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int PWMDAT;
float ADC_DAT;
float IAC;  //IAC=K3*PFC_CURRENT
void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt(void);
struct _pid{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err; //定义偏差值
float err_next; //定义上一个偏差值
float err_last; //定义最上前的偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
}pid;
void PID_init()
{
        pi_dc.SetSpeed=0.0;
        pi_dc.ActualSpeed=0.0;
        pi_dc.err=0.0;
        pi_dc.err_last=0.0;
        pi_dc.err_next=0.0;
        pi_dc.Kp=0.22;
        pi_dc.Ki=0.015;
        pi_dc.Kd=0.0;

        pi_cs.SetSpeed=0.0;
        pi_cs.ActualSpeed=0.0;
        pi_cs.err=0.0;
        pi_cs.err_last=0.0;
        pi_cs.err_next=0.0;
        pi_cs.Kp=0.35;
        pi_cs.Ki=0.01;
        pi_cs.Kd=0.0;

}
float VDCcompute(float speed,float CurrentValue)
{
        pi_dc.SetSpeed=speed;
        pi_dc.err=pi_dc.SetSpeed-CurrentValue;
        float incrementSpeed=pi_dc.Kp*(pi_dc.err-pi_dc.err_next)+pi_dc.Ki*pi_dc.err-pid.Kd*(pi_dc.err-2*pi_dc.err_next+pi_dc.err_last);
        pi_dc.ActualSpeed+=incrementSpeed;
        pi_dc.err_last=pi_dc.err_next;
        pi_dc.err_next=pi_dc.err;
        return pi_dc.ActualSpeed;
}
float PFCcompute(float speed,float CurrentValue)
{
        pi_cs.SetSpeed=speed;
        pi_cs.err=pi_cs.SetSpeed-CurrentValue;
        float incrementSpeed=pi_cs.Kp*(pi_cs.err-pi_cs.err_next)+pi_cs.Ki*pi_cs.err-pid.Kd*(pi_cs.err-2*pi_cs.err_next+pi_cs.err_last);
        pi_cs.ActualSpeed+=incrementSpeed;
        pi_cs.err_last=pi_cs.err_next;
        pi_cs.err_next=pi_cs.err;
        return pi_cs.ActualSpeed;
}
void System_Init(void)
{
   TRISB &= ~0xfc00;//RB10-RB15 清零
   IOCON1 = 0x0000;//GPIO 模块控制 PWMxH PWMxL引脚
}
int main(void)
{
    // The CPU clock frequency is Fcy = Fosc/2 = 40 MHz.
    CLKDIVbits.PLLPRE = 0; /* N2 = 2  7.3728M/2=3.6864*/
    PLLFBD = 41; /* M = 43  3.6864*43=158.5*/
    CLKDIVbits.PLLPOST = 0; /* N1 = 2 158.5M/2=79.25M */
    OSCTUN = 0;
    /* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
    __builtin_write_OSCCONH(0x03);
    __builtin_write_OSCCONL(0x01);
    while (OSCCONbits.COSC != 0x3);
    while (_LOCK == 0); /* Wait for PLL lock at 40 MIPS */
    Delayus(5000);
    System_Init();
    Timer3_Timing_Init();
    initAdc1();
    OC1_Init();
    PID_init();
    while(1)
    {
         
    }
}
/*-----------------------------------------------
  名称:ADC初始化程序
  编写: Transmigration
  日期:2016-09-12
  修改:无
  内容: 10位 4路同时采样ADC配置
------------------------------------------------*/
void initAdc1(void)
{
    /* ADC端口配置 */
    ANSELA = ANSELB = 0x0000;
    ANSELAbits.ANSA0 = 1; // Ensure AN0/RA0 is analog
    ANSELAbits.ANSA1 = 1; // Ensure AN1/RA1 is analog
    ANSELBbits.ANSB0 = 1; // Ensure AN2/RB0 is analog
    ANSELBbits.ANSB3 = 1; // Ensure AN5/RB3 is analog
    /* Initialize and enable ADC module */
    AD1CON1bits.FORM=0b00;//AD结果为整数
    AD1CON1bits.SIMSAM=1;  //同时采样
    AD1CON1bits.ASAM=1;    //上次采样结束立即开始采样
    AD1CON1bits.SSRCG=0;
    AD1CON1bits.SSRC=0b010; //定时器3比较结束立即开始采样
    //AD12B=1;//12位ADC
    AD1CON2bits.VCFG=0b000; //参考电压为VCC电压
    AD1CON2bits.CHPS=0b11; //同时采样4个通道
    AD1CON2bits.SMPI=0b00001;//每完成2次采样产生ADC中断
    AD1CON3 = 0x0007;//AD转换时钟TP(ADCS<7:0> + 1) =8  Tcy*8 = TAD=0.00000025*8=0.0000002 TCON=12*0.0000002=0.0000024=416K
    //FCY=Fsoc/2;TCY=1/Fcy; TCY=1/40M=0.000000025  采样同期TAD=(Tcy*(ADCS+1));转换时间TCON=(12*TAD)或14*TAD
    AD1CON4 = 0x0000;
    AD1CSSH = 0x0000;
    AD1CSSL = 0x0000;
    AD1CHS0bits.CH0SA = 5; // Select AN5 for CH0 +ve input
    AD1CHS0bits.CH0NA = 0; // Select Vref- for CH0 -ve input
    AD1CHS123bits.CH123SA = 0; // Select AN0 for CH1 +ve input
    AD1CHS123bits.CH123NA = 0; // Select Vref- for CH1/CH2/CH3 -ve inputs
    /*ADC中断设置*/
     IFS0bits.AD1IF = 0;             // Clear the A/D interrupt flag bit
     IEC0bits.AD1IE = 1;             // Do Not Enable A/D interrupt
    _AD1IP=6;
     AD1CON1bits.ADON = 1;           // Turn on the A/D converter
}
/*-----------------------------------------------
  名称:Timer3定时器初始化
  编写: Transmigration
  日期:2016-09-12
  修改:无
  内容: 产生80KHZ时钟信号
*      提供ADC中断触发信号
*      提供OCx比较输出信号
*      改变RP3的值可改变OCx频率
------------------------------------------------*/
void Timer3_Timing_Init(void)//定时器模式
{
     T3CONbits.TON = 0;//禁止16位Timer3
    T3CONbits.TCS = 0;//内部时钟Fosc/2
    T3CONbits.TGATE = 0;//门控时间累加位 禁止
    T3CONbits.TCKPS = 0x00;//输入时钟预分频比1:1
    T3CONbits.TSIDL = 0;//空闲模式继续工作
   
    TMR3 =0x0000;//初始值*/
    PR3 =500;//周期值80KHZ   FCY=FOC/2=80M/2=40M/500=80K
    _T3IP = 0x01; // 优先级1
    IFS0bits.T3IF = 0; // Timer3中断标志状态位 清零
    IEC0bits.T3IE = 0; // Timer3中断允许位 禁止
    T3CONbits.TON = 1;//启动使能16位Timer3
}
/*-----------------------------------------------
  名称:输出比较PWM初始化程序
  编写: Transmigration
  日期:2016-09-12
  修改:无
  内容: 配置OC1 OC2 为边沿PWM模式带故障保护
*      改变OC1R OC2R 可改变占空比
------------------------------------------------*/
void OC1_Init(void)
{
    RPOR4bits.RP43R = 0b010000;//RP43连接到输出比较 1 输出   OC1映射到RP引脚
      RPOR4bits.RP42R = 0b010001;//RP43连接到输出比较 2 输出
    OC1CON1bits.OCM = 0b000;//禁止输出比较
    OC1CON1bits.OCSIDL = 0;//空闲模式继续
    OC1CON1bits.OCTSEL = 0b001;//比较Timer3的时钟源
    //OC1CON1bits.OCTSEL = 0;//比较Timer2的时钟源
    OC1CON2bits.SYNCSEL=0b01101;//Timer3 同步或触发 OC1
    //OC1CON2bits.SYNCSEL=0b01100;//Timer2 同步或触发 OC1
    OC1R = 0;//输出比较寄存器
    OC1RS =0;

    OC2CON1bits.OCM = 0b000;//禁止输出比较
    OC2CON1bits.OCSIDL = 0;//空闲模式继续
    OC2CON1bits.OCTSEL = 0b001;//比较Timer3的时钟源
    //OC2CON1bits.OCTSEL = 0b000;//比较Timer2的时钟源
     OC2CON2bits.SYNCSEL=0b01101;//同步Timer3同步或触发 OC2
   // OC2CON2bits.SYNCSEL=0b01100;//同步Timer2同步或触发 OC2

      OC2R = 0;//输出比较寄存器
      OC2RS = 0;

    //OC1 CO2 故障设置
    RPINR11bits.OCFAR=36;    //选择映射脚到RP36即RB4为故障输入低电平有效
    OC1CON1bits.ENFLTA=1;
    OC1CON1bits.OCFLTA=1;
    OC1CON2bits.FLTTRIEN=0;    //发生故障输出状态由FLTOUT决定
    OC1CON2bits.FLTOUT=0;   //发生故障输出为低电平
   // OC1CON2bits.FLTMD=1;    //PWM故障为无效模式

    OC2CON1bits.ENFLTA=1;   //使能a 故障输入
    OC2CON1bits.OCFLTA=1;   //产生故障条件
    OC2CON2bits.FLTTRIEN=0;    //发生故障输出状态由FLTOUT决定
    OC2CON2bits.FLTOUT=0;   //发生故障输出为低电平

    IPC0bits.OC1IP = 0x02;// 中断优先级2
    IFS0bits.OC1IF = 0;// 清中断
    IEC0bits.OC1IE = 0;// 禁止中断
  
   
     IPC1bits.OC2IP = 0x01;// 中断优先级2
     IFS0bits.OC2IF = 0;// 清中断
    IEC0bits.OC2IE = 0;// 禁止中断
    OC1CON1bits.OCM = 0b110;//将OC1引脚初始化为低电平,在OCx引脚上产生连续输出脉冲
    OC2CON1bits.OCM = 0b110;//将OC1引脚初始化为低电平,在OCx引脚上产生连续输出脉冲

}
void Delayus(unsigned int delay)
{
    for (i = 0; i < delay; i++)
    {
        asm  volatile ("repeat #39");
        asm volatile ("nop");
    }
}
/* ADC1中断,每2次采样产生一次中断40KHZ*/
void __attribute__((interrupt, no_auto_psv))  _AD1Interrupt(void)
{
    IFS0bits.AD1IF = 0;             // Clear the ADC1 Interrupt Fla
     PFC_CURRENT = ADC1BUF2; // Read the AN1 conversion result
     //电压PI补偿器计算
    if(flag==0)
    {
        DC_BUSSENSE = ADC1BUF1; //Read the AN0 输出直流检
        DC_DAT=VDCcompute(740.0,DC_BUSSENSE);
    }
    //读取ACV瞬时值
    if(flag==1)
    {
        ACV_SENSE = ADC1BUF3;// Read the AN2 conversion result
    }
    //进入电流环PI补偿器计算
     if(DC_BUSSENSE>=780)
     {   OC1R=OC2R=1;}
         else
         {
              ADC_DAT=(ACV_SENSE*DC_DAT);
              ADC_DAT=(ADC_DAT/495)*4.1;
              PWMDAT=PFCcompute(ADC_DAT, PFC_CURRENT);
              if(PWMDAT<=65) PWMDAT=65;
              PWMDAT=500-PWMDAT;
              OC1R=OC2R=PWMDAT;
           }
    flag++;
    if(flag>=2)flag=0;
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-10-26 20:59:28 | 显示全部楼层
整流桥的导通角还不够呀
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 17:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表