Programación Específica > Microcontroladores

 Retardos...

(1/2) > >>

eliza_marti:
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 ---;---------------------------------------------;Subrutina de temporizar 1 segundo.;---------------------------------------------;Frecuencia del cristal es 4Mhz.;La señal de entrada al TMR0 es fosc./4, o sea, 1Mhz (T= 1 useg.).;El divisor de frecuencia divide por 256, con lo que la señal de 1 Mhz se;transforma en una de 3906,25 Hz (T= 0,256 mseg.);1seg= 1000 mseg.;0,256 mseg x 3900= 998,4 mseg;El TMR0 va a contar desde 216 a 255 que son 39 impulsos de 0,256 mseg.;y esto lo va hacer 100 veces, o sea, las 3900 veces que necesito.   cuenta1   bsf    INTCON,T0IE;      activo int. timer0.  bcf    INTCON,T0IF;  poner a cero el flag del;                                                           timer0.    movlw  0d8h;      d8h= 216 decimal  movwf  TMR0;                    255 - 216 = 39.cuentaetc................ 
Gracias por leer este post... :hola: ..y si alguien me puede decir el porqué se lo agredecería muchio..bye.. :comp:  :ph34r:

eliza_marti:
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:

Huguen_aus_Tirol:
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:
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:

Huguen_aus_Tirol:
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 ---  TITLE "Temporizador general programable";; Autor:     Hugo Erhard, <hugoerhard@yahoo.de>; Inicio:    23-08-2002 ; Terminado:  25-08-2002;; Revisiones:  1.00  23-08-2002 Initial release;    1.01  25-08-2002 Se define constante para Xtal 3.57 MHz;     ;===============================================================================;;===============================================================================;  errorlevel -215, -302, -301  list p=pic16f84  include "p16f84.h"  __CONFIG 0x3FF1;;-------------------------------------------------------------------------------;  DEFINICION DE VARIABLES;  CBLOCK  0x0E;  T0_ADJ&#59; para correccion de error en timer  T0_SEG&#59; post scaler para 1 segundo  MIL50&#59; contador de 50 milisegundos  CNT_SEG&#59; contador de segundos  CNT  &#59; contador general;  ENDC;;  DEFINICION DE PINES;#DEFINE  SELECT    PORTA,0&#59; selector base de tiempo#DEFINE  START_SW  PORTA,1&#59; pulso de inicio#DEFINE  OUT      PORTA,2&#59; salida, 1 mientras temporiza#DEFINE  BUZZER    PORTA,3&#59; zumbador#DEFINE  LED      PORTA,4&#59; led;;  DEFINICION DE CONSTANTES;XTAL  EQU    .10  &#59; si usas xtal de 4 MHz declaralo aqui;   if  XTAL == .4;COUNTS  EQU    .61  &#59; 61 -> Xtal = 4 MHz // 81 -> Xtal = 3.57 MHzK_1seg  EQU    .20  &#59; 20 cuentas de 50 µseg = 1 seg;  else;COUNTS  EQU    .159&#59; 159 -> Xtal = 10 MHzK_1seg  EQU    .100&#59; 100 cuentas de 10 µseg = 1 seg;  endif;;-------------------------------------------------------------------------------;  ORG  0POR  GOTO  MAIN  &#59; reset, salto al programa principal;  ORG  4ISR  MOVWF  SAVE_W  &#59; salvo W  SWAPF  STATUS,W&#59; cargo STATUS  MOVWF  SAVE_S  &#59; y salvo  CLRF  STATUS  &#59; para asegurar que este en banco 0  BTFSC  T0IF  &#59; interrupcion de timer ?  GOTO  T0ISR  &#59; si, atiendo...INTEND  SWAPF  SAVE_S,W&#59; recupero STATUS invirtiendo nibbles  MOVWF  STATUS  &#59;   SWAPF  SAVE_W,F&#59; recupero W de esta manera para no afectar  SWAPF  SAVE_W,W&#59; los bits de STATUS  RETFIE      &#59; y salgo de interrupcion habilitandolas;-------------------------------------------------------------------------------;; T0 INTERRUPT SERVICE ROUTINE;; Cristal = 4 MHz; Ciclo = 1 µseg, prescaler = 256; TMR0 se incrementa cada 1 µseg * 256 = 256 µseg; Para llegar a 50 mseg -> 50000 µseg / 256 µseg = 195.31 -> 195 cuentas; Cargando TMR0 con 256 - 195 = 61, se genera una interrupcion cada 195; cuentas, es decir cada 195 * 256 µseg = 49.92 mseg.; Esto genera un error de 50000 µseg - 49920 µseg = 80 µseg.;; NOTA: si se utiliza un cristal de 3.579545 MHz, se tiene:;  temporizador MINUTOS cuenta cada 1.11746 minutos;  temporizador HORAS cuenta cada 1h 7' 2"; Si se utiliza este cristal, para conservar los tiempos de temporizacion,; cargar TMR0 con 81 (175 cuentas) en lugar de 61 (195 cuentas). ; Se agrega un error de 3 mseg por segundo de temporizacion.; *** VER EN DECLARACION CONSTANTES ***;; CONSTANTES PARA CRISTAL DE 10 MHz;; Cristal = 10 MHz; Ciclo = 0.4 µseg, prescaler = 256; TMR0 se incrementa cada 0.4 µseg * 256 = 102.4 µseg; Para llegar a 50 mseg -> 50000 µseg / 102.4 µseg = 488.28 -> 488 cuentas;; Me pase, puedo tener maximo 256 cuentas!!!!!!!; Probamos con temporizacion de 10 mseg = 10000 µseg:;; Para llegar a 10 mseg -> 10000 µseg / 102.4 µseg = 97.65 -> 97 cuentas;; Cargando TMR0 con 256 - 97 = 159, se genera una interrupcion cada 97; cuentas, es decir cada 97 * 102.4 µseg = 9.9328 mseg.; Esto genera un error de 10000 µseg - 9932.8 µseg = 67.2 µseg.; Este error corresponde a 67.2 µseg / 0.4 µseg = 168 instrucciones; T0ISR  if  XTAL == .4;; Se compila si se usa XTAL de 4 MHz;  NOP        &#59; este lazo genera una demora de 80 µseg  MOVLW  .15    &#59; para compenzar el error del timer  MOVWF  T0_ADJ  &#59;   GOTO  $+1    &#59; para gastar 2 ciclos ahorrando memoria  DECFSZ  T0_ADJ,1&#59;   GOTO  $-2    &#59; ;  else;; Se compila si se usa XTAL de 10 MHz (o distinto de 4 MHz OJO!!!);  GOTO  $+1    &#59; para compenzar error  GOTO  $+1    &#59;   MOVLW  .30    &#59; para compenzar el error del timer  MOVWF  T0_ADJ  &#59;   GOTO  $+1    &#59; para gastar 2 ciclos ahorrando memoria  DECFSZ  T0_ADJ,1&#59;   GOTO  $-2    &#59; ;  endif;  MOVLW  COUNTS  &#59; cargo TMR0 para N cuentas  MOVWF  TMR0  &#59;   DECF  MIL50,1  &#59;   DECFSZ  T0_SEG,1&#59; decremento post-scaler de 1 segundo  GOTO  T0END  &#59; si falta salgo;  MOVLW  K_1seg  &#59; valor de recarga de post-scaler de 1 segundo  MOVWF  T0_SEG  &#59;   DECF  CNT_SEG,1&#59; decremento contador de segundosT0END  BCF    T0IF  &#59; rehabilito interrupcion de timer  GOTO  INTEND  &#59; y salgo;-------------------------------------------------------------------------------;; Aqui salta despues de un reset, se inicializan todos los registros;MAIN  CLRF  STATUS  &#59; borro STATUS para saber como inicializo  BSF    RP0    &#59; banco 1  MOVLW  b'00000011'&#59; PORTA -> xxxOOOII  MOVWF  TRISA  &#59;   MOVLW  b'11111111'&#59; PORTB -> IIIIIIII  MOVWF  TRISB  &#59;   MOVLW  b'00000111'&#59; RB pull up enabled, x, TMR0 ck internal,   MOVWF  OPTION_REG&#59; x, prescaler to TMR0, prescaler = 256  BCF    RP0    &#59; banco 0  CLRF  PORTA  &#59; borro puerto A  MOVLW  K_1seg  &#59; inicializo base de tiempos de segundos  MOVWF  T0_SEG  &#59;   MOVLW  COUNTS  &#59; inicializo timer 0  MOVWF  TMR0  &#59;   MOVLW  b'10100000'&#59; habilito interrupciones, solo timer 0  MOVWF  INTCON  &#59; ;-------------------------------------------------------------------------------;; Lazo principal, salida permanece baja por 58 seg y alta por 2 seg; La salida se refleja en el led;MAIN_LOOP  BCF    OUT    &#59; salida en 0  BSF    LED    &#59; led apagado  MOVLW  .58    &#59; preparo demora de 58 seg  MOVWF  CNT_SEG  &#59; WAIT_LOW  TSTF  CNT_SEG  &#59;   BNZ    WAIT_LOW&#59; espero a que pasen los 58 seg  BSF    OUT    &#59; salida en 1  BCF    LED    &#59; led encendido  MOVLW  .2    &#59; preparo demora de 2 seg  MOVWF  CNT_SEG  &#59; WAIT_HIGH  TSTF  CNT_SEG  &#59;   BNZ    WAIT_HIGH&#59; espero a que pasen los 2 seg  GOTO  MAIN_LOOP&#59; y repito for ever...;  END  

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

Ir a la versión completa