Autor Tema: ¿Timer modo Temporizador en PIC?  (Leído 3752 veces)

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

Desconectado elektronik29

  • PIC10
  • *
  • Mensajes: 18
¿Timer modo Temporizador en PIC?
« en: 16 de Agosto de 2019, 20:01:25 »
Hola a todos! soy relativamente "nuevo" en programacion de PICs y estoy trabajando con el compilador CCS y el uc 16F628A, estuve haciendo un programa guiandome de la ayuda que le brindo KILLERJC a otro post .. pero no se si lo programé mal o proteus no lo esta simulando bien, quiero salir de dudas en:

1. ¿Se puede tener el clock externo a 4MHz y aparte el clock del timer también externo a 32768 HZ? (Dos cristales externos)
2. ¿Es factible simularlo o de frente grabar el codigo en el uC y ver la salida desde el osciloscopio .

POSDATA:
El calculo fue para 20 segundos, pero en la simulacion a veces cuenta 26 y ahora 30 seg......:'(


Código: [Seleccionar]
#include <16F628A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES CPD                      //Data EEPROM Code Protected
#FUSES PROTECT                  //Code protected from reads
#FUSES MCLR
#FUSES HS
#use delay(clock=4MHz)


#DEFINE  LEDESTADO   PIN_A1
#DEFINE  ENCLAVO   PIN_A0
#DEFINE  BTN   PIN_B0

int setpoint=24576;
int CONT=0,A=0;
int8 flag;
#bit FBYN1_PRESS = flag.0

#INT_TIMER1
void  TIMER1_isr(void)
{
 
   IF(A==1){
   
      IF(CONT==1){
     
         OUTPUT_LOW(LEDESTADO);
         OUTPUT_LOW(ENCLAVO);
         SET_TIMER1(setpoint);

      }
     
      CONT++;
   
      IF(CONT>=2){
   
         CONT=0;
         A=0;
     
      }
  }
}

void main()
{
   
   SET_TRIS_A(0b00000);
   OUTPUT_LOW(LEDESTADO);
   


   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_8);   
 
   SET_TIMER1(setpoint); //24576

   SETUP_CCP1(CCP_OFF);
   SETUP_COMPARATOR(NC_NC_NC_NC);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
 
 
   while(TRUE)
   {
   
      if(!INPUT(BTN) && !FBYN1_PRESS){
   
         FBYN1_PRESS=1;
     
         OUTPUT_HIGH(ENCLAVO);
         OUTPUT_HIGH(LEDESTADO);
         A=1;
     
      }
     
      else if(FBYN1_PRESS &&INPUT(BTN)){
     
         FBYN1_PRESS=0;
      }
   }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Timer modo Temporizador en PIC?
« Respuesta #1 en: 16 de Agosto de 2019, 20:33:18 »
Citar
1. ¿Se puede tener el clock externo a 4MHz y aparte el clock del timer también externo a 32768 HZ? (Dos cristales externos)

Si, el Timer 1 posee un circuito oscilador en sus pines que te permite usar el cristal de 32K. Lo podes ver en el diagrama de bloque del Timer1.


Citar
2. ¿Es factible simularlo o de frente grabar el codigo en el uC y ver la salida desde el osciloscopio .

Esta si que no puedo asegurartelo.

Puedo ver donde esta el error. Pero antes de intentar arreglarlo, ¿podrias explicar que es lo que buscas hacer en tu programa? Su que queres una espera de 20s pero no se que queres hacer con los botones.

Desconectado elektronik29

  • PIC10
  • *
  • Mensajes: 18
Re:¿Timer modo Temporizador en PIC?
« Respuesta #2 en: 16 de Agosto de 2019, 21:38:00 »
Gracias por responder KILLERJC,

Citar
¿podrias explicar que es lo que buscas hacer en tu programa? Su que queres una espera de 20s pero no se que queres hacer con los botones.

Lo que quiero hacer es que al pulsar el botón comience en un estado alto el pin A1 durante 10 minutos, pero por ahora estoy probando con segundos, el programa va asi:

1. Pulso boton
2. Pone en alto el pin A1 durante 20 segundos (los 20 segundos los consegui a partir de la cuenta de 10 segundos con cont=0 y cont=1)
3. Despues de esos 20 segundos se apaga hasta volver a presionar el boton

No se si sea el mas "factible" estoy atento a tus sugerencias! Gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Timer modo Temporizador en PIC?
« Respuesta #3 en: 16 de Agosto de 2019, 23:06:33 »
¿Que tal algo asi?

Código: C
  1. #include <16F628A.h>
  2. #FUSES NOWDT                    //No Watch Dog Timer
  3. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  4. #FUSES CPD                      //Data EEPROM Code Protected
  5. #FUSES PROTECT                  //Code protected from reads
  6. #FUSES MCLR
  7. #FUSES HS
  8. #use delay(clock=4MHz)
  9.  
  10.  
  11. #DEFINE  LEDESTADO   PIN_A1
  12. #DEFINE  ENCLAVO   PIN_A0
  13. #DEFINE  BTN   PIN_B0
  14.  
  15. const unsigned long setpoint = 24576;
  16. int A=0;
  17. int1 FBYN1_PRESS = 0;
  18.  
  19. #INT_TIMER1
  20. void  TIMER1_isr(void)
  21. {
  22.     set_timer1(setpoint);
  23.     if(--A == 0){
  24.         disable_interrupts(INT_TIMER1);
  25.         OUTPUT_LOW(ENCLAVO);
  26.         OUTPUT_LOW(LEDESTADO);
  27.     }
  28. }
  29.  
  30. void main()
  31. {
  32.    
  33.    SET_TRIS_A(0b00000);
  34.    OUTPUT_LOW(ENCLAVO);
  35.    OUTPUT_LOW(LEDESTADO);
  36.    setup_timer_1(T1_EXTERNAL|T1_DIV_BY_8);
  37.    SETUP_CCP1(CCP_OFF);
  38.    SETUP_COMPARATOR(NC_NC_NC_NC);
  39.    enable_interrupts(GLOBAL);  
  40.  
  41.  
  42.    while(TRUE)
  43.    {
  44.  
  45.       if(!INPUT(BTN)){
  46.    
  47.          OUTPUT_HIGH(ENCLAVO);
  48.          OUTPUT_HIGH(LEDESTADO);
  49.          A=2; // 20 segundos
  50.          SET_TIMER1(setpoint); //24576
  51.          enable_interrupts(INT_TIMER1);
  52.          while(!INPUT(BTN));
  53.       }
  54.    }
  55. }

Los cambios que realice fueron los siguientes:
- Cambie el codigo de la interrupcion, unicamente cuando llega "A" a 0 es que apaga todo e incluso deshabilita la interrupcion, asi no se ejecuta mas.
- Los botones por ahora para probar (asi no entra muchas veces) le puse un while, pero basicamente carga los datos que son "A" que es el contador de veces que entra en la interrupcion y recarga el Timer1. Asi comenzar correctamente los segundos. Recien ahi habilita la interrupcion.

Observa que si se presiona de nuevo el boton estarias reiniciando esos 10s de la interrupcion, y los valores que obtendrias no serian los correctos.
Considero que uno de los problemas que tenias en tu codigo es que cuando presionas el boton no arrancas de 0 a contar, sino que si la interrupcion habia ocurrido hace 4s, vos lo activas y tenes esos 6s + las 2 interrupciones. Por lo tanto tenias esos 26s en ves de 20s. Obviamente este rango podia variar de 20s a 30s segun cuando tuvieras la suerte de apretar el boton.

Desconectado elektronik29

  • PIC10
  • *
  • Mensajes: 18
Re:¿Timer modo Temporizador en PIC?
« Respuesta #4 en: 17 de Agosto de 2019, 10:50:53 »
Gracias por corregirme KILLERJC!

Una consulta, si deseo mostrar cada valor de segundo de manera descendente por ejemplo seteo A = 2 (20 segundos) entonces quiero mostrar el valor 20, 19 , 18 , 17 ,16 , será posible con un for ? o que me recomiendas? Gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Timer modo Temporizador en PIC?
« Respuesta #5 en: 17 de Agosto de 2019, 11:13:07 »
Te recomendaria de que en ves de hacer una interrupcion cada 10s lo hagas cada 1s.

En la interrupcion no vas a mostrar nada, la interrupcion es solo para contar,mostrar solo lo vas a hacer en el main.

Desconectado elektronik29

  • PIC10
  • *
  • Mensajes: 18
Re:¿Timer modo Temporizador en PIC?
« Respuesta #6 en: 18 de Agosto de 2019, 14:51:43 »
Hola KILLERJC, de nuevo por aquí molestando estoy :D

Tengo una duda, hay alguna forma de leer el estado de un pin de salida?

Por ejemplo:

Si la salida B0 está en "1", B1 = 0, y si B0 está en "0", B1=1

Estaba probando con B1=~B0, pero ni al caso está mal :( alguna sugerencia, gracias Crack!

Desconectado elektronik29

  • PIC10
  • *
  • Mensajes: 18
Re:¿Timer modo Temporizador en PIC?
« Respuesta #7 en: 18 de Agosto de 2019, 15:16:08 »
[ACTUALIZO]

Consegui hacerlo pero en la simulacion me baja el ultimo digito del conteo

está 1 segundo el temporizador

Código: C
  1. #INT_TIMER1
  2. void  TIMER1_isr(void)
  3. {
  4.     set_timer1(setpoint);
  5.     OUTPUT_TOGGLE(A);
  6.     B=~input_state(A);
  7. }

Funciona sí, pero en el counter de Proteus,

A=1seg
B=0.99999
A=1seg
B=0.99998
A=1seg
B=0.99997
....
Y así sucesivamente  :o :o :o :o :? :? :? :? :? :? :? :-/

Algo para corregir en el código? Gracias!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Timer modo Temporizador en PIC?
« Respuesta #8 en: 18 de Agosto de 2019, 18:41:51 »
No creo que sea el codigo. Considero que esta bien.... Los errores que se pudieron haber cometido son:

- El cristal no es exacto, lo raro es que esto ocurra en una simulacion.
- Debido a que funciona con 2 cristales, existe un error ya que esta sincronizado con el reloj principal (y solo se actualiza en 2 ciclos de los 4 que ocupa el PIC), pero como la frecuencia del oscilador de 32k es muy baja comparada con la otra no deberias tener TANTOS problemas. Debido a esto deberia ser un poco mas de 1s, y no menos como presentas.