📄 pmsm.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 + -