Autor Tema: otra forma de generar retardos con el Timer  (Leído 26535 veces)

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

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
otra forma de generar retardos con el Timer
« en: 25 de Abril de 2007, 15:31:38 »
Introducción:

Después de leer varios post aquí en el foro acerca del tema, es hora de tomar conciencia y avanzar en cuanto a la forma de programar.

cuando uno se inicia en el mundo de los pic´s y llega un ejemplo que involucra retardos, lo primero que se usa el método fácil: el método del retardo cíclico  (por allí leí en un libro que lo llaman: delay loop method)

les confieso que hasta hace poco creía que los timer´s eran de poco uso, que se limitaba hacer labores de conteo externo (RTCC) y que usandolo como temporizador era innecesario debido al poco tiempo generado y que para ello estaban los codigos redundantes...

pués estaba equivocado. El hecho de que con el timer no se pueda lograr tiempos largos no quiere decir que no se usará. Una cosa que debe tener en cuenta el picmaníaco a la hora de escribir un código, es saber redistribuir los procesos en el tiempo. no importa en que intervalo de tiempo los haga, pero lo importante es que logre su cometido (pensando en asm).

Esto precisamente yo lo aplicaba en ensamblador cuando requería hacer varias cosas, pero nunca se me ocurrió aplicarlo a los retardos involucrados, por supuesto que el código parecerá complicado, pero mas eficiente en su ejecución. podemos ejecutar otros procesos en vez de estar perdiendo tiempo precioso. Esto se puede dar en varios casos, como también puede ocurrir que sea mejor aplicar el otro método. ejemplos particulares.

hasta aquí la introducción...

Después de pensar hacer un ejemplo donde se involucre un retardo grande y a la vez qu el pic ejecute otros procesos, se me ocurrió este:

- se tienen 5 led´s inicialmente apagado.
- hay 5 interruptores normalmente abiertos uno para cada led.

Sn -> Ln : para todo n perteneciente a [1,5]
Sn = interruptor (n)
Ln = Led (n)

- al presionar uno de los switche, se enciende su led coterráneo ej: S1 -> L1.
- el tiempo de encendido: 2 minutos.
- se pueden presionar otros S entre retardos.
- se repite el proceso descrito.

validación:
- si L1 está encendido cuando se presiona S1, se hará caso omiso, solo hasta que L1 <- Off.
- el debounce ó antirebote estará asegurado por una bandera (flag)

posible solución:

- para el retardo de 2 minutos: el Timer1
- se hará uso de interrupciones por desbordamiento del par TMRH:TMRL.

usando una temporización de 524,2 mS interrumpiendo ó desbordandose 229 veces tenemos ~ 120 S = 2 Minutos

para configurar el timer1, podemos usar la formula T = 65536 x 8 x 4 / 4MHZ

ó

podemos usar la herramienta PicMultiCalc que ya nos dá el valor de acuerdo a nuestro cálculo



- para 'tratar' de optimizar el programa desde el punto de vista del C , se observa que se puede manejar las variables como un arreglo, ya que los interruptores y los pines de salida son contiguos. (mejor que mejor) :)

- en el bucle principal se estará preguntando por cada entrada de los Sn y a la vez el timer estará contando e interrumpiendo, en la rutina del servicio de interrupción se estará preguntando por los ~ 2 minutos necesarios para apagar el/los led(s) correspondiente(s).

esto se resuelve declarando un arreglo para los contadores de los 2 minutos y uno para la bandera.

la finalidad de las banderas es mantener la cuenta después que se activó un Sn y la de evitar reiniciar el retardo si se pulsa de nuevo Sn entre los 2 minutos

Código: C
  1. //---------------------------------------------
  2. // manejando retardos con el timer1
  3. // PalitroqueZ 25-Abr-07
  4. //---------------------------------------------
  5. #include <16F877.h>
  6.  
  7. #fuses XT,NOPROTECT,NOPUT,NOWDT,NOBROWNOUT,NOLVP,NOCPD,WRT
  8. #use delay (clock=4000000)
  9.  
  10. #byte portb=0x6
  11.  
  12. static int contador[5]; // contadores para generar los 2 minutos
  13. static int bandera;   // flag
  14.  
  15. #define bs(x) bit_test(bandera,x) //
  16. //*************************************************
  17. #INT_TIMER1  // rutina de servicio de interrupcion
  18. void mitimer(){
  19. int k;
  20.         for(k=0;k<5;k++){   // barrido
  21.                 if(contador[k]==228 && bs(k)){ // pasaron los 2 minutos?
  22.                         output_bit(48+k,0); // apaga el led correspondiente
  23.                         contador[k]=0;   // reinicia el contador
  24.                         bit_clear(bandera,k);  
  25.                         // libera el swuitche correspondiente
  26.                 }
  27.                 else{
  28.                         contador[k]++;
  29.                         // no llega a 2 minutos, continua la cuenta
  30.                         // igual cuenta si no hay pulsacion en las Sn
  31.                 }  
  32.         }
  33. }
  34. //*************************************************
  35. void main(){
  36.    int t;
  37.         set_tris_b(0x0);
  38.    set_tris_c(0b11111);
  39.    portb=0x0;
  40.    setup_timer_1(t1_internal | t1_div_by_8);
  41.    set_timer1(0);
  42.    enable_interrupts(INT_TIMER1);
  43.    enable_interrupts(GLOBAL);
  44.         while(1){ // bucle eterno
  45.                 for(t=0;t<5;t++){ // barrido
  46.                         if(input(56+t)){  // pregunta por el switche correspondiente
  47.                                 if(!bs(t)){   // para evitar reiniciar el temporizador en una cuenta
  48.                                         bit_set(bandera,t);  // se activa el flag correspondiente
  49.                                         output_bit(48+t,1); // se activa el led correspodiente
  50.                                         contador[t]=0; // se resetea el contador
  51.                                 } //fin del if2
  52.                         } // fin del if1
  53.                 } // fin del for
  54.         } // fin del while
  55. } // fin del main

como veran, estoy utilizando un timer para varios procesos, y estos procesos a su vez comparten la temporización del timer sin afectar al resto.

para aquellos que usen el Proteus, aquí va un pantallazo de simulación:


   
cabe destacar que fué montado,cronometrado y comprobado fisicamente con resultados satisfactorios
   
este es un primer intento, les invito a que participen en la creación de otros ejemplos, para que así nos vayamos ejercitando y podamos dominar este método (para los que no sabemos  :P).
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado paco1980

  • PIC16
  • ***
  • Mensajes: 129
Re: otra forma de generar retardos con el Timer
« Respuesta #1 en: 30 de Abril de 2007, 14:39:16 »
hola palitroquez.
En tu ejemplo veo como utilizas  el timer 1 como temporizador interno del pic.
Pero, ¿ como has de configurarlo si lo que pretendieras es que funcionara como contador externo asincrono, poniendole un cristal en sus pines correspondientes?
Gracias
Un saludo

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: otra forma de generar retardos con el Timer
« Respuesta #2 en: 30 de Abril de 2007, 16:49:37 »
Hola paco1980

en el ejemplo puse al timer1 a trabajar como temporizador, mediante

setup_timer_1(t1_internal | t1_div_by_8);


la idea es que realice un retardo sumando cuentas hasta los 65535*8*4/4Mhz = 0.5 segundos antes de desbordarse.


La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: otra forma de generar retardos con el Timer
« Respuesta #3 en: 02 de Mayo de 2007, 15:37:39 »
...
¿ como has de configurarlo si lo que pretendieras es que funcionara como contador externo asincrono, poniendole un cristal en sus pines correspondientes?
...

disculpa paco, no se en que planeta estaba cuando te respondí anteriormente   :z) esa parte no la ensayado todavía por la que no puedo darte una respuesta justa. lo que se, es la parte teorica que menciona la datasheet.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado paco1980

  • PIC16
  • ***
  • Mensajes: 129
Re: otra forma de generar retardos con el Timer
« Respuesta #4 en: 04 de Mayo de 2007, 06:03:10 »
pues yo lo intento y lo intento, pero no doy con la tela, y no he encontrado ningún ejemplo por acá.
Un saludo.
Nota: si consigues algo, aqui te espero. Gracias.

Desconectado zagoaristides

  • PIC12
  • **
  • Mensajes: 99
    • deportes de contacto y fitness
Re: otra forma de generar retardos con el Timer
« Respuesta #5 en: 08 de Agosto de 2007, 09:35:01 »
Muchas gracias. Lo voy a tratar de implementar en un proyectito que estoy haciendo de un sistema de control de acceso con alarma sonora y aviso sms. Un abrazo.
Nadie nació sabiendo...Que genio ese Nadie!!!

Desconectado ESTECA55

  • PIC24H
  • ******
  • Mensajes: 1404
Re: otra forma de generar retardos con el Timer
« Respuesta #6 en: 08 de Agosto de 2007, 10:35:22 »
Muy buen ejemplo PalitroqueZ!!!

Yo suelo usar siempre el Timer  para retardos y demas, es mas suelo adosarle varias cosas, pero hasta ahora venia trabajando en asembler, y estoy empezando con el C, así que me viene de 10 para ir aprendiendo a como usar C en los pic jejejeje

Gracias por el aporte

Saludos
Hay que esforzarse por ser el mejor, no creerse el mejor

Desconectado jeleee

  • PIC10
  • *
  • Mensajes: 3
Re: otra forma de generar retardos con el Timer
« Respuesta #7 en: 08 de Agosto de 2007, 16:00:45 »
  Solo una pregunta, de donde sacas el 56 y el 48?

       
Código: C
  1. if(input(56+t)){  // pregunta por el switche correspondiente                           
  2. if(!bs(t)){   // para evitar reiniciar el temporizador en una cuenta                                   
  3. bit_set(bandera,t);  // se activa el flag correspondiente                                      
  4. output_bit(48+t,1); //

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: otra forma de generar retardos con el Timer
« Respuesta #8 en: 09 de Agosto de 2007, 13:31:43 »
son los apuntadores en ccs del pin correspondiente,

48 = 6*8-> RB0
56 = 7*8-> RC0

como en C un arreglo se caracteriza por tener las direcciones contiguas, entonces para recorrer ambos puertos, bastaría:

48+t

56+t

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: otra forma de generar retardos con el Timer
« Respuesta #9 en: 10 de Octubre de 2007, 14:12:47 »
Hola PalitroqueZ. Pase el programa de c a asm. ¿Cómo? muy facil pero trabajoso. Primero copié el programa, lo abri en el Mplab, luego cree el prooyecto y una vez generado el hex, lo abrí con el ICPROG y este tiene una herramienta que lo pasa a asm (lee el hex y da el asm, obvio).
El problema que no es muy legible, ya que no da la primera columna con palabras que usa el usuario. Si alguien le interesa, lo subo al foro.

Saludos.  :-/ :-/
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado Rulo

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 168
Re: otra forma de generar retardos con el Timer
« Respuesta #10 en: 10 de Octubre de 2007, 14:46:23 »


         Tal vez ya lo sepan, pero si usan CCS una vez compilado el archivo en el menu compile se van a la opcion C/ASM List y obtienen tambien el codigo en ASM, una herramienta muy util tambien.

       

                   Saludos  :-/

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: otra forma de generar retardos con el Timer
« Respuesta #11 en: 10 de Octubre de 2007, 14:56:32 »
Rulo, y es mas potente que solo pasar de C a ASM, ya que te separa cada comando que escribiste en C y te dice el equivalente en ASM de el.

SALUDOS!!

Desconectado Rulo

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 168
Re: otra forma de generar retardos con el Timer
« Respuesta #12 en: 10 de Octubre de 2007, 15:13:49 »


       Si lo se  :mrgreen: , mi intencion es que se anime a probarlo quien no lo haya hecho, insisto, es una herramienta muy util.


            Saludos  :-/

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: otra forma de generar retardos con el Timer
« Respuesta #13 en: 10 de Octubre de 2007, 15:17:25 »
Rulo, yo tambien lo decía para los que no lo conocen..

SALUDOS!!  :-/

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: otra forma de generar retardos con el Timer
« Respuesta #14 en: 11 de Octubre de 2007, 08:29:15 »
Muy bueno!!

Yo suelo utilizar un solo timer, con una base de tiempo definida y estable, y los tiempos de cada temporizador los programo en cantidad de interrupciones de este timer. Cuando los valores programados son sobrepasados pongo en uno la banderas de cada temporizador y pongo en cero su contador.

Algo muy similar a esto pero sin utilizar un array, que es una idea muy original por cierto !! :-/
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.


 

anything