// 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; frecuencia de la red // in[1]= Vref; tension de referencia sin normalizar // in[2]= fs; frecuencia de conmutación: La frecuencia de muestreo es fm=fs // in[3]= Vcc; tension de la barra CC // in[4]= vo; tension de salida en bornes del capacitor del filtro LC // in[5]= iL; corriente del inductor del filtro LC // in[6]= t_rampa; tiempo final de la rampa de variación de la referencia #include "dll.h" #include // Coeficientes del controlador PD: #define Kc 8.992633333333334 //Kc #define zPDKc -8.333333333333334 //zPD x Kc // ** Configurar el registro de periodo del contador para el periodo de muestreo elegido // TPER: Para timer de 16 bits, puede ser cualquier valor entero de 1 a 65535. // PRESC: Puede ser 1, 2, 4, 16, 32. // Periodo de muestreo: Tm = TPER*PRESC*Tosc // Ejemplo: fs=100 Hz; Tm = 0.01024seg, Fosc = 500kHz y PRESC = 32 => TPER = Tm*Fosc/PRESC = 160 // Para el presente caso: Tm=0.012 s; Fosc = 1 MHz; PRESC = 4 => TPER = Tm*Fosc/PRESC = 3000 #define TPER 3000 // Define el periodo del Timer del PWM (12ms). #define PRESC 4 // Define el prescaler del Timer1. void __declspec(dllexport) simuser (double t, double delt, double *in, double *out) { static double y=0; // Variable controlada static double uk=0, uc=0; static double ek=0, ekm1=0; static double ref; static double Tm; // Periodo de muestreo static double Fclock, Tclock; // Variables p/calculo de la relación Ncont. static double muestra=0; // Variables enteras static int contador=0, Ncont, calculo_u, muestreo = 1, direccion = 1; static int PWM1, PWM2; static int ComparReg1, ComparReg2; // Se calcula el número de conteos en un periodo: Valor máximo del contador //---------------------------------------------------------------------------------- // CÁLCULOS INICIALES //---------------------------------------------------------------------------------- Fclock = in[2]; // Adquiere frecuencia del oscilador Tm = (TPER*PRESC)/Fclock; //Tm = 0.0120000000; Ncont=Tm/delt; // Número de conteos del timer muestra=0; if(muestreo == 1) { muestreo=0; // Se realiza el muestreo de las variables controladas y = in[1]; calculo_u=1; // Llama a rutina de cálculo de la acción de control } if (calculo_u==1) { calculo_u=0; ref = in[0]; // Toma la referencia impuesta en PSIM /*********************************************************************************/ /* Se calcula el error entre la salida de la planta y la referencia */ /*********************************************************************************/ ek = ref - y; /*********************************************************************************/ /* Calculo del controlador */ /*********************************************************************************/ // Controlador PD para regular la posición angular del eje de un motor CC // upd(km) = Kc*e(km) - zPD*Kc*e(km-1); uk = Kc*ek + zPDKc*ekm1; // Se calcula acción de control ekm1 = ek; // Se actualiza el error una muestra atrasada. //Para lazo abierto //uk = ref; } //termina el cálculo de la estrategia de control //**********************************************************// // Incrementamos o decrementamos el contador segun corresponda // Aqui se implementa un contador up-down contador = contador + direccion; if (contador == 0) { direccion=1; muestreo=1; muestra=1; //out[0] = uk; } if (contador == Ncont/2) { direccion=-1; muestreo=0; muestra=0; } // Se actualizan los valores de las salidas out[0] = uk; out[1] = ref; out[2] = y; out[3] = ek; out[4] = contador; out[5] = muestra*3000; } BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { switch(fdwReason) { case DLL_PROCESS_ATTACH: { break; } case DLL_PROCESS_DETACH: { break; } case DLL_THREAD_ATTACH: { break; } case DLL_THREAD_DETACH: { break; } } /* Return TRUE on success, FALSE on failure */ return TRUE; }