This example adds current vector control to Example 2.
/****************************************************************************** ** Copyright (C) 2010 Pablo Garcia ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Lesser General Public License for more details. ** You should have received a copy of the GNU Lesser General Public ** License along with this library; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ******************************************************************************/ //----------------------------------------------------------- // Includes // ------------------------------------------------------------- #include "Example3.h" // includes for our particular project //----------------------------------------------------------- // Define //----------------------------------------------------------- #define VBUS 50 // A/D #defines #define IA_CH 0 // ia A/D channel #define IB_CH 0 // ib A/D channel //----------------------------------------------------------- // Implemented Functions // ------------------------------------------------------------- interrupt void ADInterrupt(void); interrupt void pwmInterrupt(void); //----------------------------------------------------------- // Globals //----------------------------------------------------------- const _iq Vbus = _IQ(VBUS); // bus voltage const _iq Vmax = _IQ(VBUS>>1); // max output const _iq Fmax = _IQ(50); // max frequency const Uint16 DB_US = 3; // dead time (us) // A/D variables volatile _iq ia, ib; // measured currents // pwm variables volatile _iq vas, vbs, vcs; // phase voltages volatile _iq f; // frequency // Current regulator volatile struct sqddata idqs_s; // current vector in stationary reference frame volatile struct sqddata idqs_s_ref; // reference current vector in stationary reference frame volatile struct qddata err_idqs; // current regulator error volatile struct qddata vdqs_s; // voltage vector in stationary reference frame _iq Kp_current, Ki_current; //----------------------------------------------------------- interrupt void ADInterrupt(void) { ia = ReadADInputWriteRaw(ADCINA2); ib = ReadADInputWriteRaw(ADCINB2); // update states UPDATEQD_STATE(err_idqs); UPDATEQD_STATE(vdqs_s); // abc phase currents to two current vector in stator reference frame PH2QD(ia,ib,idqs_s); // Current Regulator err_idqs.d[N] = idqs_s_ref.d - idqs_s.d; err_idqs.q[N] = idqs_s_ref.q - idqs_s.q; PI_QD_REG(err_idqs,vdqs_s,Kp_current,Ki_current); // dq to abc DQ2PH_QDDATA(vdqs_s,vas,vbs,vcs); // preload PWM values to be updated in next sample UpdatePWM3ph(vas,vbs,vcs,1); // prepare next adquisition ReinitAD(); } //----------------------------------------------------------- //----------------------------------------------------------- // ISR on PWM //----------------------------------------------------------- interrupt void pwmInterrupt(void) { // process ..... // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3; // PABLO: Interrupt ACK should go to UpdatePWM function // Clear INT flag for this timer EPwm1Regs.ETCLR.bit.INT = 1; } //----------------------------------------------------------- //----------------------------------------------------------- // main // ------------------------------------------------------------- void main(void) { // init current control variables Kp_current = _IQ(150.0); Ki_current = _IQ(50.0); INIT_QDDATA(err_idqs); INIT_QDDATA(vdqs_s); idqs_s_ref.d = _IQ(0); idqs_s_ref.q = _IQ(0); // SYSCLKOUT = 150Mhz // HSPCLK SYSCLKOUT/8 = 18.75MHz // LSPCLK= SYSCLKOUT/4 InitCPU(8, 4); // Init three phase PWM Init3phPWM(pwmInterrupt, EPWMA, 100, DB_US, Vbus, SOCA); // AD initialization ConfigureAD(ADInterrupt, CASCADED_SEQ_MODE, SIMULTANEOUS_MODE, PWM_SOC, 0); // ------------------ Add AD channels // ------------------- Current Sensor data ----------------------------- // loops = 2; // rt = 1/1000; // Rm = 150; (143 measured between input and GND) // op_gain = 0.5; // MAXBITS = 4096; // Vmax = 3 // GAIN: % 1/(loops*rt_sensor*Rm*op_gain*MAXBITS/Vmax) // ------------------- Current Sensor data------ ------------------------ AddChannel(ADCINA2, IA_CH, _IQ(0.03493696), _IQ(0.00512)); // ia current AddChannel(ADCINB2, IB_CH, _IQ(-0.104635519999999), _IQ(0.00512)); // ib current // Configure Memory to store AD samples (OVERWRITE/NOVERWRITE) InitDataStorageBuffer(NOVERWRITE); SetTrigger(); // enable trigger to store AD samples // Enable PWM clock EnableEPWMModuleTBCLK(); // enable PIE module and CPU interrupts EnableInterrupts(); // <-- PABLO: This call MUST BE the last one // main loop while(1){ IDLE; } }