TEMPORIZADORES DEL 80C31 1. INTRODUCCION En estas notas se examinan los temporizadores del 80C31. Se inicia con una simplificada vista de los temporizadores como ellos son comúnmente usados con microprocesadores o microcontroladores. Un temporizador es una serie de flip-flops divisores por dos que reciben una señal de entrada como una fuente de reloj. El reloj se aplica al primer flip-flop, el que divide a la frecuencia del reloj por 2. La salida del primer flip-flop sirve de reloj del segundo flip-flop, el que también divide por 2, y así sucesivamente. ya que cada etapa sucesiva divide by 2, un temporizador con n etapas divide a la frecuencia de la entrada de reloj by 2n. la salida de la última etapa funciona como reloj del flip-flop con la bandera que indica el desborde del temporizador, la cual es probada por el software o genera una interrupción. El valor binario en los flip-flops del temporizador pueden tomarse como un "conteo" del número de pulsos de reloj (o " eventos") ya que el temporizador fue arrancado. Un timer de16 bits, por ejemplo, contaría desde 0000H hasta FFFFH. La bandera de desborde se hace “1” en el desborde del contador de FFFFH a 0000H. La operación de un temporizador simple se ilustra en la Figura 1 para un timer de 3 bits. Cada etapa se muestra como un flip-flop tipo D disparado por flanco negativo operando en el modo de división por dos (i.e., la salida se conecta a la entrada D ). El flip-flop de bandera es simplemente un candado tipo D, que se hace “1” por la última etapa del timer. Es evidente en el diagrama de tiempos en la Figura 1b que la primera etapa (Q0) conmuta a una frecuencia 1/2 de la del reloj, la segunda etapa a 1/4 la frecuencia del reloj, y así sucesivamente. El conteo se exhibe en decimal, y es verificado fácilmente al examinar el estado del los tres flip-flops. Por ejemplo, el conteo "4" ocurre cuando Q0, = 1, Q1, = 0, y Q2,= 0 (410 = l002). Los temporizadores son usados en virtualmente todas las aplicaciones orientadas al control, y los temporizadores del 8051 no son la excepción. hay dos temporizadores de 16-bit cada uno con cuatro modos de operación. Un tercer temporizador de 16-bits con tres modos de operación se añadió al 8052. Los temporizadores se usan para (a) intervalos de tiempo, (b) conteo de eventos, o (c) generación de baud rates para el puerto serial. Cada uno es un timer de 16 bits, por tanto, la 16ava o última etapa divide la frecuencia de la entrada de reloj por 216 = 65,536. En aplicaciones de intervalos de tiempo, un temporizador se programa para desbordarse a un intervalo regular y hacer “1” a la bandera de desborde del temporizador. la bandera es usada para sincronizar al programa para llevar a cabo una acción tal como cotejar el estado de una entrada o de envío de datos hacia las salidas. Otras aplicaciones pueden usar los pulsos regulares del temporizador para medir e tiempo transcurrido entre dos condiciones (e.g., medición del ancho de un pulso). Fig. 1 Temporizador de tres bits a) Diagrama b) Señales en el tiempo. Profr. Salvador Saucedo 1 El conteo de eventos se usa para determinar el número de ocurrencias de un evento, más que el medir el lapso de tiempo entre eventos. Un "evento" es cualquier estímulo externo que provee una transición 1 a 0 a la pata del chip 80C51. Los temporizadores pueden también proveer los relojes del baud rate para el puerto interno serial del 80C51. Los temporizadores del 8051 se acceden usando seis registros especiales de función. (Ver Tabla 1.) Un 5○ SFR adicional proporciona acceso al tercer temporizador en el 8052. 2 REGISTRO de MODOS del TEMPORIZADOR (TMOD) El registro TMOD contiene dos grupos de cuatro bits que fijan el modo de operación par el Temporizador 0 y el Temporizador 1. (Ver Tabla 2 y Tabla 3.) TMOD no es bit-direccionable, ni necesita serlo. Generalmente, el es cargado una vez por el software al inicio de un programa para iniciar el modo del temporizador . En lo sucesivo, el temporizador puede ser parado, arrancado, y así na y otra vez al acceder a otros SFRs del temporizador. Tabla 1. Registros de Función Especial de los Temporizadores SFRs del Timer TCON TMOD TL0 TL1 TH0 TH1 PROPOSITO Control Modo Temporizador Temporizador Temporizador Temporizador DIRECCION 88h 89h 8Ah 8Bh 8Ch 8Dh 0 Byte bajo 1 Byte bajo 0 Byte alto 1 Byte alto BIT DIRECCIONABLE Si No No No No No Tabla 2 Resumen del registro TMOD BIT 7 NOMBRE GATE TEMPORIZADOR 1 6 C/ T 1 5 4 3 2 M1 M0 GATE C/ T 1 1 0 0 1 0 M1 M0 0 0 DESCRIPCION Bit de compuerta. Si es “1” el temporizador sólo corre cuando INT 1 está en alto Bit selector Contador/Temporizador “1” = Contador de Eventos “0” = Intervalo de Tiempo Bit 1 del modo (ver tabla 3) Bit 0 del modo (ver tabla 3) Bit de compuerta del temporizador 0 Bit selector Contador/Temporizador del temporizador 0 Bit 1 del modo de temporizador 0 Bit 0 del modo de temporizador 0 Tabla 3 Resumen de modos del temporizador M1 0 0 1 1 3. M0 0 1 0 1 MODO 0 1 2 3 DESCRIPCION Modo de 13 Bits (modo 8048) Modo de 16 Bits Modo 8 Bits con auto recarga Modo partido: Temporizador 0: TL0 es un temporizador de 8 bits fijado por bits de modo del temporizador 0. TH0 es un temporizador de 8 bits fijado por bits de modo del temporizador 1. REGISTRO de CONTROL del TEMPORIZADOR (TCON) El registro TCON contiene bits de estatus y de control para el Temporizador 0 y para el Temporizador 1 (ver Tabla 4). Los cuatro bits superiores en TCON (TCON.4 a TCON.7) se usan para apagar y encender los temporizadores (TR0, TR1), o para señalar el desborde de un temporizador (TF0, TF1). Profr. Salvador Saucedo 2 Tales bits se usan extensivamente en los ejemplos en estas notas. Los cuatro bits más bajos en TCON (TCON.0 a TCON.3) no tienen nada que hacer con los temporizadores. Ellos se usan para detectar e iniciar interrupciones externas. La discusión de esos bits se hizo en las notas del puerto serial. Tabla 4 Resumen del registro TCON (Control del Temporizador) BIT TCON.7 NOMBRE TF1 DIRECC. BIT 8FH TCON.6 TR1 8EH TCON.5 TF0 8DH TCON.4 TR0 8CH TCON.3 IE1 8BH TCON.2 TCON.1 TCON.0 IT1 IE0 IT0 8AH 89H 88H DESCRIPCION Bandera de deborde del temporizador 1. El hardware la hace “1”, el software la hace “0” o el hardware cuando salta a rutina de servicio a interrupción. Bit de Control del Temporizador 1 “1” = Enciende al timer “0” = Apaga al timer Bandera de deborde del temporizador 0. El hardware la hace “1”, el software la hace “0” o el hardware cuando salta a rutina de servicio a interrupción. Bit de Control del Temporizador 0 “1” = Enciende al timer “0” = Apaga al timer Bandera de flanco de interrupción externa 1. El hardware la hace “1” al detectar flanco negativo en INT 1 , el software la hace “0” o el hardware cuando salta a rutina de servicio a interrupción. Bandera de tipo de interrupción externa 1. Bandera de flanco de interrupción externa 0. Bandera de tipo de interrupción externa 0. 4 MODOS del Temporizador y bandera de Desborde Cada temporizador se discute a continuación. Ya que hay dos temporizadores en el 80C51, la notación "x" se usará para implicar ya sea al Temporizador 0 o al Temporizador 1; o sea. "THx" significa bien TH1 o TH0 dependiendo del timer. El arreglo de registros de temporizador TLx y THx y de banderas de desborde de temporizador TFx se muestran en la Figura 2 para cada modo. 4.1 Modo Temporizador de 13 Bits (Modo 0) El modo 0 es un temporizador en modo de 13-bit que provee compatibilidad con el predecesor del 8051, el microcontrolador de INTEL, el 8048. Este modo no es generalmente usado en diseños nuevos. (ver Figura 2a.) El byte alto del temporizador (THx) se pone en cascada con los cinco bits menos significativos del byte bajo (TLx) del temporizador para formar un timer de 13 bits. Los tres bits altos de TLx no se usan. Profr. Salvador Saucedo 3 Fig. 2 Modos de operación de los temporizadores. 4.2 Modo Temporizador de 16 Bits (Modo 1) El modo 1 es un temporizador en modo de 16 bits y es como el modo 0, excepto que el temporizador está operando como un timer completo de 16 bits. El reloj se aplica a los registros alto y bajo combinados del temporizador (TLx/THx). A medida que los pulsos del reloj son recibidos, la cuenta del temporizador sube: 0000H, 0001H, 0002H, etc. Un desborde ocurre en la transición FFFFH a 0000H del conteo y hace “1” la bandera de desborde del temporizador. El temporizador continúa el conteo. La bandera de desborde es el bit TFx en TCON que es leído o escrito mediante software. (ver Figura 2b.) El bis más significativo (MSB) del valor en los registros del temporizador es THx bit 7, y el bit menos significativo (LSB) es TLx bit 0. El LSB conmuta con una frecuencia igual a la entrada de reloj dividida por 2, mientras el MSB conmuta a una frecuencia igual a la entrada de reloj dividida por 65,536 (i.e.. Profr. Salvador Saucedo 4 216). Los registros del temporizador (TLx/THx) se pueden leer o escribir en cualquier tiempo por el software. 4.3 Modo de 8 Bits con Auto Recarga (Modo 2) El modo 2 es de 8 bits con auto recarga. El byte bajo del temporizador (TLx) opera como un temporizador de 8 bits mientras el byte alto del temporizador (THx) guarda el valor de recarga. Cuando el contador se desborda desde FFH a 00H, no sólo es la bandera del temporizador que se hace “1”, sino que el valor en THx es cargado en TLx; el conteo continúa desde este valor up hacia arriba hasta la siguiente transición de FFH a 00H, y así indefinidamente. Este modo es conveniente, ya que el temporizador se desborda a intervalos específicos, periódicos, una vez que TMOD y THx han sido iniciados. (ver Figura 2c.) 4.4 Modo de Temporizador partido (Modo 3) El modo 3 es el temporizador partido y es diferente para cada timer. El temporizador 0 en modo 3 es partido en dos temporizadores de 8 bits. TL0 y TH0 actúan como temporizadores separados con desbordes que hacen “1” los bits TF0 y TF1 respectivamente. El temporizador 1 se detiene en modo 3, pero puede ser arrancado al ponerlo en uno de los otros modos. La única limitación es que la bandera de desborde usual del Temporizador 1. TF1, no es afectada por los desbordes del Temporizador 1, ya que éste está conectado a TH0. El modo 3 brinda esencialmente un timer extra de 8 bits: El 8051 parece tener un tercer timer. Cuando el temporizador 0 está en modo 3, el temporizador 1 puede detenerse y arrancarse al conmutarlo de su propio modo 3. El puede todavía ser usado por el puerto serial como un generador de baud rate, o él puede usarse en cualquier manera que no requiera interrupciones (ya que no está más conectado a TF1). 5 Fuentes de Reloj La figura 2 nos muestra como los temporizadores son excitados. Hay dos posibles fuentes de reloj, seleccionadas al escribir al bit contador/temporizador (C/ T ) en TMOD cuando el temporizador es iniciado. Una fuente de reloj es usada para producir intervalos de tiempo, la otra para contar eventos. 5.1 Generación de Intervalos de Tiempo Si C/ T = 0, la operación continua del temporizador es seleccionada y el temporizador es avanzado desde el oscilador interno. Una etapa para dividir por 12 se agrega para reducir la frecuencia de reloj a valores razonables para la mayoría de las aplicaciones. Cuando la operación continua del temporizador es seleccionada, el temporizador se usa para producir intervalos regulares de tiempo. Los registros del temporizador (TLx/THx) incrementan a una tasa de 1/12avo la frecuencia del oscilador interno: entonces, un cristal de 11.0592 MHz producirá un reloj de 921,600 Hz. Los desbordes del Temporizador ocurren tras un número fijo de pulsos del reloj, dependiendo en el valor inicial cargado en los registros del temporizador, TLx/THx. Fig. 3 Fuentes de señales de Reloj para el timer. Profr. Salvador Saucedo 5 5.2 Conteo de Eventos Si C/ T = 1, el temporizador es avanzado desde una fuente externa. En la mayor parte de las aplicaciones, tal fuente externa suministra al temporizador con un pulso por la ocurrencia de un "evento” ya que temporizador está contando eventos. El número de eventos está determinado en software al leer los registros del temporizador TLx/THx, ya que los valores de 16 bits en tales registros se incrementan en la unidad por cada evento. La fuente externa de reloj llega a través de las patitas de las funciones alternativas del puerto 3. El bit 4 del puerto 3 (P3.4) sirve como la entrada externa de reloj para el temporizador 0 y es denotada por "T0" en este contexto. P3.5, o "T1", es la entrada externa de reloj para el temporizador 1. (ver Figura 3). En aplicaciones de conteos, los registros del temporizador se incrementan en respuesta a una transición de 1 a 0 en la entrada externa. Tx. La entrada externa es muestreada durante S5P2 de cada ciclo de máquina; luego, cuando la entrada exhibe un “1” en un ciclo y un “0” en el siguiente, el contador es incrementado. El nuevo valor aparece en los registros del temporizador durante S3P1 del ciclo que sigue a aquél en que la transición es detectada. Ya que toma dos ciclos de máquina (2.17 μs) el reconocer una transición de 1 a 0, la frecuencia máxima externa es 460 kHz (asumiendo una operación de 11.0592 MHz). 6. Arrancando, Deteniendo y Controlando los Temporizadores La figura 2 ilustra las varias configuraciones para los registros TLx y THx del temporizador, y las banderas, TFx, de desborde del temporizador. Las dos posibilidades para avanzar los temporizadores se muestran en la figura 3. Ahora se demostrará como arrancar, parar, y controlar a los temporizadores. El método más simple para arrancar y parar los temporizadores es con el bit de control de corrida, TRx, en TCON. TRx es limpiado tras un reset del sistema; ello es, los temporizadores se deshabilitan (parados) por default. TRx se hace “1” mediante software para echar a volar los temporizadores (ver figura 4). Ya que TRx está en el registro bit-direccionable TCON, es fácil arrancar y detener los temporizadores dentro de un programa. Por ejemplo, el temporizador 0 es arrancado mediante SETB TR0 y detenido mediante CLR TR0 El ensamblador llevará a cabo la necesaria conversión simbolica de "TR0” a la dirección correcta del bit. SETB TR0 es exactamente lo mismo que SETB 8CH. Fig. 4. Deteniendo y corriendo un Temporizador. Otro método para controlar los timers es con el bit GATE en TMOD y la entrada externa INTx . Haciendo GATE = 1 permite al timer ser controlado mediante INTx . ello es útil para medir ancho de Profr. Salvador Saucedo 6 pulsos como sigue. Asumir que INT 0 es bajo pero pulsará alto por un periodo de tiempo a ser medido. Iniciar al Timer 0 para modo 2, modo timer de 16-bit, con TL0/TH0 = 0000H, GATE = 1, y TR0 = 1. Al subir INT 0 , el timer es "permitido" y es avanzado a una tasa de 921.6 kHz. Al bajar INT 0 , el timer es "detenido" y la duración del pulso en microsegundos es el conteo en TL0/TH0 multiplicado por 1.085. ( INT 0 Puede ser programado para generar una interrupción cuando ella retorne a “0”). Para completar el cuadro, la figura 5 ilustra al Timer 0 operando en modo 1 como un timer de 16 bits. Así como los registros TL0/TH0 del timer y a la bandera de desborde TF0, el diagrama muestra las posibilidades para las fuentes de reloj y para arrancar, detener, y controlar el timer. Fig. 5. Temporizador 0 en el modo 1. 7 Inicializando y Accesando los Registros del TIMER Los timers son usualmente iniciados una vez al comienzo de un programa para fijar el modo correcto de operación. En lo sucesivo, dentro del cuerpo de un programa, los timers se arrancan, detienen, lo bits de bandera se prueban y limpian, los registros del temporizador son leídos o actualizados, etc., como requiera la aplicación. TMOD es el primer registro iniciado, ya que él fija el modo de operación. Por ejemplo, la siguiente instrucción inicia al Timer 1 como un timer de 16-bits (modo 1) avanzado por el oscilador interno (intervalo de tiempo): MOV TMOD, #00010000B El efecto de tal instrucción es hacer M1 = 0 y M0 = 1 para modo 1, deja a C/ T = 0 y GATE = 0 para emplear el reloj interno, y limpiar los bits de modo del Timer 0. (Ver Tabla 2). Por supuesto, el timer realmente no empieza a correr hasta que su bit de control de corrida, TR1, es puesto a “1”. Si un conteo inicial es necesario, los registros del timer TL1/TH1 deben también ser inicializados. Recordando que los timers cuentan de modo ascendente y hacen “1” a la bandera de desborde en una transición de FFFFH a 0000H, un intervalo de 370 μs debe programarse inicializando TL1/TH1 a 341 cuentas menos que 0000H. El valor correcto es -341 o FEABH. Las siguientes instrucciones hacen la tarea: MOV MOV TL1, #0ABH TH1, #0FEH ; = FEABH = 65,195 El timer es entonces arrancado al poner el bit de control de corrida como sigue: Profr. Salvador Saucedo 7 SETB TRl La bandera de desborde es automáticamente puesta a “1” 370 μs más tarde. El software puede holgar en un "lazo de espera" por 370 μs usando una instrucción booleana de brinco condicional que retorna a si misma en tanto la bandera d desborde no se haga “1”: WACHA: JNB TF1, WACHA Cuando el timer se desborda, es necesario parar el timer y limpiar la bandera de desborde con software: CLR CLR TR1 TF1 ; lo detiene ; limpia bandera 7.1 Leyendo un Timer "en caliente" En algunas aplicaciones, es necesario leer el valor en los registros del timer "en caliente". Existe un problema potencial que es simple protegerse contra él en software. Dado que dos registros del timer deben ser leídos, un "error de fase " puede ocurrir si el byte bajo se desborda en el byte alto entre las dos operaciones de lectura. Un valor que nunca se tuvo puede ser leído. La solución es leer el byte alto primero, luego el byte bajo, y entonces leer el byte alto otra vez. Si el byte alto ha cambiado, repetir las operaciones de lectura. Las instrucciones siguientes leen los contenidos de los registros TL0/TH0 del timer en los registros R6/R7, lidiando correctamente con tal problema. REPITE: MOV MOV CJNE MOV A,TH0 ; Lee byte alto R6,TL0 A,TH0, REPITE R7,A Ejemplo 1 Generación de un tren de Pulsos a 38.5 kHz con 41% de Duty El siguiente programa crea quince pulsos con periodo de cada onda igual a 26 μs usando sólo software. En el campo de comentarios para cada instrucción se colocó el número de ciclos de máquina que toma la instrucción. Al sumar los ciclos se obtiene que el periodo de la onda consta de 24 ciclos de máquina, diez de ellos en alto y 14 en bajo. Como cada ciclo de máquina dura 1.085 μs, el periodo es igual a 26.04 μs, o sea 38.4 kHz. Se supone un cristal de 11.0592MHz. MOV ACALL NOP ... LAZO: SETB ACALL CLR NOP NOP ACALL DJNZ RET R2,#15 LAZO P1.0 DOS P1.0 DOS R2,LAZO DOS: MOV LOOP: DJNZ RET Profr. Salvador Saucedo R3,#2 R3,LOOP ; ; ; ; ; ; ; 1 (14 EN BAJO) 2+7 1 (10 EN ALTO) 1 1 2+7 2 ; 1 ; 2*2 ; 2 ( 7 CICLOS TOTAL) 8 La rutina dos toma siete ciclos, más otros dos ciclos que toma la instrucción que la llama son nueve en total. Por lo tanto el número de ciclos que está P1.0 en alto es igual a 10. Notar que al ejecutarse la P1.0 la patita del puerto se hace “1” hasta el final del ciclo que tarda dicha instrucción setb instrucción. El tren de 15 pulsos toma 390 μs. Ejemplo 2: Onda Cuadrada de 4.8 kHz Escribir un programa usando al Timer 0 para crear una onda cuadrada de 4.8 kHz en P1.0. Una onda cuadrada de 4800 Hz requiere un tiempo alto de 104.16 μs y un tiempo bajo de 104.16 μs. Puesto que esta intervalo es menor que 277 μs, el timer 0 en modo 2 puede usarse. Se supone un cristal de 11.0592 MHz. Un desborde cada 104.16 μs requiere un valor de recarga en TH0 de 96 cuentas menos que 00H, o -96. Aquí está el programa: ORG MOV MOV SETB BUC: JNB CLR CPL SJMP END 100H TMOD, #02H TH0, #-96 TR0 TF0, BUC TF0 P1.0 BUC ; 8 bits, modo de auto recarga ;-96 valor de recarga en TH0 ; arranca al timer ; espera el desborde ; limpia bandera del desborde del timer ; conmuta bit del puerto ; repite Este programa usa una instrucción para complementar el bit (CPL) en lugar de las instrucciones booleanas SETB y CLR del ejemplo previo. Entre cada operación de complemento, un retardo de 1/2 el periodo deseado (104.16 μs) es programado usando al Timer 0 en el modo de 8-bits con auto-recarga. El valor de recarga puede ser especificado usando notación decimal como -96, en vez de usar notación hexadecimal. El ensamblador realiza la conversión necesaria (0A0H). Notar que la bandera de desborde del timer (TF0) debe ser explícitamente limpiada por el software después de cada desborde. Los intervalos de tiempo mayores que 277 μs deben usar a timer en modo 1 de 16 bits. El retardo máximo es 216 = 65,536 cuentas, alrededor de 71.1 milisegundos. El inconveniente del modo 1 es que los registros del timer deben reiniciarse ras cada desborde, mientras que la recarga es automática en el modo 2. Ejemplo 3: Onda Cuadrada de 600 Hz Escribir un programa usando al Timer 0 para crear una onda cuadrada de 600 Hz en P1.0. Una onda cuadrada de 600 Hz requiere un tiempo alto de 833.33 μs y un tiempo bajo de 833.33 μs. Puesto que esta intervalo es mayor que 277 μs, el timer 0 en modo 1 debe usarse. Se supone un cristal de 11.0592 MHz. Un desborde cada 833.33 μs requiere un valor de recarga en TH0 de 768 cuentas menos que 0000H, o -768. Aquí está el programa: 5 6 7 8 9 10 11 12 13 14 15 16 0100 0100 0103 0106 0109 010B 010E 0110 0112 0114 0116 0116 758901 758CFD 758A00 D28C 308DFD C28C C28D B290 80ED Profr. Salvador Saucedo LAZO: BUC: ORG 100H MOV TMOD, #01H ; 16 bits, modo 1, sin recarga MOV TH0, #0FDH ; valor de carga en TH0 MOV TL0, #00H ; valor de carga en TL0 SETB TR0 ; arranca al timer JNB TF0, BUC ; espera el desborde CLR TR0 ; apaga el Timer CLR TF0 ; limpia bandera del desborde CPL P1.0 ; conmuta bit del puerto SJMP LAZO ; repite end 9 Existe un ligero error en la frecuencia del programa anterior. Tal error se debe al uso de instrucciones extras insertadas tras el desborde del timer para poder reiniciarlo. Si se necesitan exactamente 600 Hz el valor de carga se debe ajustar ligeramente para obtenerlo. El ensamblador realiza la conversión necesaria para pasar el decimal -768 a hexadecimal (0FD00H). Notar que la bandera de desborde del timer (TF0) debe ser explícitamente limpiada por el software después de cada desborde. Los intervalos de tiempo mayores que 71.1 ms deben usar a timer en modo 1 de 16 bits pero combinándolo con un contador dentro de un bucle de software. El retardo máximo del modo 1, como ya se dijo, es 216 = 65,536 cuentas de 1.085 μs cada una, alrededor de 71.1 milisegundos. Ejemplo 4. Tres Ondas Cuadradas Usando Interrupciones y un contador Escribir un programa usando interrupciones para simultáneamente crear tres ondas cuadradas: una de 14.4 kHz, otra de 300 Hz y una más de 15 Hz en P1.7, P1.6 y P1.5, respectivamente. La configuración de hardware con la temporización para las formas de onda deseadas se ofrece en la Figura 6. Tal combinación de salidas sería extremadamente difícil de generar en un sistema sin interrupciones. El timer 0, provee sincronización para la señal de 14.4 kHz, opera en el modo 2, como en el ejemplo previo: y el timer 1, provee sincronización para la onda de 300 Hz. Puesto que la señal de 300 Hz necesita 1.666 ms en alto y también 1.666 ms en bajo, el modo 2 no se puede usar para este caso. (Recordar que 277 μs es el máximo intervalo de tiempo en el modo 2 cuando el 80C31 opera a 11.0592 MHz.) Aquí está el programa: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0000 0000 000B 000B 001B 001B 001D 0030 0030 0033 0033 0036 0038 003A 003D 003F 0041 0041 0043 0044 0044 0046 0049 004C 004E 0050 0051 0054 0056 0058 0059 802E 8034 8027 758912 MAIN: 758CE0 D28C D28F 75A88A 7C00 80FE ORG SJMP ORG SJMP ORG SJMP 0 MAIN 00BH T0ISR 01BH TlISR ORG MOV 0030H TMOD,#12H ;Timer 1 = modo 1 ;Timer 0 = modo 2 TH0,#-32 ;14.4 kHz usando timer 0 TR0 TF1 ;fuerza interrupcion timer 1 IE,#8AH ;permite ambos timers interrumpan R4,#0 ; inicia contador $ MOV SETB SETB MOV MOV SJMP ; vector del Timer 0 ; vector del Timer 1 B297 32 T0ISR: CPL RETI P1.7 C28E 758DFA 758B00 D28E B296 0C BC1404 7C00 B295 32 TlISR: CLR MOV MOV SETB CPL INC CJNE MOV CPL RETI END TR1 ; Apaga al timer TH1, #HIGH(-1536) ; 1.666 ms tiempo alto & TL1, #LOW(-1536) ; tiempo bajo igual TR1 ; enciende al timer P1.6 R4 ; incrementa contador R4,#20,FIN R4,#0 ; reinicia contador P1.5 FIN: Aquí, el marco es para un programa completo que puede ser instalado en EPROM o ROM en un producto basado en el 80C31. El programa principal y las ISRs se localizan encima de las localidades de los vectores para el reset del sistema y ambas interrupciones, aunque la ISR para el timer 0 sólo mide tres bytes, por lo que bien pudo quedar a partir de la localidad 000BH. Las tres formas de ondas se crean mediante instrucciones booleanas "CPL"; empero, los intervalos de tiempo necesitan métodos algo diferentes para cada uno. Puesto que los registros TL1/TH1 deben ser recargados tras cada desborde (i.e. después de cada interrupción), la ISR del timer 1 (a) detiene al timer, (b) recarga TL1/TH1, (c) arranca al timer, luego (d) complementa al bit 6 del puerto 1, y si procede complementa el bit P1.5 para los 15 Hz. Notar Profr. Salvador Saucedo 10 además, que TL1/TH1 no son inicializados al principio del programa principal, a diferencia de TH0. Ya que TL1/TH1 deben ser reiniciados tras cada desborde, TF1 se hace “1” en el programa principal por software para "forzar" una interrupción inicial tan pronto como las interrupciones sean encendidas. Esto efectivamente hace que la forma de onda de 300 Hz se produzca. Fig. 6. Formas de onda (sin escala) del ejemplo. La ISR del Timer 0, como era de esperarse, simplemente complementa el bit 7 del puerto 1 y retorna, mediante la instrucción RETI al programa principal. SJMP $ se usa en el programa principal para abreviar la forma de ACA: SJMP ACA. Las dos formas son funcionalmente equivalentes. Notar que las banderas de desborde TF0 y TF1 no son limpiadas explícitamente por el software, pues al usar interrupciones dichas banderas son borradas por el hardware al saltar a la ISR (Rutina de Servicio a Interrupción) respectiva. Ejemplo 5. Interfaz de un Buzzer Un buzzer se conecta a P1.7 y un switch sin rebotes se conecta a P1.6. Escribir un programa que lea el nivel lógico producido por el switch y suene el buzzer por un segundo por cada transición de1 a 0 detectada. El buzzer en la figura 7 es un transductor piezo cerámico que vibra cuando es estimulado con un voltaje de CD. El objetivo aquí es generar un tono alrededor de 3.3 kHz a 5 voltios CD. Un inversor se usa como driver pues el buzzer toma 8 mA de corriente. Como indican las características de CD del 8051 en el manual, las patas del Puerto 1 pueden sumir un máximo de 1.6 mA. Crear retardos de software es uno de las más comunes tareas de programación dadas a estudiantes de microprocesadores. El método usual de decrementar un contador dentro de un bucle no es necesario en el 8031, pues cuenta con timers propios. Una subrutina de 1 segundo de retardo usando al Timer 0 se muestra en este ejemplo. Profr. Salvador Saucedo 11 Fig. 7 Ejemplo del zumbador. La transición de 1 a 0 en P1.6 es detectada esperando por un 1 (JNB esperando por un 0 (JB P1.6, WACHA). Veamos el programa: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 0000 0000 0100 0100 0103 0106 0109 010B 010E 0110 0112 0114 0117 011A 011C 011F 0121 0123 0125 0126 CIENTO CUENTA 758901 3096FD 2096FD D297 120112 C297 80F1 7F64 758C24 758A01 D28C 308DFD C28D C28C DFEF 22 LAZO: WACHA: DELAY: OTRA: ACA: EQU EQU ORG MOV JNB JB SETB CALL CLR SJMP MOV MOV MOV SETB JNB CLR CLR DJNZ RET END P1.6, LAZO) y luego 100 ;100x9217*1.085 us = 1 SEG 9217 100h TMOD,#0lH ;usa timer 0 en modo 1 P1.6,LAZO ;espera por 1 en entr. P1.6,WACHA ;espera por 0 en entr. P1.7 ; ARRANCA AL BUZZER DELAY ; espera 1 segundo P1.7 ; APAGA AL BUZZER LAZO R7, #CIENTO TH0,#HIGH CUENTA TL0,#LOW CUENTA TR0 TF0, ACA TF0 TR0 R7,OTRA Hay dos situaciones no manejadas en el ejemplo visto. Primero, si la entrada conmuta durante el segundo que el buzzer está sonando, la transición no es detectada, ya que el software está ocupado en la rutina delay. Segundo, si la entrada conmuta rápidamente en fracción de milisegundo la transición puede ser no detectada tanto por las instrucciones JNB y JB. PROBLEMAS Escribir un programa para el 80C31 que produzca una onda casi cuadrada en P1.5 de 48.5 1. kHz, sin usar los timers. Escribir un programa en el 80C31 que produzca una onda cuadrada en P1.2 de 12.5 kHz, 2. usando el timer 0. Modificar el ejemplo 3 para que la frecuencia sea de 440 Hz. 3. Modificar ejemplo 1 para obtener una frecuencia de 30.8 kHz con 40% de duty, 4. tiempo _ alto duty= 100 %. periodo Modificar ejemplo 4 para que la onda en P1.5 sea de 60Hz. 5. Programar el timer 1 para tener un baud rate de 19,200 bps en el puerto serial. 6. Modificar ejemplo 5 para que el buzzer suene en una detección si y la siguiente no. 7. Usar interrupciones en el timer 0, modo 1, para generar en P1.5 un periodo de 20 ms con 8. 33% de duty. Profr. Salvador Saucedo 12 9. Programar el timer 0 como contador de eventos, usando interrupciones, para implementar un reloj en tiempo real que se actualice cada segundo. Poner en RAM interna la hora del día en hh:mm:ss, en las localidades 60h a 62h. Usar el circuito del diagrama siguiente. 10. Añadir el circuito dado del problema anterior al cableado de la práctica 5 que corre al programa monitor, pero usando la entrada INT 0 y programar la interrupción externa. Enviar el tiempo real a exhibirse en la pantalla de la PC, cada 5 segundos. Profr. Salvador Saucedo 13 Profr. Salvador Saucedo 14