/*******************************************************************/
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File
#define PERIOD 20000
/*******************************************************************/
unsigned int rc=4; //设定转速rc (round/0.1s)必须为整数(3~5)
//在图形窗口观察到的是10*rc (round/s)
unsigned int curve[1000];
unsigned int int_flag=0;
unsigned int count1=0;
unsigned int count2=0;
double percent=0.0;
unsigned int i=0;
unsigned int j=0;
unsigned int k=0;
unsigned int m=0;
unsigned int n=0;
unsigned int high=0;
unsigned int low=0;
double e0,e1,e2,y0,y1,y2,x;
double Kp =3; //3比例系数
double Ti = 1.0; //积分时间常数
double Td = 0.2; //微分时间常数
double T = 0.1; //采样周期
double a0,a1,a2;
void init_xint2() //中断pdpintb初始化子程序
{
XIntruptRegs.XINT2CR.all=0x0001;
}
void init_timer1(void)
{
// Initialize EVA Timer 1:
// Setup Timer 1 Registers (EV A)
EvaRegs.GPTCONA.all = 0;
// Set the Period for the GP timer 1 to 0x8200;
EvaRegs.T1PR = 0xB200; // Period
EvaRegs.T1CMPR = 0x0000; // Compare Reg
// Enable Period interrupt bits for GP timer 1
// Count up, x128, internal clk, enable compare, use own period
EvaRegs.EVAIMRA.bit.T1PINT = 1;
EvaRegs.EVAIFRA.bit.T1PINT = 1;
// Clear the counter for GP timer 1
EvaRegs.T1CNT = 0x0000;
EvaRegs.T1CON.all = 0x1742;
// Start EVA ADC Conversion on timer 1 Period interrupt
EvaRegs.GPTCONA.bit.T1TOADC = 2;
}
interrupt void xint2_isr() //外部中断2中断子程序
{
count1++; //转速计累加
// Acknowledge interrupt to receive more interrupts from PIE group 2
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
return;
}
interrupt void timer1_isr() //定时中断子程序
{
if(int_flag==1)
{
y2 = y1;
y1 = y0;
y0 = count1;
e0 = rc - y0;
e1 = rc - y1;
e2 = rc - y2;
percent=(a0*e0 - a1*e1 + a2*e2)*0.05;
high+=PERIOD*percent;
//if(high>=20000)high=20000;
if(high<=0)high=0;
low=PERIOD-high;
}
if(n==10)
{
curve[m]=count2;
m++;
n=0;
count2=0;
}
n++;
count2+=count1;
count1=0; //转速计清零
// Enable more interrupts from this timer
EvaRegs.EVAIMRA.bit.T1PINT = 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 = BIT7;
// Acknowledge interrupt to receive more interrupts from PIE group 2
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
return;
}
void main()
{
int m;
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP281x_SysCtrl.c file.
InitSysCtrl();
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
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).
InitPieVectTable();
EALLOW;
GpioMuxRegs.GPFMUX.all=0xffff; //as xf
// GpioMuxRegs.GPBMUX.all=0x0000; //as GPIO
// GpioMuxRegs.GPBDIR.bit.GPIOB15=1; //GPIOB15 as output
EDIS;
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.T1PINT = &timer1_isr;
PieVectTable.XINT2 = &xint2_isr;
EDIS;
// This function is found in DSP281x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
init_xint2();
init_timer1();
PieCtrlRegs.PIEIER1.all = M_INT5; //xint2
// Enable PIE group 2 interrupt 4 for T1PINT
PieCtrlRegs.PIEIER2.all = M_INT4;
IER |= M_INT1 ;//xint2
// Enable CPU INT2 for T1PINT
IER |= M_INT2 ;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
for(m=0;m<1000;m++)
{
curve[m]=0;
}
a0 = Kp*(1.0 + T/Ti + Td/T);
a1 = Kp*(1.0 + 2.0*Td/T);
a2 = Kp*Td/T;
e0=e1=e2=y0=y1=y2=0;
for(i=0;i<5000;i++) //启动电机,使之处于高速状态
{
for(j=0;j<5000;j++)
// GpioDataRegs.GPBDAT.bit.GPIOB5=0; //PWM12引脚为低
asm(" clrc xf");
}
int_flag=1;
for(;;)
{
// GpioDataRegs.GPBDAT.bit.GPIOB5=0; // as low ; //PWM12/io7引脚为低
asm(" clrc xf");
for(j=0;j<high;j++);
// GpioDataRegs.GPBDAT.bit.GPIOB5=1; // as high //PWM12/io7引脚为高
asm(" setc xf");
for(k=0;k<low;k++);
}
}
|