Está en la página 1de 3

Archivo: /home/ccova/Escritorio/PID Discreto/pid.

c
//EJEMPLO 16. CONTROL DIGITAL. //Guia del Compilador C. PIC16C74A. 4 de marzo del 2001. //Realizar //Solucion: //Se utilizara el algoritmo de control PID tipo posicion que maneja el libro //"Sistemas de Control en Tiempo Discreto", de K. Ogata (capitulo 3, Funcion //de transferencia de pulsos de un controlador PID digital, en forma de posicion). //Funcion de transferencia de pulsos, forma de posicion: //Gd(z) = Kp + Ki/(1-z-1) + Kd(1-z-1) //donde: // Kp = K - KT/2Ti = Ganancia proporcional (controlador digital). // Ki = KT/Ti = Ganancia integral. // Kd = KTd/T = Ganancia derivativa. // Ti = Tiempo integral (o tiempo de restablecimiento, segundos). // Td = Tiempo derivativo (o tasa de tiempo, segundos). // K = Ganancia proporcional (controlador analogico). // T = Periodo de muestreo (segundos). //Los parametros anteriores, junto con otras seales, seran capturados //utilizando los canales de entrada analogica de los puertos A y E en el //siguiente orden: //Ti //Td //K //SP //RETRO //T Canal Canal Canal Canal Canal Canal A/D A/D A/D A/D A/D A/D 0 1 2 3 4 5 (Tiempo integral, segundos, PA0). (Tiempo derivativo, segundos, PA1). (Constante proporcional, segundos, PA2). (Set Point, PA3). (Retroalimentacion, PA5). (Periodo de muestreo, segundos, PE0). un controlador PID digital.

Pgina 1 de 3

//Para la salida de control del PID, se utilizara la operacion PWM del modulo CCP1 //(pin PC2). Esta salida nos indica la magnitud en 8 bits de la accion de control. //El signo de la accion de control se muestra en el pin PC0 (0 positivo, 1 negativo). //Directivas. #include <16C74.H> //Especificando dispositivo a utilizar y constantes generales (pag. 47). //Fusibles de configuracion de hardware (pag. 31). //Base de tiempo para retardos (pag. 17).

#fuses XT,NOWDT,NOPROTECT,PUT #use delay(clock = 4000000) #use fast_io(C) #byte portc = 0x07 #bit PC0 = 0x07.0 #bit PC2 = 0x07.2 //Variables globales:

//Directiva para el manejo normal de puertos (pag. 13). //Declarando la direccion del puerto C. //Apuntando como una constante al bit de un puerto (pag. 30).

int Ti, Td, K, SP, RETRO, T; //Variables de 8 bits sin signo. float m0,m1,e0,e1,e2; //Variables en punto flotante de 32 bits (pag. 7). int magnitud; //Variable de 8 bits sin signo. Magnitud accion de control. short signo; //Variable tipo bit. Signo accion de control. //Funcion de inicializacion. inicializar() {

Archivo: /home/ccova/Escritorio/PID Discreto/pid.c

Pgina 2 de 3

//Inicializando la operacion analogica del puerto A. setup_port_a(ALL_ANALOG); //Especificando operacion analogica de puertos A y E, Vref = Vdd. (pag. 13). set_tris_a(0b00111111); //Configurando puerto A como entrada (pag. 13). set_tris_e(0b00000111); //Configurando puerto E como entrada (pag. 13). setup_adc(ADC_CLOCK_INTERNAL); //Habilitando el convertidor A/D con reloj interno (pag. 16). //Inicializando el modo PWM del modulo CCP1. portc = 0; //Valor inicial del puerto C. set_tris_c(0b11111010); //Configurando PC0 y PC2 como salidas (pag. 13). setup_ccp1(CCP_PWM); //Configurando el modulo CCP1 en modo PWM (pag. 15). setup_timer_2(T2_DIV_BY_4, 167, 0); //Definiendo el periodo del PWM con la configuracion //del temporizador 2 (para es te caso periodo //pwm = (167)(4)/(4000000/4) = 668 us (pag. 15). //Ver tambien ejemplo 14. set_pwm1_duty(0); //Valor inicial salida PWM. m1 = 0; e1 = 0; e2 = 0; } //Valor inicial parametros PID. //Fin inicializar.

//Funcion de adquisicion de datos. adquisicion_datos() { set_adc_channel(0); delay_cycles(3); Ti = read_adc(); set_adc_channel(1); delay_cycles(3); Td = read_adc(); set_adc_channel(2); delay_cycles(3); K = read_adc(); set_adc_channel(3); delay_cycles(3); SP = read_adc(); set_adc_channel(4); delay_cycles(3); RETRO = read_adc(); set_adc_channel(5); delay_cycles(3); T = read_adc(); } //Adquisicion canal 0, Ti.

//Adquisicion canal 1, Td.

//Adquisicion canal 2, K.

//Adquisicion canal 3, SP.

//Adquisicion canal 4, RETRO.

//Adquisicion canal 5, T, en segundos.

//Fin adquisicion.

//Funcion del controlador PID digital de posicion (algoritmo del libro de Control Discreto de K. Ogata). control_PID() { float Ts, Kp, Ki, Kd, salida_PID; //Variables locales en punto flotante de 32 bits. Ts = T/1000; //Convirtiendo el periodo T de segundos a milisegundos. Kp = K - (K*Ts/2*Ti); //Calculo de los parametros Kp, Ki y Kd segun algoritmo. Ki = K*Ts/Ti; Kd = K*Td/Ts; m0 = m1+(Kp+Ki+Kd)*e0-(Kp+2*Kd)*e1+Kd*e2;//Calculo de la accion de control m(kT). if( m0<0 ) { //Detectando el signo de la accion de control.

Archivo: /home/ccova/Escritorio/PID Discreto/pid.c


signo = 1; //m0 negativo, signo = 1, m0 positivo, signo = 0. salida_PID = -m0; //Calculando valor absoluto de m0. } else { signo = 0; salida_PID = m0; }

Pgina 3 de 3

if(salida_PID>255) salida_PID = 255; //Limitando la magnitud de la accion de control a 255. magnitud = (int)salida_PID; //Cambiando de tipo de dato float a //8 bits sin signo. e2 = e1; //Actualizando e(k-2). e1 = e0; //Actualizando e(k-1). if(signo == 1) m1 = -salida_PID; //Actualizando m(k-1). else m1 = salida_PID; } //fin control PID.

//Funcion principal. main() { inicializar(); while(TRUE) { //Inicio programa principal. //Llamada a funcion inicializar. //Inicio ciclo continuo. //Llamada a funcion de adquisicion de datos.

adquisicion_datos(); e0 = SP - RETRO; control_PID();

//Calculo del error actual. //Llamada al controlador PID.

set_pwm1_duty(magnitud);//Actuacion del PWM en funcion de la magnitud //de la accion de control calculada. PC0 = signo; //Salida del signo de la accion de control. delay_ms(T); } } //Retardo segun periodo de muestreo. //Fin while. //Fin main.

También podría gustarte