pmsm3_4.c
来自「通过F2812产生PWM波形来控制电机的运转.」· C语言 代码 · 共 478 行 · 第 1/2 页
C
478 行
pwmdac1.init(&pwmdac1);
// Initialize DATALOG module
dlog.iptr1 = &DlogCh1;
dlog.iptr2 = &DlogCh2;
dlog.iptr3 = &DlogCh3;
dlog.iptr4 = &DlogCh4;
dlog.trig_value = 0x1;
dlog.size = 0x400;
dlog.prescalar = 1;
dlog.init(&dlog);
// Initialize QEP module
qep1.LineEncoder = 500;//gaidong
qep1.MechScaler = _IQ30(0.25/qep1.LineEncoder);
qep1.PolePairs = P/2;
qep1.CalibratedAngle = 0; //-1250;
qep1.init(&qep1);
// Initialize the Speed module for QEP based speed calculation
speed1.K1 = _IQ21(1/(BASE_FREQ*T));
speed1.K2 = _IQ(1/(1+T*2*PI*30)); // Low-pass cut-off frequency
speed1.K3 = _IQ(1)-speed1.K2;
speed1.BaseRpm = 120*(BASE_FREQ/P);
// Initialize enable drive module (FOR DMC1500 ONLY)
drv1.init(&drv1);
// Initialize ADC module
// Note for DMC550:
// - At 24 dc-bus volt, the ADC input for measured Vdc_bus range is 24*1/(24.9+1) = 0.927 volt
// - Then, Vdc_bus gain = 3.0/0.927 = 3.2375 (or 0x675C in Q13)
ilg2_vdc1.VdcMeasGain = 0x675C;
//ilg2_vdc1.ChSelect = 0x0610;
ilg2_vdc1.init(&ilg2_vdc1);
// Initialize the RAMPGEN module
rg1.StepAngleMax = _IQ(BASE_FREQ*T);
// Initialize the RAMPGEN module
rc1.RampDelayMax = 5;
// Initialize the PID_REG3 module for Id
pid1_id.Kp = _IQ(0.1);
pid1_id.Ki = _IQ(T/0.02);
pid1_id.Kd = _IQ(0/T);
pid1_id.Kc = _IQ(0.5);
pid1_id.OutMax = _IQ(0.30);
pid1_id.OutMin = _IQ(-0.30);
// Initialize the PID_REG3 module for Iq
pid1_iq.Kp = _IQ(0.1);
pid1_iq.Ki = _IQ(T/0.02);
pid1_iq.Kd = _IQ(0/T);
pid1_iq.Kc = _IQ(0.5);
pid1_iq.OutMax = _IQ(0.95);
pid1_iq.OutMin = _IQ(-0.95);
// Initialize the PID_REG3 module for speed control
pid1_spd.Kp = _IQ(1);
pid1_spd.Ki = _IQ(T*SpeedLoopPrescaler/0.3);
pid1_spd.Kd = _IQ(0/(T*SpeedLoopPrescaler));
pid1_spd.Kc = _IQ(0.2);
pid1_spd.OutMax = _IQ(1);
pid1_spd.OutMin = _IQ(-1);
// Initialize the PID_REG3 module for position control
pid1_pos.Kp = _IQ(28.2);
pid1_pos.Ki = _IQ(0); // Integral term is not used
pid1_pos.Kd = _IQ(0); // Derivative term is not used
pid1_pos.Kc = _IQ(0);
pid1_pos.OutMax = _IQ(1);
pid1_pos.OutMin = _IQ(-1);
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// IDLE loop. Just sit and loop forever:
for(;;) BackTicker++;
}
interrupt void MainISR(void)
{
if(key_addr == 0x00EF)
EvaRegs.COMCONA.all=0x0100; //STOP KEY
if (key_addr == 0x00FD) //START KEY
EvaRegs.COMCONA.all=0xA200;
// Verifying the ISR
IsrTicker++;
//EvaRegs.COMCONA.all=0x0100;
//#else if /*(&(0xa0001)!=0x00EF);*/
// continue;
// ***************** LEVEL1 *****************
#if (BUILDLEVEL==LEVEL1)
// ------------------------------------------------------------------------------
// Connect inputs of the RMP module and call the Ramp control
// calculation function.
// ------------------------------------------------------------------------------
rc1.TargetValue = _IQ(SpeedRef);
rc1.calc(&rc1);
// ------------------------------------------------------------------------------
// Connect inputs of the RAMP GEN module and call the Ramp generator
// calculation function.
// ------------------------------------------------------------------------------
rg1.Freq = rc1.SetpointValue;
rg1.calc(&rg1);
// ------------------------------------------------------------------------------
// Connect inputs of the INV_PARK module and call the inverse park transformation
// calculation function.
// ------------------------------------------------------------------------------
ipark1.Ds = _IQ(VdTesting);
ipark1.Qs = _IQ(VqTesting);
ipark1.Angle = rg1.Out;
ipark1.calc(&ipark1);
// ------------------------------------------------------------------------------
// Connect inputs of the SVGEN_DQ module and call the space-vector gen.
// calculation function.
// ------------------------------------------------------------------------------
svgen_dq1.Ualpha = ipark1.Alpha;
svgen_dq1.Ubeta = ipark1.Beta;
svgen_dq1.calc(&svgen_dq1);
// ------------------------------------------------------------------------------
// Connect inputs of the PWM_DRV module and call the PWM signal generation
// update function.
// ------------------------------------------------------------------------------
pwm1.MfuncC1 = (int16)_IQtoIQ15(svgen_dq1.Ta); // MfuncC1 is in Q15
pwm1.MfuncC2 = (int16)_IQtoIQ15(svgen_dq1.Tb); // MfuncC2 is in Q15
pwm1.MfuncC3 = (int16)_IQtoIQ15(svgen_dq1.Tc); // MfuncC3 is in Q15
pwm1.update(&pwm1);
// ------------------------------------------------------------------------------
// Connect inputs of the PWMDAC module
// ------------------------------------------------------------------------------
PwmDacCh1 = (int16)_IQtoIQ15(svgen_dq1.Ta);
PwmDacCh2 = (int16)_IQtoIQ15(svgen_dq1.Tb);
PwmDacCh3 = (int16)_IQtoIQ15(svgen_dq1.Tc);
// ------------------------------------------------------------------------------
// Connect inputs of the DATALOG module
// ------------------------------------------------------------------------------
DlogCh1 = (int16)_IQtoIQ15(svgen_dq1.Ta);
DlogCh2 = (int16)_IQtoIQ15(svgen_dq1.Tb);
DlogCh3 = (int16)_IQtoIQ15(svgen_dq1.Tc);
DlogCh4 = (int16)_IQtoIQ15(svgen_dq1.Ta-svgen_dq1.Tb);
// ------------------------------------------------------------------------------
// Connect inputs of the EN_DRV module and call the enable/disable PWM signal
// update function. (FOR DMC1500 ONLY)
// ------------------------------------------------------------------------------
drv1.EnableFlag = EnableFlag;
drv1.update(&drv1);
#endif // (BUILDLEVEL==LEVEL1)
// ------------------------------------------------------------------------------
// Call the PWMDAC update function.
// ------------------------------------------------------------------------------
pwmdac1.update(&pwmdac1);
// ------------------------------------------------------------------------------
// Call the DATALOG update function.
// ------------------------------------------------------------------------------
dlog.update(&dlog);
#if (DSP_TARGET==F2812)
// Enable more interrupts from this timer
EvaRegs.EVAIMRA.bit.T1UFINT = 1;
// Note: To be safe, use a mask value to write to the entire
// EVAIFRA register. Writing to one bit will cause a read-modify-write
// operation that may have the result of writing 1's to clear
// bits other then those intended.
EvaRegs.EVAIFRA.all = BIT9;
// Acknowledge interrupt to recieve more interrupts from PIE group 2
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP2;
#endif
}
#if (DSP_TARGET==F2812)
interrupt void QepISR(void)
{
// ------------------------------------------------------------------------------
// Call the QEP_DRV isr function.
// ------------------------------------------------------------------------------
qep1.isr(&qep1);
// Enable more interrupts from this timer
EvaRegs.EVAIMRC.bit.CAP3INT = 1;
// Note: To be safe, use a mask value to write to the entire
// EVAIFRC register. Writing to one bit will cause a read-modify-write
// operation that may have the result of writing 1's to clear
// bits other then those intended.
EvaRegs.EVAIFRC.all = BIT2;
// Acknowledge interrupt to recieve more interrupts from PIE group 3
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3;
}
#endif
//===========================================================================
// No more.
//===========================================================================
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?