.: Como hacer una temporización con el registro TMR0
El tiempo empleado en una temporización se puede calcular a partir de un ciclo de instrucción (es decir 1 instrucción por cada microsegundo, si estas trabajando con un XT de 4 Mhz), también necesitas el valor del Divisor de Frecuencia (el que seleccionabas con los Bit's PS2, PS1 y PS0), y finalmente con el complemento del valor cargado en TMR0 (es decir 255-TMR0), la ecuación que te permite realizar el cálculo es la que sigue...
Temporización = Ciclo de instrucción * (255-TMR0) * Divisor de Frecuencia
Vemos un ejemplo...???
Suponte que deseas una temporización de 10 ms (10 milisegundos), que estás trabajando con un XT de 4 Mhz, y que a demás seleccionaste como Divisor de frecuencia 256 (es decir PS2,PS1,PS0 = 1,1,1).
Pregunta... (como en el secundario...)
Cuál es el valor que se debe cargar en TMR0...???
Lo arreglaremos con un pasaje de términos...
255-TMR0 = Temporización(en microsegundos)/(1 ciclo/us * Div. de Frec.)
y reemplazando tendrás...
255-TMR0 = 10000 us/(1 ciclo/us * 256)
255-TMR0 = 10000 /(256 ciclos)
255-TMR0 = 39,0625 ciclos
255-TMR0 ~ 39 ciclos
|
Eso significa que en TMR0 deberás cargar 255-39=216 (0xD8 en hexa) y a partir de allí el TMR0 contará los 39 ciclos que faltan para desbordarse y producir la interrupción, y el tiempo que tardará en hacerlo es aproximadamente 10000 us, o sea 10 ms.
Antes de seguir, despejemos un par de dudas:
1 seg. = 1000 ms = 1000000 us y ...
1 ciclos/us es el tiempo empleado en ejecutarse una instrucción
ok..., sería bueno que me confirmes si la mayor temporización que se puede obtener haciendo uso de este registro es 0,06528 segundos, será...??? ahí queda...!!!
Lo que haremos ahora, será codificar el ejemplo visto anteriormente, pero una vez producida la interrupción encendemos un LED, luego volvemos, temporizamos 10 ms y en la próxima interrupción, lo apagamos, es decir, el LED parpadeará cada 10 ms, como es obvio, no lo vamos a notar, así que sólo lo simularemos en MPLAB, (en realidad si se nota, luego te cuento como).
Bien, el código es el siguiente...
;---------------Encabezado-------------
LIST P=16F84
#include <P16F84.INC>
;-------Configuración de puertos-------
ORG 0x00
GOTO inicio
ORG 0X04 ; Atiendo la interrupción
BTFSS PORTB,0 ; si el LED está apagado
GOTO LED ; voy a LED y lo enciendo
BCF PORTB,0 ; sino apago el LED
BCF INTCON,2 ; limpio la bandera T0IF
RETFIE ; regreso habilitando la interrupción
LED BSF PORTB,0 ; enciendo el LED
BCF INTCON,2 ; borro la bandera T0IF
RETFIE ; regreso habilitando la interrupción
inicio BSF STATUS,5 ; configurando puertos
CLRF TRISB ; puerto B es salida
MOVLW 0x07 ; cargo w con 00000111
MOVWF OPTION_REG ; el Divisor = 256
BCF STATUS,5
MOVLW 0XA0 ; cargo w con 10100000
MOVWF INTCON ; habilitamos GIE y T0IE
CLRF PORTB ; limpiamos PORTB
tiempo MOVLW 0XD8 ; cargo w con 216
MOVWF TMR0 ; lo paso a TMR0
NADA BTFSC TMR0,7 ; me quedo haciendo nada
GOTO NADA ; hasta que TMR0 desborde, y entonces
GOTO tiempo ; volveré a cargar TMR0
;------------------------------------------
END
;------------------------------------------
|
|
Aquí vamos...
ORG 0X04 ; Atiendo la interrupción
Aquí vendremos cuando se desborde el TMR0, es decir cuando se produzca la interrupción y no haremos una ISR aparte como lo hicimos anteriormente, atenderemos la interrupción directamente aquí.
El código que sigue es como dice el comentario, se trata de verificar si RB0 está a 1 (es decir si el LED esta encendido), y como de comienzo no lo está, irá a GOTO LED, ahí lo enciende, luego...
BCF INTCON,2 ; limpio la bandera T0IF
Esto es lo que debemos tener en cuenta para salir de una interrupción, borrar la bandera que indica al micro que hubo una interrupción, o nos quedaremos siempre en la rutina de servicio. Finalmente con...
RETFIE
habilitamos nuevamente la interrupción.
Pasemos ahora a la etiqueta inicio, lo primero que haremos será cambiar de banco y luego configurar el puerto B como salida, y aquí viene lo nuevo...
MOVLW 0x07 ; cargo w con 00000111
MOVWF OPTION_REG ; el Divisor = 256
Veamos que Bit's estamos configurando en OPTION_REG
Los Bit's 7 y 6 no los utilizamos por ahora, T0CS=0 (TMR0 es temporizador), T0SE=0 (no se usa), PSA=0 (Prescaler asignado a TMR0), PS2,PS1,PS0=1,1,1 (Prescaler es 256), en conclusión 00000111=0x07 y es lo que cargamos en el registro OPTION.
Ahora cambiamos de banco y habilitamos las interrupciones GIE, y en especial T0IE, que es la interrupción por desbordamiento del registro TMR0, luego...
CLRF PORTB ; limpiamos PORTB
Lo que viene ahora es preparar la temporización, y de los cálculos que hicimos debíamos cargar 216 en TMR0 y a partir de ahí esperar a que este registro se desborde y produzca la interrupción, entonces hacemos eso justamente...
tiempo MOVLW 0XD8 ; cargo w con 216 MOVWF TMR0 ; lo paso a TMR0
tiempo es la etiqueta en donde cargaré el registro TMR0 cada vez que quiera hacer una temporización, y 0xD8 es 216 en hexadecimal
NADA BTFSC TMR0,7 ; me quedo haciendo nada
GOTO NADA ; hasta que TMR0 desborde, y entonces
GOTO tiempo ; volveré a cargar TMR0
La verdad es que ya no tengo nada que hacer, sino esperar a que desborde el TMR0, así es que hice un bucle al cuete, con BTFSC TMR0,7 estas probando si el Bit7 de TMR0 está a 0, y como ya sabemos que estará a 1, pues ahí te quedas dando vueltas en ese bucle mientras el tiempo pasa, hasta que de repente se produce una interrupción, luego vas, la atiendes y cuando regresas caes en...
GOTO tiempo ; volveré a cargar TMR0
para que comiences a temporizar nuevamente, es decir recargar TMR0 con 216 para luego quedarte en el bucle a esperar la interrupción.
Ahora pasemos a lo mejor de todo esto, La simulación en MPLAB, allá vamos...
R-Luis...
<-- Anterior
Introducción
Siguiente -->
Tabla de Referencias
|