// 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 con compensación del ZOH y un epsilon = 0.1 // Periodo de muestreo T = 0.05 seg. #define k1 0.48 #define k2 -0.2 #define k3 1.0578 #define k4 -0.9314 #define k5 0.08256 #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, ukm2=0, uc=0; static double ek=0, ekm1=0, ekm2=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; // 0.05/5us (delt es el paso de simulación en PSIM) 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 = k1*ukm2 + k2*ukm1 + k3*ek + k4*ekm1 + k5*ekm2; // Calcula acción de control con comp. ZOH // Se actualizan los valores anteriores de las variables de error y acción de control ekm2 = ekm1; ekm1 = ek; ukm2 = ukm1; ukm1 = uk; } //termina el calculo de la acción de control //**********************************************************// // Incrementamos o decrementamos el contador segun corresponda // para sincronizar el muestreo de la variable controlada contador = contador + direccion; if (contador == 0) { direccion=1; muestreo=1; muestra=1; } if (contador == Ncont/2) { direccion=-1; muestreo=0; muestra=0; } // El conversor AD interrumpe a la CPU para realizar el muestreo y conversión if(muestreo==1) { muestreo=0; // Se realiza el muestreo de la variable controlada y = in[1]; // Llama a rutina de cálculo de la acción de control calculo_u=1; } // Se actualizan los valores a las salidas out[0] = 0; out[1] = 0; out[2] = uk; out[3] = ref; out[4] = y; out[5] = ek; out[6] = contador; out[7] = muestra*2500; }