// t: Time, passed from PSIM by value // delt: Time step, passed from PSIM by value // in: input array, passed from PSIM by reference // out: output array, sent back to PSIM (Note: the values of out[*] can // be modified in PSIM) // The maximum length of the input and output array "in" and "out" is 30. // Las entradas del sistema son // in[0]= fr; Entrada de referencia (Escalón o Rampa) // in[1]= Vref; Variable de salida de la planta a controlar // in[2]= fs; Frecuencia del oscilador del microprocesador #include "dll.h" #include // Coeficientes del controlador de adelanto. Periodo de muestreo T = 0.05 seg. #define a1 0.5289 #define a2 -0.4128 #define a3 0.6 #define PER1 12500 // Define el periodo del Timer1. #define PRESC1 2 // Define el prescaler del Timer1. // PER1: Para timer de 16 bits, puede ser cualquier valor entero de 1 a 65535. // PRESC1: Puede ser 1, 2, 4, 16, 32. // Periodo de muestreo: Ts = PER1*PRESC1*Tosc // // Ejemplo: fs=100 Hz; Ts = 0.01024seg, Fosc = 500kHz y PRESC1 = 32 => PER1 = Ts*Fosc/PRESC1 = 160. void __declspec(dllexport) simuser (double t, double delt, double *in, double *out) { static double y=0; // variable controlada static double uk=0, ukm1=0, uc=0; static double ek=0, ekm1=0; static double ref; static double Ts; /* Periodo de muestreo */ static double Fcpu, Tcpu; // Variables p/calculo de la relación Ncont. static double muestra=0; // Variables enteras static int contador=0, Ncont, calculo_u=1, muestreo=0, direccion = 1; static int PWM1, PWM2; static int ComparReg1, ComparReg2; // Se calcula el numero de conteos en un periodo: Valor máximo del contador //---------------------------------------------------------------------------------- // CÁLCULOS INICIALES //---------------------------------------------------------------------------------- Fcpu = in[2]; // Adquiere frecuencia del oscilador Tcpu = 1/Fcpu; // y calcula periodo de la CPU. Ts = (PER1*PRESC1)/Fcpu; // Calcula el periodo de muestreo Ncont=Ts/delt; muestra=0; if (calculo_u==1) { calculo_u=0; ref = in[0]; // Toma la referencia impuesta en el PSIM /*********************************************************************************/ /* Se calcula el error entre la salida de la planta y la referencia */ /*********************************************************************************/ ek = ref - y; /*********************************************************************************/ /* Calculo de la acción de control */ /*********************************************************************************/ // Se utiliza un controlador de adelanto de fase // u(k) = a1*e(k) + a2*e(k-1) + a3*u(k-1); uk = a1*ek + a2*ekm1 + a3*ukm1; // Calcula acc. de control // Se actualizan los valores anteriores de las variables de error y acción de control ekm1 = ek; ukm1 = uk; uc=(Ncont/4)*uk; } //termina el calculo de la estrategia de control //**********************************************************// // Incrementamos o decrementamos el contador segun corresponda contador = contador + direccion; if (contador == 0) { direccion=1; muestreo=1; muestra=1; } if (contador == Ncont/2) { direccion=-1; muestreo=0; muestra=0; } if (contador == Ncont/2) //((cont==0) || (cont==Ncont/2)) { ComparReg1= uc + Ncont/4; ComparReg2= -uc + Ncont/4; } // Maquina de estado que define el patron PWM if (ComparReg1 > contador) PWM1=1; else PWM1=0; if (ComparReg2 > contador) PWM2=1; else PWM2=0; if(muestreo==1) { muestreo=0; // Se realiza el muestreo de las variables controladas y = in[1]; calculo_u=1; } // Se actualizan los valores de las salidas out[0] = PWM1; //brazo 1 out[1] = PWM2; //brazo 2 out[2] = uk; out[3] = ref; out[4] = y; out[5] = ek; out[6] = contador; out[7] = muestra*500; }