interpretacion_codigo_control digital

11
INTERPRETACION DEL CODIGO #include <16f690.h> #use delay (clock=8MHZ) Estas 2 primeras instrucciones describen el microcontrolador a utilizar (en este caso el 16f690, pero se puede elegir el que se desee utilizar) .luego la frecuencia del oscilador (cristal de cuarzo, oscilador interno que algunos pic disponen, circuito RC, cualquier fuente que genere los pulsos para sincronizar las operaciones internas) Unsigned int8 n_pls, r_pls, Kp,Ki; Unsigned long duty, r_value, k; Signed long uc, e_pls, Iold, Inew; Luego de las instrucciones anteriores proseguimos a declarar las variables que vamos a utilizar, en este caso son variables globales, es decir se pueden obtener sus valores en cualquier parte del programa, no están restringidas a un espacio (como por ejemplo una función).Lo más importante que hay que saber es que mediante la declaración de variables reservamos espacio en la memoria. SIGNIFICADO DE CADA VARIABLE: UNSIGNED INT8 n_pls, r_pls, Kp, Ki Unsigned int8 define una variable sin signo (Unsigned), generalmente se está hablando de valores positivos nunca negativos, el tamaño de esta variable es un entero de 8 bits (int8). n_pls Como se utiliza un encoder para poder sensar la velocidad de motor, es necesario conocer la cantidad de pulsos que genera el encoder en un tiempo determinado (tiempo de muestreo), esa cantidad de pulsos de almacenan en esta variable. n_pls significa o es un acrónimo de número(n) de pulsos (pls). r_pls La velocidad del motor se modifica mediante un potenciómetro (entrada de referencia).Este potenciómetro va conectado a uno de los conversores del pic (ADC), de esta manera asociamos un valor del potenciómetro con una determinada velocidad. Recordar que en el caso de los ADC del pic 16f690 tienen una resolución de 10 bits, esto quiere decir que puedo obtener 1024 valores. Por lo tanto podemos decir: 5 voltios (valor máximo) es igual 1024 0 voltios(valor mínimo) es igual a 0 De esta manera podemos asociar cualquier voltaje del potenciómetro con su respectivo valor digital.

Upload: santiago

Post on 18-Aug-2015

212 views

Category:

Documents


0 download

DESCRIPTION

descripción de programa destinado al control de velocidad de un motor dc

TRANSCRIPT

INTERPRETACION DEL CODIGO #include #use delay (clock=8MHZ) Estas 2 primeras instrucciones describen el microcontrolador a utilizar (en este caso el 16f690, pero se puede elegir el que se desee utilizar) .luego la frecuencia del oscilador (cristaldecuarzo,osciladorinternoquealgunospicdisponen,circuitoRC,cualquier fuente que genere los pulsos para sincronizar las operaciones internas) Unsigned int8 n_pls, r_pls, Kp,Ki; Unsigned long duty, r_value, k; Signed long uc, e_pls, Iold, Inew; Luego de las instrucciones anteriores proseguimos a declarar las variables que vamos a utilizar, en este caso son variables globales, es decir se pueden obtener sus valores en cualquier parte del programa, no estn restringidas a un espacio (como por ejemplo una funcin).Lo ms importante que hay que saber es que mediante la declaracin de variables reservamos espacio en la memoria. SIGNIFICADO DE CADA VARIABLE: UNSIGNED INT8n_pls, r_pls, Kp, Ki Unsignedint8defineunavariablesinsigno(Unsigned),generalmenteseest hablandodevalorespositivosnuncanegativos,eltamaodeestavariableesun entero de 8 bits (int8). n_pls Comoseutilizaunencoderparapodersensarlavelocidaddemotor,es necesario conocer la cantidad de pulsos que genera el encoder en un tiempo determinado (tiempo de muestreo), esa cantidad de pulsos de almacenanen esta variable. n_pls significa o es un acrnimo denmero(n) de pulsos (pls). r_pls Lavelocidaddelmotorsemodificamedianteunpotencimetro(entradade referencia).Este potencimetro va conectado a uno de los conversores del pic (ADC),deestamaneraasociamosunvalordelpotencimetroconuna determinadavelocidad.RecordarqueenelcasodelosADCdelpic16f690 tienenunaresolucinde10bits,estoquieredecirquepuedoobtener1024 valores. Por lo tanto podemos decir: 5 voltios (valor mximo)es igual 1024 0 voltios(valor mnimo) es igual a 0 De esta manera podemos asociar cualquier voltaje del potencimetro con su respectivo valor digital. r_pls significa o es un acrnimo de pulsos (pls) de referencia(r).Lo que trae la idea que mediante el potencimetro le comunico al pic cuantos pulsos quiero quecomiencearegistraroacontarelencoder,todoestosetraducea:que velocidad del motor deseo. KP,KI EstasvariablessonlosparmetrosdelcontroladorPI.Laconstante proporcional (KP) y la constante integral (KI). UNSIGNED LONG duty, r_value, k; Unsignedlongdefineunavariablesinsigno(Unsigned),generalmenteseest hablandodevalorespositivosnuncanegativos,eltamaodeestavariableesun entero de 16 bits (long), tambin pudo ser int16 (es lo mismo). Duty Esta variable hace referencia al ciclo de trabajo (duty cicle) de la seal PWM, necesariaparamodificarlavelocidaddelmotor(enrealidadelobjetivode todoelprogramaespodervariarautomticamenteestevalorsegn convenga). r_value Esta variable almacena o toma los valores del potencimetro despus de haber convertido el nivel de voltaje a un valor numrico (digital).Es decir y como ya haba mencionado antes: Sielvoltajeenelpotencimetroes5voltiossuequivalenteen digital seria 1024.Por lo tanto r_value sera igual a 1024. r_value=1024y as con los dems valores K La variable k solo se utiliza para poder contar y poder visualizar el nmero de interrupciones que se estn produciendo desde el momento en que comience afuncionartodoelprograma.Suvalornoesmuyimportanteparael funcionamiento detodoelprograma.Cmo dijees paradarme una idea de cuantasveceselpicsehadetenidoaleersuentradadereferenciayactuar conforme a ello (para esto son las interrupciones). SIGNED LONG uc, e_pls, Iold,Inew Signed long define una variable consigno (Signed), estamoshablando de valores positivos onegativos, el tamao de esta variable es un entero de 16 bits (long), tambin pudo ser int16 (es lo mismo). UC EstavariableeslaaccindecontroldelcontroladorPI,seutilizapara almacenar el resultadode la accin proporcional y la accin integral. Es el resultado total de todo el cdigo del programa (mejor dicho todo se basa en obtener este valor, por qu es quien modifica el ciclo de trabajo de la seal PWM) e_pls e_plssignificaoesunacrnimodepulsos(pls)deerror(e).Enestavariable almacenamos el error obtenido entre mi entrada de referencia (r_pls) y el valor obtenido en el encoder (n_pls). Iold,Inew Enestasdosvariablesalmacenamoselvalordelaaccinintegral.Lanueva accin integral (Inew) y la antigua o anterior accin integral (Iold).Las dos estn relacionadas, ya que el nuevo valor de la accin integral se logra calcular con el valor anterior de la accin integral. #int_TIMER1 VoidTIMER1_isr (void){ INSTRUCCIONES A EJECUTAR } La directiva#int_Timer1 esla funcin de interrupcin, es decir elespacio del programa en donde yo, voy a describir (programar) que es lo que va hacer el microcontrolador cada cierto tiempo (tiempo de muestreo).Mejor dicho el pic se va a detener cada cierto tiempo para realizar lo que hay dentro de esta funcin (instrucciones a ejecutar), luego de haberse ejecutado, seguir con su normal funcionamiento y as todo el tiempo. Para saber dnde comienzayacabaestebloquetengoqueidentificarlasllaves({}),queinicializany terminan esta parte. La parte voidTIMER1_isr (void) describe lo siguiente: Elprimervoid(vaco)significaquelafuncindeinterrupcinnovaa devolverningnvalor,esdecirqueningnvalordealgunavariableo resultadoqueseencuentredentrodeestebloque,sevapasaraotra funcin, para que sea utilizada. Elsegundovoid(vaco),elqueestentreparntesissignificaquela funcinnovaarecibirningnparmetroovalorprovenientedeotra funcin. TIMER1_isr, es el nombre que quieres que lleve la funcin (puedes poner cualquier nombre como identificador).El nombre que aparece aqu, es el que te pone por defecto pic c. AHORAVAMOSADESCRIBIRQUEHAYENELINTERIORDELAFUNCINEXPLICADA ANTERIORMENTE (INSTRUCCIONES A EJECUTAR): output_high(PIN_C0); Esta instruccin que significa poner en alto el pin C0 del microcontrolador, sirve para podervisualizarodetectarcuandoseproducelasinterrupcionesycuntotiempo duran (menciono cuanto tiempo duran porque al final de la funcin de interrupcinsevisualizaotrainstruccincontrariaaesta,llamadaoutput_low(PIN_C0);quelo que hace es poner en bajo el pin C0 del microcontrolador. As queyo puedo medir el tiempo que dura o hay entre su estado alto y bajo del pin C0.Por ejemplo mediante un osciloscopio. Si nocoloco esta instruccin afecta en algo el funcionamiento del programa? No, ya que solo es una manera para comprobar que los tiempos de interrupcin son correctos. set_timer1(40535); // Init timer1 to get Fm = 10 Hz. Tm = 0.1 sec Esta instruccin me permite definir el tiempo de muestreo. El timer 1 del pic 16f690 (que es el que se ha utilizado en este caso) tiene una resolucin de 16 bits es decir que puede tomar 65535 valores posibles. Pero valores de qu? En este caso de tiempo Cunto dura cada valor? Dependedelvalordelosciladorautilizar.Cuandoyasehadefinidoelvalordel oscilador (4MHZ, 8MHZ, etc.), se tiene que necesariamente dividir este valor entre 4.Hechoesto,elresultadoeseltiempoqueduracadaunodelos65535posibles valores del timer 1. NOTA ANTES DE SEGUIR: LA INSTRUCCINPOR DEFECTO ES: Set_timer_1 (PRE_CARGA) Para este caso PRE_CARGA=40535 Ejemplo: 1.Utilizo un cristal de cuarzo de f=4MHZ 2.Lo divido entre 4 ,que sera f_1=1MHZ 3.Convierto esta frecuencia en tiempo T=

_=

= 1 us Este es el valor de cada uno de los 65535 valores del timer 1: 1 microsegundo Por lo que deducimos que el timer 1 puede contar hasta: 65535x1 us=65535 us Eleccin de la PRE_CARGA Supongamos que ya defin o determine el valor que quiero como tiempo de muestreo Tm=0.1 us (para este caso). Aplico la siguiente relacin: Tm=_ ( _) El PRE-ESCALADOR es un factor de divisin de frecuencia. Para TIMER1 puede tomar valores de: 1, 2, 4 y 8, y para TIMER2 valores de 1, 4 o 16. Reemplazandotiempodemuestreo,frecuenciadeosciladoryescogiendoel pre_escalador igual a 8, obtenemos: PRE_CARGA=40535 n_pls = get_timer0(); // READ AND RESET ITMER0 El nmero de pulsos del encoder se leenmediante el timer 0 del pic. Esta instruccin me dice que el timer 0 va a contar el nmero del pulsos (flancos de una onda cuadrada) del encoder y el valor obtenido se almacenara en la variable n_pls. El timer 0 del pic (16f690), tiene una resolucin de 8 bits, por lo tanto 255 valores o cuentas como mximo. set_timer0(0); Esta instruccin inicializa el timer 0 en cero, lo que significa ceros pulsos contados por el timer. Cada vez que se produce una interrupcin el timer registra en nmero de pulsos, utilizalainformacinyluegoinicializamoseltimeracero,paracomenzarunanueva cuenta, as sucesivamente. r_value = read_adc(); // read reference volts Esta instruccin me indica que el valor obtenido del potencimetro se almacenara en la variabler_value.read_adc () significa leo el valor del ADC. r_pls = (unsigned int8)(r_value/5); El timer 0, habamos dicho que cuenta hasta una mximo de 255(hay que tenerlo en cuenta, ya que es la razn de porque la divisin entre 5) El valor digital mximo obtenido del potencimetro es 1024. Ahorayo tendr que hacer la tarea que esos 1024 valores posibles del potencimetropuedan entrar en 8 bits (que es la mxima resolucin del timer 0), todo se hace con el objetivo de poder comparar el nmero de pulsos (n_pls) ledos por el timer 0 y el valor ledo por el potencimetro (r_value). As que divido el valor ledo por el potencimetro entre 5, yasignoel resultado a la variable a r_pls. e_pls =(signed long)r_pls - (signed long)n_pls; // error en nmero de pulsos Aqu calculo el error que hay entre mi referencia (r_pls) y los pulsos contados por el timer 0 (n_pls). Lapalabraqueestaentreparntesisantesdecadavariable(Signedlong),mevaa permitir convertirlas variables enteras de 8 bitsr_pls y n_pls tomen el formato de variables con signo de 16 bits. Esto se hace porque la variable e_pls tiene ese formato y tenemos que asegurar que la resta de r_pls y n_pls den como resultado un valor de tipo Signed long. Inew = Iold + Ki*e_pls/10; // implementar el termino integral if(Inew > 400) // stop wind up Inew = 400; Toda esta parte describe la accin integral del controlador: Inew = Iold + Ki*e_pls/10; Comovemoslanuevaaccinintegral(Inew)dependedelvaloranterior(Iold),dela constante integral (Ki) y del error (e_pls).La divisin entre 10 forma parte del diseo del controlador,asqueesposiblecambiarestevalorparaajustarelcontroladorsegn convenga. La condicin: Por qu si Inew es mayor a 400 su valor ser de Inew = 400? El ciclo de trabajo de la seal pwm o mejor dicho el tiempo en el cual la seal esta en alto tiene como valor mximo 400(es el 100%).As que para asegurarnos, que en caso Inew alcance valores mayores a este, le asignamos el valor mximo. If (Inew > 400) Inew = 400; Por qu 400 y no otro valor? Puede tomar otro valor, pero para este caso ha sido configurado como valor mximo del ciclo de trabajo (duty cicle) del pwm en 400. Cmoseobtuvoestevalor?Severmsadelanteenlaconfiguracindelpwmdel microcontrolador. uc = Kp * e_pls + Inew; // implementar controlador PI Esta parte es la expresin completa del controlador, es decir es la accin del controlador. Iold = Inew; Cadavezqueseterminadeejecutaruc(accindecontrol),laaccinintegralcalculada (Inew),pasaaserlaantiguaoanterioraccinintegral(Iold),estoesdebidoaquenuevamente se tendr calcular una nueva accin integral. printf("# = %Lu UC = %Ld \r\n",k,uc); MepermitevisualizarelvalordeKydeUCpormediodelpuertoserial(enproteus conecto un terminal virtual y podre observar peridicamente estos valores)

if(uc < 0) // uc no puede ser negativo ni mayor de 400 uc = 0; if(uc > 400) uc = 400; Como haba visto anteriormente el ciclo de trabajo del pwm no puede ser mayor de 400 y tampoco ser menor a cero, con estas condiciones nos aseguramosque se cumpla. duty = uc; //d= 0%equ a duty = 00, d = 100%is duty = 400 Al final la accin de control (uc), se asigna como valor del ciclo de trabajo de la seal pwm. Lo que quiere decir que uc modifica el tiempo en el cual la seal pwm se mantiene en alto. set_pwm1_duty(duty);Por ultimo mediante esta instruccin hacemos efectiva el cambio de la seal pwm segn el valor de duty. Esta instruccin nos dice que establecemos el valor del ciclo de trabajo de la seal pwm segn los valores que adquiere duty.

printf(" Ref= %u N de P. Med. = %uError = %Ld Duty = %Lu \n\r",r_pls, n_pls, e_pls, duty); Nuevamente con esta instruccin podremos visualizar por medio del puerto serial los valores que adquieren peridicamente las variables: r_pls, n_pls, e_pls, duty. output_low(PIN_C0); k = k +1; Estn explicadas al comienzo. AHORA PASAREMOS A EXPLICAR LA PARTE QUE CORRESPONDE A LA CONFIGURACION DEL MICROCONTROLADOR void main() { CONFIGURACIONWhile (1) { } } Esta es la funcin principal de todo programa hecho en pic. Todo programa debe tener un void main (), es lo primero queejecuta el microcontrolador al encenderse. El inicio y fin de esta funcin estn dadas por las llaves ({}). ElWhile(1){},esparacrearunbucleinfinito(queserepitacontinuamente),su significadoesmientrasseaverdadero(1),quesigaejecutndoseloquesehaya definido que haga el microcontrolador. CONFIGURACION DEL CONVERSOR ANALOGICO-DIGITAL setup_adc_ports( sAN0|VSS_VDD ); Con esta instruccin configuro el conversor analgico-digital del pic (ADC).Como unpicpuedetenervariosADCenvariospinesdelmicrocontrolador,conesta instruccin le indico que voy a utilizar soloel ADC 0 (sAN0). setup_adc(ADC_CLOCK_INTERNAL ); El ADC funciona con una seal de reloj, la fuente o de donde proviene esta seal se indica mediante esta instruccin: Paraestecasoestamosindicamosquevamosutilizarlasealde reloj interna del pic (ADC_CLOCK_INTERNAL). Tambin puede ser externa(de algn circuito externo que genere una seal de reloj:ADC_CLOCK_EXTERNAL) set_adc_channel( 0 ); Habilito el ADC 0 o mejor dicho el canal 0. CONFIGURACION DEL TIMER 0 setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_2); Conestainstruccinconfiguramoseltimer0.Eltimer0seutilizaenestecasopara contar pulsos generados por el encoder (ondas cuadradas).Pero lo que el realmente cuenta o detecta son los flancos de bajada o subida de los pulsos. Entonces el pic detecta o bien el flanco de subida o el flanco de bajada. Cmo le digo que flanco detecte? Esto se hace con la instruccin: RTCC_EXT_L_TO_H. Estainstruccinindicaqueeltimer0vaadetectarflancosexternos(EXT),quevan desde alto a bajo (L_TO_H), es decir un flanco de bajada. La instruccin RTCC_DIV_2, indica que cada 2 flancos se van a contar como uno (DIV_2) set_timer0(0); Inicializo el timer 0 a cero CONFIGURACION DEL TIMER 1 setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); T1_INTERNAL;indicaqueutilizaremoslasealderelojinternadelpic (INTERNAL), la cual equivale a la frecuencia del oscilador dividido entre 4. set_timer1(40535); // Fm = 10 Hz. Tm = 0.1 sec; Esta explicado anteriormente.

CONFIGURACION DEL TIMER 2 Los registros del timer 2 se utilizan para configurar el mdulo PWM.Asi que tendremos quedeterminarlafrecuenciadelasealpwm,superiodoyelduty cicleociclode trabajo de la seal(es decir el rango que puede tomar elduty cicle). Para lo cual utilizaremos las siguientes expresiones: PRESCALER: para TIMER2 valores de 1, 4 o 16. Tosc = 1/Fosc Dnde: Tosc periodo de la oscilador utilizado, Foscfrecuencia del oscilador utilizado setup_timer_2(T2_DIV_BY_1,99,1); La instruccin por defecto es: setup_timer_2 (T2_DIV_BY_1, PR2, PRESCALER); Ahora lo que tengo que hacer es solo reemplazarlos valores de PR2 y del PRESCALER CONFIGURACION DEL MODULO CCP El pic contiene un mdulo llamado CCP (comparador, captura y pwm).Por lo tanto puede trabajar a la vez con solo una de esas funciones. As que: setup_ccp1(CCP_PWM); Indico que el mdulo CCP, trabajara como PWM. set_pwm1_duty(200L); Inicializo el ciclo de trabajo delpwm en la mitadde su valor mximo (400), es decir 200.Lo que equivale a decir que el ciclo de trabajo est al 50% de su valor. OTRAS CONFIGURACIONES enable_interrupts(INT_TIMER1); enable_interrupts (GLOBAL); La primera instruccin me permite habilitar la interrupcin del timer 1. Conlasegundainstruccinhabilitolasinterrupcionesglobales (siempreque sevayaautilizarcualquierinterrupcinsetienenecesariamentequeponer esta instruccin. setup_oscillator(OSC_8MHZ); Esta instruccin ndica que voy a utilizar el oscilador interno del pic, es decir que no voy a utilizar ningn cristal u oscilador externo. Esto es posible solo en algunos microcontroladores, en este caso el 16f690, si lo permite. En caso se quiera utilizar un cristal, esta instruccin no se coloca. // TODO: USER CODE!! Kp = 5; Ki = 5; Iold = 0; Inew = 0; k = 1;De esta manera inicializamos las variables Kp, Ki, Iold, Inew, K HASTAAQUESTODO