?? main.c
字號:
/* ==============================================================================
System Name: PMSM31
File Name: PMSM3_1.C
Description: Primary system file for the Real Implementation of Sensored
Field Orientation Control for a Three Phase Permanent-Magnet
Synchronous Motor (PMSM) using QEP sensor
Originator: Digital control systems Group - Texas Instruments
Note: In this software, the default inverter is supposed to be DMC1500 board.
=====================================================================================
History:
-------------------------------------------------------------------------------------
04-15-2005 Version 3.20: Support both F280x and F281x targets
04-25-2005 Version 3.21: Move EINT and ERTM down to ensure that all initialization
is completed before interrupts are allowed.
================================================================================= */
#include "DSP281x_Device.h"
#include "IQmathLib.h"
#include "pmsm3_1.h"
#include "parameter.h"
#include "build.h"
//=========本文件中用到的函數原型聲明============
interrupt void MainISR(void);
interrupt void QepISR(void);
interrupt void SCIB_IX_ISR(void);
void Delay_Us(Uint16,Uint16);
#define CPU_CLOCK_SPEED 6.6667L // for a 150MHz CPU clock speed
#define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_CLOCK_SPEED) - 9.0L) / 5.0L)
extern void DSP28x_usDelay(unsigned long Count);
//============全局變量聲明=======================
float32 T = 0.001/ISR_FREQUENCY; //PWM頻率20KHZ,周期50us
float32 SpeedRef = 0.15; //速度參考值(標幺值),(0.2)
float32 IqRef = 0.1; // Iq參考值(標幺值)
float32 IdRef = 0; // Id參考值(標幺值)
float32 VqTesting = 0.18; // Vq測試值(標幺值),(0.25)
float32 VdTesting = 0; // Vd測試值(標幺值)
float32 angle;
Uint16 BackTicker = 0;
Uint16 IsrTicker = 0;
int16 PwmDacCh1=0;
int16 PwmDacCh2=0;
int16 PwmDacCh3=0;
int16 DlogCh1 = 0;
int16 DlogCh2 = 0;
int16 DlogCh3 = 0;
int16 DlogCh4 = 0;
Uint16 LockRotorFlag = FALSE;
Uint16 SpeedLoopPrescaler =10; // Speed loop prescaler
Uint16 SpeedLoopCount = 1; // Speed loop counter
Uint16 Counter1,Counter2; //用作臨時循環變量
Uint16 rcounter=0; //旋轉的圈數
Uint16 SCI_1; //發送給SCI口的4個8位的數據:SCI_4-SCI_3-SCI_2-SCI_1
Uint16 SCI_2;
Uint16 SCI_3;
Uint16 SCI_4;
//============全局變量聲明結束=======================
//=============全局對象聲明及初始構造================
//電流(直流電壓)ADC對象
ILEG2DCBUSMEAS ilg2_vdc1 = ILEG2DCBUSMEAS_DEFAULTS;
//位置角度及轉速計算對象
QEP qep1 = QEP_DEFAULTS;
SPEED_MEAS_QEP speed1 = SPEED_MEAS_QEP_DEFAULTS;
//坐標變換對象
CLARKE clarke1 = CLARKE_DEFAULTS;
PARK park1 = PARK_DEFAULTS;
IPARK ipark1 = IPARK_DEFAULTS;
//PID控制器對象
PIDREG3 pid1_spd = PIDREG3_DEFAULTS;
PIDREG3 pid1_iq = PIDREG3_DEFAULTS;
PIDREG3 pid1_id = PIDREG3_DEFAULTS;
//空間矢量運算及PWM相關對象
SVGENDQ svgen_dq1 = SVGENDQ_DEFAULTS;
PWMGEN pwm1 = PWMGEN_DEFAULTS;
PWMDAC pwmdac1 = PWMDAC_DEFAULTS;
//其它輔助對象
RMPCNTL rc1 = RMPCNTL_DEFAULTS;
RAMPGEN rg1 = RAMPGEN_DEFAULTS;
DLOG_4CH dlog = DLOG_4CH_DEFAULTS;
//=============全局對象聲明及初始構造結束================
//==================主函數===============================
void main(void)
{
//初始化系統設置
InitSysCtrl(); //關閉看門狗;設置PLL(5*30MHZ);設置并打開打開默認高低速外設時鐘
EALLOW;
SysCtrlRegs.HISPCP.all = 0x0000; // 設置高速外設時鐘為150MHZ
SysCtrlRegs.LOSPCP.all=0x0002; //設置高速外設時鐘(SCI)37.5MHZ
EDIS;
//禁止并清除所有CPU中斷
DINT;
IER = 0x0000;
IFR = 0x0000;
//填充中斷向量表
InitPieCtrl(); //DINT;不使能PIE;清除12組PIEIER和PIEIFR
InitPieVectTable(); //把中斷向量表區裝滿指向形式ISR的指針;使能PIE
EALLOW;
PieVectTable.T1UFINT = &MainISR; //主中斷是T1下溢中斷
PieVectTable.CAPINT3 = &QepISR; //cap3中斷
PieVectTable.TXBINT=&SCIB_IX_ISR;
EDIS;
//開通串口SCI-A
EALLOW;
GpioMuxRegs.GPGMUX.all=0x0030; //GPIOF4和GPIOF5作為SCI口
EDIS;
ScibRegs.SCICCR.all=0x0007; //8位數據,無奇偶校驗,一位停止位
ScibRegs.SCICTL1.all=0x0022; //使SCI退出復位狀態,使能發送
ScibRegs.SCIHBAUD=0x0000;
ScibRegs.SCILBAUD=0x0027; //波特率為117187b/s
//初始化EVA的通用定時器控制寄存器A
EvaRegs.GPTCONA.all = 0; //T1、T2無事件驅動ADC,禁止定時器比較輸出T1PWM、T2PWM
//開通T1UFINT,CAP3,SCITXINTB中斷
EvaRegs.EVAIMRA.bit.T1UFINT = 1; //使能T1UFINT
EvaRegs.EVAIFRA.bit.T1UFINT = 1; //清除T1UFINT中斷標志
EvaRegs.EVAIMRC.bit.CAP3INT = 1; //使能CAP3中斷
EvaRegs.EVAIFRC.bit.CAP3INT = 1; //清除CAP3中斷標志
PieCtrlRegs.PIEIER9.all = M_INT4;
PieCtrlRegs.PIEIER2.all = M_INT6;
PieCtrlRegs.PIEIER3.all = M_INT7;
IER |= (M_INT2 | M_INT3| M_INT9);
//初始化GBIOB6(s4)和GPIOB7(s12)引腳作為輸入引腳,其中s4升速,s12減速
//初始化GBIOB8(s5)和GPIOE0(s13)引腳作為輸入引腳,其中s5提升轉矩,s13降低轉矩
GpioMuxRegs.GPBMUX.bit.T3PWM_GPIOB6=0x0; //I/O
GpioMuxRegs.GPBMUX.bit.T4PWM_GPIOB7=0x0; //I/O
GpioMuxRegs.GPBMUX.bit.CAP4Q1_GPIOB8=0x0; //I/O
GpioMuxRegs.GPEMUX.bit.XINT1_XBIO_GPIOE0=0x0; //I/O
GpioMuxRegs.GPBDIR.bit.GPIOB6=0x0; //IN
GpioMuxRegs.GPBDIR.bit.GPIOB7=0x0; //IN
GpioMuxRegs.GPBDIR.bit.GPIOB8=0x0; //IN
GpioMuxRegs.GPEDIR.bit.GPIOE0=0x0; //IN
//=========各個對象的參數設置及硬件初始化動作============
//電流(直流電壓)ADC對象
ilg2_vdc1.ChSelect=0x3210; //Ia:ADINA0;Ib:ADCINA1;Ic:ADCINA2;vsense:ADCINA3
ilg2_vdc1.init(&ilg2_vdc1); //T1下溢時啟動AD轉換,采用查詢方式讀取電流和電壓的AD結果
//角度及速度計算對象
qep1.LineEncoder = 2500;
qep1.MechScaler = _IQ30(0.25/qep1.LineEncoder); //一個定時器計數值代表的機械圈數
qep1.PolePairs = P/2;
qep1.CalibratedAngle = -2365;
qep1.init(&qep1); //CAP1、CAP2作為QEP1、QEP2引腳,T2計脈沖數;CAP3作為捕獲T2的引腳,捕獲上升沿
speed1.K1 = _IQ21(1/(BASE_FREQ*T));
speed1.K2 = _IQ(1/(1+T*2*PI*30)); // Low-pass cut-off frequency,截至頻率為30HZ
speed1.K3 = _IQ(1)-speed1.K2;
speed1.BaseRpm = 120*(BASE_FREQ/P); //電同步轉速
//初始化PID控制器對象
pid1_id.Kp = _IQ(0.75);
pid1_id.Ki = _IQ(T/0.0005);
pid1_id.Kd = _IQ(0/T);
pid1_id.Kc = _IQ(0.2);
pid1_id.OutMax = _IQ(0.30);
pid1_id.OutMin = _IQ(-0.30);
pid1_iq.Kp = _IQ(0.75);
pid1_iq.Ki = _IQ(T/0.0005);
pid1_iq.Kd = _IQ(0/T);
pid1_iq.Kc = _IQ(0.2);
pid1_iq.OutMax = _IQ(0.95);
pid1_iq.OutMin = _IQ(-0.95);
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);
//初始化PWM相關對象
//仿真掛起,則當前定時器周期結束停止;150MHZ;連續增減(對稱PWM)
//每一對都是前者高有效,后者低有效
//死區時間(10×8)/150M=0.533us
//當T1下溢或周期匹配時,CMPRx重載
pwm1.PeriodMax = SYSTEM_FREQUENCY*1000000*T/2; //半個采樣周期內的CPU時鐘周期數
pwm1.init(&pwm1);
//仿真掛起,則當前定時器周期結束停止;150MHZ;連續增減(對稱PWM)
//每一對都是前者低有效,后者高有效
//死區時間0
//僅當T1下溢時,CMPRx重載
pwmdac1.PeriodMax = (SYSTEM_FREQUENCY*200/(30*2))*5; // PWMDAC Frequency = 30 kHz
pwmdac1.PwmDacInPointer0 = &PwmDacCh1;
pwmdac1.PwmDacInPointer1 = &PwmDacCh2;
pwmdac1.PwmDacInPointer2 = &PwmDacCh3;
pwmdac1.init(&pwmdac1);
//初始化其它模塊
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);
rc1.RampDelayMax=40; //加速的快慢
rg1.StepAngleMax = _IQ(BASE_FREQ*T);//電機全速(速度標幺值為1)運行下一個PWM周期內旋轉磁場轉過的電角度(標幺值)
//====各個對象的參數設置及硬件初始化動作完成=============
//通入某一電壓矢量0.5S,使轉子磁場和定子磁場對準,定位初始轉子位置
angle=-0.25;
ipark1.Ds = _IQ(VdTesting);
ipark1.Qs = _IQ(VqTesting);
ipark1.Angle=_IQ(angle);
ipark1.calc(&ipark1);
svgen_dq1.Ualpha = ipark1.Alpha;
svgen_dq1.Ubeta = ipark1.Beta;
svgen_dq1.calc(&svgen_dq1);
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);
DELAY_US(10000);
//使能全局中斷、INTM實時中斷DBGM
EINT;
ERTM;
for(;;)
{
BackTicker++; //死循環
//=======處理升降速按鍵========
if (GpioDataRegs.GPBDAT.bit.GPIOB6==0) //s4按下為0,升速
{
//去抖
Delay_Us(2000,1000);
SpeedRef+=0.01;
if (SpeedRef>0.99) SpeedRef=0.99;
}
if (GpioDataRegs.GPBDAT.bit.GPIOB7==0) //s12按下為0,減速
{
//去抖
Delay_Us(2000,1000);
SpeedRef-=0.01;
if (SpeedRef<0.01) SpeedRef=0.01;
}
//=======處理升降力矩按鍵========
if (GpioDataRegs.GPBDAT.bit.GPIOB8==0) //s5按下為0,提升力矩
{
//去抖
Delay_Us(2000,1000);
VqTesting+=0.01;
if (VqTesting>0.8) VqTesting=0.8;
}
if (GpioDataRegs.GPEDAT.bit.GPIOE0==0) //s13按下為0,降低力矩
{
//去抖
Delay_Us(2000,1000);
VqTesting-=0.01;
if (VqTesting<0.01) VqTesting=0.01;
}
}
}
//======================中斷函數定義=====================
interrupt void MainISR(void)
{
// Verifying the ISR
IsrTicker++;
#if (BUILDLEVEL==LEVEL1)
//***************** LEVEL1 *****************
// ------------------------------------------------------------------------------
// 經過RampDelayMax(40)個PWM周期調整一次SetPointValue(瞬時速度標幺值)
// 直到SetPointValue接近SpeedRef,模擬升速
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -