📄 aci3_4.c
字号:
/* ==============================================================================
System Name: ACI34
File Name: ACI3_4.C
Description: Primary system file for the Real Implementation of Sensorless Direct
Field Orientation Control for a Three Phase AC Induction Motor.
Originator: Digital control systems Group - Texas Instruments
=====================================================================================
History:
-------------------------------------------------------------------------------------
05-15-2002 Release Rev 1.0
================================================================================= */
#include "IQmathLib.h" /* Include header for IQmath library */
#include "DSP28_Device.h"
#include "aci3_4.h"
#include "parameter.h"
#include "build.h"
// Prototype statements for functions found within this file.
interrupt void EvaTimer1(void);
// Global variables used in this system
float Vd_testing = 0.25; /* Vd testing (pu) */
float Vq_testing = 0; /* Vq testing (pu) */
float Id_ref = 0.4; /* Id reference (pu) */
float Iq_ref = 0.05; /* Iq reference (pu) */
float speed_ref = 0.5; /* Speed reference (pu) */
float T = 0.001/ISR_FREQUENCY; /* Samping period (sec), see parameter.h */
int isr_ticker = 0;
int pwmdac_ch1=0;
int pwmdac_ch2=0;
int pwmdac_ch3=0;
volatile int enable_flg=0;
int speed_loop_ps = 10; // Speed loop prescaler
int speed_loop_count = 1; // Speed loop counter
ACIFE fe1 = ACIFE_DEFAULTS;
ACISE se1 = ACISE_DEFAULTS;
CLARKE clarke1 = CLARKE_DEFAULTS;
PARK park1 = PARK_DEFAULTS;
IPARK ipark1 = IPARK_DEFAULTS;
PIDREG3 pid1_id = PIDREG3_DEFAULTS;
PIDREG3 pid1_iq = PIDREG3_DEFAULTS;
PIDREG3 pid1_spd = PIDREG3_DEFAULTS;
PWMGEN pwm1 = PWMGEN_DEFAULTS;
PWMDAC pwmdac1 = PWMDAC_DEFAULTS;
SVGENDQ svgen_dq1 = SVGENDQ_DEFAULTS;
CAPTURE cap1 = CAPTURE_DEFAULTS;
SPEED_MEAS_CAP speed1 = SPEED_MEAS_CAP_DEFAULTS;
DRIVE drv1 = DRIVE_DEFAULTS;
RMPCNTL rc1 = RMPCNTL_DEFAULTS;
RAMPGEN rg1 = RAMPGEN_DEFAULTS;
PHASEVOLTAGE volt1 = PHASEVOLTAGE_DEFAULTS;
ILEG2DCBUSMEAS ilg2_vdc1 = ILEG2DCBUSMEAS_DEFAULTS;
ACIFE_CONST fe1_const = ACIFE_CONST_DEFAULTS;
ACISE_CONST se1_const = ACISE_CONST_DEFAULTS;
void main(void)
{
// Initialize System Control registers, PLL, WatchDog, Clocks to default state:
// This function is found in the DSP28_SysCtrl.c file.
InitSysCtrl();
// HISPCP prescale register settings, normally it will be set to default values
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.HISPCP.all = 0x0000; /* SYSCLKOUT/1 */
EDIS; // This is needed to disable write to EALLOW protected registers
// Disable and clear all CPU interrupts:
DINT;
IER = 0x0000;
IFR = 0x0000;
// Initialize Pie Control Registers To Default State:
// This function is found in the DSP28_PieCtrl.c file.
InitPieCtrl();
// Initialize the PIE Vector Table To a Known State:
// This function is found in DSP28_PieVect.c.
// This function populates the PIE vector table with pointers
// to the shell ISR functions found in DSP28_DefaultIsr.c.
InitPieVectTable();
// User specific functions, Reassign vectors (optional), Enable Interrupts:
// Initialize EVA Timer 1:
// Setup Timer 1 Registers (EV A)
EvaRegs.GPTCONA.all = 0;
// Waiting for enable flag set
while (enable_flg==0)
{
// Enable Underflow interrupt bits for GP timer 1
EvaRegs.EVAIMRA.bit.T1UFINT = 1;
EvaRegs.EVAIFRA.bit.T1UFINT = 1;
};
// Reassign ISRs.
// Reassign the PIE vector for T1PINT and T3PTINT to point to a different
// ISR then the shell routine found in DSP28_DefaultIsr.c.
// This is done if the user does not want to use the shell ISR routine
// but instead wants to use their own ISR. This step is optional:
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.T1UFINT = &EvaTimer1;
EDIS; // This is needed to disable write to EALLOW protected registers
// Enable PIE group 2 interrupt 6 for T1UFINT
PieCtrlRegs.PIEIER2.all = M_INT6;
// Enable CPU INT2 for T1UFINT:
IER |= M_INT2;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
/* Initialize modules */
pwm1.n_period = SYSTEM_FREQUENCY*1000000*T/2; /* Perscaler X1 (T1), ISR period = T x 1 */
pwm1.init(&pwm1);
pwmdac1.pwmdac_period = 2500; /* PWM frequency = 30 kHz */
pwmdac1.PWM_DAC_IPTR0 = &pwmdac_ch1;
pwmdac1.PWM_DAC_IPTR1 = &pwmdac_ch2;
pwmdac1.PWM_DAC_IPTR2 = &pwmdac_ch3;
pwmdac1.init(&pwmdac1);
cap1.init(&cap1);
drv1.init(&drv1);
ilg2_vdc1.init(&ilg2_vdc1);
/* Initialize the SPEED_PR module (x128-T2, 50MHz, 25-teeth sprocket */
speed1.rpm_max = 120*BASE_FREQ/P;
speed1.speed_scaler = 60*(SYSTEM_FREQUENCY*1000000/(128*25*speed1.rpm_max));
/* Initialize the RAMPGEN module */
rg1.step_angle_max = _IQ(BASE_FREQ*T);
/* Initialize the ACI_FE module */
fe1_const.Rs = RS;
fe1_const.Rr = RR;
fe1_const.Ls = LS;
fe1_const.Lr = LR;
fe1_const.Lm = LM;
fe1_const.Ib = BASE_CURRENT;
fe1_const.Vb = BASE_VOLTAGE;
fe1_const.Ts = T;
fe1_const.calc(&fe1_const);
fe1.K1_fe = _IQ(fe1_const.K1);
fe1.K2_fe = _IQ(fe1_const.K2);
fe1.K3_fe = _IQ(fe1_const.K3);
fe1.K4_fe = _IQ(fe1_const.K4);
fe1.K5_fe = _IQ(fe1_const.K5);
fe1.K6_fe = _IQ(fe1_const.K6);
fe1.K7_fe = _IQ(fe1_const.K7);
fe1.K8_fe = _IQ(fe1_const.K8);
fe1.Kp_fe = _IQ(0.082);
fe1.Ki_fe = _IQ(T/0.1447);
/* Initialize the ACI_SE module */
se1_const.Rr = RR;
se1_const.Lr = LR;
se1_const.fb = BASE_FREQ;
se1_const.fc = 200;
se1_const.Ts = T;
se1_const.calc(&se1_const);
se1.K1_se = _IQ(se1_const.K1);
se1.K2_se = _IQ21(se1_const.K2);
se1.K3_se = _IQ(se1_const.K3);
se1.K4_se = _IQ(se1_const.K4);
se1.base_rpm_se = 120*BASE_FREQ/P;
/* Initialize the PID_REG3 module for Id */
pid1_id.Kp_reg3 = _IQ(0.9463);
pid1_id.Ki_reg3 = _IQ(T/0.04);
pid1_id.Kd_reg3 = _IQ(0/T);
pid1_id.Kc_reg3 = _IQ(0.2);
pid1_id.pid_out_max = _IQ(0.30);
pid1_id.pid_out_min = _IQ(-0.30);
/* Initialize the PID_REG3 module for Iq */
pid1_iq.Kp_reg3 = _IQ(0.9463);
pid1_iq.Ki_reg3 = _IQ(T/0.04);
pid1_iq.Kd_reg3 = _IQ(0/T);
pid1_iq.Kc_reg3 = _IQ(0.2);
pid1_iq.pid_out_max = _IQ(0.95);
pid1_iq.pid_out_min = _IQ(-0.95);
/* Initialize the PID_REG3 module for speed */
pid1_spd.Kp_reg3 = _IQ(1);
pid1_spd.Ki_reg3 = _IQ(T*speed_loop_ps/0.3);
pid1_spd.Kd_reg3 = _IQ(0/(T*speed_loop_ps));
pid1_spd.Kc_reg3 = _IQ(0.2);
pid1_spd.pid_out_max = _IQ(1);
pid1_spd.pid_out_min = _IQ(-1);
// IDLE loop. Just sit and loop forever:
for(;;);
}
interrupt void EvaTimer1(void)
{
isr_ticker++;
/* ***************** LEVEL1 ***************** */
#if (BUILDLEVEL==LEVEL1)
rc1.target_value = _IQ(speed_ref);
rc1.calc(&rc1);
rg1.rmp_freq = rc1.setpt_value;
rg1.calc(&rg1);
ipark1.de = _IQ(Vd_testing);
ipark1.qe = _IQ(Vq_testing);
ipark1.ang = rg1.rmp_out;
ipark1.calc(&ipark1);
svgen_dq1.Ualfa = ipark1.ds;
svgen_dq1.Ubeta = ipark1.qs;
svgen_dq1.calc(&svgen_dq1);
pwm1.Mfunc_c1 = (int)_IQtoIQ15(svgen_dq1.Ta); /* Mfunc_c1 is in Q15 */
pwm1.Mfunc_c2 = (int)_IQtoIQ15(svgen_dq1.Tb); /* Mfunc_c2 is in Q15 */
pwm1.Mfunc_c3 = (int)_IQtoIQ15(svgen_dq1.Tc); /* Mfunc_c3 is in Q15 */
pwm1.update(&pwm1);
pwmdac_ch1 = (int)_IQtoIQ15(svgen_dq1.Ta);
pwmdac_ch2 = (int)_IQtoIQ15(svgen_dq1.Tb);
pwmdac_ch3 = (int)_IQtoIQ15(svgen_dq1.Tc);
drv1.enable_flg = enable_flg;
drv1.update(&drv1);
#endif /* (BUILDLEVEL==LEVEL1) */
/* ***************** LEVEL2 ***************** */
#if (BUILDLEVEL==LEVEL2)
rc1.target_value = _IQ(speed_ref);
rc1.calc(&rc1);
rg1.rmp_freq = rc1.setpt_value;
rg1.calc(&rg1);
ipark1.de = _IQ(Vd_testing);
ipark1.qe = _IQ(Vq_testing);
ipark1.ang = rg1.rmp_out;
ipark1.calc(&ipark1);
svgen_dq1.Ualfa = ipark1.ds;
svgen_dq1.Ubeta = ipark1.qs;
svgen_dq1.calc(&svgen_dq1);
pwm1.Mfunc_c1 = (int)_IQtoIQ15(svgen_dq1.Ta); /* Mfunc_c1 is in Q15 */
pwm1.Mfunc_c2 = (int)_IQtoIQ15(svgen_dq1.Tb); /* Mfunc_c2 is in Q15 */
pwm1.Mfunc_c3 = (int)_IQtoIQ15(svgen_dq1.Tc); /* Mfunc_c3 is in Q15 */
pwm1.update(&pwm1);
ilg2_vdc1.read(&ilg2_vdc1);
clarke1.as = _IQ15toIQ((long)ilg2_vdc1.Imeas_a);
clarke1.bs = _IQ15toIQ((long)ilg2_vdc1.Imeas_b);
clarke1.calc(&clarke1);
park1.ds = clarke1.ds;
park1.qs = clarke1.qs;
park1.ang = rg1.rmp_out;
park1.calc(&park1);
volt1.DC_bus = _IQ15toIQ((long)ilg2_vdc1.Vdc_meas);
volt1.Mfunc_V1 = svgen_dq1.Ta;
volt1.Mfunc_V2 = svgen_dq1.Tb;
volt1.Mfunc_V3 = svgen_dq1.Tc;
volt1.calc(&volt1);
if((cap1.read(&cap1))==0) /* Call the capture read function */
{
speed1.time_stamp=(long)(cap1.time_stamp); /* Read out new time stamp */
speed1.calc(&speed1); /* Call the speed calulator */
}
pwmdac_ch1 = (int)_IQtoIQ15(clarke1.as);
pwmdac_ch2 = (int)_IQtoIQ15(clarke1.bs);
pwmdac_ch3 = (int)_IQtoIQ15(volt1.DC_bus);
drv1.enable_flg = enable_flg;
drv1.update(&drv1);
#endif /* (BUILDLEVEL==LEVEL2) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -