Práctica TIM: Timers 1. Objetivos Familiarizarse con el manejo de los timers en 167. Filtrado de rebotes utilizando funciones de retardo. 2. Trabajo previo Realizar un pseudocódigo para el programa del apartado 6 3. Programa ejemplo Crear una nueva carpeta en el directorio de trabajo. Volcar al directorio de trabajo los ficheros la página web (Proyecto TIM) http:// www.iit.upco.es/˜cesar/timer Hacer doble click sobre el icono: timer.Uv2 Ejecutar en tarjeta. 4. Ejemplo de función de retardo Una forma sencilla de comprobar el funcionamiento de un timer es cambiar el estado de unos leds cada vez que el timer rebosa. El proyecto “timer” ofrece un ejemplo de función de retardo que se puede utilizar para realizar labor anteriormente indicada. La función retardo: $nonsegmented $include (reg167.inc) ej ini ini ej section code at 0H proc NEAR jmp progra endp ends ej1 progra section code at 300H proc NEAR diswdt mov mov DP2,#0ffffh P2,#0 ; disable watchdog mov mov r4,#0 r5,#6 call xor jmpr retardo P2,#0ffffh cc_uc,bucle ; Diodos encendidos ; Valor de cuenta ; Valor de preescalado bucle: retardo: ; En r4 <- valor de cuenta ; en r5 <- valor de preescalado push mov r0 T01CON,r5 1 mov mov mov or T0REL,#0 T0,r4 r0,#0x40 T01CON,r0 mov and jmpr r0,T0IC r0,#0x80 cc_eq,noreb mov cpl and mov cpl and pop ret r0,#0x40 r0 T01CON,r0 r0,#0x80 r0 T0IC,r0 r0 ; Arranca el timer noreb: ; Para el timer ; Borra el flag de rebose recibe dos parámetros en sendos registros (r4 y r5). Estos parámetros se utilizan para programar el timer0 del procesador. La función arranca el timer, y espera a que este rebose. El programa principal utilizará esta función cada vez que quiera realizar un retraso (suspender su ejecución durante un tiempo definido). Dos notas importantes con respecto a la realización de la función: La función ha sido realizada de forma que el programa principal (para provocar un retraso) no necesita conocer los detalles del manejo del timer0: registros de programación. Estos detalles están “encapsulados” en el código de la función (norma: realizar funciones genéricas y reutilizables). La programación de los registros del timer se ha realizado utilizando máscaras para poner/borrar bits de forma selectiva. El 167 tiene instrucciones especı́ficas a nivel de bit que hacen que este tipo de funciones resulten más fáciles de realizar (y de depurar). La desventaja es que estas funciones no son directamente portables a un procesador que no disponga de instrucciones a nivel de bit. Utilizando instrucciones a nivel de bit la función de retado queda como sigue: retardo: ; En r4 <- valor de cuenta ; en r5 <- valor de preescalado push mov mov mov bset r0 T01CON,r5 T0REL,#0 T0,r4 T0R jnb T0IR,noreb bclr bclr pop ret T0R T0IR r0 ; Arranca el timer noreb: ; Para el timer ; Borra el flag de rebose La sencillez de la función ası́ escrita es evidente. Los proyectos incluidos en la página WEB (timer y timerb) proporcionan ambos ejemplos. Comprobar el correcto funcionamiento de ambos ejemplos en tarjeta. 5. Ejemplo timer en lenguaje C En este apartado presentamos la función de retardo en lenguaje C. No es necesario probarla, se presenta únicamente a modo informativo. La función que presentamos a continuación hace uso de máscaras, aunque el compilador KEIL para 167 permite realizar esta función utilizando instrucciones a nivel de bit. 2 #include <reg167.h> void retraso(int cuenta, int preesc) { T0REL = 0; T0 = cuenta; T01CON = preesc; T01CON = T01CON | 0x40; // arranca timer while (!(T0IC & 0x80)); T0IC = T0IC & 0x7f; T01CON = T01CON & 0xbf; // bucle de espera de rebose // borra flag de rebose // para el timer } void main(void) { DP2 = 0xffff; P2 = 0; while(1) { retraso(0x0,0x6); P2 = P2 ˆ 0xffff; } } 6. Ejercicio: “rota luz” Haciendo uso de la subrutina del ejercicio anterior, escribir un programa que “rote” una luz del puerto P2 a ritmo de rebose de timer. El programa comienza encendiendo el diodo conectado a la lı́nea menos significativa del puerto P2. Cuando el timer rebosa la luz se desplaza a la posición adyacente. Con sucesivos reboses se va desplazando hacia posiciones más significativas. Cuando la luz está en la posición más significativa y se produce un nuevo rebose, la luz pasa a la posición menos significativa del puerto P2. El proceso se repite indefinidamente. La frecuencia a la que se desplaza la luz (8 bits más altos del valor de la cuenta a efectuar en el timer0) se obtienen de los interruptores conectados al puerto P2 (parte alta). Trabajo previo: Pseudocódigo C del programa “rota luz”. 7. Ejercicio opcional: Contador sin rebotes Preparar un contador de 8 bits, con salida por puerto 2 parte baja, y con entrada la lı́nea P2.8. El contador se incrementa cada vez que esta lı́nea pasa de 0 a 1. El programa se elaborará en dos fases: Sin filtrado de rebotes. Cada vez que se acciona el interruptor conectado a una lı́nea de entrada, el contador se incrementará en varias unidades. Introducir un retado para evitar que el procesador capture los rebotes en la lı́nea de entrada. Implantar el software necesario para que el contador incremente únicamente en las transiciones de 0 a 1 (no incrementa en las de 1 a 0). ¿Es necesario introducir un filtrado de rebotes en las transiciones de 1 a 0? 3