📄 main.c
字号:
//********************************************
//采用TMS320F2812实现二相永磁同步电机的磁场定向控制
//文件名称:PMSM3_1.C
//*******************************************
//#include "IQmathLib.h"/*包含IQmath库函数的头文件*/
//void mian()
//{}
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "pid.h"
#define TXCOUNT 10
#define RXCOUNT 1000
#define N 10
long loopcount=0;
Uint16 CAN_REV_H[1000];
Uint16 CAN_REV_L[1000];
Uint16 ConversionCount=0;
long CAN_REV;
long m=0;
void InitEcan(void);
void IODIS(void);
Uint16 filter(Uint16 *);
int t1_cnt=0;
//ECAN0 interrupt declaration
interrupt void ECAN0_ISR(void);
interrupt void adc_isr(void);
interrupt void eva_timer1_isr(void);
//Function declaration
void can_send(void);
Uint16 Loopcnt;
//Uint16 ConversionCount;
Uint16 Voltage1[N];
Uint16 Voltage2[N];
Uint16 temp;
Uint32 sum=0;
Uint16 tmp=0;
Uint16 value[N];
float32 v_p;
Uint16 v_p1;
struct STRUCT_PID sPID; //PID Control Stucture
Uint32 rOut=0; //PID Response(Output)
Uint32 rIn=0; //PID Feedback(Input)
void main(void)
{
struct ECAN_REGS ECanaShadow;
Loopcnt=0;
//pid parameters setting
PID_Init(&sPID);//Initialize Stucture
sPID.Derivative=1;
sPID.Integral=2;
sPID.LastError=0;
sPID.PrevError=0;
sPID.Proportion=2;
sPID.SetPoint=1;
sPID.SumError=0;
// ConversionCount=0;
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP281x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP281x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// For this example use the following configuration:
InitGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP281x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP281x_DefaultIsr.c.
// This function is found in DSP281x_PieVect.c.
InitPieVectTable();
InitECan();
InitAdc();
// Reconfigure PIE vector address
EALLOW;
PieVectTable.T1CINT=&eva_timer1_isr;
PieVectTable.ECAN0INTA=&ECAN0_ISR;
PieVectTable.ADCINT=&adc_isr;
EDIS;
// Enable ECAN0
PieCtrlRegs.PIEIER1.bit.INTx6=1; //A/D interrupt
PieCtrlRegs.PIEIER2.all=M_INT5; //T1PR interrupt
PieCtrlRegs.PIEIER9.all=M_INT5; // CAN interrupt
IER|=(M_INT1|M_INT2|M_INT9);
InitEv();
EINT;
ERTM;
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP281x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
//EvaRegs.T1CMPR=0x0080;
//EvaRegs.T1PR=0xFFFF;
//EvaRegs.GPTCONA.bit.T1TOADC=1;
//EvaRegs.T1CON.all=0x1042;
//while(1)
//{
//while(ECanaRegs.CANRMP.all!=0xFFFFFFFF){}
//ECanaRegs.CANRMP.all=0xFFFFFFFF;
//}
//start to send
while(1)
{
can_send();
Loopcnt++;
// IODIS();
}
/******************/
// CAN 接受程序
/******************/
}
interrupt void ECAN0_ISR(void)
{
m++;
CAN_REV_H[m]=ECanaMboxes.MBOX3.MDH.word.HI_WORD;
CAN_REV_L[m]=ECanaMboxes.MBOX3.MDL.word.LOW_WORD;
CAN_REV=CAN_REV_H[m]*65536+CAN_REV_L[m];
ECanaMboxes.MBOX0.MDH.all=CAN_REV_H[m];
ECanaMboxes.MBOX0.MDL.all=CAN_REV_L[m];
ECanaRegs.CANRMP.bit.RMP3=1;
if(m>1000)
{m=0;}
can_send();
return;
}
interrupt void adc_isr(void)
{
Voltage1[ConversionCount]=(AdcRegs.ADCRESULT0)/16;
Voltage2[ConversionCount]=AdcRegs.ADCRESULT1;
if(ConversionCount==N-1)
{
IODIS();
temp=filter(Voltage1)/(8);
v_p=((float32)(temp))/4095*3.3;
v_p1=(Uint16)(v_p*1000);
BC7281Init(v_p1);
delay_loop();
rIn++;
rOut=PIDCalc(sPID,rIn);
if(rIn>4095)
{rIn=0;}
//can_send();
//temp=temp*256;
//InitEva(0x7FFF);
ConversionCount=0;
}
else ConversionCount++;
// restart next ADC conversion
AdcRegs.ADCTRL2.bit.RST_SEQ1=1; // reset SEQ1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
//can_send();
return;
}
//中值滤波程序
Uint16 filter(Uint16 *a)
{
char i,j;
sum=0;
for(i=0;i<N;i++)
{
value[i]=a[i];
}
//排序算法,总共要进行(N-1)+(N-2)+....1次才可以
for(j=0;j<N-1;j++)//j=0--10
{
for(i=0;i<N-1-j;i++)//(i=0-11,---i=0--1)
{
if(value[i]>value[i+1])
{
tmp=value[i];
value[i]=value[i+1];
value[i+1]=tmp;
}
}
}
sum=value[1]+value[2]+value[3]+value[4]+value[5]+value[6]+value[7]+value[8];
return sum;
}
//定时器1中断程序
interrupt void eva_timer1_isr(void)
{
PieCtrlRegs.PIEIER1.bit.INTx6=0;
if(t1_cnt>4)
{
EvaRegs.CMPR1=0x01FF;
EvaRegs.T1CMPR=0x01FF;
t1_cnt=0;
}
else
{t1_cnt++;
EvaRegs.CMPR1=0x00FF;
EvaRegs.T1CMPR=0x00FF;
}
//can_send();
EvaRegs.EVAIMRA.bit.T1CINT=1;
EvaRegs.EVAIFRA.all=BIT8;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP2;
PieCtrlRegs.PIEIER1.bit.INTx6=1;
return;
}
//CAN发送程序
void can_send(void)
{
int i;
struct ECAN_REGS ECanaShadow;
for (i=0;i<TXCOUNT;i++)
{
ECanaShadow.CANTRS.all=0;
ECanaShadow.CANTRS.bit.TRS0=1;
ECanaRegs.CANTRS.all=ECanaShadow.CANTRS.all;
while(ECanaRegs.CANTA.bit.TA0==0){} //wait the finish of transmit msg
ECanaShadow.CANTA.all=0;
ECanaShadow.CANTA.bit.TA0=1; // clear TA1
ECanaRegs.CANTA.all=ECanaShadow.CANTA.all;
loopcount++;
}
loopcount=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -