⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmsm.c

📁 基于DSP 2812的永磁同步电动机矢量控制程序
💻 C
字号:

#include "DSP281x_Device.h"       // DSP281x Headerfile Include File
#include "DSP281x_Examples.h"     // DSP281x Examples Include File
#include "IQmathLib.h"            // Include header for IQmath library
#include "pmsm.h"
#include "parameter.h"
#include <math.h>

//  主中断
interrupt void MainISR(void);
void init_evb(void);              // EVB PWM 9 :

void scia_loopback_init(void);    // SCI寄存器设置
void scia_fifo_init(void);        // 初始化SCI_FIFO
void scia_xmit(int a);            // SCI发送

void spi_init(void);               //初始化spi
void spi_fifo_init(void);
unsigned int spi_read(void);             //spi接收 
void spi_xmit(int a);

void set_cs(void);
void reset_cs(void);

//  全局变量定义
long i=0;
long m=0;
unsigned int  Resolver[500];

Uint16 Resol_Mech_Theta = 0;
Uint16 Rotor_Mech_Theta = 0;
Uint16 Rotor_Elec_Theta_Temp=0;
float32  Ele_Theta_temp;
_iq Rotor_Elec_Theta;

//  Adc(内部AD)变量
Uint16 Voltage1;
Uint16 Voltage2;
Uint16 Voltage3;
Uint16 Voltage4;

Uint16 SendChar;                  // SCI发送变量
Uint16 ReceivedChar;

float32 VdTesting = 0;            // Vd testing (pu) 
float32 VqTesting = 0.5;          // Vq testing (pu)
float32 SpeedRef = 0.3;           // Speed reference (pu)
float32 T = 0.001/ISR_FREQUENCY;  // 采样周期 (sec), see parameter.h 

int16 DlogCh1 = 0;                // 
int16 DlogCh2 = 0;
int16 DlogCh3 = 0;
int16 DlogCh4 = 0;

Uint16 IsrTicker = 0;
Uint16 BackTicker = 0;

//  CLARKE,PARK,IPARK:初始值
CLARKE clarke1 = CLARKE_DEFAULTS;
PARK park1 = PARK_DEFAULTS;
IPARK ipark1 = IPARK_DEFAULTS;

//  PWM:初始值
PWMGEN pwm1 = PWMGEN_DEFAULTS;

//  SVPWM:初始值
SVGENDQ svgen_dq1 = SVGENDQ_DEFAULTS;

//  RMPCNTL:初始值
RMPCNTL rc1 = RMPCNTL_DEFAULTS;

//  RAMPGEN:初始值
RAMPGEN rg1 = RAMPGEN_DEFAULTS;

//  DLOG:初始值
DLOG_4CH dlog = DLOG_4CH_DEFAULTS;

//  主程序
void main(void)
{

//  系统初始化,系统时钟=150M,使能外设时钟(高速,低速),在DSP281x_SysCtrl.c文件中
    InitSysCtrl();

//  GPIO为片内外设
    EALLOW;

    GpioMuxRegs.GPAMUX.all = 0x003F;   // GPIOA0-GPIO5 : EVA PWM 1-6  
    GpioMuxRegs.GPBMUX.bit.PWM9_GPIOB2 = 1;   //  EVB PWM 9 :Sample
    GpioMuxRegs.GPFMUX.all = 0x003f;   // GPIOF4 : SCITXDA

    EDIS;
    
//  禁止CPU中断
    DINT;

//  PIE初始化,禁止PIE中断,PIE中断标志清零,在DSP281x_PieCtrl.c文件中
    InitPieCtrl();

//  禁止CPU中断,CPU中断标志清零
    IER = 0x0000;
    IFR = 0x0000;

//  PIE向量表初始化,在DSP281x_PieVect.c文件中
    InitPieVectTable();
   
//  Adc(内部AD)初始化,在DSP281x_Adc.c文件中
    InitAdc();
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 8;
    AdcRegs.ADCMAXCONV.all=0x0003;
    AdcRegs.ADCCHSELSEQ1.bit.CONV00=0x0008;
    AdcRegs.ADCCHSELSEQ1.bit.CONV01=0x0009;
    AdcRegs.ADCCHSELSEQ1.bit.CONV02=0x00010;
    AdcRegs.ADCCHSELSEQ1.bit.CONV03=0x00011;

    scia_fifo_init();      // 初始化SCI_FIFO
    scia_loopback_init();  // SCI寄存器设置

//  使能PIE外部中断1
    IER|=M_INT1;
  
//  初始化 EVA Timer 1:
//  设置EVA寄存器
    EvaRegs.GPTCONA.all = 0;
   
//  使能 GP timer 1 下溢中断
    EvaRegs.EVAIMRA.bit.T1UFINT = 1;
    EvaRegs.EVAIFRA.bit.T1UFINT = 1;

//  主中断
	EALLOW;
	PieVectTable.T1UFINT = &MainISR;
	EDIS;

//  使能 PIE group 2 interrupt 6 for T1UFINT
    PieCtrlRegs.PIEIER2.all = M_INT6;

//  使能 CPU INT2 for T1UFINT
	IER |= M_INT2;

//  EVA时钟是高速外设时钟,是CPU的1/2	
    pwm1.PeriodMax = SYSTEM_FREQUENCY*1000000*T/2;
	pwm1.init(&pwm1);
	        
    init_evb();

//  初始化 DATALOG 模块
    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);
        
//  初始化 RAMPGEN 模块
    rg1.StepAngleMax = _IQ(BASE_FREQ*T);

//  使能CPU中断

    EINT;
    ERTM;

	spi_fifo_init();
	spi_init();

    SciaRegs.SCITXBUF = 0;
    SpiaRegs.SPIRXBUF = 0;

    while (1)
    {
     BackTicker++;
     scia_xmit(Resolver[m]);
    }

}

interrupt void MainISR(void)
{
// Strat of Reading the Electric Theta
    spi_xmit(0x0fff);
    Resolver[m] = spi_read();

	Resolver[m] = Resolver[m]+518;
	if (Resolver[m]>=4095)
	  {
	   Resolver[m] = Resolver[m]-4095;
	  }
    Rotor_Mech_Theta = Resolver[m];

	Ele_Theta_temp = (float32)Rotor_Mech_Theta/819.0;  

	 if (Ele_Theta_temp <= 1)
	   {
	    Rotor_Elec_Theta = Ele_Theta_temp * (_IQ(1))+(_IQ(0));
	   }
     else if((Ele_Theta_temp > 1)&&(Ele_Theta_temp <= 2))
	   {
	    Rotor_Elec_Theta = (Ele_Theta_temp-1)*(_IQ(1))+(_IQ(0));
	   }
     else if((Ele_Theta_temp > 2)&&(Ele_Theta_temp <= 3))
	   {
	    Rotor_Elec_Theta = (Ele_Theta_temp-2)*(_IQ(1))+(_IQ(0));
	   } 
     else if((Ele_Theta_temp > 3)&&(Ele_Theta_temp <= 4))
	   {
	    Rotor_Elec_Theta = (Ele_Theta_temp-3)*(_IQ(1))+(_IQ(0));
	   } 
     else if((Ele_Theta_temp > 4)&&(Ele_Theta_temp <= 5))
	   {
	    Rotor_Elec_Theta = (Ele_Theta_temp-4)*(_IQ(1))+(_IQ(0));
	   }  
// End of Reading the Electric Theta 


// ------------------------------------------------------------------------------
//    RAMP_CNTL 模块 
// ------------------------------------------------------------------------------
    rc1.TargetValue = _IQ(SpeedRef);
    rc1.calc(&rc1);

// ------------------------------------------------------------------------------
//    RAMP_GEN 模块 
// ------------------------------------------------------------------------------
    rg1.Freq = rc1.SetpointValue;
    rg1.calc(&rg1);

// ------------------------------------------------------------------------------
//    I_PARK 模块
// ------------------------------------------------------------------------------
    ipark1.Ds = _IQ(VdTesting);
    ipark1.Qs = _IQ(VqTesting);	
    ipark1.Angle = Rotor_Elec_Theta;
//    ipark1.Angle = rg1.Out;
    ipark1.calc(&ipark1);

// ------------------------------------------------------------------------------
//    SVGEN_DQ 模块
// ------------------------------------------------------------------------------
  	svgen_dq1.Ualpha = ipark1.Alpha;
 	svgen_dq1.Ubeta = ipark1.Beta;
  	svgen_dq1.calc(&svgen_dq1);	

// ------------------------------------------------------------------------------
//    PWM 模块
// ------------------------------------------------------------------------------
    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); 

// ------------------------------------------------------------------------------
//    DATALOG 模块的显示数据 
// ------------------------------------------------------------------------------
    DlogCh1 = (int16)_IQtoIQ15(svgen_dq1.Tc);
    DlogCh2 = (int16)_IQtoIQ15(svgen_dq1.Tb);
    DlogCh3 = (int16)_IQtoIQ15(svgen_dq1.Tc);
    DlogCh4 = (int16)_IQtoIQ15(svgen_dq1.Ta-svgen_dq1.Tb);
    
// ------------------------------------------------------------------------------
//    DATALOG 模块显示
// ------------------------------------------------------------------------------
    dlog.update(&dlog);
    
//  使能 GP timer 1 下溢中断
	EvaRegs.EVAIMRA.bit.T1UFINT = 1;
	
//  判断是否发生中断,读后置0 
    EvaRegs.EVAIFRA.all = BIT9;
	
//  使能 PIE group 2 全部中断
	PieCtrlRegs.PIEACK.all |= PIEACK_GROUP2;
}

void init_evb()
{

    EvbRegs.T3PR = 0x1D4C;         // 20K
   
    EvbRegs.T3CNT = 0x0000;
    EvbRegs.T3CON.all = 0x1040;    // 连续增

    EvbRegs.CMPR5 = 0x0064;
 
    EvbRegs.ACTRB.all = 0x0666;
    EvbRegs.DBTCONB.all = 0x0000;  // 禁止死区
    EvbRegs.COMCONB.all = 0xA600;

}

//  SCI寄存器设置
void scia_loopback_init()
{
    SciaRegs.SCICCR.all = 0x0007;       // 1个结束位,禁止回送测试,无奇偶校验位
                                        // 选择空闲线协议,8位数据位
    SciaRegs.SCICTL1.all = 0x0003;      // 使能TX,RX,SCICLK,SCI软件复位

    SciaRegs.SCICTL2.all = 0x0000;      // 禁止接收和发送中断 

    SciaRegs.SCIHBAUD    = 0x0001;
    SciaRegs.SCILBAUD    = 0x00E7;      // Baud:9600

    SciaRegs.SCICCR.bit.LOOPBKENA =1;   // 使能回送测试  
    SciaRegs.SCICTL1.all = 0x0023;      // 重启SCI 
}

//  初始化SCI_FIFO
void scia_fifo_init()										
{
    SciaRegs.SCIFFTX.all=0xE040;       // 
    SciaRegs.SCIFFRX.all=0x605f;       //
    SciaRegs.SCIFFCT.all=0x0000;       //
}

//  SCI发送
void scia_xmit(int a)
{
   while (!(SciaRegs.SCICTL2.bit.TXRDY));     
    SciaRegs.SCITXBUF = a>>8; 

    while (!(SciaRegs.SCICTL2.bit.TXRDY));
    SciaRegs.SCITXBUF = a;
}

void spi_init(void)
{
    EALLOW;
    GpioMuxRegs.GPFMUX.bit.SPISIMOA_GPIOF0 = 1;   
	GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1 = 1;
	GpioMuxRegs.GPFMUX.bit.SPICLKA_GPIOF2 = 1;
	GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3=1;   
    EDIS;
     
    SpiaRegs.SPICCR.all=0x004b;        // 数据长度为12位,在时钟下降沿发送数据,在上升沿接收数据
    SpiaRegs.SPICTL.all=0x0006;        // 主工作方式,允许发送,禁止中断;spi时钟相位延时
    SpiaRegs.SPIBRR=0x0049;            // 波特率0.5M

    SpiaRegs.SPICCR.all= 0x00cb;       // 启动SPI
} 

void spi_fifo_init(void)										
{
    SpiaRegs.SPIFFTX.all=0xE040;       // 
    SpiaRegs.SPIFFRX.all=0x204f;       //
    SpiaRegs.SPIFFCT.all=0x0000;       //
}

unsigned int spi_read(void)
   {
    unsigned int temp;
//    reset_cs ();
	while(SpiaRegs.SPIFFRX.bit.RXFFST == 0);
    temp = SpiaRegs.SPIRXBUF;
//	set_cs();
	return (temp&0x0fff);

   }

void spi_xmit(int a)
   {
//   while(SpiaRegs.SPIFFTX.bit.TXFFST != 1);
   SpiaRegs.SPITXBUF=a;
   }

void set_cs(void)
{
//     EALLOW;   
     GpioDataRegs.GPFDAT.bit.GPIOF3=1;             // 将IOPF3输出为1,spiste===CS 
//     EDIS;      
}

void reset_cs(void)
{                                                  // 将片选信号置低,选中芯片
//    EALLOW;   
     GpioDataRegs.GPFDAT.bit.GPIOF3=0;             // 将IOPF3输出为0,spiste===CS 
//    EDIS;    

} 



//===========================================================================
// No more.
//===========================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -