Autor Tema: Timer0 Como segundero en 18f452  (Leído 5874 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado lopb

  • PIC12
  • **
  • Mensajes: 77
    • contactos lopb
Timer0 Como segundero en 18f452
« en: 20 de Diciembre de 2010, 11:32:41 »
Hola,

       Alguien sabe porque este segundero no me funciona?
necesito contar segundos con timer0 o timer3 porque los otros los tengo en uso.

#include <18F452.h>
//////// Fuses: LP,XT,HS,RC,EC,EC_IO,H4,RC_IO,PROTECT,NOPROTECT,OSCSEN
//////// Fuses: NOOSCSEN,NOBROWNOUT,BROWNOUT,WDT1,WDT2,WDT4,WDT8,WDT16,WDT32
//////// Fuses: WDT64,WDT128,WDT,NOWDT,BORV20,BORV27,BORV42,BORV45,PUT,NOPUT
//////// Fuses: CCP2C1,CCP2B3,NOSTVREN,STVREN,NODEBUG,DEBUG,NOLVP,LVP,WRT
//////// Fuses: NOWRT,NOWRTD,WRTD,NOWRTB,WRTB,WRTC,NOWRTC,CPD,NOCPD,CPB
//////// Fuses: NOCPB,EBTR,NOEBTR,EBTRB,NOEBTRB
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOOSCSEN
#FUSES NOPUT
#FUSES CCP2C1
#FUSES NOSTVREN
#FUSES NODEBUG
#FUSES NOWRTD
#FUSES NOWRTB
#FUSES NOWRTC
#FUSES NOCPB
#FUSES NOEBTR
#FUSES NOEBTRB

#use delay(clock = 20000000)
#use rs232 (baud=9600,xmit=PIN_C6,rcv=PIN_C7)

unsigned int16 seconds = 0;

#INT_RTCC                                    //Interrupt procedure
clock_isr() {                                //called every time RTCC

      ++seconds;   //Inc SECONDS counter every
                                           //76 times to keep time
}

void main() {                                //a simple stopwatch program

   setup_timer_0(RTCC_8_BIT | RTCC_INTERNAL | RTCC_DIV_256 );
   set_timer0(0);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   do {
      delay_ms(500);
      printf("%lu seconds.nr", seconds);
   } while (TRUE);
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Timer0 Como segundero en 18f452
« Respuesta #1 en: 20 de Diciembre de 2010, 11:44:10 »
Y que hace o  porque decís que no funciona?  :rolleyes:
No contesto mensajes privados, las consultas en el foro

Desconectado lopb

  • PIC12
  • **
  • Mensajes: 77
    • contactos lopb
Re: Timer0 Como segundero en 18f452
« Respuesta #2 en: 20 de Diciembre de 2010, 12:43:58 »
Y que hace o  porque decís que no funciona?  :rolleyes:
:D una masa suky, siempre estas :P
mira, me imprime esto:
38 seconds.nr
77 seconds.nr
116 seconds.nr
155 seconds.nr
194 seconds.nr
233 seconds.nr
272 seconds.nr
312 seconds.nr
351 seconds.nr
390 seconds.nr
429 seconds.nr
468 seconds.nr
507 seconds.nr
546 seconds.nr
586 seconds.nr
625 seconds.nr
664 seconds.nr
703 seconds.nr 

no se calcular? :D       

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Timer0 Como segundero en 18f452
« Respuesta #3 en: 20 de Diciembre de 2010, 13:38:45 »
El problema es que, estás trabajando con un timer a 8-bits, 256 de pre-escaler y 20MHz de Fosc. O sea, el timer interrumpe cada 13.1 ms... En cambio si trabajas con el timer a 16-bits podes hacer que interrumpa cada 1 segundo, creo que cargando el timer con 46005 da aprox. la temporización necesaria.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado lopb

  • PIC12
  • **
  • Mensajes: 77
    • contactos lopb
Re: Timer0 Como segundero en 18f452
« Respuesta #4 en: 20 de Diciembre de 2010, 14:00:32 »
El problema es que, estás trabajando con un timer a 8-bits, 256 de pre-escaler y 20MHz de Fosc. O sea, el timer interrumpe cada 13.1 ms... En cambio si trabajas con el timer a 16-bits podes hacer que interrumpa cada 1 segundo, creo que cargando el timer con 46005 da aprox. la temporización necesaria.


Saludos!
gracias suky---
va un poco lento, digamos 3 segundos maso. por interrupcion.
Como calculo eso?
plisi plisi plisi mr smookyman

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Timer0 Como segundero en 18f452
« Respuesta #5 en: 20 de Diciembre de 2010, 14:38:28 »
En el datasheet se explica, pero la formula que se puede emplear es: Temporización = (4/20MHz) . (65536-TMR0) . Divisor de Frecuencia.


Entonces TMR0 es el valor que debes cargar en el timer para que interrumpa y logres la Temporización deseada. Para más información, ejemplos, ect. utiliza el buscador, hay de todo!!!


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Simon21

  • PIC18
  • ****
  • Mensajes: 302
Re: Timer0 Como segundero en 18f452
« Respuesta #6 en: 17 de Enero de 2013, 13:46:36 »
Si cargas en el timer el valor 46005, el tiempo que tardará en desbordar
será igual a 0.9999872 seg. por lo que estaríamos cometiendo un error..

Alguien pudo hacer que el timer desborde a 1 segundo exacto ?

O a 0.5 segundos ??

En el datasheet del 18F452 no encontré la formula para calcular esto,
simplemente utilizé la misma formula que siempre venia utilizando, la misma
que escribió Suky. Temporización = (4/20MHz) . (65536-TMR0) . Divisor de Frecuencia.

Veo que en esa fórmula no se tienen en cuenta la cantidad de bits que elegimos...
« Última modificación: 17 de Enero de 2013, 13:48:50 por Simon21 »
INGENIERIA ELECTRONICA
UNIVERSIDAD TECNOLOGICA NACIONAL

Desconectado willynovi

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 546
Re: Timer0 Como segundero en 18f452
« Respuesta #7 en: 17 de Enero de 2013, 16:08:49 »
Alguien pudo hacer que el timer desborde a 1 segundo exacto ?

O a 0.5 segundos ??

Por qué necesitas 1 segundo exacto? O, con que precisión trabajas?

Supongo que es cuestión de analizar los errores y la suma de ellos.
Si me decis que tu programa es un reloj, pues con ese error acumulado en un día vas a tener 2 segundos menos.

Pero si por ejemplo usas los 0,5 segundos como refrezco de un display creo que el error no es apreciable.
Intento enseñarte a pescar, si solo quieres pescados, espera que un pescador te regale los suyos.

Desconectado Simon21

  • PIC18
  • ****
  • Mensajes: 302
Re: Timer0 Como segundero en 18f452
« Respuesta #8 en: 17 de Enero de 2013, 23:39:57 »
Es verdad willynovi, ahora bien, lo que necesito es que el programa realize una rutina
cada 5 o 10 segundos aproximadamente.. Como hago para que el timer desborde a ese tiempo??

Pregunto esto ya que de esta manera evito que entre tantas veces a la interrupcion en vano !

Gracias por las respuestas !!
INGENIERIA ELECTRONICA
UNIVERSIDAD TECNOLOGICA NACIONAL

Desconectado willynovi

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 546
Re: Timer0 Como segundero en 18f452
« Respuesta #9 en: 18 de Enero de 2013, 00:03:17 »
Si con el valor 46005 interrumpe a aprox 1 segundo, con un valor de 6945 tendria que interrumpir a 3 segundos.
Si 3 no es suficiente y quieres agregar 2 segundos mas, antes de salir de la rutina de interrupcion cargas el timer0 con 26475 y te vuelve a interrumpir en esos 2 segundos.

Lo que tienes que hacer es crear una variable que usas como flag de cuando se producen los 5 segundos, seria un contador que va de 0 a 1 y vuelve a 0. Cuando cargas el tmr0 para que interrumpa a 3 segundos lo pones en 0 y cuando interrumpe en 2 segundos lo pones a 1. Y asi en tu programa principal sabes cuando han pasado los 5 segundos.

Espero no haberte liado con el rollo  :oops:
Intento enseñarte a pescar, si solo quieres pescados, espera que un pescador te regale los suyos.

Desconectado Simon21

  • PIC18
  • ****
  • Mensajes: 302
Re: Timer0 Como segundero en 18f452
« Respuesta #10 en: 18 de Enero de 2013, 10:58:33 »
De cuantos bits configuro el timer y que preescaler decis que use ??
INGENIERIA ELECTRONICA
UNIVERSIDAD TECNOLOGICA NACIONAL

Desconectado willynovi

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 546
Re: Timer0 Como segundero en 18f452
« Respuesta #11 en: 18 de Enero de 2013, 11:10:02 »
De cuantos bits configuro el timer y que preescaler decis que use ??

Igual que como tenes hoy, hice los calculos en base a los datos que dabas mas arriba.

Citar
Si cargas en el timer el valor 46005, el tiempo que tardará en desbordar
será igual a 0.9999872 seg. por lo que estaríamos cometiendo un error..
Intento enseñarte a pescar, si solo quieres pescados, espera que un pescador te regale los suyos.

Desconectado Simon21

  • PIC18
  • ****
  • Mensajes: 302
Re: Timer0 Como segundero en 18f452
« Respuesta #12 en: 18 de Enero de 2013, 22:02:28 »
Ahora bien, una consulta...

Puedo usar el TIMER0 de manera independiente con el módulo CCP ??

La pregunta se debe a que estoy utilizando una interrupción por flanco ascendente en el
pin RC2/CCP1, y por otro lado el TIMER0, a lo que tengo entendido trabajan en conjunto.

Gracias a todos por la ayuda.
INGENIERIA ELECTRONICA
UNIVERSIDAD TECNOLOGICA NACIONAL

Desconectado Simon21

  • PIC18
  • ****
  • Mensajes: 302
Re: Timer0 Como segundero en 18f452
« Respuesta #13 en: 05 de Febrero de 2013, 09:11:34 »
Hola a todos..
Tengo un inconveniente, no me ingresa en la interrupciòn del CCP1.
El objetivo es que cada vez que se presiona un pulsador (activo por nivel
bajo) se incremente el valor de la variable que luego harà mostrar el dato
correspondiente dentro de la estructura switch.
Agradezco sugerencias del motivo porque no se incrementa dicha variable.
Les dejo el codigo a continuacion es bastante simple, no se porque no entra
dicha interrupcion. EN PROTEUS FUNCIONA A LA PERFECCION.

Saludos a todos

Código: [Seleccionar]
#include <18F452.h>

#use standard_io (A)
#use standard_io (B)
#use standard_io (C)
#use standard_io (D)

#use delay(clock=20000000)       // EL USE DELAY DEBE IR ANTES DEL INCLUDE LCD420.C YA QUE EL MISMO USA DELAYS.

#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)

#include <LCD420.C>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD, HS PARA 20 MHz
#FUSES NOPROTECT                //Código sin Protección para Lectura
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPUT                    //No Power Up Timer
 
#define SDO PIN_C5
#define SCK PIN_C3
#define SDI PIN_C4

///////////////////////////////////////////////////////////////////////////////
//////////////////////// VARIABLES GLOBALES ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
unsigned int8 vector_1 [17], vector_3 [14], vector_5 [9];      //int8 es lo mismo que int, va de 0 a 255, el signed int va desde -128 a +127
signed int8 vector_2 [4], vector_4 [72], vector_6 [21];

unsigned int16 vector_3_16[7]={0};
signed int16 vector_4_16[36]={0};

unsigned int32 vector_5_32[3]={0};
signed int32 vector_6_32[7]={0};

int1 parametros_modificados=0;

int pantalla=0;        // Utilizado para cambiar de pantalla a mostrar en el LCD
int variables_a_recibir [cantidad_datos_recibir];
int variables_a_enviar [cantidad_datos_enviar]={2, 2, 5, 5, 10, 10, 30, 0}; // Lo inicializo con los valores por defecto, en el otro programa hay que multiplicar para hacer la equivalencia a segundos!!!!
int estado_rs232=0; //Me indica el estado de la comunicacion, Finalizada=0, En curso=1
int cantidad_recibida=0;

int1 parametros_no_enviados=0;

int contador=0;      // Variable utilizada para la interrupcion por desbordamiento del timer1, el mismo desborda cada 3 segundos, por lo que debe desbordar dos veces para contar 6 seg.
int1 pedir_datos=0; // Cuando esta variable sea 1 hay que pedir datos a la otra placa (cada 6 segundos)
int1 programando_parametros=0; // Cuando esta variable sea 1, significa que se estan programando los parámetros

//*****************************************************************************************//
//     FUNCIÓNES DE INTERRUPCIÓN DEL MÓDULO CCP1 (PULSADOR CAMBIO MENU)                    //
//*****************************************************************************************//

#INT_CCP1                    // Los registros CCP son de 16Bits.
void  CCP1_int()
{
   if (pantalla < cantidad_pantallas){
      pantalla++;}

   else {
      pantalla=0;
      lcd_putc("\f");
      }
}
 
//*****************************************************************************************//
//             FUNCIÓN PARA MOSTRAR LOS DATOS SEGÚN LA PANTALLA EN EL LCD                  //
//*****************************************************************************************//

// Según el dato solicitado "pantalla", se muestra la pantalla correspondiente

void mostrar_dato()
{
   switch(pantalla){
    
      case 0: // PROGRAMACION DE PARAMETROS
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 01    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
    
      case 1: // INFORMACION GENERAL 1
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 02    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;                                      
      
      case 2: // DATOS ELECTRICOS 1
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 03    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 3: // DATOS ELECTRICOS 2
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 04    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 4: // DATOS ELECTRICOS 3
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 05    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 5: // DATOS ELECTRICOS 4
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 06    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");      
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 6: // DATOS ELECTRICOS 5
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 07    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");      
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 7: // DATOS MECANICOS 1
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 08    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 8: // DATOS MECANICOS 2
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 09    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");      
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 9: // DATOS MECANICOS 3
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 10    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");        
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 10: // DATOS MECANICOS 4
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 11    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");      
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;
      case 11: // PARADA DE EMERGENCIA !!
         lcd_gotoxy(1,1);
         printf(lcd_putc, "     Pantalla 12    ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, "PARADA DE EMERGENCIA");
         lcd_gotoxy(1,3);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");      
         lcd_gotoxy(1,4);
         printf(lcd_putc, " xxxxxxxxxxxxxxxxxx ");
         delay_ms(300);
         break;

   }
}

//*****************************************************************************************//
//                               FUNCIÓN CONTADORA DE 1 SEGUNDO                            //
//                        (Interrupcion por desbordamiento del TIMER1)                     //
//           Esta función se llamará automaticamente cada ve que el timer1 se desborde     //
//*****************************************************************************************//

#int_TIMER0        

void contadora_segundos (){     //Cada vez que pasen 3 segundos el timer0 desborda y entra en esta funcion

    contador++;
    if (contador == 2){  // Si la variable contador es igual a 2, significa que pasaron 6 segundos (ya que entro 2 veces en la interrupcion)
       contador= 0;
       pedir_datos= 1;
       } // Dentro de este if levanto la bandera enviar datos para que envie datos por rs-232

set_timer1 (6942);      // Cargandole este valor, hace que se se llame a la interrupcion cada 3 segundos, ya que el timer desborda a los 3 segundos.  
                     }  // Cierro la funcion contadora_segundos
                    
///////////////////////////////////////////////////////////////////////////////
//////////////////////// PROGRAMA PRINCIPAL ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void main(void)
{

lcd_init();        // INICIO EL LCD
delay_ms(500);     // ESPERO UN TIEMPO
lcd_putc('\f');    // LIMPIO PANTALLA
presentacion();  // Presentación en LCD.
  
// HABILITACION DE INTERRUPCIONES

//----------> Configuro el timer1 que contara los segundos <-----------------------//

setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_256 );   //TMR1 Interno y preescaler de 1:8
set_timer0 (6942);    // Cargo el timer con dicho valor para que al cabo de 500 ms desborde el timer1 y llame a la interrupcion (cada medio segundo)
enable_interrupts(int_timer0);  //Activa interrupción del timer1

//---------------------------------------------------------------------------------//

enable_interrupts (int_RDA);                  // Habilito la interrupción que se llamará cada vez que llegue un nuevo dato por RS-232
//setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);     // Configuración TMR1.
setup_ccp1(CCP_CAPTURE_FE);                   // Modo Captura. RE: Flanco Bajada (ya que activa por nivel bajo).
enable_interrupts(INT_CCP1);                  // Habilito la interrupcion del modulo CCP1 (pulsador cambio pantalla).

enable_interrupts (global);                   // Habilito todas las interrupciones

output_low(SCK); // Pongo a cero el pin SCK (usado para comunicacion SPI)

   while (1)
   {
  


mostrar_dato (); // Llamo a la funcion que mostrara los datos en pantalla segun la opcion (dentro del CCP1)

  
   }  
}


INGENIERIA ELECTRONICA
UNIVERSIDAD TECNOLOGICA NACIONAL


 

anything