0% encontró este documento útil (0 votos)
971 vistas9 páginas

Ejemplos para Pic16f877a

Este documento presenta varios ejemplos de uso de temporizadores, PWM y ADC en microcontroladores. El Ejemplo 3 muestra el uso de Timer0 como contador para activar un relé cuando se presiona un botón la cantidad de veces especificada. El Ejemplo 4 utiliza interrupciones de Timer0, Timer1 y Timer2 para encender y apagar un puerto después de un cierto número de interrupciones sin usar retardos. El Ejemplo 6 muestra el uso del módulo CCP1 en modo PWM, donde los botones pueden cambiar la duración del pulso y se muestra el
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
971 vistas9 páginas

Ejemplos para Pic16f877a

Este documento presenta varios ejemplos de uso de temporizadores, PWM y ADC en microcontroladores. El Ejemplo 3 muestra el uso de Timer0 como contador para activar un relé cuando se presiona un botón la cantidad de veces especificada. El Ejemplo 4 utiliza interrupciones de Timer0, Timer1 y Timer2 para encender y apagar un puerto después de un cierto número de interrupciones sin usar retardos. El Ejemplo 6 muestra el uso del módulo CCP1 en modo PWM, donde los botones pueden cambiar la duración del pulso y se muestra el
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 9

Ejemplos para los modulos, timer, PWM y ADC

http://www.mikroe.com/chapters/view/82/#c4v5

4.5 EJEMPLO 3
Timer0 como un contador, declarar variables nuevas, constantes de enumeracin, utilizar rels... En cuanto a los ejemplos anteriores, el microcontrolador ha ejecutado el programa sin haber sido afectado de ninguna forma por su entorno. En la prctica, hay pocos dispositivos que funcionen de esta manera (por ejemplo, un simple controlador de luz de nen). Los pines de entrada se utilizan tambin en este ejemplo. En la siguiente figura se muestra un esquema, mientras que el programa est en la siguiente pgina. Todo sigue siendo muy simple. El temporizador Timer0 se utiliza como un contador. La entrada del contador est conectada a un botn de presin, as que cada vez que se presiona el botn, el temporizador Timer0 cuenta un pulso. Cuando el nmero de pulsos coincida con el nmero almacenado en el registro TEST, un uno lgico (5V) aparecer en el pin PORTD.3. Este voltaje activa un rel electromecnico, y por eso este bit se le denomina REL en el programa.

/*Cabecera****************************************************/ void main() { char TEST = 5; // Constante TEST = 5 enum salidas {REL = 3}; // Constante RELAY = 3 ANSEL = 0; ANSELH = 0; PORTA = 0; TRISA = 0xFF; // Todos los pines de E/S se configuran como digitales // Reiniciar el puerto PORTA // Todos los pines del puerto PORTA se configuran como entradas

PORTD = 0; TRISD = 0b11110111; OPTION_REG.F5 = 1; OPTION_REG.F3 = 1; TMR0 = 0; do { if (TMR0 == TEST) } while (1); }

// // // // // //

Reiniciar el puerto PORTD Pin RD3 se configura como salida, mientras que los dems se configuran como entradas Contador TMR0 recibe los pulsos por el pin RA4 Valor del pre-escalador 1:1 Reiniciar el temporizador/contador TMR0

// Coincide el nmero en el temporizador con la // constante TEST? (PORTD.RELAY = 1);// Nmeros coinciden. Poner el bit RD3 a uno (salida REL) // Quedarse en el bucle infinito

Slo una constante de enumeracin REL se utiliza en este ejemplo. Se le asigna un valor mediante la declaracin.
enum salidas {REL = 3}; // Constante REL = 3

Si varios pines del puerto PORTD estn conectados a los rels, la expresin anterior se puede escribir de la siguiente manera tambin:
enum salidas {REL=3, CALENTADOR, MOTOR=6, SURTIDOR};

A todas las constantes, precedidas por las constantes con valores asignados (REL=3 y MOTOR=6), se les asignan automticamente los valores de las constantes precedentes, incrementados en 1. En este ejemplo, a las constantes CALENTADOR y SURTIDOR se les asignan los valores 4 y 7, es decir (CALENTADOR=4 y SURTIDOR=7), respectivamente.

4.6 EJEMPLO 4
Utilizar los temporizadores Timer0, Timer1 y Timer2. Utilizar interrupciones, declarar nuevas funciones... Al analizar los ejemplos anteriores, es probable que se haya fijado en la desventaja de proporcionar tiempo de retardo por medio de la funcin Delay. En estos casos, el microcontrolador se queda esttico y no hace nada. Simplemente espera que transcurra una cierta cantidad de tiempo. Tal prdida de tiempo es un lujo inaceptable, por lo que se deber aplicar otro mtodo. Se acuerda usted del captulo de los temporizadores? Se acuerda de lo de interrupciones? Este ejemplo los conecta de una manera prctica. El esquema se queda inalterado, y el desafo sigue siendo presente. Es necesario proporcionar un tiempo de retardo suficiente largo para darse cuenta de los cambios en el puerto. Para este propsito se utiliza el temporizador Timer0 con el preescalador asignado. Siempre que se genere una interrupcin con cada desbordamiento en el registro del temporizador, la variable cnt se aumenta automticamente en 1 al ejecutarse cada rutina de interrupcin. Cuando la variable llega al valor 400, el puerto PORTB se incrementa en 1. Todo el procedimiento se lleva a cabo entre bastidores, lo que habilita al microcontrolador hacer otra tarea.

/*Cabecera******************************************************/ unsigned cnt; void interrupt() { cnt++; TMR0 = 96; INTCON = 0x20; } void main(){ OPTION_REG = 0x84; ANSEL = 0; ANSELH = 0; TRISB = 0; PORTB = 0x0; TMR0 = 96; INTCON = 0xA0; cnt = 0; do { if (cnt == 400) { PORTB = PORTB++; cnt = 0; } } while(1); } // Definir la variable cnt // Con una interrupcin la cnt se incrementa en 1 // El valor inicial se devuelve en el temporizador TMR0 // Bit T0IE se pone a 1, el bit T0IF se pone a 0

// Pre-escalador se le asigna al temporizador TMR0 // Todos los pines de E/S se configuran como digitales // Todos los pines de puerto PORTB se configuran // // // // // // // // // como salidas Reiniciar el puerto PORTB Temporizador T0 cuenta de 96 a 255 Habilitada interrupcin TMR0 A la variable cnt se le asigna un 0 Bucle infinito Incrementar el puerto PORTB despus 400 interrupciones Incrementar nmero en el puerto PORTB en 1 Reiniciar la variable cnt

Siempre que se produzca un desbordamiento en el registro del temporizador TRM0, ocurre una interrupcin.
/*Cabecera******************************************************/ unsigned short cnt; void interrupt() { cnt++ ; PIR1.TMR1IF = 0; TMR1H = 0x80; TMR1L = 0x00; } void main() { ANSEL = 0; ANSELH = 0; PORTB = 0xF0; TRISB = 0; T1CON = 1; PIR1.TMR1IF = 0; TMR1H = 0x80; TMR1L = 0x00; PIE1.TMR1IE = 1; desbordamiento cnt = 0; INTCON = 0xC0; do { if (cnt == 76) { interrupciones PORTB = ~PORTB; cnt = 0; } } while (1); } // Definir la variable cnt // // // // Con una interrupcin la cnt se incrementa en 1 Reiniciar el bit TMR1IF El valor inicial se devuelve en los registros del temporizador TMR1H y TMR1L

// Todos los pines de E/S se configuran como digitales // // // // // Valor inicial de los bits del puerto PORTB Pines del puerto PORTB se configuran como salidas Configurar el temporizador TMR1 Reiniciar el bit TMR1IF Ajustar el valor inicial del temporizador TMR1

// Habilitar la interrupcin al producirse un // Reiniciar la variable cnt // Interrupcin habilitada (bits GIE y PEIE) // Bucle infinito // Cambiar el estado del puerto PORTB despus de 76 // Nmero en el puerto PORTB est invertido // Reiniciar la variable cnt

En este caso, una interrupcin se habilita despus de que se produzca un desbordamiento en el registro del temporizador TMR1 (TMR1H, TMR1L). Adems, la combinacin de los bits que vara en el puerto POTRB difiere de la en el ejemplo anterior.
/*Cabecera******************************************************/ unsigned short cnt; void Reemplazar() { PORTB = ~PORTB; } void interrupt() { // Definir la variable cnt // Definir nueva funcin Reemplazar // Funcin invierte el estado del puerto

if (PIR1.TMR2IF) { cnt++ ; PIR1.TMR2IF = 0; TMR2 = 0; }

// // // //

Si el bit TMR2IF = 1, Incrementar variable la cnt en 1 Reiniciar el bit y Reiniciar el registro TMR2

// main void main() { cnt = 0; ANSEL = 0; ANSELH = 0; PORTB = 0b10101010; TRISB = 0; salidas T2CON = 0xFF; TMR2 = 0; PIE1.TMR2IE = 1; INTCON = 0xC0; while (1) { if (cnt > 30) { Reemplazar(); cnt = 0;

// Reiniciar la variable cnt // Todos los pines de E/S se configuran como digitales // Estado lgico en los pines del puerto PORTB // Todos los pines del puerto PORTB se configuran como // // // // // // // // // Configurar el temporizador T2 Valor inicial del registro del temporizador TMR2 Interrupcin habilitada Bits GIE y PEIE se ponen a 1 Bucle infinito Cambiar el estado del puerto PORTB despus de ms de 30 interrupciones Funcin Reemplazar invierte el estado del puerto PORTB Reiniciar la variable cnt

} } }

En este ejemplo, una interrupcin ocurre despus de que se produce un desbordamiento en el registro del temporizador TMR2. Para invertir el estado lgico de los pines del puerto se utiliza la funcin Reemplazar, que normalmente no pertenece al lenguaje C estndar.

4.7 EJEMPLO 5
Utilizar el temporizador perro - guardin Este ejemplo muestra cmo NO se debe utilizar el temporizador perro-guardin. Un comando utilizado para reiniciar este temporizador se omite a propsito en el bucle del programa principal, lo que habilita al temporizador perro guardin ganar la batalla del tiempo y reiniciar al microcontrolador. Por consiguiente, el microcontrolador se va a reiniciar sin parar, lo que indicar el parpadeo de los LEDs del puerto PORTB.

/*Cabecera******************************************************/ void main() { OPTION_REG = 0x0E; asm CLRWDT; WDT PORTB = 0x0F; TRISB = 0; salidas Delay_ms(300); PORTB = 0xF0; while (1); } // Pre-escalador se le asigna al temporizador WDT (1:64) // Comando en ensamblador para reiniciar el temporizador // Valor inicial del registro PORTB // Todos los pines del puerto PORTB se configuran como // Tiempo de retardo de 30mS // Valor del puerto PORTB diferente del inicial // Bucle infinito. El programa se queda aqu hasta que el // temporizador WDT reinicie al microcontrolador

Para que este ejemplo funcione apropiadamente, es necesario habilitar al temporizador perroguardin al seleccionar la opcin Tools/mE Programmer/Watchdog Timer - Enabled.

4.8 EJEMPLO 6
Mdulo CCP1 como generador de seal PWM Este ejemplo muestra el uso del mdulo CCP1 en modo PWM. Para hacer las cosas ms interesantes, la duracin de los pulsos en la salida P1A (PORTC,2) se puede cambiar por medio de los botones de presin simblicamente denominados OSCURO y CLARO. La duracin ajustada se visualiza como una combinacin binaria en el puerto PORTB. El funcionamiento de este mdulo est bajo el control de las funciones pertenecientes a la librera especializada PWM. Aqu se utilizan las tres de ellas:
1. PWM1_init tiene el prototipo: void Pwm1_Init(long freq); El parmetro freq ajusta la

frecuencia de la seal PWM expresada en hercios. En este ejemplo equivale a 5kHz. 2. PWM1_Start tiene el prototipo: void Pwm1_Start(void); 3. PWM1_Set_Duty tiene el prototipo: void Pwm1_Set_Duty(unsigned short duty_ratio); El parmetro duty_ratio ajusta la duracin de pulsos en una secuencia de pulsos. La librera PWM tambin contiene la funcin PWM_Stop utilizada para deshabilitar este modo. Su prototipo es: void Pwm1_Stop(void);

/*Cabecera******************************************************/ // Definir las variables ciclo_de_trabajo_actual, // ciclo_de trabajo_anterior unsigned short ciclo_de_trabajo_actual; unsigned short ciclo_de trabajo_anterior; void initMain() { ANSEL = 0; // Todos los pines de E/S se configuran como digitales ANSELH = 0; PORTA = 255; // Estado inicial del puerto PORTA TRISA = 255; // Todos los pines del puerto PORTA se configuran como entradas PORTB = 0; // Estado inicial del puerto PORTB TRISB = 0; // Todos los pines del puerto PORTB se configuran como salidas

PORTC = 0; // Estado inicial del puerto PORTC TRISC = 0; // Todos los pines del puerto PORTC se configuranccomo salidas PWM1_Init(5000); // Inicializacin del mdulo PWM (5KHz)

void main() { initMain(); ciclo_de_trabajo_actual = 16; ciclo_de trabajo_anterior = 0; PWM1_Start(); while (1) { if (Button(&PORTA, 0,1,1)) ciclo_de_trabajo_actual++ ; if (Button(&PORTA, 1,1,1)) ciclo_de_trabajo_actual-- ;

// // // // // // // // // // // //

Valor inicial de la variable ciclo_de_trabajo_actual Reiniciar la variable ciclo_de trabajo_anterior Iniciar el mdulo PWM1 Bucle infinito Si se presiona el botn incrementar el valor de variable current_duty Si se presiona el botn decrementar el valor de variable current_duty conectado al RA0 la conectado al RA1 la

if (old_duty != ciclo_de_trabajo_actual) { // Si ciclo_de_trabajo_actual y // ciclo_de trabajo_anterior no son iguales PWM1_Set_Duty(ciclo_de_trabajo_actual); // ajustar un nuevo valor a PWM, ciclo_de trabajo_anterior = ciclo_de_trabajo_actual; // Guardar el nuevo valor PORTB = ciclo_de trabajo_anterior; // y visualizarlo en el puerto PORTB } Delay_ms(200); // Tiempo de retardo de 200mS } }

Para que este ejemplo funcione apropiadamente, es necesario marcar las siguientes libreras en la ventana Library Manager antes de compilar el programa:

PWM Button

4.9 EXAMPLE 7
Utilizar el convertidor A/D El convertidor A/D del microcontrolador PIC16F887 se utiliza en este ejemplo. Hace falta decir que todo es pan comido? Una seal analgica variable se aplica al pin AN2, mientras que el resultado de la conversin de 10 bits se muestra en los puertos POTRB y PORTD (8 bits menos significativos en el puerto PORTD y 2 bits ms significativos en el puerto PORTB). La Tierra (GND) se utiliza como voltaje de referencia bajo Vref-, mientras que el voltaje de referencia alto se aplica al pin AN3. Esto habilita que la escala de medicin se estire y encoja. IEn otras palabras, el convertidor A/D siempre genera un resultado binario de 10 bits, lo que significa que reconoce 1024 niveles de voltaje en total (210=1024). La diferencia entre dos niveles de voltaje no es siempre la misma. Cuanto menor sea la diferencia entre Vref+ y Vref-, tanto menor ser la diferencia entre dos de 1024 niveles. Como hemos visto, el convertidor A/D es capaz de detectar pequeos cambios de voltaje.

/*Cabecera******************************************************/ unsigned int temp_res; void main() { ANSEL = 0x0C; TRISA = 0xFF; ANSELH = 0; TRISB = 0x3F; TRISD = 0; ADCON1.F4 = 1 ; do { temp_res = ADC_Read(2); PORTD = temp_res; PORTB = temp_res >> 2; } while(1); // // // // // // // // // // // // // Pines AN2 y AN3 se configuran como analgicos Todos los pines del puerto PORTA se configuran como entradas Los dems pines se configuran como digitales Pines del puerto PORTB, RB7 y RB6 se configuran como salidas Todos los pines del PORTD se configuran como salidas Voltaje de referencia es llevado al pin RA3. Resultado de la conversin A/D es copiado a temp_res 8 bits menos significativos se mueven al puerto PORTD 2 bits ms significativos se mueven a los bits RB6 y RB7 Bucle infinito

Para que este ejemplo funcione apropiadamente, es necesario marcar la librera ADC en la ventana Library Manager antes de compilar el programa:

ADC

También podría gustarte