36
Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com PIC18F14K50: Temporizadores (Timers) Los temporizadores son una parte importante de cualquier uC. Son básicamente un contador que es controlado por un reloj externo o interno y pueden ser desde 8 bits hasta 32 bits. El temporizador puede ser iniciado o detenido por software, al igual que cargarle un valor inicial. Los temporizadores pueden generar una interrupción cuando llegan a cierta cuenta o se desbordan (overflow). Algunos uC tienen funciones de captura y comparación donde el valor del temporizador puede ser leído cuando un evento externo ocurra o ser comparado con un valor preestablecido y generar una interrupción si ese valor es alcanzado. Se utilizan para varios procesos como: generar señales con tiempos específicos, interrupciones en intervalos, medir frecuencia y tiempo, etc. El PIC18F14K50 cuenta con cuatro temporizadores que se explicaran a continuación. 1.1. Timer0 Las características generales del Timer0 son: Temporizador o Contador. 8 / 16 bits. 3 bits de pre-escala (1:1 -> 1:256). Reloj de origen interno o externo. Selección de flanco con reloj externo. Interrupción al desbordarse. Para configurar el timer0 se utiliza el registro T0CON donde:

PIC18F14K50: Temporizadores (Timers)

Embed Size (px)

DESCRIPTION

Manejo de temporizadores (timers)

Citation preview

Page 1: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

PIC18F14K50: Temporizadores (Timers)

Los temporizadores son una parte importante de cualquier uC. Son básicamente un contador que es controlado por un

reloj externo o interno y pueden ser desde 8 bits hasta 32 bits. El temporizador puede ser iniciado o detenido por

software, al igual que cargarle un valor inicial. Los temporizadores pueden generar una interrupción cuando llegan a

cierta cuenta o se desbordan (overflow).

Algunos uC tienen funciones de captura y comparación donde el valor del temporizador puede ser leído cuando un

evento externo ocurra o ser comparado con un valor preestablecido y generar una interrupción si ese valor es

alcanzado.

Se utilizan para varios procesos como: generar señales con tiempos específicos, interrupciones en intervalos, medir

frecuencia y tiempo, etc.

El PIC18F14K50 cuenta con cuatro temporizadores que se explicaran a continuación.

1.1. Timer0

Las características generales del Timer0 son:

Temporizador o Contador.

8 / 16 bits.

3 bits de pre-escala (1:1 -> 1:256).

Reloj de origen interno o externo.

Selección de flanco con reloj externo.

Interrupción al desbordarse.

Para configurar el timer0 se utiliza el registro T0CON donde:

Page 2: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Este temporizador puede trabajar con 8 bits o 16 bits y sus diagramas son los siguientes:

Timer0 en modo 8 bits:

Timer0 en modo16 bits:

La secuencia para trabajar el Timer0 es:

Desactivarlo en TMR0ON.

Seleccionar si será temporizador o contador en T0CS.

Establecer si trabajaremos 8 o 16 bits en T08BIT.

Si es contador seleccionar el flanco de conteo en T0SE.

Si se utilizará pre-escala activarlo en PSA y seleccionar la relación T0PS.

Escribir el valor inicial en TMR0H (modo 16 bits) y después TMR0L.

Si se utilizaran interrupciones activarlas.

Activarlo en TMR0ON para que empiece a funcionar.

Si se desea leer el valor, primero leer TMR0L y después TMR0H.

Page 3: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.1.1. Timer0: Contador de Pulsos (8 y 16 bits)

Para este ejemplo se diseñara una aplicación sencilla que se encargara de contar pulsos que serán generados con un interruptor con anti rebote y la cuenta será mostrada en un LCD. Se utilizara modo de 8 y 16 bits.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/15/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ u16 intctr = 0; /** DEFINES ********************************************************/ //#define USE_8B #define USE_INT /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section

Page 4: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

#pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. #ifdef USE_INT if(INTT0Flag == 1){ intctr++; } INTT0FlagClear(); #endif } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ s8 String[21]; SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR0 - Counter "); lcd_goto(3,1); #ifdef USE_8B lcd_write_pgm(" 8b,LTH,WOPSA,"); #else lcd_write_pgm("16b,LTH,WOPSA,"); #endif lcd_goto(3,15); #ifdef USE_INT lcd_write_pgm(" INT "); #else lcd_write_pgm("WOINT "); #endif #ifdef USE_INT // Interruption Configuration //INTPT0HPriority(); INTT0FlagClear(); INTT0Enable(); //INTPEnable(); PEIEnable(); GIEnable(); #endif // Timer0 Ctr StopT0(); OpenCtrT0(); #ifdef USE_8B Set8BitsT0(); #else Set16BitsT0(); #endif SetLTHCtrT0(); NoUsePSAT0(); // Initial value and start #ifdef USE_8B #ifdef USE_INT Write8bT0(254); #else Write8bT0(0); #endif #else #ifdef USE_INT Write16bT0(65534); #else Write16bT0(0); #endif #endif StartT0(); while(true){ // Update data all time

Page 5: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

#ifdef USE_8B sprintf(&String[0],"%.5hu - %.3hhu",intctr,Read8bT0()); lcd_goto(4,6); #else sprintf(&String[0],"%.5hu - %.5hu",intctr,Read16bT0()); lcd_goto(4,5); #endif lcd_write(&String[0]); } // end while } // end main()

Diagrama esquemático:

Circuito armado:

Page 6: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.1.2. Timer0: Temporizador de Segundos

Para este ejemplo se diseñara un contador de segundos utilizando el Timer0 como temporizador.

Para determinar cuántas veces debe incrementarse el temporizador para alcanzar el tiempo que necesitamos debemos utilizar la siguiente ecuación:

Para 32Mhz el TC = 125 nS, por lo tanto la cantidad de cuentas C = 8, 000, 000. Pero nuestro contador en modo 16 bits solo podrá contar hasta 65535, lo que significa que tendremos que utilizar la pre-escala o la interrupción con un contador adicional para alcanzar la cuenta requerida. Existen muchas formas de realizar la cuenta pero en este ejemplo solamente se mostraran de dos maneras:

8b con pre-escala, interrupción y contador adicional (1:256*250*125).

16b con pre-escala e interrupción (1:256*31250).

Los datos del LCD serán actualizados en la ISR.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c

Page 7: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

* Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/16/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ //#define USE_8B /** VARIABLES ******************************************************/ u16 Segundos = 0; #ifdef USE_8B u8 AC8b = 0; #endif /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. s8 String[21]; if(INTT0Flag == 1){ #ifdef USE_8B Write8bT0(6); // 256-250 = 6 AC8b++; if(AC8b > 125){ AC8b = 0; Segundos++; // Update data sprintf(&String[0],"%.5hu s",Segundos); lcd_goto(4,9); lcd_write(&String[0]); } #else Write16bT0(34286); // 65536-31250 = 34286 Segundos++; // Update data sprintf(&String[0],"%.5hu s",Segundos); lcd_goto(4,9); lcd_write(&String[0]); #endif } INTT0FlagClear(); } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz();

Page 8: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

// LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR0 - Timer "); lcd_goto(3,1); #ifdef USE_8B lcd_write_pgm(" 8b (1:256*250*125) "); #else lcd_write_pgm(" 16b (1:256*31250) "); #endif // Interruption Configuration INTT0FlagClear(); INTT0Enable(); PEIEnable(); GIEnable(); // Timer0 tmr StopT0(); OpenTmrT0(); #ifdef USE_8B Set8BitsT0(); #else Set16BitsT0(); #endif UsePSAT0(); SetPS(7); // 1:256 // Initial value and start #ifdef USE_8B Write8bT0(6); // 256-250 = 6 #else Write16bT0(34286); // 65536-31250 = 34286 #endif StartT0(); while(true){ ; } // end while } // end main()

Diagrama esquemático:

Page 9: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Circuito armado:

1.2. Timer1

Las características generales del Timer1 son:

Temporizador o Contador (Síncrono como el Timer0 o Asíncrono).

Temporizador tipo RTC utilizando un oscilador externo de 32.768KHz.

16 bits.

2 bits de pre-escala (1:1 -> 1:8).

Reloj de origen interno o externo.

Interrupción al desbordarse.

Evento especial al utilizarse con CCP.

Para configurar el timer1 se utiliza el registro T1CON donde:

Page 10: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com El diagrama de bloque de este temporizador es:

La secuencia para trabajar el Timer1 es:

Desactivar TMR1 en TMR1ON.

Seleccionar si será temporizador o contador en TMR1CS.

Si se utilizara como RTC desactivar las entradas análogas y activar el oscilador externo en T1OSCEN.

Si es contador desactivar las entradas análogas correspondientes y seleccionar si será síncrono o asíncrono en ̅̅ ̅̅ ̅̅ ̅̅ ̅̅ ̅̅ (El

Timer0 lo utiliza como síncrono).

Si se utilizará pre-escala seleccionar la relación T1CKPS.

Activar el modo de lectura/escritura de 16 bits en RD16.

Escribir el valor inicial en TMR1H y después TMR1L.

Si se utilizaran interrupciones activarlas.

Activarlo en TMR1ON para que empiece a funcionar.

Si se desea leer el valor, primero leer TMR1L y después TMR1H.

Page 11: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.2.1. Timer1: Contador de Pulsos

Utilizaremos el mismo ejemplo que el Timer0, contaremos pulsos de un interruptor con anti rebote, con y sin interrupciones.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/17/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ #define USE_INT /** VARIABLES ******************************************************/ s8 String[21]; u16 intctr = 0; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt.

Page 12: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

//Service the interrupt //Clear the interrupt flag //Etc. #ifdef USE_INT if(INTT1Flag == 1){ intctr++; } INTT1FlagClear(); #endif } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR1 - Counter "); lcd_goto(3,1); lcd_write_pgm("16b, ,WOPSA,"); lcd_goto(3,15); #ifdef USE_INT lcd_write_pgm(" INT "); #else lcd_write_pgm("WOINT "); #endif #ifdef USE_INT // Interruption Configuration INTT1FlagClear(); INTT1Enable(); PEIEnable(); GIEnable(); #endif // Timer0 Ctr StopT1(); OpenCtrT1(); CtrSyncT1(); UseRWOneOP(); // Initial value and start #ifdef USE_INT Write16bT1(65530); #else Write16bT1(0); #endif StartT1(); while(true){ // Update data all time #ifdef USE_INT sprintf(&String[0],"%.5hu - %.5hu",intctr,Read16bT1()); lcd_goto(4,5); #else sprintf(&String[0],"%.5hu",Read16bT1()); lcd_goto(4,9); #endif lcd_write(&String[0]); } // end while } // end main()

Page 13: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Diagrama esquemático:

Circuito armado:

Page 14: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.2.2. Timer1: Temporizador de Segundos

Se realizará también un contador de segundos utilizando el Timer1 como temporizador. El único inconveniente es que la pre-escala solo llega hasta 1:8 por lo que a 32Mhz de reloj interno necesitaremos 1, 000, 000 cuentas y con 16b no se alcanza. Para solucionar esto utilizaremos un contador adicional intermedio, el cual puede ser distribuido de diferentes maneras pero para este ejemplo será: 1:8 * 50, 000 * 20 = 8, 000, 000 cuentas.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/17/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ s8 String[21]; u16 Segundos = 0; u8 t = 0; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm }

Page 15: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

#pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INTT1Flag == 1){ Write16bT1(15536);// 65536-50000 = 15536 t++; if(t == 20){ t = 0; Segundos++; // Update data sprintf(&String[0],"%.5hu s",Segundos); lcd_goto(4,9); lcd_write(&String[0]); } } INTT1FlagClear(); } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR1 - Timer "); lcd_goto(3,1); lcd_write_pgm("16b (1:8*50,000*20) "); sprintf(&String[0],"00000 s"); lcd_goto(4,9); lcd_write(&String[0]); // Interruption Configuration INTT1FlagClear(); INTT1Enable(); PEIEnable(); GIEnable(); // Timer0 tmr StopT1(); OpenTmrT1(); // As timer SetPST1(3); // 1:8 UseRWOneOPT1(); // Initial value and start Write16bT1(15536);// 65536-50000 = 15536 StartT1(); while(true){ ; } // end while } // end main()

Page 16: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Diagrama esquemático:

Circuito armado:

Page 17: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.2.3. Timer1: Cronometro con RTC

Este uC nos ofrece la ventaja de tener un temporizador con su oscilador independiente que puede ser utilizado como reloj en tiempo real (Real Time Clock). Para lograr esto se necesita un oscilador externo conectado entre T1OSI y T1OSO con sus correspondientes capacitores como se muestra en la siguiente imagen:

El cristal debe ser de 32.768 KHz para lograr un segundo exacto sin exceder los 16 bits. Se deben utilizar interrupciones al alcanzar un segundo para realizar los ajustes de segundos, minutos y horas en software. Otra ventaja es que se puede dormir el uC y despertarlo en cada interrupción para ahorrar energía.

Realizare un cronometro sencillo con: segundos, minutos y horas, que pueda ser reseteado con un botón, el uC dormirá mientras no pase ningún evento y despertara con interrupciones únicamente.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/17/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h>

Page 18: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

/** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ s8 String[21]; struct { u8 Hour; u8 Minute; u8 Second; } Now; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); void ResetChronometer(void); void UpdateChronometer(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INTT1Flag == 1){ Write16bT1(0x8000); // 32,768 = 1s Now.Second++; if(Now.Second == 60){ Now.Second = 0; Now.Minute++; if(Now.Minute == 60){ Now.Minute = 0; Now.Hour++; if(Now.Hour == 24) Now.Hour = 0; } } UpdateChronometer(); INTT1FlagClear(); } if(INT0Flag == 1){ ResetChronometer(); INT0FlagClear(); } } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR1 - RTC "); lcd_goto(3,1); lcd_write_pgm(" Ext OSC 32.768 KHz "); // INT0 configuration (HP allways) OpenInRC0(); INT0Enable(); INT0FEdg(); INT0FlagClear();

Page 19: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

// Interruption Configuration INTT1FlagClear(); INTT1Enable(); PEIEnable(); GIEnable(); // Timer0 RTC StopT1(); OpenRTCT1(); // As RTC // Initial value and start ResetChronometer(); Write16bT1(0x8000); // 32,768 = 1s StartT1(); while(true){ Sleep(); } // end while } // end main() void ResetChronometer(void){ Now.Hour = 0; Now.Minute = 0; Now.Second = 0; UpdateChronometer(); } void UpdateChronometer(void){ // Update data sprintf(&String[0],"%.2hhu:%.2hhu:%.2hhu",Now.Hour,Now.Minute,Now.Second); lcd_goto(4,7); lcd_write(&String[0]); }

Diagrama esquemático:

Page 20: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Circuito armado:

1.3. Timer2

Las características generales del Timer2 son:

Temporizador y Comparador.

8 bits.

2 bits de pre-escala (1:1, 1:4, 1:8 y 1:16).

4 bits de pos-escala (1:1 -> 1:16).

Interrupción al coincidir TMR2 con PR2 (Comparación).

El timer2 es mucho más fácil de trabajar que los dos anteriores, pero es algo diferente ya que la interrupción no se

genera al desbordarse de FF a 00 si no al coincidir el registro TMR2 y PR2, el cual se comprara en cada ciclo. Este

temporizador también se utiliza para el módulo CCP (PWM) o para MSSP (SPI) pero se verá en su correspondiente

capitulo.

Para configurar el timer2 se utiliza el registro T2CON donde:

Page 21: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com El diagrama de bloque de este temporizador es:

La secuencia para trabajar el Timer2 es:

Desactivar TMR2 en TMR2ON.

Si se utilizará pre-escala seleccionar la relación en T2CKPS.

Si se utilizará pos-escala seleccionar la relación en T2OUTPS.

Borrar el temporizador TMR2 y cargar el valor al que contara en PR2.

Si se utilizaran interrupciones activarlas.

Activarlo en TMR2ON para que empiece a funcionar.

1.3.1. Timer2: Generador Señal Cuadrada de 125Hz (P =8ms)

Para este ejemplo se diseñara un programa que generada una señal cuadrada de 125Hz (periodo de 8ms), utilizando el Timer2.

Para lograr esto necesitamos que el Timer2 nos genere una interrupción cada 4ms para cambiar el nivel lógico de la salida digital que se utilizara. Para lograr 4ms con un reloj interno de 32MHz se necesitan 32,000 cuentas, si utilizamos la pre-escala de 1:16 quedarían 2,000, lo que sobrepasa los 8 bits, pero podemos utilizar la pos-escala a 1:16 y se bajaría a 125 que es el valor que tenemos que cargar en PR2.

Tiempo de interrupción = 16*125*16 = 32,000 = 4ms (Fosc = 32MHz).

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

Page 22: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

/********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/19/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INTT2Flag == 1){ WriteRA5(~ReadRA5()); } INTT2FlagClear(); } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR2 - Timer "); lcd_goto(3,1); lcd_write_pgm("Square Signal -- RA5"); lcd_goto(4,1); lcd_write_pgm(" Period = 8ms "); // Digital Output OpenOutRA5(); WriteRA5(0); // Interruption Configuration INTT2FlagClear();

Page 23: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

INTT2Enable(); PEIEnable(); GIEnable(); // Timer2 StopT2(); SetPST2(3); // Prescaler 1:16 SetOUTPST2(15); // Poscaler 1:16 // Initial value and start WritePR2(125); StartT2(); while(true){ ; } // end while } // end main()

Diagrama esquemático:

Page 24: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Circuito armado:

Page 25: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.4. Timer3

Las características generales del Timer3 son:

Temporizador o Contador (utilizando T13CKI).

RTC utilizando el Oscilador externo del Timer1.

16 bits.

2 bits de pre-escala (1:1 -> 1:8).

Reloj de origen interno o externo.

Interrupción al desbordarse.

Evento especial al utilizarse con CCP.

Este temporizador es igual al timer1, incluso para trabajar como contador o RTC utiliza las funciones del mismo timer1.

Para configurar el timer1 se utiliza el registro T3CON donde:

Page 26: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com El diagrama de bloque de este temporizador es:

La secuencia para trabajar el timer3 es idéntica al timer1.

Page 27: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.4.1. Timer3: Contador de Pulsos

Utilizaremos el mismo ejemplo que el Timer1, contaremos pulsos de un interruptor con anti rebote, con y sin interrupciones.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/20/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ #define USE_INT /** VARIABLES ******************************************************/ s8 String[21]; u16 intctr = 0; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt.

Page 28: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

//Service the interrupt //Clear the interrupt flag //Etc. #ifdef USE_INT if(INTT3Flag == 1){ intctr++; } INTT3FlagClear(); #endif } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR3 - Counter "); lcd_goto(3,1); lcd_write_pgm("16b, ,WOPSA,"); lcd_goto(3,15); #ifdef USE_INT lcd_write_pgm(" INT "); #else lcd_write_pgm("WOINT "); #endif #ifdef USE_INT // Interruption Configuration INTT3FlagClear(); INTT3Enable(); PEIEnable(); GIEnable(); #endif // Timer0 Ctr StopT3(); OpenCtrT3(); CtrSyncT3(); // Like Timer0 Counter UseRWOneOPT3(); // Initial value and start #ifdef USE_INT WriteT3(65530); #else WriteT3(0); #endif StartT3(); while(true){ // Update data all time #ifdef USE_INT sprintf(&String[0],"%.5hu - %.5hu",intctr,ReadT3()); lcd_goto(4,5); #else sprintf(&String[0],"%.5hu",ReadT3()); lcd_goto(4,9); #endif lcd_write(&String[0]); } // end while } // end main()

Page 29: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Diagrama esquemático:

Circuito armado:

Page 30: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.4.2. Timer3: Temporizador de Segundos

Se realizará también un contador de segundos utilizando el Timer3 como temporizador. El único inconveniente es que la pre-escala solo llega hasta 1:8 por lo que a 32Mhz de reloj interno necesitaremos 1, 000, 000 cuentas y con 16b no se alcanza. Para solucionar esto utilizaremos un contador adicional intermedio, el cual puede ser distribuido de diferentes maneras pero para este ejemplo será: 1:8 * 50, 000 * 20 = 8, 000, 000 cuentas.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/20/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ s8 String[21]; u16 Segundos = 0; u8 t = 0; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm }

Page 31: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

#pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INTT3Flag == 1){ WriteT3(15536);// 65536-50000 = 15536 t++; if(t == 20){ t = 0; Segundos++; // Update data sprintf(&String[0],"%.5hu s",Segundos); lcd_goto(4,9); lcd_write(&String[0]); } } INTT3FlagClear(); } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR3 - Timer "); lcd_goto(3,1); lcd_write_pgm("16b (1:8*50,000*20) "); sprintf(&String[0],"00000 s"); lcd_goto(4,9); lcd_write(&String[0]); // Interruption Configuration INTT3FlagClear(); INTT3Enable(); PEIEnable(); GIEnable(); // Timer0 tmr StopT3(); OpenTmrT3(); // As timer SetPST3(3); // 1:8 UseRWOneOPT3(); // Initial value and start WriteT3(15536);// 65536-50000 = 15536 StartT3(); while(true){ ; } // end while } // end main()

Page 32: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com Diagrama esquemático:

Circuito armado:

Page 33: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

1.4.3. Timer3: Cronometro con RTC

Este temporizador también puede ser utilizado como RTC utilizando el oscilador externo del timer1. Se utilizara el mismo ejemplo que en Timer1 como cronometro pero utilizando el Timer3.

main.c

/* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/17/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "pic18f14k50_timers.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ s8 String[21]; struct { u8 Hour; u8 Minute; u8 Second; } Now; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); void ResetChronometer(void); void UpdateChronometer(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR

Page 34: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

_endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. if(INTT3Flag == 1){ WriteT3(0x8000); // 32,768 = 1s Now.Second++; if(Now.Second == 60){ Now.Second = 0; Now.Minute++; if(Now.Minute == 60){ Now.Minute = 0; Now.Hour++; if(Now.Hour == 24) Now.Hour = 0; } } UpdateChronometer(); INTT3FlagClear(); } if(INT0Flag == 1){ ResetChronometer(); INT0FlagClear(); } } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects "); lcd_goto(2,1); lcd_write_pgm(" TMR3 - RTC "); lcd_goto(3,1); lcd_write_pgm(" Ext OSC 32.768 KHz "); // INT0 configuration (HP allways) OpenInRC0(); INT0Enable(); INT0FEdg(); INT0FlagClear(); // Interruption Configuration INTT3FlagClear(); INTT3Enable(); PEIEnable(); GIEnable(); // Timer0 RTC StopT3(); OpenRTCT3(); // As RTC // Initial value and start ResetChronometer(); WriteT3(0x8000); // 32,768 = 1s StartT3(); while(true){ Sleep(); } // end while } // end main() void ResetChronometer(void){ Now.Hour = 0; Now.Minute = 0; Now.Second = 0; UpdateChronometer(); } void UpdateChronometer(void){

Page 35: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

// Update data sprintf(&String[0],"%.2hhu:%.2hhu:%.2hhu",Now.Hour,Now.Minute,Now.Second); lcd_goto(4,7); lcd_write(&String[0]); }

Diagrama esquemático:

Circuito armado:

Page 36: PIC18F14K50: Temporizadores (Timers)

Omar Gurrola 05/28/13 http://www.proprojects.wordpress.com

Referencias

Microchip, “PIC18F/LF1XK50 Data Sheet”, 2010, http://ww1.microchip.com/downloads/en/DeviceDoc/41350E.pdf