• Nenhum resultado encontrado

Esse apêndice contém o programa em linguagem C implementado no Code Composer 3.3. Este programa foi utilizado no controle de corrente e de posição do motor-mancal de indução de rotor externo. Sendo parte integrante do projeto.

////############################################################# ##############

//Controle de Posicionamento - Motor Mancal

//############################################################## //

#include "DSP28x_Project.h" #include <math.h>

// Prototipo das fun‡äes

void InitECapture(void); void InitEPwm1(void); void InitEPwm2(void); void InitEPwm3(void); void ConfigCAD(void); void ConfigGPIO(void);

88

void init_zone7(void); void InitXintf16Gpio(void);

// Rotina de controle, executa a 100us - Interrup interrupt void adc_isr(void);

// Para coletar dados para a Tese

#pragma DATA_SECTION(Buffer1,"ZONE7DATA"); #pragma DATA_SECTION(Buffer2,"ZONE7DATA"); #pragma DATA_SECTION(Buffer3,"ZONE7DATA"); #pragma DATA_SECTION(Buffer4,"ZONE7DATA"); #pragma DATA_SECTION(Buffer5,"ZONE7DATA"); #pragma DATA_SECTION(Buffer6,"ZONE7DATA");

float barramento= 30.0, ativa_posicao = 0;

float ang = 0, is1 = 0, is2 = 0, is3 = 0, cosp = 0, senp =0, freq = 60.0;

float temp[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, temp1[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},

temp2[7] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, mPosXf = 0.0,

mPosYf = 0.0;

Uint16 fim_flag_matlab = 0, janelaplot = 0;

//******************************************************

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

89

//Para a coleta para a Tese float Buffer1[10500], Buffer2[10500], Buffer3[10500], Buffer4[10500], Buffer5[10500], Buffer6[10500];

//(2).Variaveis para ADC

signed int sinal1 = 0,

sinal2 = 0, sinal3 = 0, sinal4 = 0, sinal5 = 0, sinal6 = 0, sinalx = 0, sinaly = 0; float corrente1=0.0, corrente2=0.0, corrente3=0.0, corrente4=0.0, corrente5=0.0, corrente6=0.0; float corrente1f=0.0, corrente2f=0.0,

90 corrente3f=0.0, corrente4f=0.0, corrente5f=0.0, corrente6f=0.0; float PosX=0.0, PosY=0.0, PosXf=0.0, PosYf=0.0; float velo_X = 0, velo_Y = 0, erroX = 0, erroY = 0, erroX_ant = 0, erroY_ant = 0, propx = 0, derivx = 0, integx = 0, derivx_ant = 0, integx_ant = 0, derivy_ant = 0, integy_ant = 0, propy = 0, derivy = 0, integy = 0, iX = 0, iY = 0, iX_ant = 0,

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO 91 iY_ant = 0, ganho_limY = 1.5, ganho_limX = 1.5; float Ux = 0.0, Uy = 0.0, px = 0.0, py = 0.0; Uint16 intp = 0;

//(3).Variaveis - Controle de Corrente

float kpi = 8.0, //Ganho do Controlador Proporcional de Corrente kii = 0.06;// 1.464844e-6; //Ganho do Controlador Integrativo de Corrente

float kpi2 = 6.0, //Ganho do Controlador Proporcional de Corrente kii2 = 0.04;// 1.464844e-6; //Ganho do Controlador Integrativo de Corrente

float kpi3 = 3.8, //Ganho do Controlador Proporcional de Corrente kii3 = 0.085;// 1.464844e-6; //Ganho do Controlador Integrativo de Corrente float ref1 = 0.0, ref2 = 0.0, ref3 = 0.0, ref4 = 0.0, ref5 = 0.0,

92

ref6 = 0.0;

//(4). Parƒmetros refente a coleta - Matlab

Uint16 indexb = 0, flag_matlab = 0,

tam_index = 10500; //Para coleta do treino da rna //tam_index = 21800; //Para a coleta de resultados da tese

float tempo = 0.0, tf = 50; float ReferX = 1923.0, ReferY = 1687.0, ux = 0.0, uy = 0.0, x_al = 0, y_be = 0, ua = 0.0, ub = 0.0, uc = 0.0; float Kpx = 0.0005, //0.00015, Kdx = 0.00058, //0.058, Kix = 1e-08, Kpy = 0.000125, //0.00025, Kdy = 0.0023, //0.05,

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO 93 Kiy = 1e-08, limX = 1.0; float cosp1 = 0.0, senp1 = 0.0; // ****************************************************************** // *********** Defini‡Æo das estruturas dos Parametros do PID ******* // ******************************************************************

typedef struct {

float Ref; // Entrada referente ao set-point float Fbk; // Entrada referente ao feedback float Out; // Saida do controlador

} PID_TERMINALS;

typedef struct {

float Kp; // Parametro: proportional loop gain float Ki; // Parametro: integral gain

float Km; // Parametro: derivative weighting float Umax; // Parametro: upper saturation limit float Umin; // Parametro: lower saturation limit } PID_PARAMETERS;

typedef struct {

float up; // Data: proportional term

float ui; // Data: integral term

float v1; // Data: pre-saturated controller output float i1; // Data: integrator storage: ui(k-1)

94

float w1; // Data: saturation record: [u(k-1) - v(k- 1)] } PID_DATA; typedef struct { PID_TERMINALS term; PID_PARAMETERS param; PID_DATA data; } PID_CONTROLLER;

//Prot¢tico para inicializar parametros do Controlador void PID_init(PID_CONTROLLER *v);

void PID_FUNC(PID_CONTROLLER *v);

// Instƒncia dos Controladores PID_CONTROLLER PI_Corrente1; PID_CONTROLLER PI_Corrente2; PID_CONTROLLER PI_Corrente3; PID_CONTROLLER PI_Corrente4; PID_CONTROLLER PI_Corrente5; PID_CONTROLLER PI_Corrente6; void main(void) {

// Step 1. Initialize System Control:

// PLL, WatchDog, enable Peripheral Clocks

InitSysCtrl();

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

95

// Step 2. Initalize GPIO:

// Init GPIO pins for ePWM1A,ePWM1B ePWM2A, ePWM2B, ePWM3A e ePWM3B e Ecap1

InitEPwmGpio(); InitECap1Gpio();

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

DINT;

// Initialize the PIE control registers to their default state. 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();

// Interrupts are re-mapped to ISR functions found within this file. EALLOW;

96

EDIS;

// Step 4. Initialize A/D Peripheral: InitECapture();

InitAdc();

// Stop PWM counter timer ( TBCLKSYNC - Sincroniza os clocks e Parando todos os m¢duloas PWM)

EALLOW;

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // - reseta TBCLKSYNC EDIS;

InitEPwm1(); InitEPwm2(); InitEPwm3();

// Start PWM counter timer. All PWM Channels are syncronized EALLOW;

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS;

// Step 5. User specific code, enable interrupts: IER |= M_INT1; //interrupcao do Timer0 & ADC

// Enable ADCINT in PIE

PieCtrlRegs.PIEIER1.bit.INTx6 = 1; //Utilizar a interrupcao do ADC

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

97

EINT; // Enable Global interrupt INTM

ERTM; // Enable Global realtime interrupt DBGM

// Step 6. IDLE loop.

ConfigGPIO(); // Configura os pinos IO init_zone7(); // Memoria externa

//Fun‡Æo que configura o ADC para realizar a conversÆo via interrup‡Æo do PWM ConfigCAD(); // Inicializa os Controladores PID_init(&PI_Corrente1); PID_init(&PI_Corrente2); PID_init(&PI_Corrente3); PID_init(&PI_Corrente4); PID_init(&PI_Corrente5); PID_init(&PI_Corrente6); for(;;) { } } /////////////////////////////////////////////////////////////////////// ////////////////////////Rotina Principal////////////////////////////// ///////////////////////////////////////////////////////////////////////

98

interrupt void adc_isr(void) {

GpioDataRegs.GPASET.bit.GPIO13 = 1;

//////////////////////////////////////////////////////////////////////////////////////

// Gera‡Æo do ƒngulo para as correntes de referˆncia a partir do sensor de velocidade

/////////////////////////////////////////////////////////////////////////////////////

ang=ang + 6.2832e-004 * freq;

if (ang > 6.28318530717) ang = ang - 6.28318530717; if (ang < -6.28318530717) ang = 6.28318530717 + ang;

is1 = (Imax) * sin(ang); is2 = (Imax) * sin(ang - 2.0944 ); is3 = (Imax) * sin(ang + 2.0944 );

cosp = cos(ang); senp = sin(ang);

///////////////////////////////////////////////////////////////////////

// Leitura de Posi‡Æo - Eixos X e Y

///////////////////////////////////////////////////////////////////////

//Filtro Digital

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

99

PosY = (float)(AdcRegs.ADCRESULT7 >>4);

PosXf = (PosXf * 0.9500) + (PosX * 0.0500); PosYf = (PosYf * 0.9500) + (PosY * 0.0500);

temp1[0] = temp1[1]; temp1[1] = temp1[2]; temp1[2] = temp1[3]; temp1[3] = temp1[4]; temp1[4] = temp1[5]; temp1[5] = temp1[6]; temp1[6] = PosXf; temp2[0] = temp2[1]; temp2[1] = temp2[2]; temp2[2] = temp2[3]; temp2[3] = temp2[4]; temp2[4] = temp2[5]; temp2[5] = temp2[6]; temp2[6] = PosYf;

mPosXf = temp1[6] + 0.1428571 * (temp1[5] - temp1[0]); mPosYf = temp2[6] + 0.1428571 * (temp2[5] - temp2[0]);

erroX = -(ReferX - PosXf); erroY = +(ReferY - PosYf);

100

diferro_X = velo_X;

velo_Y = (erroY - erroY_ant); // - "velocidade" na dire‡Æo Y diferro_Y = velo_Y;

erroX_ant = erroX; erroY_ant = erroY;

// Controle de posi‡Æo radial

// Controle X X X X X X X X X X X X X X X X X X X X X X X X X X // C lculo do controle PD propx = Kpx * erroX; derivx = Kdx * velo_X; iX += Kix * erroX; // Saturador integrativo

if (iX > ganho_limX) iX = ganho_limX; if (iX < -ganho_limX) iX = -ganho_limX; integx = iX;

// Lei de controle X

Ux = propx + derivx+ integx;

// Controle Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y // C lculo do controle PD

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

101

derivy = Kdy * velo_Y; iY += Kiy * erroY;

// Saturador integrativo

if (iY > ganho_limY) iY = ganho_limY; if (iY < -ganho_limY) iY = -ganho_limY; integy = iY;

// Lei de controle Y

Uy = propy + derivy + integy;

//---

// Limitadores

Ux = __fmax((__fmin( limX, Ux)), -limX); Uy = __fmax((__fmin( limX, Uy)), -limX);

x_al = Ux * senp - Uy * cosp ; y_be = -Ux * cosp - Uy * senp ;

if (ativa_posicao == 1) { ua = x_al; ub = y_be * 0.8660254 + x_al * 0.5; uc = ub - x_al; } else { ua = 0; ub = 0;

102

uc = 0; }

//---

ref1 = is1 + ua; ref2 = is1 - ua;

ref3 = is2 + ub; ref4 = is2 - ub;

ref5 = is3 + uc; ref6 = is3 - uc;

/*

ref1 = is1 + ua; ref2 = is1 - ua;

ref3 = 0;//is2 + ub; ref4 = 0;//is2 - ub;

ref5 = 0;//is3 + uc; ref6 = 0;//is3 - uc; */

/////////////////////////////////////////////////////////////////////// // Rotina para Ler as Correntes ///////////////////////////////////////////////////////////////////////

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO 103 sinal2 = (AdcRegs.ADCRESULT1 >>4) - 1966; sinal3 = (AdcRegs.ADCRESULT2 >>4) - 1978; sinal4 = (AdcRegs.ADCRESULT3 >>4) - 1977; sinal5 = (AdcRegs.ADCRESULT4 >>4) - 1992; sinal6 = (AdcRegs.ADCRESULT5 >>4) - 1995;

corrente1 = (float) -7.234 * (sinal1/2048.0);

corrente1f = corrente1f * 0.6858 + corrente1 * 0.3142 ; //500

corrente2 = (float) -6.9051 * (sinal2/2048.0);

corrente2f = corrente2f * 0.6858 + corrente2 * 0.3142;

corrente3 = (float) -7.5425 * (sinal3/2048.0);

corrente3f = corrente3f * 0.6858 + corrente3 * 0.3142;

corrente4 = (float) -7.3091 * (sinal4/2048.0);

corrente4f = corrente4f * 0.6858 + corrente4 * 0.3142;

corrente5 = (float) -7.4077 * (sinal5/2048.0);

corrente5f = corrente5f * 0.6858 + corrente5 * 0.3142;

corrente6 = (float) -7.6512 * (sinal6/2048.0);

104

///////////////////////////////////////////////////////////////////////

// Controle PI de Corrente

/////////////////////////////////////////////////////////////////////// // Mediu o barramento foi 22 VCA

// Umax = 22 /2 = 11 90% = 9.9 // Umin = -9.9 //Controlador 1 PI_Corrente1.param.Kp = kpi; PI_Corrente1.param.Ki = kii; PI_Corrente1.param.Umax = (barramento/2) * 0.9;// 73.1325; PI_Corrente1.param.Umin = -(barramento/2) * 0.9; PI_Corrente1.term.Ref = ref1;

PI_Corrente1.term.Fbk = corrente1f; //sinal 5

//Controlador 2 PI_Corrente2.param.Kp = kpi; PI_Corrente2.param.Ki = kii; PI_Corrente2.param.Umax = (barramento/2) * 0.9;//9.9; PI_Corrente2.param.Umin = -(barramento/2) * 0.9;//9.9; PI_Corrente2.term.Ref = ref2;

PI_Corrente2.term.Fbk = corrente2f; //sinal 6

//Controlador 3

PI_Corrente3.param.Kp = kpi2; PI_Corrente3.param.Ki = kii2;

PI_Corrente3.param.Umax = (barramento/2) * 0.9;//9.9; PI_Corrente3.param.Umin = -(barramento/2) * 0.9;//9.9;

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

105

PI_Corrente3.term.Ref = ref3;

PI_Corrente3.term.Fbk = corrente3f; //sinal 1

//Controlador 4 PI_Corrente4.param.Kp = kpi2; PI_Corrente4.param.Ki = kii2; PI_Corrente4.param.Umax = (barramento/2) * 0.9;//9.9; PI_Corrente4.param.Umin = -(barramento/2) * 0.9;//9.9; PI_Corrente4.term.Ref = ref4;

PI_Corrente4.term.Fbk = corrente4f; //sinal 2

//Controlador 5 PI_Corrente5.param.Kp = kpi3; PI_Corrente5.param.Ki = kii3; PI_Corrente5.param.Umax = (barramento/2) * 0.9;//9.9; PI_Corrente5.param.Umin = -(barramento/2) * 0.9;//9.9; PI_Corrente5.term.Ref = ref5;

PI_Corrente5.term.Fbk = corrente5f; //sinal 3

//Controlador 6

PI_Corrente6.param.Kp = kpi3; PI_Corrente6.param.Ki = kii3;

PI_Corrente6.param.Umax = (barramento/2) * 0.9;//9.9; PI_Corrente6.param.Umin = -(barramento/2) * 0.9;//9.9;

106

PI_Corrente6.term.Ref = ref6;

PI_Corrente6.term.Fbk = corrente6f; //sinal 4

PID_FUNC(&PI_Corrente1); //Ref1 PID_FUNC(&PI_Corrente2); //Ref2 PID_FUNC(&PI_Corrente3); //Ref3 PID_FUNC(&PI_Corrente4); //Ref4 PID_FUNC(&PI_Corrente5); //Ref5 PID_FUNC(&PI_Corrente6); //Ref6 ////////////////////////////////////////////////////////////////////// // Aplica o sinal de controle nos PWMs ///////////////////////////////////////////////////////////////////////

EPwm1Regs.CMPA.half.CMPA = ((PI_Corrente1.term.Out/ barramento) + (0.5)) * EPwm1Regs.TBPRD; EPwm1Regs.CMPB = ((PI_Corrente2.term.Out/barramento) + (0.5)) * EPwm1Regs.TBPRD; EPwm2Regs.CMPA.half.CMPA = ((PI_Corrente3.term.Out/barramento) + (0.5)) * EPwm2Regs.TBPRD; EPwm2Regs.CMPB = ((PI_Corrente4.term.Out/barramento) + (0.5)) * EPwm2Regs.TBPRD; EPwm3Regs.CMPA.half.CMPA = ((PI_Corrente5.term.Out/barramento) + (0.5)) * EPwm3Regs.TBPRD; EPwm3Regs.CMPB =((PI_Corrente6.term.Out/barramento) + (0.5)) * EPwm3Regs.TBPRD; if(flag_matlab) {

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO 107 if(indexb < tam_index) { if(janelaplot == 0) { Buffer1[indexb] = erroX;//ref1; Buffer2[indexb] = erroY;//corrente1f; Buffer3[indexb] = velo_X;//ref2; Buffer4[indexb] = velo_Y;//corrente2f; Buffer5[indexb] = Ux;//ref3; Buffer6[indexb] = Uy;//corrente3f; indexb++; }else { Buffer1[indexb] = ref4; Buffer2[indexb] = corrente4f; Buffer3[indexb] = ref5; Buffer4[indexb] = corrente5f; Buffer5[indexb] = ref6; Buffer6[indexb] = corrente6f; indexb++;

108 } }//(indexb < tam_index) else { flag_matlab = 0; indexb =0; } } /////////////////////////////////////////////////////////////////////// // Reinicializa a sequencia do Conversor ADC ///////////////////////////////////////////////////////////////////////

AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1

AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit GpioDataRegs.GPACLEAR.bit.GPIO13 = 1;

PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE

}

void InitEPwm1() {

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

109

// Setup TBCLK

EPwm1Regs.TBPRD = 7500; // Set timer period 801 TBCLKs EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0

EPwm1Regs.TBCTR = 0x0000; // Clear counter

// Set Compare values

EPwm1Regs.CMPA.half.CMPA = 0; // inicializa o registradore de compara‡Æo A com zero

EPwm1Regs.CMPB = 0; // inicializa o registradore de compara‡Æo B com zero

// Setup counter mode

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Contagem up/down

EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading

EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //Clock PWM = Clock Sistema - Clock ratio to SYSCLKOUT

EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

// Setup shadowing

EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Usa buffer duplo

EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Usa buffer duplo

EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero - CC_CTR_PRD

EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on Zero - CC_CTR_PRD

// Set actions

EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;

110

EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;

// Set SOCA trigger;

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group (Habilita Start do Conversor ADC)

EPwm1Regs.ETSEL.bit.SOCASEL = 2; // 2 (contador = periodo ) 4 (contador = cmpa); // Select SOC from CTR=PRD

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event }

void InitEPwm2() {

// Setup TBCLK

EPwm2Regs.TBPRD = 7500; // Set timer period 801 TBCLKs EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0

EPwm2Regs.TBCTR = 0x0000; // Clear counter

// Set Compare values

EPwm2Regs.CMPA.half.CMPA = 0; // inicializa o registradore de compara‡Æo A com zero

EPwm2Regs.CMPB = 0; // inicializa o registradore de compara‡Æo B com zero

// Setup counter mode

EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Contagem up/down

EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading

EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

111

// Setup shadowing

EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Usa buffer duplo

EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero

EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Load on Zero

EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on Zero - CC_CTR_PRD

// Set actions

EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;//AQ_CLEAR;// When TBCTR is incrementing and TBCTR=CMPA set EPWM1A low

EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;//AQ_SET; // When TBCTR is in decrementing and TBCTR=CMPA set EPWM1A high

EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;//AQ_CLEAR; // Set PWM3B on event B, up count

EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;//AQ_SET; // Clear PWM3B on event B, down count

}

void InitEPwm3(void) {

// Setup TBCLK

EPwm3Regs.TBPRD = 7500; // Set timer period 801 TBCLKs EPwm3Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0

EPwm3Regs.TBCTR = 0x0000; // Clear counter

112

// Set Compare values

EPwm3Regs.CMPA.half.CMPA = 0; // inicializa o registradore de compara‡Æo A com zero

EPwm3Regs.CMPB = 0; // inicializa o registradore de compara‡Æo B com zero

// Setup counter mode

EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Contagem up/down

EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading

EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT

EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;

// Setup shadowing

EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Usa buffer duplo

EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero - CC_CTR_PRD

EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Load on Zero

EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Load on Zero - CC_CTR_PRD

// Set actions

EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;//AQ_CLEAR;// When TBCTR is incrementing and TBCTR=CMPA set EPWM1A low

EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;//AQ_SET; // When TBCTR is in decrementing and TBCTR=CMPA set EPWM1A high

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

113

EPwm3Regs.AQCTLB.bit.CBU = AQ_SET;//AQ_CLEAR; // Set PWM3B on event B, up count

EPwm3Regs.AQCTLB.bit.CBD = AQ_CLEAR;//AQ_SET; // Clear PWM3B on event B, down count

}

void ConfigCAD(void) {

// 1. Define a janela de tempo

AdcRegs.ADCTRL1.bit.ACQ_PS = 10; //(Mudar p/ 15) // Defini um numero 0 - 15, sendo 0 para um ciclo

// de clock para definir a Janela de amostragem

//2. Numero de canais a ser convertido

// AdcRegs.ADCMAXCONV.all = 0x0007; //Caso for utilizar para ler 16 variaveis via ADC

AdcRegs.ADCMAXCONV.all = 0x0004; // Por que esta lendo via ADC 8 variaveis [0, 1 , 2 e 3]

AdcRegs.ADCTRL3.bit.SMODE_SEL = 1; //Simultaneous sampling mode, default =0 modo sequencial

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

//3. E Quais Canais selecionados a serem convertidos

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup conv from ADCINA0 &amp; ADCINB0

AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup conv from ADCINA1 AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // Setup conv from ADCINA2 AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // Setup conv from ADCINA3

//4. Quem vai start a conversÆo - PWM

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // Enable SOCA from ePWM to start SEQ1

114

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

//5. Conversor AD trabalhando a 75 Mhz AdcRegs.ADCTRL1.bit.CPS = 0;

AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; //Dividindo a freq/2

}

void ConfigGPIO(void) {

// Configura GPIO EALLOW;

// Configura os pinos GPIO28 e GPIO29 como SCI-A GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // SCITXDA GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // SCIRXDA

// Configura o pino GPIO13 como um sa¡da

GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; //Configura como o pino como digital

GpioCtrlRegs.GPADIR.bit.GPIO13 = 1; //Configura como entrada (bit 0) e saida (bit 1)

EDIS;

}

void InitECapture() {

ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

115

ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped

ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1; // One-shot ECap1Regs.ECCTL2.bit.STOP_WRAP = 0; // Stop at 1 events ECap1Regs.ECCTL1.bit.CAP1POL = 0; // borda de subida

ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // Difference operation ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter ECap1Regs.ECCTL2.bit.REARM = 1; // arm one-shot

ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads

ECap1Regs.ECEINT.bit.CEVT1 = 1; // 1 events = interrupt

}

void init_zone7(void) {

// Make sure the XINTF clock is enabled

SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;

// Configure the GPIO for XINTF with a 16-bit data bus // This function is in DSP2833x_Xintf.c

InitXintf16Gpio();

EALLOW;

// All Zones---

// Timing for all zones based on XTIMCLK = SYSCLKOUT XintfRegs.XINTCNF2.bit.XTIMCLK = 0;

116 // Buffer up to 3 writes XintfRegs.XINTCNF2.bit.WRBUFF = 3; // XCLKOUT is enabled XintfRegs.XINTCNF2.bit.CLKOFF = 0; // XCLKOUT = XTIMCLK XintfRegs.XINTCNF2.bit.CLKMODE = 0; // Zone 7---

// When using ready, ACTIVE must be 1 or greater // Lead must always be 1 or greater

// Zone write timing

XintfRegs.XTIMING7.bit.XWRLEAD = 1; XintfRegs.XTIMING7.bit.XWRACTIVE = 2; XintfRegs.XTIMING7.bit.XWRTRAIL = 1; // Zone read timing

XintfRegs.XTIMING7.bit.XRDLEAD = 1; XintfRegs.XTIMING7.bit.XRDACTIVE = 3; XintfRegs.XTIMING7.bit.XRDTRAIL = 0;

// don't double all Zone read/write lead/active/trail timing XintfRegs.XTIMING7.bit.X2TIMING = 0;

// Zone will not sample XREADY signal XintfRegs.XTIMING7.bit.USEREADY = 0; XintfRegs.XTIMING7.bit.READYMODE = 0;

// 1,1 = x16 data bus // 0,1 = x32 data bus

// other values are reserved

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO

117

EDIS;

//Force a pipeline flush to ensure that the write to //the last register configured occurs before returning. asm(" RPT #7 || NOP"); } void InitXintf16Gpio() { EALLOW; GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 3; // XD15 GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 3; // XD14 GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 3; // XD13 GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 3; // XD12 GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 3; // XD11 GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 3; // XD10 GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 3; // XD19 GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 3; // XD8 GpioCtrlRegs.GPCMUX1.bit.GPIO72 = 3; // XD7 GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 3; // XD6 GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 3; // XD5 GpioCtrlRegs.GPCMUX1.bit.GPIO75 = 3; // XD4 GpioCtrlRegs.GPCMUX1.bit.GPIO76 = 3; // XD3 GpioCtrlRegs.GPCMUX1.bit.GPIO77 = 3; // XD2 GpioCtrlRegs.GPCMUX1.bit.GPIO78 = 3; // XD1 GpioCtrlRegs.GPCMUX1.bit.GPIO79 = 3; // XD0 GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 3; // XA0/XWE1n GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 3; // XA1 GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3; // XA2

118 GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3; // XA3 GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 3; // XA4 GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 3; // XA5 GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 3; // XA6 GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 3; // XA7 GpioCtrlRegs.GPCMUX2.bit.GPIO80 = 3; // XA8 GpioCtrlRegs.GPCMUX2.bit.GPIO81 = 3; // XA9 GpioCtrlRegs.GPCMUX2.bit.GPIO82 = 3; // XA10 GpioCtrlRegs.GPCMUX2.bit.GPIO83 = 3; // XA11 GpioCtrlRegs.GPCMUX2.bit.GPIO84 = 3; // XA12 GpioCtrlRegs.GPCMUX2.bit.GPIO85 = 3; // XA13 GpioCtrlRegs.GPCMUX2.bit.GPIO86 = 3; // XA14 GpioCtrlRegs.GPCMUX2.bit.GPIO87 = 3; // XA15 GpioCtrlRegs.GPBMUX1.bit.GPIO39 = 3; // XA16 GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 3; // XA17 GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 3; // XA18 // GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 3; // XA19 GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 3; // XREADY GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 3; // XRNW GpioCtrlRegs.GPBMUX1.bit.GPIO38 = 3; // XWE0 // GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 3; // XZCS0 GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 3; // XZCS7 // GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 3; // XZCS6 EDIS; } //---

APÊNDICE A – PROGRAMA DO CONTROLE DE CORRENTE E DE POSIÇÃO 119 void PID_init(PID_CONTROLLER *v) { v->term.Ref=0; v->term.Fbk=0; v->term.Out=0; // v->term.c1=0; // v->term.c2=0; // v->param.Kr = (1.0); v->param.Kp = (1.0); v->param.Ki = (0.0); // v->param.Kd = (0.0); v->param.Km = (1.0); v->param.Umax = (1.0); v->param.Umin = (-1.0); v->data.up = (0.0); v->data.ui = (0.0); // v->data.ud = (0.0); v->data.v1 = (0.0); v->data.i1 = (0.0); // v->data.d1 = (0.0); // v->data.d2 = (0.0); v->data.w1 = (1.0); } void PID_FUNC(PID_CONTROLLER *v) { /* proportional term */

120

v->data.up = (v->term.Ref) - v->term.Fbk;

/* integral term */

v->data.ui = (v->param.Ki* (v->data.w1* (v->term.Ref - v->term.Fbk))) + v->data.i1;

v->data.i1 = v->data.ui;

/* derivative term */

// v->data.d2 = (v->param.Kd* (v->term.c1* ((v->term.Ref* v->param.Km) - v->term.Fbk))) - v->data.d2;

// v->data.ud = v->data.d2 + v->data.d1; // v->data.d1 = (v->data.ud* v->term.c2);

/* control output */

// v->data.v1 = (v->param.Kp* (v->data.up + v->data.ui + v->data.ud)); v->data.v1 = (v->param.Kp* (v->data.up + v->data.ui));

v->term.Out= __fmax((__fmin(v->param.Umax,v->data.v1)),v- >param.Umin);

v->data.w1 = (v->term.Out == v->data.v1) ? (1.0) : (0.0); }

//***************************************************************************************** ****************

APÊNDICE B – TRABALHOS PUBLICADOS EM CONGRESSOS E OU REVISTAS

121

APÊNDICE B

TRABALHOS PUBLICADOS EM

Documentos relacionados