• Domingo 22 de Diciembre de 2024, 13:45

Autor Tema:  Retardos...  (Leído 5990 veces)

eliza_marti

  • Miembro MUY activo
  • ***
  • Mensajes: 267
    • Ver Perfil
    • http://www.solocodigo.com
Retardos...
« en: Martes 1 de Marzo de 2005, 02:53 »
0
Hola Chicos.. :hola: ..Sé que no me debo concentrar en esto..y que con la práctica usaré el programa de retardos.. :) ..pero siempre es bueno saber!..estaba viendo una rutina de 1seg..y me quedaron ciertas dudas..se que el valor del cristal a utilizar siempre se divide para 4 entiendo porqué perfectamente..pero ?  :unsure: ..porqué el divisor de frecuencia es 256??..a que se debe?.. :huh:
Aqui está la rutina...

Código: Text
  1. ;---------------------------------------------
  2. ;Subrutina de temporizar 1 segundo.
  3. ;---------------------------------------------
  4. ;Frecuencia del cristal es 4Mhz.
  5. ;La señal de entrada al TMR0 es fosc./4, o sea, 1Mhz (T= 1 useg.).
  6. ;El divisor de frecuencia divide por 256, con lo que la señal de 1 Mhz se
  7. ;transforma en una de 3906,25 Hz (T= 0,256 mseg.)
  8. ;1seg= 1000 mseg.
  9. ;0,256 mseg x 3900= 998,4 mseg
  10. ;El TMR0 va a contar desde 216 a 255 que son 39 impulsos de 0,256 mseg.
  11. ;y esto lo va hacer 100 veces, o sea, las 3900 veces que necesito.  
  12.  
  13. cuenta1
  14.   bsf    INTCON,T0IE;      activo int. timer0.
  15.   bcf    INTCON,T0IF;  poner a cero el flag del
  16. ;                                                           timer0.
  17.  
  18.   movlw  0d8h;      d8h= 216 decimal
  19.   movwf  TMR0;                    255 - 216 = 39.
  20. cuenta
  21. etc................
  22.  

Gracias por leer este post... :hola: ..y si alguien me puede decir el porqué se lo agredecería muchio..bye.. :comp:  :ph34r:
Conserva la Paz con tu Alma en la bulliciosa confusión de la vida, aún con toda su farsa, penalidades y sueños fallidos, el mundo es todavia Hermoso....

http]
programacion,c,c++,
C#,java,linux,videojuegos,
directX,.NET,allegro,asm,codigo
[

eliza_marti

  • Miembro MUY activo
  • ***
  • Mensajes: 267
    • Ver Perfil
    • http://www.solocodigo.com
Re: Retardos...
« Respuesta #1 en: Martes 1 de Marzo de 2005, 05:05 »
0
Yo entiendo así.. :)  Corríjanme si estoy mal…sé que cada instrucción puede tardar en ejecutarse uno o dos ciclos de reloj..(dependiendo).. :) .pero la duración de cada  ciclo de reloj puede variar dependiendo que cristal utilices u otros…por ejemplo si utilizo un cristal de 4Mhz…Quiere decir que puedo procesar 4’000000 de ciclos por segundo..que dividido para 4 me dará el valor en si del temporizador o sea 1Mhz…entonces cada ciclo de reloj me durará 1/1’000000 = 0,000001 seg. = 1useg.. o sea que para simular un retardo de 1 seg. Debo de ejecutar a lo mucho 1’000000 de ciclos (1’000000 useg)..es válida mi conclusión?... :huh: entonces porqué en algunos ejemplos se pasan de los 1’000000 useg?...no son exactos?.. :o .hay unos que son exactos y otros no?... :o
Gracias a Todos por leer… :hola: ….todas sus opiniones son bienvenidas…. ;)   :hola:  :comp:
Conserva la Paz con tu Alma en la bulliciosa confusión de la vida, aún con toda su farsa, penalidades y sueños fallidos, el mundo es todavia Hermoso....

http]
programacion,c,c++,
C#,java,linux,videojuegos,
directX,.NET,allegro,asm,codigo
[

Huguen_aus_Tirol

  • Miembro MUY activo
  • ***
  • Mensajes: 318
    • Ver Perfil
    • http://www.erhard-automation.co.cc
Re: Retardos...
« Respuesta #2 en: Martes 1 de Marzo de 2005, 07:01 »
0
Hola! Hay muchísimas formas de hacer retardos en los microcontroladores; yo personalmente uso el timer0 y obtengo bases de tiempo de, p.e., 10 mseg, 1 seg, 1 min, etc. Todo depende de que es lo que se quiera hacer.
Hacer que sea exacto quizá no debería preocuparte tanto, si tienes un error de algunos µseg cada segundo no es tan trágico. P.e., un error de 20 µseg por cada segundo (20 instrucciones, y es mucho) te da un segundo de error por cada, aprox., 14 horas!
Si solo se quiere hacer parpadear un led para indicar un estado, o algo, tal vez sea lo mismo que parpadee a 1.2 seg, 1 seg, ó a 0.95 seg :)
En este foro existen ya rutinas de tiempos hechas, si no me equivoco Jonathan ya te pasó el link. Eso te facilita el trabajo de hacerlas, pero fijate como funcionan; puedes sacar muchas cosas en claro, y que despues seguro te serviran para solucionar otros problemas ;)
Bueno, a seguir practicando, hasta que salga humo de nuestras cabezas, o del micro :D . Lo importante es aprender!

PD Jonathan, gracias por aclarar el tema del warning! Siempre había tenido la duda...

Saludos

eliza_marti

  • Miembro MUY activo
  • ***
  • Mensajes: 267
    • Ver Perfil
    • http://www.solocodigo.com
Re: Retardos...
« Respuesta #3 en: Martes 1 de Marzo de 2005, 19:23 »
0
Hola Chicos!.. :hola: ...Huguen_aus_Tirol... :o ..es verdad lo que dijiste en este foro  ya hay una explicación sobre tiempos utilizando el temporizador interno:

Retardo En 16f84

y... :D ..no estaba equivocada en lo del manejo del tiempo...

aunque todavia no entiendo muy bien el ejemplo que puse al principio.. :huh: ..

Bueno..Muchas Gracias por tu ayuda!.. ;) ..Bye!.. :hola:  :comp:  :ph34r:
Conserva la Paz con tu Alma en la bulliciosa confusión de la vida, aún con toda su farsa, penalidades y sueños fallidos, el mundo es todavia Hermoso....

http]
programacion,c,c++,
C#,java,linux,videojuegos,
directX,.NET,allegro,asm,codigo
[

Huguen_aus_Tirol

  • Miembro MUY activo
  • ***
  • Mensajes: 318
    • Ver Perfil
    • http://www.erhard-automation.co.cc
Re: Retardos...
« Respuesta #4 en: Martes 1 de Marzo de 2005, 22:08 »
0
Hola! Aca les paso un pequeño programa de ejemplo, en el que está como utilizo el timer0 para generar retardos; me funciona muy bien, tal vez no tan exacto, pero me sirve a la perfección para lo que necesito. Además me parece fácil de adaptar a cualquier necesidad de tiempos...
Usé el mismo concepto con los ST de Thompson, despues con los 16Fxx, y ahora me da excelentes resultados con los 18F.
Bueno, espero no se mareen, pero me pareció mejor darlo asi como está...
Ah, y si alguien lo entiende, le agradecería me explique como funciona!! :D  (es chiste)
Saludos y suerte

Código: Text
  1.   TITLE "Temporizador general programable"
  2. ;
  3. ; Autor:     Hugo Erhard, <hugoerhard@yahoo.de>
  4. ; Inicio:    23-08-2002
  5. ; Terminado:  25-08-2002
  6. ;
  7. ; Revisiones:  1.00  23-08-2002 Initial release
  8. ;    1.01  25-08-2002 Se define constante para Xtal 3.57 MHz
  9. ;    
  10. ;===============================================================================
  11. ;
  12. ;===============================================================================
  13. ;
  14.   errorlevel -215, -302, -301
  15.   list p=pic16f84
  16.   include "p16f84.h"
  17.   __CONFIG 0x3FF1
  18. ;
  19. ;-------------------------------------------------------------------------------
  20. ;  DEFINICION DE VARIABLES
  21. ;
  22.   CBLOCK  0x0E
  23. ;
  24.   T0_ADJ&#59; para correccion de error en timer
  25.   T0_SEG&#59; post scaler para 1 segundo
  26.   MIL50&#59; contador de 50 milisegundos
  27.   CNT_SEG&#59; contador de segundos
  28.   CNT  &#59; contador general
  29. ;
  30.   ENDC
  31. ;
  32. ;  DEFINICION DE PINES
  33. ;
  34. #DEFINE  SELECT    PORTA,0&#59; selector base de tiempo
  35. #DEFINE  START_SW  PORTA,1&#59; pulso de inicio
  36. #DEFINE  OUT      PORTA,2&#59; salida, 1 mientras temporiza
  37. #DEFINE  BUZZER    PORTA,3&#59; zumbador
  38. #DEFINE  LED      PORTA,4&#59; led
  39. ;
  40. ;  DEFINICION DE CONSTANTES
  41. ;
  42. XTAL  EQU    .10  &#59; si usas xtal de 4 MHz declaralo aqui
  43. ;
  44.  
  45.   if  XTAL == .4
  46. ;
  47. COUNTS  EQU    .61  &#59; 61 -> Xtal = 4 MHz // 81 -> Xtal = 3.57 MHz
  48. K_1seg  EQU    .20  &#59; 20 cuentas de 50 µseg = 1 seg
  49. ;
  50.   else
  51. ;
  52. COUNTS  EQU    .159&#59; 159 -> Xtal = 10 MHz
  53. K_1seg  EQU    .100&#59; 100 cuentas de 10 µseg = 1 seg
  54. ;
  55.   endif
  56. ;
  57. ;-------------------------------------------------------------------------------
  58. ;
  59.   ORG  0
  60. POR
  61.   GOTO  MAIN  &#59; reset, salto al programa principal
  62. ;
  63.   ORG  4
  64. ISR
  65.   MOVWF  SAVE_W  &#59; salvo W
  66.   SWAPF  STATUS,W&#59; cargo STATUS
  67.   MOVWF  SAVE_S  &#59; y salvo
  68.   CLRF  STATUS  &#59; para asegurar que este en banco 0
  69.   BTFSC  T0IF  &#59; interrupcion de timer ?
  70.   GOTO  T0ISR  &#59; si, atiendo...
  71. INTEND
  72.   SWAPF  SAVE_S,W&#59; recupero STATUS invirtiendo nibbles
  73.   MOVWF  STATUS  &#59;
  74.   SWAPF  SAVE_W,F&#59; recupero W de esta manera para no afectar
  75.   SWAPF  SAVE_W,W&#59; los bits de STATUS
  76.   RETFIE      &#59; y salgo de interrupcion habilitandolas
  77. ;-------------------------------------------------------------------------------
  78. ;
  79. ; T0 INTERRUPT SERVICE ROUTINE
  80. ;
  81. ; Cristal = 4 MHz
  82. ; Ciclo = 1 µseg, prescaler = 256
  83. ; TMR0 se incrementa cada 1 µseg * 256 = 256 µseg
  84. ; Para llegar a 50 mseg -> 50000 µseg / 256 µseg = 195.31 -> 195 cuentas
  85. ; Cargando TMR0 con 256 - 195 = 61, se genera una interrupcion cada 195
  86. ; cuentas, es decir cada 195 * 256 µseg = 49.92 mseg.
  87. ; Esto genera un error de 50000 µseg - 49920 µseg = 80 µseg.
  88. ;
  89. ; NOTA: si se utiliza un cristal de 3.579545 MHz, se tiene:
  90. ;  temporizador MINUTOS cuenta cada 1.11746 minutos
  91. ;  temporizador HORAS cuenta cada 1h 7' 2"
  92. ; Si se utiliza este cristal, para conservar los tiempos de temporizacion,
  93. ; cargar TMR0 con 81 (175 cuentas) en lugar de 61 (195 cuentas).
  94. ; Se agrega un error de 3 mseg por segundo de temporizacion.
  95. ; *** VER EN DECLARACION CONSTANTES ***
  96. ;
  97. ; CONSTANTES PARA CRISTAL DE 10 MHz
  98. ;
  99. ; Cristal = 10 MHz
  100. ; Ciclo = 0.4 µseg, prescaler = 256
  101. ; TMR0 se incrementa cada 0.4 µseg * 256 = 102.4 µseg
  102. ; Para llegar a 50 mseg -> 50000 µseg / 102.4 µseg = 488.28 -> 488 cuentas
  103. ;
  104. ; Me pase, puedo tener maximo 256 cuentas!!!!!!!
  105. ; Probamos con temporizacion de 10 mseg = 10000 µseg:
  106. ;
  107. ; Para llegar a 10 mseg -> 10000 µseg / 102.4 µseg = 97.65 -> 97 cuentas
  108. ;
  109. ; Cargando TMR0 con 256 - 97 = 159, se genera una interrupcion cada 97
  110. ; cuentas, es decir cada 97 * 102.4 µseg = 9.9328 mseg.
  111. ; Esto genera un error de 10000 µseg - 9932.8 µseg = 67.2 µseg.
  112. ; Este error corresponde a 67.2 µseg / 0.4 µseg = 168 instrucciones
  113. ;
  114. T0ISR
  115.   if  XTAL == .4
  116. ;
  117. ; Se compila si se usa XTAL de 4 MHz
  118. ;
  119.   NOP        &#59; este lazo genera una demora de 80 µseg
  120.   MOVLW  .15    &#59; para compenzar el error del timer
  121.   MOVWF  T0_ADJ  &#59;
  122.   GOTO  $+1    &#59; para gastar 2 ciclos ahorrando memoria
  123.   DECFSZ  T0_ADJ,1&#59;
  124.   GOTO  $-2    &#59;
  125. ;
  126.   else
  127. ;
  128. ; Se compila si se usa XTAL de 10 MHz (o distinto de 4 MHz OJO!!!)
  129. ;
  130.   GOTO  $+1    &#59; para compenzar error
  131.   GOTO  $+1    &#59;
  132.   MOVLW  .30    &#59; para compenzar el error del timer
  133.   MOVWF  T0_ADJ  &#59;
  134.   GOTO  $+1    &#59; para gastar 2 ciclos ahorrando memoria
  135.   DECFSZ  T0_ADJ,1&#59;
  136.   GOTO  $-2    &#59;
  137. ;
  138.   endif
  139. ;
  140.   MOVLW  COUNTS  &#59; cargo TMR0 para N cuentas
  141.   MOVWF  TMR0  &#59;
  142.   DECF  MIL50,1  &#59;
  143.   DECFSZ  T0_SEG,1&#59; decremento post-scaler de 1 segundo
  144.   GOTO  T0END  &#59; si falta salgo
  145. ;
  146.   MOVLW  K_1seg  &#59; valor de recarga de post-scaler de 1 segundo
  147.   MOVWF  T0_SEG  &#59;
  148.   DECF  CNT_SEG,1&#59; decremento contador de segundos
  149. T0END
  150.   BCF    T0IF  &#59; rehabilito interrupcion de timer
  151.   GOTO  INTEND  &#59; y salgo
  152. ;-------------------------------------------------------------------------------
  153. ;
  154. ; Aqui salta despues de un reset, se inicializan todos los registros
  155. ;
  156. MAIN
  157.   CLRF  STATUS  &#59; borro STATUS para saber como inicializo
  158.   BSF    RP0    &#59; banco 1
  159.   MOVLW  b'00000011'&#59; PORTA -> xxxOOOII
  160.   MOVWF  TRISA  &#59;
  161.   MOVLW  b'11111111'&#59; PORTB -> IIIIIIII
  162.   MOVWF  TRISB  &#59;
  163.   MOVLW  b'00000111'&#59; RB pull up enabled, x, TMR0 ck internal,
  164.   MOVWF  OPTION_REG&#59; x, prescaler to TMR0, prescaler = 256
  165.   BCF    RP0    &#59; banco 0
  166.   CLRF  PORTA  &#59; borro puerto A
  167.   MOVLW  K_1seg  &#59; inicializo base de tiempos de segundos
  168.   MOVWF  T0_SEG  &#59;
  169.   MOVLW  COUNTS  &#59; inicializo timer 0
  170.   MOVWF  TMR0  &#59;
  171.   MOVLW  b'10100000'&#59; habilito interrupciones, solo timer 0
  172.   MOVWF  INTCON  &#59;
  173. ;-------------------------------------------------------------------------------
  174. ;
  175. ; Lazo principal, salida permanece baja por 58 seg y alta por 2 seg
  176. ; La salida se refleja en el led
  177. ;
  178. MAIN_LOOP
  179.   BCF    OUT    &#59; salida en 0
  180.   BSF    LED    &#59; led apagado
  181.   MOVLW  .58    &#59; preparo demora de 58 seg
  182.   MOVWF  CNT_SEG  &#59;
  183. WAIT_LOW
  184.   TSTF  CNT_SEG  &#59;
  185.   BNZ    WAIT_LOW&#59; espero a que pasen los 58 seg
  186.   BSF    OUT    &#59; salida en 1
  187.   BCF    LED    &#59; led encendido
  188.   MOVLW  .2    &#59; preparo demora de 2 seg
  189.   MOVWF  CNT_SEG  &#59;
  190. WAIT_HIGH
  191.   TSTF  CNT_SEG  &#59;
  192.   BNZ    WAIT_HIGH&#59; espero a que pasen los 2 seg
  193.   GOTO  MAIN_LOOP&#59; y repito for ever...
  194. ;
  195.   END
  196.  
  197.  

© Jonathan ©

  • Moderador
  • ******
  • Mensajes: 1671
  • Nacionalidad: ar
    • Ver Perfil
    • http://www.einstec.com.ar
Re: Retardos...
« Respuesta #5 en: Miércoles 2 de Marzo de 2005, 16:18 »
0
Citar
PD Jonathan, gracias por aclarar el tema del warning! Siempre había tenido la duda...

- Hola Huguen_aus_Tirol, pues era una duda que siempre me tenia pensando, hasta que un dia se me ocurrio comenzar a experimentar y encontre que era ese el problema :D, encontre hace mucho tambien la manera de solucionar el mensaje 302, usando el codigo que pusiste mas arriba ;). Gracias por compartir tus conocimientos :) .. Suerte!!

- Eliza, veo que vas muy bien en tu aprendizaje, continua asi!! :). Saludos! :hola:
EINSTEC Tecnología «La única fuente del conocimiento es la experiencia.»

«Lo importante es no dejar de hacerse preguntas.»

eliza_marti

  • Miembro MUY activo
  • ***
  • Mensajes: 267
    • Ver Perfil
    • http://www.solocodigo.com
Re: Retardos...
« Respuesta #6 en: Miércoles 2 de Marzo de 2005, 19:38 »
0
Gracias a todos por darme de su valioso tiempo!... :hola: ...les cuento que ya descubrí lo del dividor de frecuencia del principio.. :D ..miren..

Tanto el Temporizador principal, TMR0, como el Perro guardián, WDT, a veces precisan controlar tiempos largos y aumentar la duración de los impulsos de reloj que les incre-mentan o decrementan. Para cubrir esta necesidad, se dispone de un circuito programa-ble llamado Divisor de frecuencia que divide la frecuencia utilizada por diversos rangos para poder realizar temporizaciones más largas.

El Divisor de frecuencia puede aplicarse a uno de los dos temporizadores, al TMR0 o al WDT. Con el Temporizador principal actúa en primer lugar, o sea. los impulsos pasan primero por el Divisor de frecuencia y, una vez aumentada la duración de los últimos, se aplican a TMR0. Actúa como Divisor previo o "Prescaler". Con el Perro guardián, el Divi-sor de frecuencia actúa después ("Post-scaler").

El Divisor de frecuencia puede actuar al ritmo de una señal externa aplicada sobre la pati-ta T0CKI, o bien, con la señal de reloj interna del microcontrolador CLKOUT, procedente del oscilador propio. Mediante algunos bits del Registro de opciones y la Palabra de con-figuración se controla el trabajo del Divisor de frecuencia sobre el TMR0 o el WDT.

por eso:..antes del codigo que puse al inicio iba:  :rolleyes:

Código: Text
  1. ;------------------------------------------
  2. ;Configurar el TMR0 (contador).
  3. ;------------------------------------------
  4.  
  5. bsf  STATUS,RP0;  banco1
  6. movlw  87h;               Divido la frecuencia entre 256 po-
  7. ;      niendo PS0,PS1 y PS2= 1; PSA= 0
  8. ;      asigno el divisor de frecuencia a
  9. ;      MR0; T0SE= 0 flanco ascendente;
  10. ;      T0CS= 0 pulsos de reloj interno de
  11. ;      f= fosc./4; INTEDG:= 0 flanco des-
  12. ;      cendente (no usada la /int);
  13. ;      /RBP0= 1 desactivadas (no usadas las
  14. ;      resistencias pull-up puerta B).
  15. movwf  OPTION_REG
  16.  
  17. bcf  STATUS,RP0;  banco0
  18.  


que es donde se pone el divisor de frecuencia.. :D ..
Ahora entiendo perfectamento todo sobre tiempos... :D   :P

Bueno de Nuevo Muchas Gracias!.. :)  :hola: ..bye...
Conserva la Paz con tu Alma en la bulliciosa confusión de la vida, aún con toda su farsa, penalidades y sueños fallidos, el mundo es todavia Hermoso....

http]
programacion,c,c++,
C#,java,linux,videojuegos,
directX,.NET,allegro,asm,codigo
[