ISTP - SENATI
LABORATORIO DE CIRCUITOS ELECTRONICOS IV LABORATORIO N° 09
P1) a) Visualizar el archivo de video Videotutorial 8 LCD_ADC_Programacion en C de PIC, PIC , en la
carpeta ADC, a partir del minuto 19:00 (antes está el uso del LCD. A partir de 18:05-19:00 se muestra como descargar los archivos de los videos); el Videotutorial 9 Timer0 y WatchDog Timer_Programacion en C de PIC, PIC , solo hasta el tiempo de 8:55. b) En un archivo de Word responder las preguntas del profesor sobre el módulo ADC: registros de configuración, otros registros, bits de los registros anteriores, bits de inicio y fin de conversión análogo-digital, habilitación de la interrupción del módulo ADC, registro de resultados de 8 y 10 bits, ejemplos de configuración, etc. P2) Lectura de un solo canal, adaptando código de un compilador de versión mas antigua
a) Adaptar el código del manejo del módulo ADC del PIC16F84, del video, para el PIC16F877A. Ambos compiladores son de Hi Tech, pero de versiones diferentes. Para mayor detalle, abrir el en la carpeta y buscar el módulo ADC y sus registros de archivo configuración; en ellos encontraran los nombres de los pines del pic y los nombres de los bits de los registros de configuración, para el compilador actual. Se sugiere adaptar el código para el lcd_6 hilos, previa su configuración. #include #include #include "lcd_cd4094" __CONFIG(INTIO & WDTDIS WDTDIS & MCLRDIS & LVPDIS) LVPDIS) char mensaje[16]; // alt+91 y alt+93 unsigned char adc=0; void main(void) { ANSEL=0b00001000; // poner los pines como I/O I/O digitales ̅ | X | ADON ADCON0=0b00011001; // ADCS1 | ADCS0 | CHS2 | CHS1 | CHS0 | GO/ ADCON1=0b00000000; // ADFM | X | X | X | PCFG3 | PCFG2 | PCFG1 | PCFG0 OSCCON=0b01101100; // para establecer la frecuencia frecuencia del procesador lcd_init(); lcd_gotoxy(0,0); lcd_puts("HOLA MUNDO!!"); while(1) { ADCON0|=0x04; // ALT+124 LA BARRA VERTICAL; inicia la conversion while((ADCON0&0x04)==0); //interroga por el BIT2 BIT2 de ADCON0 ADCON0 adc=ADRESH; lcd_gotoxy(0,1); sprintf(mensaje,"Valor adc = %3u",adc); lcd_puts(mensaje); delay_ms(250); } } b) Simúlelo en MPLAB SIM c) Simúlelo en ISIS, con una fuente de 1.5 Vdc y luego de 2.5 Vdc por el canal analógico. d) ¿De cuántos bits es el registro del ADC en este código? ¿Qué ocurriría si se omite ADCON1?
d) Use un potenciómetro conectado a una fuente de 5 Vdc y varíelo, para ver las variaciones en el LCD. ¿Corresponde los valores del LCD con la salida del potenciómetro? ¿Por qué? P3) a) Realice los siguientes cambios en el código anterior
//unsigned char adc=0; unsigned int adc=0; //ADCON0=0b00011001; //ADCS1 |ADCS0 | CHS2 | CHS1 ADCON0=0b11011001; // ADCS1 |ADCS0 | CHS2 | CHS1
| CHS0 | GO/ ̅ | X | ADON ̅ | CHS0 | GO/ | X | ADON
//ADCON0|=0b00000100; // ALT+124 LA BARRA VERTICAL; inicia la conversion GODONE=1; // while((ADCON0&0x04)==0); while((GODONE==1); adc=ADRESH<<8 | ADRESL; y compílelo. ¿Son equivalentes? ¿Por qué? b) Simúlelo en MPLAB SIM c) Simúlelo en ISIS, con el potenciómetro variando los valores. ¿Nota alguna diferencia? Si su respuesta es afirmativa, ¿Por qué? d) ¿De cuántos bits es el registro del ADC en este código? ¿Cómo se hace para manejar dos registros de 8 bits separados, en uno solo de 16 bits? e) En ISIS, cambie el potenciómetro por el integrado LM35 como entrada al canal analógico, para la medición de temperatura ¿son iguales los valores del integrado con lo mostrado en el LCD? ¿Por qué? ¿Qué cambios se necesita realizar? Recuerde el video 8, tiempo 48:36. P4) Lectura de dos canales
a) Agregue sentencias al código de P2 que permita manejar dos canales ADC, uno alimentado por una fuente de tensión continua y la otra por el integrado LM35. b) Simúlelo en MPLAB SIM c) Simúlelo en ISIS. ¿Nota alguna diferencia? Si su respuesta es afirmativa, ¿Por qué? P5) Lectura de dos canales adaptando un código de otro compilador (CCS)
a) En el siguiente ejercicio, se medirán dos canales analógicos (RA0 y RA1), el primero será el valor de una variable que se desea medir y el segundo será el set point. Si la variable está por encima del set point se activa un led rojo. En caso contrario se activa un led verde. Adaptar el siguiente código para el compilador Hi-Tech #include<16f877.h> #device ADC=10 #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay(clock=4000000) #use fast JO(C) #include intl6 valor=0; long setpoint=0; float p; float psp; void main(){ set_tris_c(0); setup_adc(ADC_CLOCK_INTERNAL); setup_adc_ports(ALL_ANALOG); lcd_init(); output_C(0); while (TRUE){
} }
set_adc_channel(0); delay_ms(10); valor=read_adc(); p=0.004883*valor; printf(lcd_putc/"\fSENSOR=%g\n",p); set_adc_channel(l); delay_ms(10); setpoint=read_adc(); psp=0.004883*setpoint; printf(lcd_putc,"SPOINT=%g\n",psp); if(p>=psp){ output_high(PIN_CO); output_low(PIN_Cl);} else{ output_low(PIN_CO); output_high(PIN_Cl); } delay_ms(50);
P6) PWM sin CCP
Esta publicación fue realizada con el fin de conseguir una segunda opción para los MCU que no poseen módulos PWM o bien para aquellos desarrollos que requieren más de los que posee el MCU. Si bien ya sabemos que los MCU más baratos no poseen estos módulos PWM pero con esta simple rutina es posible modular una salida cualquiera para lograr el PWM. La idea de esta rutina es manipular tantas salidas como tenga el MCU si se quisiera, de manera continua. Para ello se usara el módulo ADC que nos entregara el valor digital de la señal continua de la entrada que controla el ancho de pulso (simulada por un potenciómetro conectado a una fuente de 5 Vdc). La idea en el programa es el siguiente: #include <16F883.h> #device adc=8 #FUSES NOWDT #FUSES INTRC_IO #FUSES NOPUT #FUSES NOMCLR #FUSES NOPROTECT #FUSES NOCPD #FUSES NOBROWNOUT #FUSES IESO #FUSES FCMEN #FUSES NOLVP #FUSES NODEBUG #FUSES NOWRT #FUSES BORV40 #use delay(int=8000000) void main() { setup_adc_ports(sAN0|VSS_VDD); ///Escoge 1 canal:AN0 y Vref+=VDD, Vref-=Vss setup_adc(ADC_CLOCK_DIV_2); // tiempo de conversion por 2 (fosc/2). int8 tOFF, tON; // dos variables de 8 bits, tiempo en bajo y // tiempo en alto; manteniendo la frecuencial (periodo) fija while(1){ set_adc_channel(0);
// active el modulo, empieza la conversion y termina la conversion.
tOFF = read_adc();
// lee el valor del registro de resultados, como tiempo en bajo.
tON = 255 - tOFF; output_low(PIN_C0); delay_us(tOFF); output_high(PIN_C0); delay_us(tON); }
// calcula el valor del tiempo en alto.
}
El circuito es muy simple solamente se utiliza un pin de entrada y uno de salida, pero de todas formas lo subiré para completar la nota.
La primera parte del código (include del micro a utilizar, rango del ADC, configuración del MCU "FUSES", delay) es genérica, lo que nos interesa es el código marcado en color rojo, lo que podemos ver es que la lectura del ADC (alimentado por el potenciómetro) se guarda en tOFF, luego tON será el máximo del ADC como lo seteamos en 8 bit será de 0 a 255, por ende el valor del ADC será restado del 255 y nos dará el tON, luego utilizaremos el tON como variable del delay_us() y de la misma forma el tOFF, esto quiere decir que primero tOFF tendrá el tiempo de apagado del Led output_low(PIN_C0) y luego tON tendrá el tiempo de encendido output_high(PIN_C0). Un ejemplo de este cálculo seria: si por ejemplo situamos el potenciómetro en el centro el ADC estaría leyendo ±-2,5V que traducidos al ADC sería el valor 127, ese valor estaría en la variable tOFF, luego aparece el cálculo 255 - tOFF = tON, entonces seria 255-127 = 128, tON valdría 128, podríamos decir que el ciclo es ±50%, ahora si variamos el potenciómetro por ejemplo a 1,25V sería el valor 64 del ADC, tOFF sería igual a 64 y tON seria 255 - 64 = 191, entonces podemos decir que el ciclo de trabajo seria del 75%, de esa forma trabaja nuestra rutina, la cual se podría expandir para cada salida prolijamente dentro de una función o bien dentro de una interrupción. DutyCycle 95%
DutyCycle 50%
DutyCycle 5%
P7) Generador de señal PWM con Timer2 a) Vea el archivo de video
e indique que recursos mínimos del PIC y que registros se requieren configurar para que funcione como generador de señales PWM. b) Implemente el código del archivo de video, compílelo y simúlelo en MPLAB SIM. c) Simúlelo en ISIS de Proteus. d) ¿Hasta qué valor de ciclo de trabajo genera el código implementado?, ¿qué cambio se puede realizar para mejorarlo?, ¿se puede generar señales PWM sin el modulo comparador? P8) Funcionamiento del módulo CCP1 en modo de comparación.
Se quiere hacer trabajar al módulo CCP1 en modo comparación. El TMR1 asociado a este modo trabajará en modo contador de impulsos externos, donde la señal que se le aplica es proporcionada por el generador de la Micro PIC IÍO. Los pulsos que deberá contar vienen determinados por una constante n. A su vez, la señal de salida generada por el módulo CCP1 cuando el TMR1 llegue a su valor, es aplicada a la patita RA4/T0CKI, de modo que incremente el valor del TMRO, que estará configurado como contador de eventos externos. El tratamiento se realizará con interrupciones y un LED basculará cada vez que el TMRO se desborde. Jugando con los valores de los predivisores de frecuencia y de la constante n se pueden obtener diferentes temporizaciones. Esquema eléctrico
Con este ejercicio se pueden obtener grandes temporizaciones, ya que se está enlazando el funcionamiento de dos temporizadores. Para ello, la señal de salida del módulo CCP1 (RC2/CCP1) deberá unirse físicamente con la señal de entrada de impulsos del TMRO (RA4/T0CKI). (Figura 6.8.) La entrada de impulsos del TMR1, por su parte, vendrá dada por la unión de la patita RC0/T1CKI con el generador. El LED se corresponderá con la línea RBO, por lo que se puede utilizar uno de los diodos de la barra de LEDs. Organigrama
En el cuerpo principal del programa sólo se realizará la configuración e inicialización de los
Figura 6.8 Esquema eléctrico el ejercicio propuesto.
registros que se van a utilizar, tal y como se muestra en la Figura 6.9. Luego el programa deberá quedarse en un bucle infinito a la espera de que se produzca una interrupción. A la vuelta de la interrupción se seguirá en dicho bucle. Cuando se trabaja con interrupciones se necesita utilizar, al menos, dos organigramas: uno para el tratamiento de la interrupción y otro para el programa principal. Si el programa principal o la interrupción son complejos, sus organigramas mostrarán los llamamientos a subrutinas y éstas deberán especificarse en otros organigramas. La Figura 6.10 muestra el organigrama de tratamiento de interrupción. El primer recuadro INTER no se traduce en ninguna instrucción; representa la entrada a la rutina. La salida, asimismo, también debe ser única. Siempre que se habilite más de una interrupción, el primer paso será discriminar de entre los tipos posibles aquel que la ha producido. En nuestro caso, tenemos la interrupción del TMRO al desbordarse, lo cual hará cambiar de estado al LED conectado en RB0, y la interrupción provocada cuando el comparador del módulo CCP1 detecta la igualdad del TMR1 con el valor programado. En ambos casos se debe poner a 0 el señalizador de interrupción antes de volver.
Figura 6.9. Organigrama del cuerpo prin-
Figura 6.10. Organigrama de la rutina de
cipal del ejercicio propuesto.
tratamiento de interrupción.
P9) Funcionamiento de CCP1 en modo de comparación y CCP2 en PWM
Los módulos CCP1 y CCP2 pueden trabajar simultáneamente en diferentes modos. En este ejercicio vamos a hacer trabajar al módulo CCP2 en modulación de anchura de pulsos para el gobierno de un motor, y al módulo CCP1 en comparación para controlar el desplazamiento de dicho motor. El TMR1 actuará en modo contador de eventos externos, donde los impulsos serán generados por el encoder asociado al motor. La secuencia que se pretende realizar con este programa es: 1. Arrancar el motor suavemente en el sentido horario hasta llegar a la velocidad máxima. 2. Girar en sentido horario tantos pasos como determine la constante "HORARIO". 3. Parar un segundo.
4. Girar en sentido anti horario tantos pasos como indique la constante "ANTIHORARIO" a la velocidad que determinen los interruptores (RA4-RA0)*8. 5. Decrecer la velocidad hasta llegar a detener el motor. 6. Parar un segundo. 7. Vuelta al paso 1. Esquema eléctrico
Para la realización de este ejercicio se deben hacer las conexiones mostradas en la Figura 6.12 y que se enuncian a continuación: 1. La salida del encoder debe unirse con la entrada de pulsos del TMR1l (RC0/T1CKI). 2. La salida del módulo CCP2 (RC1/CCP2) se conecta a la entrada de activación del motor. 3. Las salidas RB1:RB0 se conectan con las líneas IN2:IN1 del motor para controlar el sentido del giro.
Figura 6.12 Esquema de conexionado del PIC con el motor y el encoder
Organigrama
Los pasos a realizar tras configurar los registros adecuadamente se pueden ver como una secuencia de acciones. En este caso, cada recuadro se corresponderá con un bloque de instrucciones. Se trata de comenzar con una velocidad nula en el motor e ir incrementándola en uno de los sentidos de giro. Esto se hará mediante PWM, aumentando la anchura del pulso en un bucle hasta llegar al máximo. En esa velocidad, el motor girará un número dado de pasos. Dichos pasos serán pulsos que el encoder acoplado al motor introduce en la patita RC07TICKI del TMR1. P10) Funcionamiento del módulo PWM del PIC16F877A
a) Visualizar el archivo de video Videotutorial 12 CCP1, CCP2 y PWM1_Programacion de C en PIC , y
compilador Hi-tech V9.83 o posteriores. b) Simularlo en MPLAB SIM c) Simularlo en ISIS.
adaptar el código para el
Figura 6.13. Organigrama del segundo
ejercicio propuesto.
Se parará el motor de golpe y permanecerá así durante un segundo. A velocidad marcada por unos interruptores el motor volverá a girar, esta vez en sentido contrario al anterior y, por último, por la misma PWM se irá decrementando la velocidad del motor hasta pararlo durante otro segundo. Durante el programa, además, se va a controlar el estado del perro guardián, introduciendo instrucciones de borrado para que resetee el PIC en el caso de que se produzca un fallo en el sistema.