0% found this document useful (0 votes)
35 views

PR Controller

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views

PR Controller

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

// TI File $Revision: /main/1 $

// Checkin $Date: May 27, 2009 13:16:04 $


//###########################################################################
//
// FILE: Example_2823xLedBlink.c
//
// TITLE: DSP2823x eZdsp LED Blink Getting Started Program.
//
// ASSUMPTIONS:
//
// This program requires the DSP2823x header files.
//
//
// As supplied, this project is configured for "boot to SARAM"
// operation. The 2823x Boot Mode table is shown below.
// For information on configuring the boot mode of an eZdsp,
// please refer to the documentation included with the eZdsp,
//
// $Boot_Table:
//
// GPIO87 GPIO86 GPIO85 GPIO84
// XA15 XA14 XA13 XA12
// PU PU PU PU
// ==========================================
// 1 1 1 1 Jump to Flash
// 1 1 1 0 SCI-A boot
// 1 1 0 1 SPI-A boot
// 1 1 0 0 I2C-A boot
// 1 0 1 1 eCAN-A boot
// 1 0 1 0 McBSP-A boot
// 1 0 0 1 Jump to XINTF x16
// 1 0 0 0 Jump to XINTF x32
// 0 1 1 1 Jump to OTP
// 0 1 1 0 Parallel GPIO I/O boot
// 0 1 0 1 Parallel XINTF boot
// 0 1 0 0 Jump to SARAM <- "boot to
SARAM"
// 0 0 1 1 Branch to check boot mode
// 0 0 1 0 Boot to flash, bypass ADC cal
// 0 0 0 1 Boot to SARAM, bypass ADC cal
// 0 0 0 0 Boot to SCI-A, bypass ADC cal
// Boot_Table_End$
//
// DESCRIPTION:
//
// This example configures CPU Timer0 for a 500 msec period, and toggles the
GPIO32
// LED on the 2823x eZdsp once per interrupt. For testing purposes, this example
// also increments a counter each time the timer asserts an interrupt.
//
// Watch Variables:
// CpuTimer0.InterruptCount
//
// Monitor the GPIO32 LED blink on (for 500 msec) and off (for 500 msec) on
the 2823x eZdsp.
//
//###########################################################################
// $TI Release: 2833x/2823x Header Files V1.32 $
// $Release Date: June 28, 2010 $
//###########################################################################

#include "DSP28x_Project.h"
#include "math.h"
// Device Headerfile and Examples Include File
#if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0
MHz
#endif
#if (CPU_FRQ_100MHZ)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0
MHz
#endif
#define ADC_CKPS 0x0 // ADC module clock = HSPCLK/1 = 25.5MHz/(1) = 25.0
MHz
#define ADC_SHCLK 0x1 // S/H width in ADC module periods = 2
ADC cycle
int a=4;
int b;
float ir = 0.0;
float del_ts = 0.00001492,Ws= 314.16,Wc=50.;
float ir_diffi, ir_diffi_pre=0., ir_diffi_pre1=0.;
float
Kp=.3,Ki=600.,Kr=50.,pr_r,Ir_r,prlimit1=.7,Ir_r_limit=3,iout_error_resonance_limit=
3,iout_error_resonance1_limit=1,iout_error_resonance2_limit=1,Error_r;
float iout_error_resonance=0., iout_error_resonance_pre=0.,
iout_error_resonance_pre1=0.,iout_error_resonance1=0.,
iout_error_resonance1_pre=0.,
iout_error_resonance1_pre1=0.,iout_error_resonance2=0.,
iout_error_resonance2_pre=0., iout_error_resonance2_pre1=0.;
float
a10,b01,b10,a1,a2,b0,b1,b2,c10,x=0.,a101,b011,b101,a11,a21,b00,b11,b21,c101,y=0.,a1
02,b012,b102,a12,a22,b000,b12,b22,c102,z=0.;
// Prototype statements for functions found within this file.
__interrupt void adca1_isr(void);
void main(void)
{

// Step 1. Initialize System Control:


// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
InitSysCtrl();
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // The system peripheral clock is divided
by 6 and the general ADC is divided by 6

// This is because the ADC can only be configured with a frequency of 25MHz.

// So the fastest conversion time is 80ns


EDIS;

// Step 2. Initalize GPIO:


// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example

// Step 3. Clear all interrupts and initialize PIE vector table:


// Disable CPU interrupts
DINT;

// Initialize the 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 DSP2833x_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 DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();
InitAdc();
EALLOW;

PieVectTable.TINT0 = &adca1_isr; // Assign ADC ISR into pie vector table


PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable that interrupt
IER = 0x0001;
IER |= M_INT1;
EDIS; EINT; ERTM;

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; // Sequential mode: Sample rate =


1/[(2+ACQ_PS)*ADC clock in ns]
// = 1/(3*40ns) =8.3MHz (for 150
MHz SYSCLKOUT)
// = 1/(3*80ns) =4.17MHz (for 100
MHz SYSCLKOUT)
// If Simultaneous mode enabled: Sample rate =
1/[(3+ACQ_PS)*ADC clock in ns]
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Setup continuous run

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 1; // convert and store in 8 results


registers

AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0x1;
// Interrupts that are used in this example are re-mapped to

// Step 4. Initialize the Device Peripheral. This function can be


// found in DSP2833x_CpuTimers.c
InitCpuTimers(); // For this example, only initialize the Cpu Timers
#if (CPU_FRQ_150MHZ)
// Configure CPU-Timer 0 to interrupt every 500 milliseconds:
// 150MHz CPU Freq, 50 millisecond Period (in uSeconds)
ConfigCpuTimer(&CpuTimer0, 150, 500000);
#endif
#if (CPU_FRQ_100MHZ)
// Configure CPU-Timer 0 to interrupt every 500 milliseconds:
// 100MHz CPU Freq, 50 millisecond Period (in uSeconds)
ConfigCpuTimer(&CpuTimer0, 100, 500000);
#endif

// To ensure precise timing, use write-only instructions to write to the entire


register. Therefore, if any
// of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in
DSP2833x_CpuTimers.h), the
// below settings must also be updated.

CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

// Step 5. User specific code, enable interrupts:

// Configure GPIO32 as a GPIO output pin


EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;
EDIS;

// Enable CPU INT1 which is connected to CPU-Timer 0:


//IER |= M_INT1;

// Enable TINT0 in the PIE: Group 1 interrupt 7


PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

// Enable global Interrupts and higher priority real-time debug events:


EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

// Step 6. IDLE loop. Just sit and loop forever (optional):


GpioDataRegs.GPBDAT.bit.GPIO32 =0;
while(1)
{
a=a+1;
if(a>=100)
{ a=0; }
}
}

__interrupt void adca1_isr(void)


{

//GpioDataRegs.GPCDAT.bit.GPIO76 =1;
// PI Controller
pr_r=ir_diffi*Kp;
if(pr_r>prlimit1)pr_r=prlimit1;
if(pr_r<-prlimit1)pr_r=-prlimit1;

Ir_r = Ir_r+Ki*ir_diffi*del_ts;

if (Ir_r>= Ir_r_limit) Ir_r=Ir_r_limit;


if (Ir_r<=-Ir_r_limit) Ir_r=-Ir_r_limit;

// 3rd harmonic resonance controller


x=sin(3*Ws*del_ts)*(Wc/2);
a10= x/Wc;
b10=2*3*Ws*cos(3*Ws*del_ts);
c10=(3*Ws-x);
b01=(3*Ws+x);
a1=b10/b01;
a2=c10/b01;
b0=Kp+Kr*(a10/b01);
b1=b10/b01;
b2=Kp*(c10/b01)-Kr*(a10/b01);

iout_error_resonance=b0*ir_diffi+b1*ir_diffi_pre+b2*ir_diffi_pre1+a1*iout_error_res
onance_pre-a2*iout_error_resonance_pre1;
iout_error_resonance_pre1= iout_error_resonance_pre;
iout_error_resonance_pre= iout_error_resonance;
ir_diffi_pre1= ir_diffi_pre;
ir_diffi_pre= ir_diffi;

if (iout_error_resonance>= iout_error_resonance_limit)
iout_error_resonance= iout_error_resonance_limit;
if (iout_error_resonance<=-iout_error_resonance_limit)
iout_error_resonance=-iout_error_resonance_limit;

// 5th harmonic resonance controller


y=sin(5*Ws*del_ts)*(Wc/2);
a101= y/Wc;
b101=2*5*Ws*cos(5*Ws*del_ts);
c101=(5*Ws-y);
b011=(5*Ws+y);
a11=b101/b011;
a21=c101/b011;
b00=Kp+Kr*(a101/b011);
b11=b101/b011;
b21=Kp*(c101/b011)-Kr*(a101/b011);

iout_error_resonance1=b0*ir_diffi+b1*ir_diffi_pre+b2*ir_diffi_pre1+a1*iout_error_re
sonance1_pre-a2*iout_error_resonance1_pre1;

iout_error_resonance1_pre1= iout_error_resonance1_pre;
iout_error_resonance1_pre= iout_error_resonance1;
ir_diffi_pre1= ir_diffi_pre;
ir_diffi_pre= ir_diffi;

if (iout_error_resonance1>=
iout_error_resonance1_limit) iout_error_resonance1= iout_error_resonance1_limit;
if (iout_error_resonance1<=-iout_error_resonance1_limit)
iout_error_resonance1=-iout_error_resonance1_limit;

// 7th harmonic resonance controller


z=sin(7*Ws*del_ts)*(Wc/2);
a102= z/Wc;
b102=2*7*Ws*cos(7*Ws*del_ts);
c102=(7*Ws-z);
b012=(7*Ws+z);
a12=b102/b012;
a22=c102/b012;
b000=Kp+Kr*(a102/b012);
b12=b102/b012;
b22=Kp*(c102/b012)-Kr*(a102/b012);

iout_error_resonance2=b0*ir_diffi+b1*ir_diffi_pre+b2*ir_diffi_pre1+a1*iout_error_re
sonance2_pre-a2*iout_error_resonance2_pre1;

iout_error_resonance2_pre1=
iout_error_resonance2_pre;
iout_error_resonance2_pre=
iout_error_resonance2;
ir_diffi_pre1= ir_diffi_pre;
ir_diffi_pre= ir_diffi;

if (iout_error_resonance2>=
iout_error_resonance2_limit) iout_error_resonance2= iout_error_resonance2_limit;
if (iout_error_resonance2<=-
iout_error_resonance2_limit) iout_error_resonance2=-iout_error_resonance2_limit;

Error_r= pr_r+Ir_r+iout_error_resonance+
iout_error_resonance1+iout_error_resonance2 ;

ir=(AdcRegs.ADCRESULT1>>4);

b=b+1;
if(b>100)
b=0;
// Import and offset. 2080 was for 20khz board. 2067 for 10 kHz board.

//Scale to real world volts?


AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge
interrupt to PIE

return;
}
//===========================================================================
// No more.
//==========================================================================

You might also like