• No se han encontrado resultados

Registro de configuración

In document Prog Pic Ensamblador (página 59-64)

Explicaré muy brevemente el registro de configuración del TIMER 0 llamado T0CON. Este registro controla el funcionamiento del Timer para usarse como temporizador o como contador, configura su prescaler y el número de bits a usar.

bit 7 TMR0ON: Enciende o apaga el Timer.

bit 6 T08BIT: En 1 configura el timer a 8 bits, en cero, lo configura a 16 bits.

bit 5 T0CS: En uno, selecciona al pin RA4 como entrada de eventos, en cero, selecciona al oscilador principal para el retardo.

bit 4 T0SE: Solo se usa para entrada de eventos de RA4, en uno, selecciona flanco de bajada, en cero, selecciona flancos de subida.

bit 3 PSA: En 1 no asignamos prescaler, en cero, asignamos prescaler. bits 2 a 0 TOPS: Selector de prescaler en caso de que PSA sea cero. 111 = 1:256 110 = 1:128 Prescale value 101 = 1:64 Prescale value 100 = 1:32 Prescale value 011 = 1:16 Prescale value 010 = 1:8 Prescale value 001 = 1:4 Prescale value 000 = 1:2 Prescale value

Timers

¿Qué es un Timer? Es un contador de ciclos de máquina o contador de ciclos de un oscilador externo, que al desbordarse produce una interrupción. También puede contar pul- sos externos.

¿Cómo funciona un Timer? Cuenta números del 0 al 255 cuando se configura en 8 bits (lo explico más adelante) o al 65536 en caso de configurarlo de 16 bits. Puede contar ciclos de máquina (en caso de usar el oscilador principal) o contar eventos externos (usando osciladores externos o pulsos de algún circuito externo como el famosisimo NE555, flip-flops, o simplemente botones PUSH) en un pin específico del cada timer. Cuando el timer llega a su cuenta máxima más uno (se desborda) activa una interrupción. Dicha interrupción, se puede utilizar como interrupción de alta prioridad o de baja prioridad (Ver tema configurar interrupciones).

¿Cómo usar un Timer? Antes de comenzar, vamos a definir un término que se llama prescaler, que es una división de frecuencia. Ejemplo, si tengo una frecuencia principal de 20MHz y un prescaler de 1, tengo la misma frecuencia final de 20MHz, si tengo el prescaler de 2, la frecuencia es de 10MHz, si tengo un prescaler de 4 tengo una frecuencia de 5MHz. Como se observa, el prescaler provoca que mis tiempos sean más largos y pueda alcanzar una cierta frecuencia más fácilmente.

Para utilizar el timer vamos a recurrir nuevamente al número mágico # usado en retardos, pero con una pequeña variante, que es la multiplicación por el prescaler y la posibilidad de usar 16 bits.

t=4∗presc∗(2 n −#) Fosc #=2n−( t∗Fosc 4∗presc) #=2n−(t∗48 MHz 4∗presc ) Donde:

n es el número de bits, pueden ser 8 o 16. t es el tiempo del timer.

Focs es la frecuencia del oscilador, en caso de bootloader es de 48MHz. Presc es el prescaler utilizado, este valor se puede proponer de 1 a 128.

Ejemplo 1: Realizar el cálculo del número mágico para obtener un retardo de aproxi-

madamente 1.25ms con 8 bits. Proponer el prescaler.

Solución 1: Después de varios intentos, obtuve un prescaler de 64 para un buen nú-

mero mágico no muy grande, pero tampoco muy pequeño.

#=28−(1.25ms∗48MHz 4∗64 ) #=256−(60000 256 ) #=256−243.37 #=21.62 #≈22

Este número será colocado en el registros TMR0L y colocar cero en TMR0H. En ca- so de ser un número de 16 bits, se debe de convertir en hexadecimal y el nibble alto deberá de colocarse en TMR0H y el nibble bajo deberá de colocarse en TMR0L.

¿Cómo configuro el timer? Según el registro de configuración T0CON deberemos de colocar los siguientes valores:

• Encender el timer.

• Configurarlo a 8 bits (para el ejemplo de 1.25ms). • Seleccionar el oscilador principal.

• No importan los flancos. Colocar cero. • Asignar prescaler.

• El prescaler es de 64.

El número que se debe de colocar en binario sería B'11000101' en hexadecimal nos quedaría 0xC5.

Ejemplo 2: Realizar el programa de configuración del Timer 0 a 8 bits para 1.25ms y

realizar su interrupción de alta prioridad para cambiar el estado de RC0 en este tiempo.

Solución 2: Configurar el programa con los números obtenidos anteriormente y

configurar la interrupción del TIMER0. En la subrutina ISRH colocar la instrucción BTG para cambiar el estado de RC0.

ISRH:

btfsc INTCON, TMR0IF ;compruebo que se realizó la interrupción. goto finisrh

bcf INTCON, TMR0IF ;Limpio la bandera.

btg PORTC, RC0 ;Cambio el estado del pin RC0. clrf TMR0H

call Configura_Timer ;Configuro el timer nuevamente. finisrh

retfie FAST

Configura_Puertos:

movlw H'0F'

movwf ADCON1 ;Todos los puertos como digitales. clrf TRISC ;Puerto C como salida.

clrf PORTC ;Apagamos el puerto C. return

Configura_Interrupciones:

bcf INTCON, TMR0IF ;Limpio la bandera.

bsf INTCON2, TMR0IP ;Interrupción de alta prioridad. bsf INTCON, TMR0IE ;Habilito la interrupción.

return Configura_Timer: clrf TMR0H movlw .22 movwf TMR0L movlw H'C5' movwf T0CON return main: clrf WREG call Configura_Puertos call Configura_Interrupciones call Configura_Timer bsf RCON, IPEN bsf INTCON, GIEH ciclo goto ciclo END

Como observamos en la rutina de interrupción, volvemos a configurar el Timer ya que, como mencioné anteriormente la interrupción se realiza cuando el contador vuelve a ce- ro y debemos volver a cargar el número para que cuente nuevamente el ciclo de 1.25ms.

Nota: El Timer 1 tiene una configuración muy parecida al TIMER 0, con la diferencia

que el Timer 2 puede contener un oscilador externo en RC0 y RC1 para un conteo de even- tos. Si colocamos un oscilador de baja frecuencia, podemos realizar un segundero. Reco- miendo usar el de 32KHz (32768 Hz) y cargar en TMR1H 0x80 y TMR0L 0x00. Este programa lo explicaré en la sección segundero.

Contadores

Los contadores de eventos son Timers que en vez de contar ciclos de oscilador, cuentan pulsos externos. Si contamos el número de pulsos en un segundo, tenemos un frecuenciometro; por el contrario, si queremos que a cierto número de cuentas se realice una interrupción, debemos de colocar un número en TMR0L para alcanzar dicha cuenta. En este caso, como no usamos oscilador interno, no dividimos la frecuencia en 4.

Para configurar el contador en el registro T0CON debemos de considerar lo si- guiente:

• Encender el Timer

• Configurarlo a 8 o 16 bits. • Seleccionar eventos externos. • Seleccionar el flanco del pulso.

• No asignar prescaler para tiempo real.

• El prescaler es irrelevante por que no ha sido asignado.

Por lógica digital todos los valores irrelevantes los consideramos cero. El valor obtenido con flancos de subida es 0xF8.

Ejemplo 1: Realizar un programa con TIMER0 que interrumpa al microcontrolador

cuando sea apretado 5 veces un botón en RA4. La interrupción deberá ser de alta prioridad y el flanco deberá de ser de subida y al realizarse deberá de cambiar de estado RC0 de forma repetitiva. Tomar en cuenta que RA4 no tiene resistencias de PULL-UP ni PULL-DOWN.

Solución 1: El número mágico deberá ser 251 para que cuando lleguemos a 255+1

se interrumpa el microcontrolador. El circuito externo deberá ser un push conectado a +5V con una resistencia de 1K a tierra. El nodo de la resistencia y botón, deberá ser llevado a RA4.

ISRH:

btfss INTCON, TMR0IF goto finisrh

bcf INTCON, TMR0IF ;Limpiamos la bandera btg PORTC, RC0 ;Cambiar el estado.

call Configura_Timer finisrh retfie FAST Configura_Puertos: movlw H'0F' movwf ADCON1

clrf TRISC ;Puerto C como salida clrf PORTC

setf TRISA ;Puerto A como entrada return

Configura_Interrupciones:

bcf INTCON, TMR0IF ;Limpio la bandera.

bsf INTCON, TMR0IE ;Habilito la interrupción. return Configura_Timer: clrf TMR0H movlw H'05' movwf TMR0L movlw H'F8' movwf T0CON return main: clrf WREG call Configura_Puertos call Configura_Interrupciones call Configura_Timer bsf RCON, IPEN bsf INTCON, GIEH ciclo goto ciclo

Como observamos es realmente similar a un temporizador, pero cambiando solo el número de T0CON.

Como explique anteriormente podemos desactivar la interrupción y contar el número de pulsos en 1 seg. Leemos el registro TMR0L y/o TMR0H y con eso conseguimos realizar un frecuenciometro.

In document Prog Pic Ensamblador (página 59-64)

Documento similar