找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4954|回复: 5
打印 上一主题 下一主题
收起左侧

微型逆变器设计资料及源码

[复制链接]
跳转到指定楼层
楼主
内容包括:
1. PCB 原理图 GERBER文件
2. BOM清单
3. MATLAB仿真工程
4. 源代码工程

The 230Vac Solar Microinverter Design Package contains the following:
- Application Note
- Schematic and Layout Files
- Gerber Files
- Source Code
- MATLAB Models
- Bill of Materials
- Demo Instructions

Getting Started:
See Grid Connected Solar Microinverter Demo Instructions.pdf for instructions on demonstration setup.

Known Issues:
The Solar Microinverter currently uses the passive method for detecting Grid failures. A future software update is  planned to implement active method for anti-islanding.

电路原理图如下:




全部资料51hei下载地址:
230Vac Grid-Connected Solar Microinverter Design Package.zip (2.45 MB, 下载次数: 115)


部分源代码如下
  1. /////////////////////////////////////////////////////////////////////////////////////////////////
  2. // ?2012 Microchip Technology Inc.
  3. //
  4. // MICROCHIP SOFTWARE NOTICE AND DISCLAIMER:  You may use this software, and any
  5. // derivatives created by any person or entity by or on your behalf, exclusively with
  6. // Microchip抯 products.  Microchip and its licensors retain all ownership and intellectual
  7. // property rights in the accompanying software and in all derivatives here to.  
  8. //
  9. // This software and any accompanying information is for suggestion only.  It does not
  10. // modify Microchip抯 standard warranty for its products.  You agree that you are solely
  11. // responsible for testing the software and determining its suitability.  Microchip has
  12. // no obligation to modify, test, certify, or support the software.
  13. //
  14. // THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
  15. // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT,
  16. // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION
  17. // WITH MICROCHIP扴 PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
  18. //
  19. // IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, TORT
  20. // (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), STRICT LIABILITY, INDEMNITY,
  21. // CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, PUNITIVE, EXEMPLARY, INCIDENTAL
  22. // OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  23. // SOFTWARE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR
  24. // THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT ALLOWABLE BY LAW, MICROCHIP'S TOTAL
  25. // LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES,
  26. // IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  27. //
  28. // MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
  29. //
  30. /////////////////////////////////////////////////////////////////////////////////////////////////

  31. #include "Solar Microinverter_Statemachine.h"

  32. // System Fault Variables
  33. unsigned char storeFaultState = 0, faultCheckFlag = 0, criticalFaultRestartFlag = 0;
  34. unsigned char pvPanelOverVoltageFlag = 0, pvPanelUnderVoltageFlag = 0, overTemperatureFlag = 0;
  35. unsigned char inverterOverVoltageFlag = 0, inverterUnderVoltageFlag = 0, pvUnderVoltageCounter = 0;
  36. unsigned char inverterUnderVoltageCounter = 0, inverterOverVoltageCounter = 0;
  37. unsigned char tempFaultCnt = 0, driveSupplyFaultCnt = 0, referenceVoltageFaultCnt = 0;
  38. unsigned int criticalFaultCounter = 0, pvPanelMPPOverVoltageCnt = 0;
  39. unsigned int inverterOutputOverCurrent = 0;

  40. // Start-up and Restart Variables
  41. unsigned char zeroCrossDelay = 45, startFullBridgeFlag = 0;
  42. unsigned char zeroCrossDelayNom = 30, zeroCrossDelayMin = 22, zeroCrossDelayMax = 37;
  43. unsigned char acCurrentOffsetFlag = 0, acCurrentOffsetCounter = 0;
  44. unsigned int systemRestartCounter = 0, acCurrentOffset = 0;
  45. unsigned int inverterPeriodMin = INVERTERPERIOD60HZMIN, inverterPeriodMax = INVERTERPERIOD50HZMAX;
  46. long unsigned int acCurrentOffsetAverage = 0;

  47. // MPPT and Load Balance Variables
  48. unsigned char  loadBalanceCounter = 0, mpptCounter = 0, mpptStartUpFlag = 0;
  49. unsigned int inputVoltageAverage = 0, inputCurrentAverage = 0, openCircuitVoltage = 0;
  50. unsigned int mpptFactor = MPPTFACTORMINIMUM;
  51. int inputPower = 0, prevInputVoltageAverage = 0, deltaDutyCycle = 0;

  52. // Startup in system error, If a fault is detected
  53. // faultstate will change during the restart counter.
  54. unsigned char systemState = SYSTEMERROR;
  55. unsigned char switchState = SWITCHOFF;
  56. unsigned char faultState = NO_FAULT;

  57. // Externally Defined Variables
  58. extern unsigned char avgInputDataReadyFlag, startupZeroCrossCounter;
  59. extern unsigned char criticalFaultFlag, acCurrentOffsetFlag, ninetyDegreeDetectFlag;
  60. extern unsigned char burstModeActiveFlag;
  61. extern unsigned int mpptFactorMaximum, numberofSamples;
  62. extern unsigned int measuredTemperature, driveSupplyVoltage, referenceVoltage;
  63. extern unsigned int averageFlybackCurrent1, averageFlybackCurrent2;
  64. extern unsigned int inverterPeriod, peakInverterOutputVoltage, burstModeActiveCounter;;
  65. extern int inverterOutputCurrent;

  66. // Variable Declaration for DMCI Debugging Tool
  67. #ifdef DMCI_STATEMACHINE
  68. int array1[100];
  69. int array2[100];
  70. int array3[100];
  71. unsigned char dmciArrayIndex = 0;
  72. #endif

  73. #ifdef DMCI_MPPT
  74. int array1[100];
  75. int array2[100];
  76. int array3[100];
  77. unsigned char dmciArrayIndex = 0;
  78. #endif


  79. // Timer 3 Interrupt (300ms interrupt) for Fault indication
  80. void __attribute__((__interrupt__, no_auto_psv)) _T3Interrupt()
  81. {
  82.         static unsigned char ledCounter = 0, interruptCounter = 0;

  83.         if(ledCounter < storeFaultState)
  84.         {
  85.                 LED_DRV1 ^= ON;                                                                                // Blink LED to indicate fault, storeFaultState is 2x to account for toggle Off
  86.                 ledCounter++;
  87.         }
  88.         else if (ledCounter < (storeFaultState + 3))                        // Wait three interrupts (Clear indication blinking has stopped)
  89.         {
  90.                 ledCounter++;
  91.         }
  92.         else
  93.         {
  94.                 ledCounter = 0;
  95.         }
  96.         
  97.         if(systemState == DAYMODE)
  98.         {
  99.                 interruptCounter++;
  100.         }

  101.         // InterruptCounter is used to diplay the last known fault for some time after
  102.         // the system restarts (300ms * 200 ~ 1 minute)
  103.         if((faultState == NO_FAULT) && (interruptCounter >= 200))
  104.         {
  105.                 T3CONbits.TON = 0;                        //Disable this interrupt if the fault is removed and the delay has passed
  106.                 ledCounter = 0;
  107.                 interruptCounter = 0;
  108.                 LED_DRV1 = OFF;
  109.         }

  110.         TMR3 = 0;
  111.         IFS0bits.T3IF = 0;
  112. }

  113. // Timer 2 Interrupt (100us interrupt), performs fault checking and system statemachine
  114. void __attribute__((__interrupt__, no_auto_psv)) _T2Interrupt()
  115. {        
  116.         // Check Inverter Output Over Voltage Condition
  117.         if((peakInverterOutputVoltage > INVERTER_OVERVOLTAGE_LIMIT) && (inverterOverVoltageFlag == 0))
  118.         {
  119.                 inverterOverVoltageCounter++;
  120.         
  121.                 if(inverterOverVoltageCounter >= 2)
  122.                 {
  123.                         if(faultState == NO_FAULT)
  124.                         {
  125.                                 faultState = INVERTER_VOLTAGE;
  126.                                 inverterOverVoltageFlag = 1;
  127.                         }
  128.                 }
  129.         }
  130.         else if((peakInverterOutputVoltage < INVERTER_OVERVOLTAGE_LIMIT_HYS) && (inverterOverVoltageFlag == 1))
  131.         {        
  132.                 if(faultState == INVERTER_VOLTAGE)
  133.                 {
  134.                         faultState = NO_FAULT;
  135.                 }
  136.                 inverterOverVoltageFlag = 0;
  137.         }
  138.         else
  139.         {
  140.                 inverterOverVoltageCounter = 0;
  141.         }

  142.         if((peakInverterOutputVoltage < INVERTER_UNDERVOLTAGE_LIMIT) && (inverterUnderVoltageFlag == 0))
  143.         {
  144.                 inverterUnderVoltageCounter++;
  145.         
  146.                 if(inverterUnderVoltageCounter >= 2)
  147.                 {
  148.                         if(faultState == NO_FAULT)
  149.                         {
  150.                                 faultState = INVERTER_VOLTAGE;
  151.                                 inverterUnderVoltageFlag = 1;
  152.                         }        

  153.                         inverterUnderVoltageCounter = 2;
  154.                 }
  155.         }
  156.         else if ((peakInverterOutputVoltage > INVERTER_UNDERVOLTAGE_LIMIT_HYS) && (inverterUnderVoltageFlag == 1))
  157.         {        
  158.                 if(faultState == INVERTER_VOLTAGE)
  159.                 {
  160.                         faultState = NO_FAULT;
  161.                 }
  162.                
  163.                 inverterUnderVoltageFlag = 0;
  164.         }
  165.         else
  166.         {
  167.                 inverterUnderVoltageCounter = 0;
  168.         }

  169.         // Only Check Input Voltage Fault When New Data is Available
  170.         if(avgInputDataReadyFlag == 1)
  171.         {
  172.                 // Check PV Panel Voltage Using the Average Input Voltage
  173.                 if((inputVoltageAverage > PVPANEL_OVERVOLTAGE_LIMIT) && (pvPanelOverVoltageFlag == 0))
  174.                 {
  175.                         if(faultState == NO_FAULT)
  176.                         {
  177.                                 faultState = PV_PANEL_VOLTAGE;
  178.                                 pvPanelOverVoltageFlag = 1;
  179.                         }
  180.                 }        
  181.                 else if((inputVoltageAverage < PVPANEL_OVERVOLTAGE_LIMIT_HYS) && (pvPanelOverVoltageFlag == 1))
  182.                 {        
  183.                         if(faultState == PV_PANEL_VOLTAGE)
  184.                         {
  185.                                 faultState = NO_FAULT;
  186.                         }
  187.                         
  188.                         pvPanelOverVoltageFlag = 0;
  189.                 }
  190.         
  191.                 // Check PV Panel Maximum Power Point Voltage Using the Average Input Voltage
  192.                 if((inputVoltageAverage > PVPANEL_MPP_LIMIT) && (systemState == DAYMODE))
  193.                 {
  194.                         pvPanelMPPOverVoltageCnt++;
  195.                         
  196.                         // Allow time for system to find MPP
  197.                         if(pvPanelMPPOverVoltageCnt > 1000)
  198.                         {
  199.                                 pvPanelOverVoltageFlag = 1;                // Set Flag so System Will Restart
  200.                                 pvPanelMPPOverVoltageCnt = 0;

  201.                                 if(faultState == NO_FAULT)
  202.                                 {
  203.                                         faultState = PV_PANEL_VOLTAGE;
  204.                                 }
  205.                         }
  206.                 }
  207.                 else
  208.                 {
  209.                         pvPanelMPPOverVoltageCnt = 0;        
  210.                 }


  211.                 // Check PV Panel Minimum Voltage Using Average Input Voltage
  212.                 if((inputVoltageAverage < PVPANEL_UNDERVOLTAGE_LIMIT) && (pvPanelUnderVoltageFlag == 0))
  213.                 {
  214.                         pvUnderVoltageCounter++;               
  215.         
  216.                         if(pvUnderVoltageCounter >= 10)
  217.                         {               
  218.                                 if(faultState == NO_FAULT)
  219.                                 {
  220.                                         faultState = PV_PANEL_VOLTAGE;
  221.                                         pvPanelUnderVoltageFlag = 1;
  222.                                 }
  223.                                 
  224.                                 pvUnderVoltageCounter = 10;
  225.         
  226.                         }
  227.                 }
  228.                 else if ((inputVoltageAverage > PVPANEL_UNDERVOLTAGE_LIMIT_HYS) && (pvPanelUnderVoltageFlag == 1))
  229.                 {
  230.                         if(faultState == PV_PANEL_VOLTAGE)
  231.                         {
  232.                                 faultState = NO_FAULT;
  233.                         }
  234.         
  235.                         pvPanelUnderVoltageFlag = 0;
  236.                 }
  237.                 else
  238.                 {
  239.                         pvUnderVoltageCounter = 0;
  240.                 }
  241.         }

  242.         // Check Over Temperature Fault
  243.         if((measuredTemperature >= MAXTEMPERATURE) && (overTemperatureFlag == 0))
  244.         {
  245.                 tempFaultCnt++;
  246.         
  247.                 if(tempFaultCnt > 100)
  248.                 {
  249.                         tempFaultCnt = 100;

  250.                         if(faultState == NO_FAULT)
  251.                         {
  252.                            faultState = TEMPERATURE;
  253.                                 overTemperatureFlag = 1;
  254.                         }
  255.                 }
  256.         }
  257.         else if ((measuredTemperature <= MAXTEMPERATURE_HYS) && (overTemperatureFlag == 1))
  258.         {
  259.                 overTemperatureFlag = 0;

  260.                 if(faultState == TEMPERATURE)
  261.                 {
  262.                         faultState = NO_FAULT;
  263.                 }
  264.         }
  265.         else
  266.         {
  267.                 tempFaultCnt = 0;
  268.         }

  269.         //Check 12V Drive Supply Voltage
  270.         if((driveSupplyVoltage > MAXDRIVEVOLTAGE) || (driveSupplyVoltage < MINDRIVEVOLTAGE))
  271.         {
  272.                 driveSupplyFaultCnt++;               

  273.                 if(driveSupplyFaultCnt > 10)
  274.                 {
  275.                         driveSupplyFaultCnt = 10;        

  276.                         if(faultState == NO_FAULT)
  277.                         {
  278.                                 faultState = DRIVE_SUPPLY;
  279.                         }
  280.                 }
  281.         }
  282.         else
  283.         {
  284.                 driveSupplyFaultCnt = 0;
  285.         
  286.                 if(faultState == DRIVE_SUPPLY)
  287.                 {
  288.                         faultState = NO_FAULT;
  289.                 }
  290.         }

  291.         // Check Reference Voltage
  292.         if((referenceVoltage < MINREFERENCEVOLTAGE) || (referenceVoltage > MAXREFERENCEVOLTAGE))
  293.         {        
  294.                 referenceVoltageFaultCnt++;
  295.         
  296.                 if(referenceVoltageFaultCnt > 10)
  297.                 {
  298.                         referenceVoltageFaultCnt = 10;

  299.                         if(faultState == NO_FAULT)
  300.                         {
  301.                                 faultState = REFERENCE_VOLTAGE;
  302.                         }
  303.                 }
  304.         }
  305.         else
  306.         {
  307.                 referenceVoltageFaultCnt = 0;

  308.                 if (faultState == REFERENCE_VOLTAGE)
  309.                 {
  310.                         faultState = NO_FAULT;
  311.                 }
  312.         }


  313.         // Check the fault state, if it is not equal to No Fault then set systemState = SYSTEM_ERROR
  314.         if (faultState != NO_FAULT)
  315.         {
  316.                 systemState = SYSTEMERROR;
  317.         }

  318.         // Check the On/Off switch state
  319.         if(PORTCbits.RC11 == 0)
  320.         {
  321.                 switchState = SWITCHON;
  322.         }
  323.         else
  324.         {
  325.                 //put system state in systemError
  326.                 switchState = SWITCHOFF;
  327.                 systemState = SYSTEMERROR;
  328.         }

  329.     switch(systemState)
  330.     {
  331.         case SYSTEMSTARTUP:
  332.                 {
  333.                         if(avgInputDataReadyFlag == 1)
  334.                         {        
  335.                                 // During system startup read the PV panel Voltage (open circuit voltage). This information
  336.                                 // is used to help speed up the time to find MPP
  337.                                 openCircuitVoltage = inputVoltageAverage;

  338.                                 avgInputDataReadyFlag = 0;
  339.                         }

  340.                         // Read AC Current offset during startup mode and verify data
  341.                         // Needs to be completed before the full-bridge is enabled during system startup
  342.                         if(acCurrentOffsetFlag == 0)
  343.                         {                                                               
  344.                                 acCurrentOffsetAverage = acCurrentOffsetAverage + inverterOutputCurrent;
  345.                
  346.                                 if(acCurrentOffsetCounter >= 255)
  347.                                 {
  348.                                         acCurrentOffset = (acCurrentOffsetAverage >> 8);
  349.                                         inverterOutputOverCurrent = INVERTER_OUTPUTCURRENT_MAX + (16383 - acCurrentOffset);
  350.                                         acCurrentOffsetFlag = 1;
  351.                                         acCurrentOffsetCounter = 0;
  352.                                         acCurrentOffsetAverage = 0;
  353.                
  354.                                         if((acCurrentOffset < MINOFFSETCURRENT) || (acCurrentOffset > MAXOFFSETCURRENT))
  355.                                         {                        
  356.                                                 if(faultState == NO_FAULT)
  357.                                                 {
  358.                                                         faultState = ACCURRENT_OFFSET;
  359.                                                 }
  360.                                         }
  361.                                 }
  362.                                 else
  363.                                 {
  364.                                         acCurrentOffsetCounter++;
  365.                                 }
  366.                         }

  367.                         // At system Start-up, enable the Full-Bridge circuit (@ peak of AC Cycle) before the flyback circuit is enabled
  368.                         // If this is not done, the flyback output will have high DC voltage and when the full-bridge is enabled at the
  369.                         // zero cross there is a large dv/dt and the output current will have a large glitch and also trip the flyback
  370.                         // OVP circuit
  371.                
  372.                         if((startupZeroCrossCounter >= (ZEROCROSSCOUNT>>1)) && (ninetyDegreeDetectFlag == 1))
  373.                         {                        
  374.                                 startFullBridgeFlag = 1;                                // Set Flag to start full-bridge drive
  375.                         }

  376.                         // After several consecutive zero crossings switch to Day Mode
  377.                         if(startupZeroCrossCounter > ZEROCROSSCOUNT)
  378.                         {
  379.                                 if ((inverterPeriod > INVERTERPERIOD60HZMIN ) && (inverterPeriod <= INVERTERPERIOD60HZMAX))
  380.                                 {
  381.                                         inverterPeriodMin = INVERTERPERIOD60HZMIN;
  382.                                         inverterPeriodMax = INVERTERPERIOD60HZMAX;
  383.                                        
  384.                                         // Delay at the zero crossings to allow AC voltage to reach flyback voltage
  385.                                         zeroCrossDelayNom = 20;
  386.                                         zeroCrossDelayMax = 22;                        // Delay slightly varies with AC voltage
  387.                                         zeroCrossDelayMin = 18;

  388.                                         zeroCrossDelay = zeroCrossDelayNom;                // Wait (17us*delay) at the zero cross before turning on flyback/full-bridge
  389.                                 }
  390.                                 else
  391.                                 {
  392.                                         inverterPeriodMin = INVERTERPERIOD50HZMIN;
  393.                                         inverterPeriodMax = INVERTERPERIOD50HZMAX;
  394.         
  395.                                         // Delay at the zero crossings to allow AC voltage to reach flyback voltage
  396.                                         zeroCrossDelayNom = 30;
  397.                                         zeroCrossDelayMax = 35;                        // Delay slightly varies with AC voltage
  398.                                         zeroCrossDelayMin = 25;
  399.                                        
  400.                                         zeroCrossDelay = zeroCrossDelayNom;                // Wait (17us*delay) at the zero cross before turning on flyback/full-bridge
  401.                                 }                                       
  402.         
  403.                                 // Change system state to Day Mode
  404.                                 systemState = DAYMODE;
  405.                         }        
  406.                 }
  407.                 break;

  408.                 case DAYMODE:
  409.                 {
  410.                         // When average input voltage and average input current are available call MPPT Routine
  411.                         if(avgInputDataReadyFlag == 1)
  412.                         {                        
  413.                                 #ifndef BENCHTESTING
  414.                                 MPPTRoutine();                        // Call MPPT Routine when data is ready
  415.                                 #endif

  416.                                 // Change Current Reference based on the PV panel voltage
  417.                                 if(inputVoltageAverage >= PVPANEL_40V)
  418.                                 {
  419.                                         CMPDAC2bits.CMREF = 700;                        // Consider current at ~39V
  420.                                         CMPDAC3bits.CMREF = 700;
  421.                                 }
  422.                                 else if(inputVoltageAverage >= PVPANEL_30V)
  423.                                 {
  424.                                         CMPDAC2bits.CMREF = 850;                        // Consider current at ~29V
  425.                                         CMPDAC3bits.CMREF = 850;
  426.                                 }
  427.                                 else
  428.                                 {
  429.                                         CMPDAC2bits.CMREF = 1000;                        // Consider current at ~20V
  430.                                         CMPDAC3bits.CMREF = 1000;
  431.                                 }

  432.                                 avgInputDataReadyFlag = 0;
  433.                         }               

  434.                         // Load Balance routine to make sure that both flyback converters are sharing the load equally ~50%
  435.                         // Execute at a slower rate 100us * LOADBALCOUNT
  436.         
  437.                         if(loadBalanceCounter >= LOADBALCOUNT)
  438.                         {
  439.                                 LoadBalance();                                // Call Load Balance Routine
  440.                                 loadBalanceCounter = 0;
  441.                         }
  442.                
  443.                         loadBalanceCounter++;
  444.                
  445.                         // Software for soft-start when using a bench supply as MPP-Tracking is removed
  446.                         #ifdef BENCHTESTING
  447.         
  448.                         mpptCounter++;

  449.                         if(mpptFactor < MPPTFACTOR_BENCHTESTING)
  450.                         {
  451.                                 if(mpptCounter >= MPPTCOUNT)
  452.                                 {
  453.                                         mpptFactor = mpptFactor + MPPTFACTORINCREMENT;
  454.                                         mpptCounter = 0;
  455.                                 }
  456.                         }
  457.                         else
  458.                         {
  459.                                 mpptFactor = MPPTFACTOR_BENCHTESTING;
  460.                                 mpptCounter = 0;
  461.                         }

  462.                         #endif        

  463.                 }                        
  464.                 break;

  465.                 case SYSTEMERROR:
  466.                 {
  467.                     IOCON1bits.OVRENH = 1;
  468.                     IOCON1bits.OVRENL = 1;
  469.                     IOCON2bits.OVRENH = 1;
  470.                     IOCON2bits.OVRENL = 1;
  471.                         IOCON3bits.OVRENH = 1;
  472.                         IOCON3bits.OVRENL = 1;
  473.                         OPTO_DRV1 = 0;
  474.                         OPTO_DRV2 = 0;
  475.                         mpptStartUpFlag = 0;
  476.                         startFullBridgeFlag = 0;                // Reset flag to start full-bridge
  477.                         burstModeActiveCounter = 0;                // Reset burst mode
  478.                         burstModeActiveFlag = 0;
  479.                         acCurrentOffset = 0;
  480.                         acCurrentOffsetFlag = 0;                // Allow system to re-calculate AC Current Offset
  481.                         mpptFactor = MPPTFACTORMINIMUM;
  482.                         inputPower = 0;
  483.                         prevInputVoltageAverage = 0;

  484.                         ClrWdt();                                                // In fault mode we need to clear WDT

  485.                         if((switchState == SWITCHON) && (faultState == NO_FAULT))
  486.                         {
  487.                                 // Switch to system startup after no faults have been detected for ~1s

  488.                                 systemRestartCounter++;
  489.                                 
  490.                                 if(systemRestartCounter >= RESTARTCOUNT)               
  491.                                 {
  492.                                         systemState = SYSTEMSTARTUP;
  493.                                         systemRestartCounter = 0;
  494.                                 }
  495.                         }        
  496.                         else if((switchState == SWITCHON) && (faultState != NO_FAULT))
  497.                         {
  498.                                 // If a fault is present then diplay the fault using T3 and LED D27 on the PCB
  499.                                 systemRestartCounter = 0;
  500.                                 storeFaultState = (faultState << 1);                // x2 to account for "off" time
  501.                                 T3CONbits.TON = 1;

  502.                                 // Remove the fault and allow system to try to restart
  503.                                 // If the fault is ac current offset or HW Zero Cross
  504.                                 if((faultState == ACCURRENT_OFFSET) || (faultState == HARDWAREZEROCROSS))
  505.                                 {
  506.                                         faultState = NO_FAULT;
  507.                                 }

  508.                                 // Critical Faults: AC Current, Flyback Over Voltage, and Flyback Over Current
  509.                                 // Handle faults differently: Allow system to try to restart only once, if fault
  510.                                 // is still present then disable PWM module.
  511.                                 if((criticalFaultFlag == 1) && (criticalFaultRestartFlag == 0))
  512.                                 {
  513.                                         criticalFaultCounter++;

  514.                                         // After 2s remove the critical fault and allow system to try to restart
  515.                                         if(criticalFaultCounter > CRITICALFAULTCOUNT)
  516.                                         {
  517.                                                 criticalFaultRestartFlag = 1;                        

  518.                                                 // As the fault for flyback over current is latched the PWM needs to
  519.                                                 // exit the latched fault mode in order to restart
  520.                                                 if(faultState == FLYBACK_OVERCURRENT)
  521.                                                 {
  522.                                                         FCLCON1bits.FLTMOD = 3;                                        // Disable Fault Mode
  523.                                                         FCLCON2bits.FLTMOD = 3;                                        // Disable Fault Mode
  524.                                                         FCLCON1bits.FLTMOD = 0;                                        // Latched Fault Mode
  525.                                                         FCLCON2bits.FLTMOD = 0;                                        // Latched Fault Mode
  526.                                                 }

  527.                                                 faultState = NO_FAULT;
  528.                                                 criticalFaultCounter = 0;        
  529.                                         }
  530.                                 }
  531.                         }
  532.                         else if (switchState == SWITCHOFF)
  533.                         {
  534.                                 // Reset Period Limits if switch is off
  535.                                 // This is only required for testing 50/60 Hz operation
  536.                                 // without having to cycle power
  537.                                 inverterPeriodMin = INVERTERPERIOD60HZMIN;
  538.                                 inverterPeriodMax = INVERTERPERIOD50HZMAX;
  539.                                 T3CONbits.TON = 0;
  540.                                 LED_DRV1 = OFF;
  541.                         }

  542.                 }
  543.                 break;
  544.         }

  545.         
  546.         // Software for debugging purposes
  547.         #ifdef DMCI_STATEMACHINE
  548.         array1 [dmciArrayIndex] = deltaDutyCycle;
  549.         array2 [dmciArrayIndex] = averageFlybackCurrent2 - averageFlybackCurrent1;
  550.         array3 [dmciArrayIndex++] = 0;
  551.         if(dmciArrayIndex >= 100)
  552.         {
  553.                 dmciArrayIndex = 0;
  554.         }
  555.         #endif


  556.     TMR2 = 0;
  557.     IFS0bits.T2IF = 0;  
  558. }


  559. // This MPPT algorithim implements the Perturbation and Observation method for detecting Maximum
  560. // Power Point. MPPT can be up to ~25000
  561. void MPPTRoutine(void)
  562. {
  563.         int deltaV = 0, prevInputPower = 0;
  564.         unsigned char mpptScaleFactor = 0;

  565.         //Store off previous inputPower
  566.         prevInputPower = inputPower;        
  567.         
  568.         // Calculate new input power and change in input voltage
  569.         inputPower = (__builtin_mulss((int)inputVoltageAverage ,(int)inputCurrentAverage) >> 15);
  570.         deltaV = inputVoltageAverage - prevInputVoltageAverage;

  571.         // If there is a large drop in voltage decrease mpptFactor at a faster rate
  572.         // Example would be large AC voltage fluctuations
  573.         if(deltaV <= PVPANEL_VOLTAGEDROP)
  574.         {
  575.                 mpptFactor = mpptFactor - (mpptFactor >> 2);                // Reset to 75% power
  576.         }
  577.          
  578.         // To find MPP faster, increase mpptFactor at a faster rate until the operating voltage
  579.         // is less than the opencircuit voltage minus ~3V. Vmp and Voc should always be more
  580.         // than 5-6V difference at any operating temperature or irradiance.
  581.         if((inputVoltageAverage > (openCircuitVoltage - 1650)) && (mpptStartUpFlag == 0))
  582.         {
  583.                 mpptFactor += 50;
  584.         }
  585.         else
  586.         {
  587.                 mpptStartUpFlag = 1;
  588.                 criticalFaultFlag = 0;                        // If system gets here without a critical fault, allow system to run as normal
  589.                 criticalFaultRestartFlag = 0;
  590.         }


  591.         if(burstModeActiveFlag == 1)
  592.         {
  593.                 mpptScaleFactor = 1;
  594.         }
  595.         else
  596.         {
  597.                 mpptScaleFactor = 0;
  598.         }

  599.         if (inputPower > prevInputPower)
  600.         {
  601.                 if (deltaV < -LARGEVOLTAGEDIFFERENCE)
  602.                 {
  603.                         mpptFactor += MININCREMENTMPPTFACTOR;
  604.                 }
  605.                 else if (deltaV < 0)
  606.                 {
  607.                         mpptFactor += MAXINCREMENTMPPTFACTOR;
  608.                 }
  609.                 else if (deltaV > LARGEVOLTAGEDIFFERENCE)
  610.                 {
  611.                         mpptFactor -= (MAXDECREMENTMPPTFACTOR << mpptScaleFactor);
  612.                 }
  613.                 else if (deltaV > 0)
  614.                 {
  615.                         mpptFactor -= (MINDECREMENTMPPTFACTOR << mpptScaleFactor);
  616.                 }        
  617.         }
  618.         else if (inputPower < prevInputPower)
  619.         {
  620.                 if (deltaV < -LARGEVOLTAGEDIFFERENCE)
  621.                 {
  622.                         mpptFactor -= (MAXDECREMENTMPPTFACTOR << mpptScaleFactor);
  623.                 }
  624.                 else if (deltaV < 0)
  625.                 {
  626.                         mpptFactor -= (MINDECREMENTMPPTFACTOR << mpptScaleFactor);
  627.                 }
  628.                 else if (deltaV > LARGEVOLTAGEDIFFERENCE)
  629.                 {
  630.                         mpptFactor += MAXINCREMENTMPPTFACTOR;
  631.                 }
  632.                 else if (deltaV > 0)
  633.                 {
  634.                         mpptFactor += MININCREMENTMPPTFACTOR;
  635.                 }
  636.         }

  637.         // Saturate the MPPT limit to min and max values
  638.         if(mpptFactor > mpptFactorMaximum)
  639.         {
  640.                 mpptFactor = mpptFactorMaximum;
  641.         }        
  642.         else if(mpptFactor < MPPTFACTORMINIMUM)
  643.         {        
  644.                 mpptFactor = MPPTFACTORMINIMUM;
  645.         }

  646.         // Store off last known input power and input voltage
  647.         prevInputVoltageAverage = inputVoltageAverage;

  648.         // Software for debugging purposes
  649.         #ifdef DMCI_MPPT
  650.         array1 [dmciArrayIndex] = mpptFactor;
  651.         array2 [dmciArrayIndex] = deltaV;
  652.         array3 [dmciArrayIndex++] = inputPower;
  653.         if(dmciArrayIndex >= 100)
  654.         {
  655.                 dmciArrayIndex = 0;
  656.         }
  657.         #endif
  658. }


  659. void LoadBalance(void)
  660. {
  661.         static int loadBalIoutput = 0;
  662.         int diffFlybackCurrent = 0, loadBalPoutput = 0, loadBalPIoutput = 0;

  663.         // Difference of the two Flyback MOSFET Currents
  664.         diffFlybackCurrent = averageFlybackCurrent2 - averageFlybackCurrent1;
  665.                                        
  666.         // Error * Proportional Gain
  667.         loadBalPoutput = ( (__builtin_mulss(diffFlybackCurrent,(int)KAQ15)) >> 15);        
  668.         
  669.         // Error * Integral Gain
  670.         loadBalIoutput = loadBalIoutput + ( (__builtin_mulss(diffFlybackCurrent,(int)KSAQ15)) >> 15);
  671.         
  672.         // Check for Integral term exceeding MAXBALANCE, If true, saturate the integral term to MAXBALANCE
  673.         // Check for Integral term going below -MAXBALANCE, If true, saturate the integral term to -MAXBALANCE
  674.         if(loadBalIoutput > MAXBALANCE)
  675.         {
  676.                 loadBalIoutput = MAXBALANCE;
  677.         }
  678.         else if(loadBalIoutput < -MAXBALANCE)
  679.         {
  680.                 loadBalIoutput = -MAXBALANCE;
  681.         }

  682.         // PI Output = Proportional Term + Integral Term
  683.         loadBalPIoutput = loadBalPoutput + loadBalIoutput;
  684.         
  685.         // Check for PI Output exceeding MAXBALANCE, If true, saturate PI Output to MAXBALANCE
  686.         // Check for PI Output going below -MAXBALANCE, If true, saturate PI Output to -MAXBALANCE
  687.         if(loadBalPIoutput > MAXBALANCE)
  688.         {
  689.                 loadBalPIoutput = MAXBALANCE;
  690.         }
  691.         else if(loadBalPIoutput < -MAXBALANCE)
  692.         {
  693.                 loadBalPIoutput = -MAXBALANCE;
  694.         }
  695.         
  696.         // Delta duty cycle to correct the two Flyback MOSFET duty cycles
  697.         deltaDutyCycle = ( (__builtin_mulss((int)loadBalPIoutput,(int)FLYBACKPERIOD)) >> 15);
  698. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:295548 发表于 2018-7-20 18:21 | 只看该作者
你这个能够实现DC-AC转换吗
回复

使用道具 举报

板凳
ID:387538 发表于 2018-8-24 12:53 | 只看该作者
楼主 这个有PCB么?
回复

使用道具 举报

地板
ID:245473 发表于 2018-11-9 11:10 | 只看该作者
文件损坏
回复

使用道具 举报

5#
ID:262587 发表于 2019-12-7 22:53 | 只看该作者
很好的资料,学习了。
回复

使用道具 举报

6#
ID:136083 发表于 2024-3-31 13:52 | 只看该作者
这个是经典的PIC的DSP芯片p33FJ16GS504的资料,官方10多年前出的资料.里面有很多值得参考的.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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