Microcontroladores. El 8051 de Intel

Microcontroladores. El 8051 de la INTEL. Índice. Tema 1 Microprocesadores, Microcomputadoras y Microcontroladores. 1.1

Views 219 Downloads 1 File size 4MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Microcontroladores. El 8051 de la INTEL.

Índice. Tema 1

Microprocesadores, Microcomputadoras y Microcontroladores. 1.1 Introduciéndonos en el Tema. 1.2 Haciendo un poco de historia. 1.3 Principales fabricantes de Microcontroladores. 1.4 Los Microcontroladores por dentro.

Tema 2

El microcontrolador 8051. 2.1 Los microcontroladores de la INTEL. 2.2 Los parientes cercanos, la Familia CMS - 52. 2.3 La Memoria Interna del microcontrolador 8051. 2.4 Las Instrucciones para trabajar con la Memoria Interna.

Tema 3

El Repertorio de Instrucciones del 8051. 3.1 Moviendo un bloque de datos. 3.2 Repertorio de Instrucciones.

Tema 4

Elementos imprescindibles en un sistema con el 8051. 4.1 Conociendo al microcontrolador 8051. 4.2 Dándole alimentación al microcontrolador. 4.3 Sincronizando la operación del microcontrolador. 4.4 Iniciando la operación del microcontrolador. 4.5 Haciendo programas para el microcontrolador.

Tema 5

Conectando dispositivos externos al microcontrolador. 5.1 Los Puertos del 8051. 5.2 El Puerto 1. 5.3 El Puerto 3. 5.4 El Puerto 2. 5.5 El Puerto 0.

Tema 6

Desarrollando aplicaciones simples con el Microcontrolador 8051. 6.1 Tomando Decisiones. 6.2 Secuencia de Eventos. 6.3 Trabajando con Tablas. 6.4 Trabajando con Display a Cristal Liquido. 6.5 Trabajando con Teclas del tipo ´Push Botom´. 6.6 Eliminando el efecto indeseable del Rebote. 6.7 Ejercicios Propuesto.

Tema 7

La Interrupción en el 8051.

1

Microcontroladores. El 8051 de la INTEL. 7.1 Encuesta o Interrupción. 7.2 El Controlador Interno de Interrupciones del 8051. 7.3 Atendiendo a los dispositivos que solicitan Interrupción. 7.4 El proceso de interrupción en el Microcontrolador. Tema 8

Sincronizando eventos impredecibles en el tiempo. 8.1 Atendiendo una Tecla del tipo ´Push Botom´ por Interrupción. 8.2 Termómetro Digital. 8.3 Sincronizando la llegada de datos desde un Teclado ASCII-Paralelo. 8.4 Generador de avisos

Tema 9

Los Temporizadores del 8051. 9.1 Los Temporizadores por dentro. 9.2 Los Registros TMOD y TCON. 9.3 Contando tiempo o eventos. 9.4. Los Modos de Trabajo de los Temporizadores. 9.5 Los Temporizadores y la Interrupción.

Tema 10

El Puerto Serie Asincrónico empotrado en el Microcontrolador 8051. 10.1 El Puerto Serie Asincrónico del 8051. 10.2 Los Modos de Operación del Puerto Serie del 8051.

Tema11

Aplicaciones de mediana complejidad con el Microcontrolador 8051. 11.1 Frecuencimetro Digital. 11.2 Controlador de Semáforo. 11.3 Medidor de la Velocidad y de la Dirección del Viento. 11.4 Mural Dinamico.

Tema 12

El Microcontrolador 8051 trabaja como Microprocesador. 12.1 Los Buses Externos del Microcontrolador 8051. 12.2 Modo Especial de Trabajo del Microcontrolador 8051. 12.3 Instrucciones para el trabajo con Memoria de Datos Externa. 12.4 Ejemplo de sistema expandido. 12.5 Diseño de un ´´Data Logger´´. 12.6 Diseñando con el Microcontrolador 8031.

2

Microcontroladores. El 8051 de la INTEL.

3

Tema 1. Microprocesadores, Microcomputadoras y Microcontroladores. 1.1 Introduciéndonos en el Tema. Cuando en al año 1971 la Compañía norteamericana INTEL irrumpía en el mercado con un circuito integrado digital cualitativamente nuevo a los existentes hasta ese momento, al que se le llamo Microprocesador, comenzaba una nueva era en el diseño de los sistemas digitales. Ahora el diseñador contaba para sus diseños con un circuito que las tareas que realizaba venían dadas por un programa desarrollado a partir de un conjunto de instrucciones que le brindaba el fabricante para trabajar con dicho circuito. Esto permitió traer al campo del diseño de los sistemas digitales técnicas hasta ese momento exclusivas para el diseño de las granes computadoras y las minicomputadoras. Se podía decir que el diseñador contaba con una computadora para resolver su aplicación. Por su puesto en los primeros años los recursos que adornaban a un microprocesador dado estaban limitados, fundamentalmente en cuanto a capacidad de memoria para almacenar los programas y los datos y con la velocidad de procesamiento, quizás de ahí viene el nombre de Microprocesador. Esta situación no duro mucho y con relativa rapidez salían nuevas versiones de microprocesadores, cada uno de ellos aventajando a su antecesor en cuanto a estos dos aspectos tan

importantes.

Esto

fue

propiciando

la

idea

de

emplear

fundamentalmente

a

los

microprocesadores en el desarrollo de Computadoras de Propósito General cada vez más potentes y con precios muy competitivos. A estos nuevos sistemas se le dio el nombre de Microcomputadora. No obstante, quedaba un gran campo de aplicaciones, fundamentalmente en la instrumentación y el control automático, que dada la envergadura de los mismo no se ajustaba el empleo de las nuevos sistemas en su solución. Nuevamente INTEL se percata de este segmento del mercado al que no se ajustaba el desarrollo vertiginoso que iban tomando los microprocesadores y saca a mediados de la década de los años 70 un circuito integrado con características muy similares a estos a los que les dio el nombre de Microcomputadora en una Pastilla. Así surge al mercado la familia CMS-48 de la que constituye su principal representante el 8748. Estos circuitos constituyeron la génesis de los circuitos que hoy se conocen con el nombre de Microcontroladores. A partir de este momento, el número de productos en el mercado que funcionan en base a uno o varios microcontroladores aumenta de forma exponencial y prácticamente no quedan campos de la vida actual en los que no encontremos equipos gobernados por el programa que se ejecuta en uno de estos dispositivos.

Microcontroladores. El 8051 de la INTEL.

Dentro del propio campo de las

4

Microcomputadoras, aparente territorio dominado por los

Microprocesadores, encontramos cada día más la presencia de estos circuitos donde casi todos sus periféricos basan su funcionamiento en el programa ejecutado por un Microcontrolador. Ejemplo de algunos de estos dispositivos que podemos mencionar. lo constituyen el ¨mouse¨, el teclado, la impresora, etc. Los Microcontroladores han irrumpido también con fuerza en nuestras casas, fundamentalmente en los equipos llamados electrodomésticos que basan su funcionamiento en estos circuito. Ejemplo de ello son, las lavadoras, los hornos, los televisores, los videos, los equipos de música, los sistemas de alarmas, etc. Según publicaciones especializadas en esta temática en los Estados Unidos se prevé que para el año 2010 en una casa típica de este país se encuentren aplicados aproximadamente entre 100 y 150 microcontroladores controlando la operación de diferentes elementos de la misma. Dentro del propio campo de las construcciones, cuando hablamos de edificios INTELigentes encontramos en los sistemas de supervisión y vigilancia la presencia de estos circuitos para optimizar el rendimiento de ascensores, calefacción, alarmas de incendio, robo, etc. Otros campos de aplicación lo constituyen: •

Los aparatos portátiles y de bolsillo.



Las Máquinas expendedoras y juguetería.



La Instrumentación.



La Industria de automoción.



El Control industrial.



La Robótica.



La Electromedicina.



Los Sistema de navegación espacial.



La Domótica.

Por lo que se puede decir sin temor a equivocarnos que, hoy en día ningún especialista que se dedique al diseño de sistemas digitales puede estar ajeno al desarrollo de los Microcontroladores y a como se esta moviendo el mercado cada vez más amplio y competitivo de estos circuitos. En este momento darle respuestas a las siguientes preguntas podría constituir un elemento imprescindible para poder seguir adelante en el estudio de los Microcontroladores.

Microcontroladores. El 8051 de la INTEL.

5

¿Que es un Microcontrolador?, ¿Que lo diferencia de un Microprocesador? ¿Qué diferencia existe entre un Microcontrolador y los tan conocidos y populares Microprocesadores? Definamos primeramente al Microprocesador. Definiremos como microprocesador a un Circuito Integrado de Muy Alta Escala de Integración, VLSI, que contiene una Unidad Central de Procesos, una Unidad Aritmético y Lógica y un conjunto de Registros, al que se le pueden conectar externamente Módulos de Memoria y de Puertos de Entrada/Salida, lo que permite la configuración de un Computador mediante la interconexión de varios circuitos integrados. Un Repertorio de Instrucciones propio y definido por el fabricante le permitirá al diseñador configurar el programa, que almacenado en uno de los Módulos de Memoria será ejecutado por el microprocesador y gobernará las operaciones de este y del Computador. Es común llamar a este Computador, como ya se definió anteriormente, Microcomputadora. Por su parte, podríamos decir que un Microcontrolador es la versión industrial de un Microprocesador, donde la preocupación de los fabricantes no esta tanto en el aumento de la capacidad de almacenamiento y de procesamiento, sino en brindar un conjunto de recursos integrados en el circuito que constituyan elementos significativos a la hora de enfrentar la solución de una aplicación dada. Algunos de estos circuitos lo constituyen: •

Memoria no volátil para contener el programa para la aplicación dada.



Memoria de lectura y escritura para guardar datos.



Líneas de Entrada/Salida digitales que agrupadas en forma de Puertos permiten la conexión de los diferentes elementos que conforman la aplicación.



Circuito de reloj interno.



Temporizadores.



Modulos de Captura.



Puertos Series Sincronicos y Asincronicos.



Perro guardián.



Convertidores A/D y D/A.

Un Microprocesador es un sistema abierto con el que el diseñador puede construir su Microcomputadora con las características que el desee, mediante el acople de los circuitos necesarios, ver Figura 1.1.1 a, mientras que un Microcontrolador es un sistema cerrado, que contiene un computador completo, de prestaciones limitadas, el que no puede ser modificado por el diseñador, ver Figura 1.1.1 b.

Microcontroladores. El 8051 de la INTEL.

6

Esta diferencia marca las posibilidades que brindan cada uno de estos dispositivos al diseñador para la solución de sus aplicaciones. Mientras que un Microcontrolador puede resolver determinadas aplicaciones por si solo sin la necesidad de ayuda de otros componentes en el sistema, los Microprocesadores siempre necesitan de otros dispositivos que lo apoyen en la solución de una aplicación dada por muy pequeña que esta sea.

F Figura 1.1.1 (a) Microcomputadora basada en un Microprocesador. (b) Microcontrolador. Esto que aparenta favorecer a los microcontroladores sobre los microprocesadores a la hora de escoger con cual resolver una aplicación dada no resulta de esta manera en todos los casos. Debemos tomar en consideración también para podernos hacer un juicio justo que permita establecer una comparación correcta los recursos limitados con que cuentan, que por lo general, los Microcontroladores y la facilidad de expansión y modificación con que cuentan los Microprocesadores. Por lo que una buena pregunta a la que deberíamos intentar dar respuesta en este momento lo podría constituir. ¿Cuándo utilizar un Microcontrolador y cuando utilizar un Microprocesador para solucionar una aplicación dada? Como pasa siempre en la ingeniería no existe una receta que al usted aplicarla le de la respuesta deseada para cualquier tipo de aplicación. No obstante, nos atreveremos a brindarle los dos consejos siguientes:

Microcontroladores. El 8051 de la INTEL. •

7

Si la aplicación a resolver es lo suficientemente pequeña que permita ser resuelta solo con los recursos internos del microcontrolador y no se prevé su expansión futura, no vacile, resuelva la aplicación con un sistema basado en el Microcontrolador en cuestión.



Si la aplicación a resolver no es lo suficientemente pequeña como para ser resuelta solo con los recursos internos del Microcontrolador y por lo tanto este necesita de dispositivos que lo apoyen y que le deben ser conectados externamente o su ampliación futura en un corto plazo esta prevista, tome papel y lápiz y saque cuenta de que le resulta mas económico.

Por su puesto nunca usted debe olvidar los campos de aplicación para los que son concebidos los Microcontroladores por parte de los fabricantes, ya que estos brindan todo un conjunto de facilidades al diseñador y al programador en la solución de dichas aplicaciones. El estado del arte actual en la fabricación de Microcontroladores y Microprocesadores no es más que el reflejo del desarrollo tecnológico alcanzado por las compañías que se dedican a la fabricación de estos dispositivos. Este desarrollo ha permitido el aumento de forma creciente de la cantidad de transistores por unidad de área en los circuitos integrados permitiendo que estos dispositivos realicen tareas más complicadas. Este proceso fue predicho por ´Moore´ en fecha tan temprana como a mediados de la década de los años 60 cuando definió lo que más tarde se conoció como la Ley que lleva su nombre en la que predecía, del punto de vista cuantitativo, a que velocidad iba a ocurrir este desarrollo. ´Moore´ planteo que, ´...el número de transistores por mm 2 en un circuito integrado se duplicaría cada 2 años´. Esta ley se ha venido cumpliendo con una buena precisión tal y como lo muestra la grafica de la figura 1.1.2.

Figura 1.1.2 Progresión de la integración de transistores por mm 2 en un circuito integrado. Ley de Moore.

Microcontroladores. El 8051 de la INTEL.

8

Les proponemos con el objetivo de lograr un mejor entendimiento del tema que estamos estudiando conocer algunos elementos de interés en el desarrollo de los microprocesadores y de los microcontroladores a partir del estudio de la evolución que han ido teniendo estos dispositivos desde su surgimiento hasta hoy. 1.2 Haciendo un poco de historia. Como ya mencionamos hacia el año 1971 una Compañía de los Estados Unidos, llamada INTEL, especializada en aquel entonces en la construcción de circuitos integrados de mediana escala de integración anuncio la salida al mercado de un circuito integrado de nuevo tipo, el 4004, al que dieron el nombre genérico de microprocesador. ¿Qué tenia de nuevo y diferente este circuito integrado comparado con los ya existentes hasta ese momento? El mercado digital hasta ese momento estaba dominado por los circuitos integrados de baja y mediana escala de integración con tecnología de fabricación Bipolar TTL y MOS. Los diseños de sistemas digitales consistían en la conjunción de compuertas lógicas, multivibradores, contadores, registros desplazamiento, almacenadotes, etc., alambrados dentro de una placa de circuito impreso. Estos circuitos integrados, dada sus características constructivas, respondían a un modo de operación único e imposible de cambiar por el diseñador una vez construidos, lo que convertía a los diseños en sistemas rígidos, imposibilitando su utilización en la solución de otras aplicaciones ligeramente diferentes. Se podría decir que, cada aplicación tenía un circuito para su solución y cada circuito solucionaba una aplicación dada. El microprocesador tenía la característica de que la función que realizaba dependía no solo de sus características constructivas sino que dependía fundamentalmente de un programa almacenado fuera de dicho circuito desarrollado por el diseñador, donde este moldeaba las funciones que quería que este realizara, lo que brindaba gran flexibilidad a los nuevos diseños. Ahora con un mismo hardware se podían realizar muchas funciones con solo cambiar el programa que gobernaba dicho hardware. Para el año, 1974, INTEL saca al mercado el microprocesador 8080, microprocesador de 8 bits, con 78 instrucciones en su repertorio de instrucciones y capacidad de memoria para almacenar programas y datos de 65 536 localizaciones, el que a la postre constituyó el primer microprocesador utilizado de forma masiva en el diseño de sistemas para la solución de aplicaciones en los más disímiles campos, lo que marco el comienzo de una nueva era, cualitativamente superior, en el diseño digital.

Microcontroladores. El 8051 de la INTEL.

9

A partir de este momento comienza una carrera vertiginosa en el desarrollo de nuevos microprocesadores en la cual no se encontraba ya solo INTEL sino que se le fueron incorporando nuevas Compañías en la lucha por el gran mercado que se comenzaba a perfilar. De esta forma aparece ZILOG con su microprocesador Z80, para muchos el microprocesador de 8 bits más potente y muy utilizado en el diseño de equipos, asi como Motorola con su microprocesador de 8 bits 6800 por solo mencionar a dos. El año 1976 marca la salida al mercado del primer microprocesador de 16 bits, el 8086, siendo nuevamente INTEL la compañía productora. Con mayor velocidad de operación, repertorio de instrucciones más completo y capacidad de almacenamiento de programas muy superior al de sus antecesores, anunciando la temprana entrada de los microprocesadores en el diseño de Computadoras Digitales de Propósito General. El año 1980 con la irrupción en el mercado de la Microcomputadora IBM-XT de la Compañía IBM, basado en un microprocesador de 16 bits interno y de 8 bits externo, el 8088 de INTEL, diseñado por encargo específicamente para este objetivo comenzó lo que se ha dado en llamar la era de las Microcomputadoras dentro del desarrollo de los microprocesadores la que se extiende hasta el día de hoy. A partir de este momento los nuevos microprocesadores van saliendo al mercado y van siendo conocidos a partir de la microcomputadora basada en el mismo. Así la década de los 80 estuvo marcada por las microcomputadoras 80286 y 80386, basadas en los microprocesadores del mismo nombre, comenzando con este ultimo la era de los microprocesadores de 32 bits y la década de los 90 por las microcomputadoras 80486 y Pentium, comenzando con este ultimo la era de los microprocesadores de 64 bits. En la actualidad las diferentes versiones de microcomputadoras basadas en un número igual de versiones de microprocesadores Pentium caracterizan el mercado del diseño de las Microcomputadoras Digitales. ¿Dónde encajan en esta historia los Microcontroladores? Con el surgimiento de los primeros microprocesadores se convirtió en un sueño para muchos diseñadores de Circuitos Integrados, entre ellos INTEL, el poder integrar en un solo circuito todos los elementos que conforman una Computadora Digital. Este sueño tuvo su primera materialización hacia el año 1976 en el que esta compañía saca al mercado un circuito integrado al que dio el

Microcontroladores. El 8051 de la INTEL.

10

nombre de Microcomputadora en una Pastilla 8048 el que constituye el antecedente primario de los microcontroladores. Esta Microcomputadora en una Pastilla se encontraba muy limitada en cuanto a la capacidad de almacenamiento interno tanto de los programas como de los datos por lo que la idea original de construir una microcomputadora basada en el mismo fue dándole paso a la de utilizarlo como controlador de los periféricos que se le conectaban a la misma. Así encontró aplicación como controlador de la operación de los Teclados, en el control de la operación de las impresoras, de los ploteadores, etc. A esta Microcomputadora en una Pastilla se le fueron agregando funciones muy útiles para desarrollar aplicaciones de instrumentación y control en la industria, surgiendo de esta forma la versión industrial de las Microcomputadoras en una Pastilla, los Microcontroladores. Así salen al mercado en la década de los 80 la familia de microcontroladores de 8 bits de la INTEL, el 8051, y mas tarde la familia de microcontroladores de 16 bits de la misma compañía el 8096/80196. Estos dispositivos produjeron un obvio beneficio en aplicaciones pequeñas siendo su característica mas sobresaliente la de constituir sistemas integrados. Es incuestionable el aumento casi exponencial de nuevos productos en el mercado basados en nuevos Microcontroladores. Mientras que los diseñadores de Microprocesadores se han dedicado a aumentar las posibilidades y velocidad de los mismos pensando en mejores y más potentes Microcomputadoras y poniendo la vista en el desarrollo de grandes redes de comunicación mediante este dispositivo, un segmento del mercado, nada despreciable, ha sido ocupado de forma creciente por los Microcontroladores. Es como si el mercado se hubiera dividido en dos partes muy bien definidas: •

Producción de Microcomputadoras en todas sus variantes, basadas en Microprocesadores cada vez más potentes.



Producción de equipos para aplicaciones a la medida, basados en Microcontroladores cada vez más versátiles.

Esto ha incorporado a un gran número de las compañías tradicionales productoras de Microprocesadores a acompañar a la INTEL en la producción de Microcontroladores como son los casos de la Motorola, la Zilog, etc., y en otros casos a que surjan nuevas compañías a competir por el mercado como es el caso de la Microchip y de la Atmel. Todo esto a traído una nueva disyuntiva a los diseñadores de equipos para solucionar aplicaciones a la medida,

Microcontroladores. El 8051 de la INTEL.

11

¿Cuál Microcontrolador escoger a la hora de implementar mi aplicación? Démosle una vista a algunos de los principales fabricantes de Microcontroladores y a sus productos para irnos aclarando la respuesta a esta pregunta. 1.3 Principales fabricantes de Microcontroladores. Se considera a INTEL como una de las Compañías lideres a nivel mundial en la fabricación de Microcontroladores, constituyendo su familia de microcontroladores de 8 bits CMS-51, del cual el 8051 es su más conocido representante, uno de las mas utilizados en la solución de aplicaciones en la industria. Con una arquitectura interna del tipo Von Newman con la memoria de datos segregada, los microcontroladores de esta compañía brindan un repertorio de instrucciones muy completo en el que se incluyen instrucciones de multiplicación, división, ajuste decimal, etc. Sus posibilidades de expansión externa son amplias permitiéndole llegar a conformar sistemas donde la capacidad de memoria de programas y de datos que puede manejar es superior a las que le estaban permitidas manejar a la mayoría de los microprocesadores de 8 bits. Quizás debido a que la línea de fabricación de Microcontroladores en la INTEL constituye realmente una producción de fondo de esta compañía las herramientas que esta brinda para la puesta a punto de los sistemas fabricados con este microcontrolador no son de las mejores en el mercado. No obstante, dada su amplia utilización otras compañías proveen herramientas muy útiles en este sentido. Otra característica de esta familia de microcontroladores de la INTEL es la de contar con numerosas segundas fuentes de compañías que brindan microcontroladores con características similares a los de esta familia. Ejemplos de ello lo constituyen la Philips y la Atmel. La Philips cuenta con una gran variedad de microcontroladores, con la característica fundamental de constituir versiones de la familia CMS-51, ofertando relaciones de potencia/costo muy ventajosas para sus aplicaciones. La Philips a incorporado a estos microcontroladores la posibilidad de utilizar su bus serie sincrónico I2C para la expansión de las posibilidades del microcontrolador de poder trabajar conjuntamente con otros dispositivos en la solución de una aplicación dada. Por su parte la Atmel se ha hecho eco de la incorporación a sus microcontroladores de las tan cómodas memorias de almacenamiento permanente del tipo Flash, con lo que se aumenta significativamente la flexibilidad de

los diseños basados en los microcontroladores de esta

compañía. Esta compañía también brinda una gran variedad de microcontroladores que constituyen versiones de los microcontroladores de 8 bits de la INTEL, encontrándonoslo con

Microcontroladores. El 8051 de la INTEL.

12

empaquetados con diferente número de terminales y con diferentes combinaciones de circuitos empotrados en el microcontrolador. Otra de las principales empresas del mundo de dispositivos programables, Motorola, que dispone del potente microcontrolador 68HC11, muestra una gran variedad de aplicaciones resueltas basadas en este Microcontrolador. Los microcontroladores PIC de la compañía Microchip se emplean en la actualidad cada vez más debido a su reducido consumo, bajo costo, pequeño tamaño, facilidad de uso y la abundancia de información y herramientas de apoyo, así como la gran variedad de dispositivos que fabrican de forma tal que se puede decir, sin temor a equivocarnos, que para cada aplicación que usted necesite resolver, usted encontrará entre los microcontroladores de la Microchip el que se ajusta a sus necesidades con una relación beneficio / costo de las más ventajosas entre todos los microcontroladores. Empleando una arquitectura interna del tipo Hardvar, lo que le permite contar con ancho de bus diferentes para códigos y datos, subdivide sus microcontroladores en tres grandes gamas, la baja, la media y la alta, con prestaciones muy interesante para los diseñadores. Basado en un repertorio de instrucciones reducido, entre 32 y 35 instrucciones en dependencia de

la gama a la que

pertenezca el microcontrolador, le permite incorporar todas las ventajas que representa para el programador el poder trabajar con un microprocesador del tipo RISCH. No obstante, la subdivisión de la memoria de datos en bancos, y la necesidad de conmutar entre bancos para trabajar con los registros y la memoria de datos puede resultar un tanto complicada y poco estimulante para los principiantes en el diseño con estos microcontroladores. También Zilog ha irrumpido con fuerza en el mercado de los microcontroladores. Recientemente ha lanzado algunos modelos con memoria OTP de la familia Z86XX, muy completos y fáciles de manejar. Otras empresas como SGS - Thomson, Hitachi, Texas, Toshiba, Nacional Semiconductor, etc., abarcan pequeñas partes del mercado con sus microcontroladores los que relacionamos en la siguiente lista: HITACHI

HD64180

SGS-THOMSON (ST)

ST-62XX

NATIONAL SEMICONDUCTOR

COP8

TEXAS INSTRUMENTS

TMS370

TOSHIBA

TLCS-870

Microcontroladores. El 8051 de la INTEL.

13

INFINEON

C500

DALLAS

DS5000

NEC

78K

Como se puede observar, cada fabricante de Microcontroladores oferta un elevado número de modelos diferentes, desde los más sencillos hasta los más complejos. Esto que podría representar un dolor de cabeza para los diseñadores al tener que escoger entre tantas posibilidades cual es el microcontrolador que más se ajusta a su aplicación, realmente constituye una gran ventaja ya que al diseñador le es posible seleccionar, tomando en cuenta la capacidad de la memoria de programa y de datos, el número de líneas de Entrada/Salida digitales y analógicas, el tipo y la cantidad de elementos auxiliares y la velocidad de funcionamiento necesarios para resolver su aplicación, prácticamente el microcontrolador a la medida logrando precios muy ventajosos. Por su puesto para poder hacer una selección adecuada se hace necesario conocer las características fundamentales de todos los microcontroladores que se producen en la actualidad, cosa esta prácticamente imposible por la gran cantidad de fabricantes, versiones y por la velocidad en que van apareciendo nuevos productos en el mercado. En la práctica los diseñadores basan sus diseños en uno o dos fabricantes, tomando en cuenta no solo las posibilidades de los Microcontroladores que estos fabrican y sus precios, sino tomando en cuenta también el contar con las herramientas que le permitan la puesta a punto de sus productos lo más rápido posible. Por lo tanto cuando usted va a emprender el diseño de un circuito para la solución de una aplicación dada y se ha decidido por basar este diseño en un microcontrolador, ante de escoger con cual de ellos lo va a llevar a cabo tome en cuenta los siguientes aspectos: •

Con que herramientas de puesta a punto del hardware y del software cuento para llevar a cabo mi tarea. Tenga siempre presente que comprar herramientas para la puesta a punto de sistemas basado en un microcontrolador cualquiera cuesta por lo general mucho más que el gasto incurrido en la materialización del circuito que nos proponemos construir.



Cantidad y fiabilidad de la información con que cuento.



Existencia de suministrador y de segundas fuentes.



Relación beneficio / costo.

Ya tenemos una visión de las diferencias que existen entre un Microprocesador y un Microcontrolador, así como la importancia cada vez creciente de estos últimos en el diseño de sistemas para la solución de una aplicación dada. Hemos visto también la gran variedad de microcontroladores que se fabrican en la actualidad por un número muy grande de compañías en el mundo, cada uno de ellos con sus propias características y ventajas. Por su puesto solo

Microcontroladores. El 8051 de la INTEL.

14

estamos comenzando a adentrarnos en este tema y una buena pregunta a darle respuesta para poder continuar podría ser la siguiente, Cuando tengo un Circuito Integrado delante, ¿Cómo saber que me encuentro en presencia de un Microcontrolador? 1.4 Los Microcontroladores por dentro. Generalmente cuando tenemos un circuito integrado delante y queremos saber que función realiza buscamos en el manual que entrega el fabricante y hay conocemos las características tanto funcionales como eléctricas del circuito al que nos estamos enfrentando, de igual forma procederíamos en el caso que el circuito integrado en cuestión resulte ser un microcontrolador. Si el manual no esta a tu alcance los fabricantes de microcontroladores entregan los ´data sheet´ de sus circuitos en ficheros ´nombre.pdf´ que por lo general son accesibles a través de la pagina ´web´ de dichas compañías, por lo que con la sola lectura de la primera pagina de dicho ´data sheet´ sabremos si nos encontramos en presencia de un microcontrolador o no. Por lo que esto no constituirá el aspecto fundamental en este tema sino, en que conozcamos cuales son las características y circuitos que nos podemos encontrar cuando estamos en presencia de un microcontrolador. La Arquitectura interna. Como ya se explico anteriormente, un Microcontrolador es un computador completo, limitado en cuanto a las prestaciones que brinda, contenido en un chip de circuito integrado y que se designa para gobernar una sola tarea, lo que lo hace un controlador dedicado. En su memoria de programa interna solo reside un programa destinado a gobernar una aplicación determinada. Sus líneas de Entrada/Salida soportan el conexionado de los sensores y actuadotes del dispositivo a controlar. Una vez configurado y programado el microcontrolador solamente sirve para gobernar la tarea asignada. Por regla general un microcontrolador posee todos los componentes de un computador, pero con características fijas que no se pueden alterar. Estos elementos constituyen partes imprescindibles en cualquier microcontrolador al que nos enfrentemos. Estas partes comunes son: •

Procesador o Unidad Central de Proceso (CPU).



Unidad Aritmético y Lógica (ULA)



Memoria no volátil para contener el programa.



Memoria de lectura y escritura para guardar los datos.

Microcontroladores. El 8051 de la INTEL. •

15

Líneas de Entrada/Salida para los periféricos.

Un conjunto de circuitos adicionales adornan a los diferentes microcontroladores en dependencia de sus particularidades y constituyen circuitos que lo caracterizan. Estas funciones pueden estar presentes o no en dependencia del microcontrolador que nos estemos enfrentando. Estos circuitos auxiliares son: •

Oscilador interno.



Temporizadores.



´watch doog´ o perro guardián.



Convertidores A/D y D/A.



Módulos de captura.

El Procesador o Unidad Central de Procesos es el elemento más importante del microcontrolador tanto a nivel hardware como software. Se encarga de direccionar la memoria de programa, recibir el código de la instrucción en curso, efectuar su decodificación y efectuar la ejecución de la operación aritmética o lógica con ayuda de la Unidad Aritmético y Lógica que implica dicha instrucción, así como la búsqueda de los operandos y el almacenamiento del resultado. La comunicación entre las diferentes secciones internas del microcontrolador con la unidad Central de Procesos se efectúa a través de un conjunto de líneas internas denominadas buses que posibilitan el movimiento de direcciones, datos y señales de control. Estas líneas tomando en cuenta la función que realizan se dividen en tres grupos o buses tal y como ocurre en los sistemas a microprocesadores: •

Bus de datos. Se emplea para transferir los datos y los códigos de las instrucciones entre la memoria y la Unidad Central de Procesos. El número de líneas de este bus es igual a la longitud de palabra del dispositivo y es lo que define si el microcontrolador es de 8 o 16 bits.



Bus de direcciones. Permite transferir información de direcciones, a través de estas líneas la Unidad Central de Procesos envía la dirección que caracteriza al dispositivo con que quiere efectuar una operación, ya sea memoria de programa, memoria de datos o dispositivo de entrada / salida. El número de líneas en el bus de direcciones determina el número de posiciones de memoria, tanto de programa como de dato, que el microcontrolador puede especificar. Un bus de direcciones de 8 líneas sería capaz de especificar 256 direcciones diferentes.

Microcontroladores. El 8051 de la INTEL. •

16

Bus de control. El procesador utiliza las líneas del bus de control para sincronizar las operaciones entre los diferentes componentes así como conocer el estado en que se encuentran algunos dispositivos.

No todos los fabricantes de microcontroladores conectan internamente sus circuitos internos a través de los buses de la misma forma y por lo general cada uno define su propia Arquitectura Interna. En el caso de los microcontroladores de INTEL esta compañía adopto como Arquitectura Interna la misma que había definido para sus microprocesadores, la arquitectura conocida como de Von Newman, la que recibe su nombre del especialista que la propuso en los albores del diseño de las Grandes Computadoras.. Esta arquitectura se caracteriza porque la Unidad Central de Procesos es conectaba a una memoria única donde coexistían tanto los datos como las instrucciones a través de un sistema de buses común, ver Figura 1.4.1.

Figura 1.4.1. Estructura interna de un Microcontrolador con arquitectura Von Newman. Los sistemas con arquitectura Von Newman al dedicar un mismo bus de datos para mover la información entre la unidad central de procesos y la memoria de programa y de datos provocan que el ancho de banda de ambas memoria tenga que ser igual, por lo que el numero de bits dedicado a representar el código de una instrucción tenga que coincidir con el número de bits con que dicha unidad esta habilitada para manejar los datos. Esto trae como consecuencias la necesidad de que los códigos de algunas de las instrucciones tengan la necesidad de ser almacenados en más de una localización en la memoria de programas, provocando los siguientes inconvenientes: •

No coincide el número de instrucciones de un programa con el número de localizaciones de memoria que este necesita para su almacenamiento.



No todas las instrucciones consumen el mismo tiempo para su ejecución.

Microcontroladores. El 8051 de la INTEL.

17

La necesidad de conseguir rendimientos elevados en el procesamiento de las instrucciones y en aprovechar al máximo la capacidad de almacenamiento interno de dichas instrucciones ha desembocado en el empleo generalizado de procesadores de arquitectura Harvard, nombre que recibe dicha arquitectura al ser desarrollada en dicha universidad de los Estados Unidos. En esta arquitectura la memoria de programas y la memoria de datos son independientes y cada una dispone de su propio sistema de buses para el acceso, ver Figura 1.4.2.

Figura 1.4.2. Estructura interna de un Microcontrolador con Arquitectura Harvard. Esta característica permite que el ancho de banda de ambas memorias pueda ser diferente permitiendo la representación de los códigos con un número de bits diferentes, por lo general superior, que los empleados para representar los datos, con lo que se ahorra espacio para almacenar los programas. Ahora los inconvenientes vistos en la arquitectura Von Newman parecen estar solucionados al tener los fabricantes la posibilidad de aumentar el número de bits posibles a almacenar en cada localización de memoria de programas de forma tal que para almacenar el código de una instrucción solo se necesite de una localización de memoria, logrando con ello: •

Coincide el número de instrucciones de n programa con el número de localizaciones de memoria de programa necesarias para almacenarlos.



Salvo excepciones, todas las instrucciones consumen el mismo tiempo en su ejecución.

Microcontroladores. El 8051 de la INTEL.

18

Otra consecuencia del empleo de una u otra arquitectura a la hora de diseñar el microcontrolador lo constituye: •

Los Microcontroladores con arquitectura Von Newman no están capacitados para que el procesador efectué dos operaciones de forma simultánea, como puede ser, traer el código de la próxima instrucción a ejecutar de la memoria de programa y escribir el resultado de la instrucción en curso en la memoria de datos al utilizar el mismo bus para ambas operaciones.



Por su parte los microcontroladores con arquitectura Harvard, al tener buses de datos para la memoria de datos y de programas separados, están capacitados para efectuar estas dos operaciones de forma simultánea con lo que se logra reducir el tiempo de ejecución de los programas.

En la figura 1.4.3 se muestra la Arquitectura Interna del Microcontrolador de la INTEL 8051, la que se corresponde con la Arquitectura Von Newman, mientras que en la Figura 1.4.4 se muestra la Arquitectura Interna del Microcontrolador 16F873 de la Microchip, la que se corresponde con la Arquitectura Harvard.

Figura 1.4.3. Arquitectura Interna del Microcontrolador 8051.

Microcontroladores. El 8051 de la INTEL.

19

Figura 1.4.4. Arquitectura Interna del Microcontrolador de la Microchip de la Gama Media PIC16F873. Al observar la arquitectura interna del Microcontrolador de la 8051 puede llamar a confusión que aparecen separadas la memoria de datos de la memoria de programa, ver Figura 1.4.3, lo que podría ser contradictorio con lo que se había definido como la arquitectura de Von Newman. No obstante, aunque ambas memorias se encuentran separadas ambas se conectan con la Unidad Central de Procesamiento a través del mismo bus de datos, lo que resulta lo característico en este tipo de arquitectura. En este caso se define la 8051 como un microcontrolador con arquitectura interna del tipo Von Newman, pero con la memoria de datos segregada. Más adelante veremos las consecuencias de esto. Por su parte al observar la arquitectura interna del microcontrolador de la Microchip 16F873 podemos notar la existencia de un bus de datos de 14 bits que conecta a la memoria de programas con la Unidad Central de Procesos a través del cual se mueven los códigos de las instrucciones a ejecutar por el microcontrolador, mientras que otro bus de datos de 8 bits es el encargado de mover los datos a todos los otros elementos que conforman al microcontrolador, lo que constituye lo típico de una arquitectura del tipo Harvard. Aunque el presente curso esta orientado al microcontrolador 8051, hemos creído oportuno comparar las arquitecturas internas de estos dos microcontroladores que caracterizan a dos de los fabricantes más importantes de estos dispositivos en la actualidad, con el objetivo de que los estudiantes puedan comprender bien las limitantes y ventajas de la arquitectura Von Newman típica del 8051 con la

arquitectura Hardvar que va apareciendo en los modernos

microcontroladores de la Microchip.

Microcontroladores. El 8051 de la INTEL.

20

Hasta aquí en muchas ocasiones hemos hecho hincapié en la existencia de un programa que el microcontrolador debe ejecutar, por lo que en este momento nos parece oportuno dar respuesta a las dos preguntas siguientes, ¿Qué es un Programa?, ¿Cómo se ejecuta este Programa? Un Programa es una lista de instrucciones al procesador que con un ordenamiento lógico busca resolver una determinada aplicación. Todos los microcontroladores tienen un conjunto de instrucciones que pueden ejecutar, definidas por el fabricante, y que constituyen su Repertorio de Instrucciones. Repertorio de Instrucciones. Cada tipo de microcontrolador tiene su propio conjunto de instrucciones, y por lo general los programas escritos para uno no funcionarán en otro. Un microcontrolador típico tendrá en su repertorio de instrucciones, instrucciones para: transferir información entre registros y memoria, realizar operaciones aritméticas y lógicas, efectuar comparaciones y pruebas sobre el contenido de sus registros de memoria, así como para controlar la secuencia de ejecución de programas, etc. Existen tres orientaciones en cuanto a la arquitectura y funcionalidad de los procesadores actuales, las que influyen decisivamente en las instrucciones que brinda el microcontrolador y la forma de programarlo. Estas tres orientaciones son: CISC, RISC y SISC. Un gran número de procesadores usados en los microcontroladores están basados en la filosofía CISC (Computadores de Juego de Instrucciones Complejo). Disponen de más de 80 instrucciones máquina en su repertorio, algunas de las cuales son muy sofisticadas y potentes, requiriendo muchos ciclos para su ejecución. Una ventaja de los procesadores CISC es que ofrecen al programador instrucciones complejas que actúan como macros, facilitándole el trabajo de programación. Tanto la industria de los computadores comerciales como la de los microcontroladores están inclinándose hacia la filosofía RISC (Computadores de Juego de Instrucciones Reducido). En estos procesadores el repertorio de instrucciones máquina es muy reducido y las instrucciones son simples y, generalmente, se ejecutan en un ciclo. La sencillez y rapidez de las instrucciones permiten optimizar el hardware y el software del procesador. En los microcontroladores destinados a aplicaciones muy concretas, el juego de instrucciones, además de ser reducido, es "específico", o sea, las instrucciones se adaptan a las necesidades de

Microcontroladores. El 8051 de la INTEL.

21

la aplicación prevista. Esta filosofía se ha bautizado con el nombre de SISC (Computadores de Juego de Instrucciones Específico). Nuevamente los dos microcontroladores que hemos estado comparando en el material se caracterizan por pertenecer a dos grupos diferentes. El 8051 se caracteriza por ser un microcontrolador tipo CISC con más de 80 instrucciones en su repertorio de instrucciones, algunas tan complejas como las instrucciones de Multiplicación y de División. Por su parte, el Microcontrolador 16F873 se caracteriza por ser un microcontrolador tipo RISC con solo 35 instrucciones en su repertorio. Por lo general la operación que una instrucción ha de ejecutar está definida por un código de operación, generalmente de un solo byte, conocido también como opcode. Algunas instrucciones requieren además del código de la instrucción, información extra para definir los operandos. Por ejemplo, una instrucción para almacenar el contenido de un registro en una posición de memoria, necesitará incluir la dirección de memoria de destino. La Unidad de Control y Decodificación de instrucciones incluida en la Unidad Central de Procesos del microcontrolador constituye el corazón del procesador. Esta es la encargada de extraer de forma secuencial las instrucciones de la memoria de programa y luego ejecutarlas. Unido a la Unidad de Control se encuentra el generador de reloj, que utiliza un oscilador para producir una señal de reloj muy precisa. El tiempo se divide en un cierto número de ciclos de la señal de reloj. El funcionamiento de la Unidad de Control y Decodificación de Instrucciones se puede dividir en dos partes o ciclos, el Ciclo de Búsqueda y el Ciclo de Ejecución. •

Ciclo de Búsqueda. En este ciclo el procesador transfiere la dirección de la siguiente instrucción a ejecutar por el microcontrolador al Bus de Direcciones interno, conjuntamente con la orden de lectura de la memoria de programa a través de las señales del Bus de Control interno. Un tiempo después, el procesador lee la información puesta en el Bus de Datos interno por parte de la memoria de programa como respuesta a la orden de lectura, transfiriendo esta información al Registro de Instrucciones.



Ciclo de ejecución. En este ciclo se ejecuta la instrucción. Para ello el Registro de Instrucciones está conectado al Decodificador de Instrucciones, que determina cuántos byte de información adicionales se requieren para poder ejecutar la instrucción, en caso de que sean necesarios. De ser necesarios, estos se cargan mediante Ciclos de Búsqueda adicionales, tantos como byte conformen la instrucción a ejecutar. Una vez que todos los

Microcontroladores. El 8051 de la INTEL.

22

operandos que intervienen en la operación son conocidos, y el microcontrolador ejecuta la instrucción. Cuando la ejecución de la instrucción es completada, el microcontrolador comienza, de forma automática un nuevo Ciclo de Búsqueda de la siguiente instrucción del programa, con lo que se garantiza la operación secuencial y cíclica del programa por parte del microcontrolador. La ejecución es por tanto, una secuencia continua de ciclos de búsqueda y ejecución. De lo explicado hasta aquí las tareas a ejecutar por el microcontrolador el diseñador se las entrega mediante un Programa diseñado a partir de las instrucciones propias del microcontrolador y que el fabricante define en el Repertorio de Instrucciones del mismo. Estas instrucciones son representadas por códigos binarios reservados traídos de la memoria de programa interna del microcontrolador hacia su Unidad Central de Procesos durante los Ciclos de Búsqueda. Con el objetivo de continuar profundizando en este tema podríamos intentar dar respuesta a la siguiente pregunta, ¿Qué características presentan estas memorias de programa interna en los microcontroladores? ¿Es el único tipo de memoria con que cuentan los microcontroladores? La Memoria interna. Los microcontrolador están diseñados para que en su Memoria de Programa interna se almacenen los códigos de todas las instrucciones que conforman el programa definitivo que solucionará una aplicación dada. Una vez definido el programa este no debe ser cambiado mientras el microcontrolador se mantenga resolviendo la aplicación para el cual fue creado. Esta característica es la que hace que la Memoria de Programa de los microcontroladores sean del tipo de almacenamiento permanente, constituyendo esta su característica común en todos los casos. Son posibles encontrar cinco tipos de Memoria de Programa en los microcontroladores: •

ROM de máscara. Esta memoria se graba en el chip durante el proceso de fabricación. Los altos costes de diseño sólo aconsejan usarla cuando se precisan series grandes.



EPROM. En la superficie de la cápsula del microcontrolador existe una ventana de cristal por la que se puede someter al chip a rayos ultravioletas para producir el borrado de la memoria con el objetivo de programarla nuevamente. Su coste unitario es elevado y se justifica en la fase de Puesta a Punto de los sistemas.

Microcontroladores. El 8051 de la INTEL. •

23

OTP (One Time Programmable). Este modelo de memoria sólo puede ser grabada una vez por parte del usuario. Su bajo precio y la sencillez de la grabación aconsejan este tipo de memoria para prototipos finales y series de producción cortas.



EEPROM. La grabación es similar a la EPROM y OTP, pero el borrado y nueva programación es mucho más sencillo al poderse ejecutar eléctricamente, en el propio circuito, las veces que se quiera. Muy utilizada para almacenar configuraciones de los sistemas que son de vital importancia para su correcto funcionamiento y que por ende no deben perderse por cualquier falla de la energía.



FLASH. Se trata de una memoria no volátil de bajo consumo que se puede escribir y borrar en el propio circuito al igual que la EEPROM, pero suele disponer de mayor capacidad que estas últimas. El borrado sólo es posible en bloques completos. Por sus mejores prestaciones está sustituyendo a la memoria EEPROM en los microcontroladores modernos.

Estos tipos de Memoria de Programa están constituidos por un conjunto de localizaciones las que se encuentra organizada de forma secuencial de las direcciones. De la explicación anterior queremos llamar la atención en dos palabras específicas, localización y dirección. Definiremos como localización al lugar físico en la memoria destinado para almacenar un contenido dado en un formato digital. Estas localizaciones están constituidas por los bits que pueden tomar el valor de ´0´ o ´1´ en dependencia de la información que se desea almacenar. El número de bits que conforman una localización dada en la memoria de programa depende del microcontrolador. Por ejemplo en el caso del microcontrolador 8051 el número de bits es de 8 mientras que en el 16F87 es de 14. Por su parte definiremos como dirección a la manera de referirnos a una localización dada a la hora de trabajar con ella. A una localización se le asigna una dirección que es única y propia de ella. Por lo tanto cuando hablamos de una localización de memoria de programa nos estaremos refiriendo a ella o bien por su contenido o por su dirección. Por lo general tanto la dirección como el contenido de una localización dada se expresa en hexadecimal, por un problema de comodidad. El esquema de la Figura 1.4.5 nos ayudará a comprender mejor lo explicado sobre este aspecto.

Microcontroladores. El 8051 de la INTEL.

24

Figura 1.4.5 Concepto de localización, dirección y contenido en la memoria de programa. El número de localizaciones define la capacidad con que cuenta la memoria de programas para almacenar las instrucciones, tablas o cualquier otra cosa que defina el diseñador del sistema. Esta capacidad se especifica en Kilo, lo que resulta equivalente a 1024 localizaciones. Por lo que cuando me definen que el microcontrolador cuenta con 2K localizaciones en su memoria de programas, me están especificando de que el microcontrolador cuenta con 2048 localizaciones para almacenar códigos u cualquier otra cosa en su memoria de programa. La cantidad de información posible almacenar en esta memoria de programa no solo depende del numero de localizaciones con que cuente, sino también dependerá del numero de bits con que este conformada dicha localización. Por ejemplo si en el caso de la memoria anterior las localizaciones estuvieran conformadas por 8 bits la capacidad de almacenamiento de la memoria en cuestión sería de 2048 bytes, se define como byte un número conformado por 8 bits, o 2 kilobyte o lo que es lo mismo 2048 x 8 bits. Tomando como ejemplo los dos microcontroladores a los que nos hemos estado refiriendo durante el material el 8051 y el 16F873, en el primero su capacidad de memoria de programa es de 8 Kilobyte, mientras que en el segundo su capacidad de memoria de programa es de 8 kx14 bits, ya que las localizaciones de memoria de programa en este microcontrolador están conformadas de 14 bits.

Microcontroladores. El 8051 de la INTEL.

25

Las localizaciones de memoria de programa internas del microcontrolador tienen direcciones fijas e impuestas por el fabricante, las que no pueden ser alteradas por el diseñador del sistema, correspondiéndole a una localización ser la de la dirección más baja y a otra la dirección mas alta. Entre estas dos se encuentran el resto de las localizaciones a las que le corresponden direcciones consecutivas. Una de estas localizaciones juega un papel trascendental a la hora de cargar nuestro programa de aplicación en la memoria de programa y es a la que le debe corresponder almacenar el código de la primera instrucción de nuestro programa. La dirección de esta localización no es la misma para todos los microcontroladores, pero si es única para un microcontrolador dado. Por ejemplo en el caso del microcontrolador 8051 esta localización es a la que le corresponde la dirección más baja, la 0000 H. En la Figura 1.4.6 se muestra de forma esquemática la estructura de la memoria de programa del microcontrolador 8051.

Figura 1.4.6 Memoria de Programa del microcontrolador 8051. Mientras que los programas deben permanecer inalterables durante el tiempo de vida del microcontrolador en una aplicación dada, los datos que manejan estos programas por lo general varían continuamente y eso exige que la memoria que los contiene nos brinde la posibilidad de almacenar datos de forma temporal y poderlos alterar cada vez que sea necesaria por el programa. de ahí que estas memoria se conozcan con el nombre de memoria de datos, aunque esto no excluya la posibilidad de que en algunos casos puedan almacenar códigos o partes integrantes de los programas. Lo anterior impone la necesidad de que las memorias que conformen la memoria de datos de los microcontroladores deban ser del tipo de lectura y escritura o como se conoce normalmente Memorias RAM.

Microcontroladores. El 8051 de la INTEL.

26

Las memorias RAM pueden ser de diferentes tipos pero todas tienen en común la característica de que la información almacenada en ellas se pierde cuando se les retira la energía, de ahí que se conozcan como memorias volátiles. Es por ello que en la mayoría de los microcontroladores el contenido de las localizaciones de la memoria de datos cuando este es energizado es desconocido. Los conceptos definidos de localización, dirección y contenido para el caso de la memoria de programa son validos para la memoria de datos también. Las memorias RAM que se fabrican en la actualidad las podemos dividir en dos grandes grupos: •

Memoria RAM Dinámica. La información almacenada en ellas tiene que ser refrescada constantemente y en intervalos de tiempo bien definidos, de no hacerse la información almacenad en ellas se pierde. Esta incomodidad en el trabajo con este tipo de memoria es recompensado con la posibilidad de obtener mucha más capacidad de memoria en una misma área que en los otros tipos.



Memoria RAM Estática. No se hace necesario el refrescamiento de la información almacenada en la memoria y el contenido de una localización una vez definido no se pierde a no ser porque el programa escriba un nuevo dato en dicha localización o la memoria pierda la energía por alguna causa.

Las memorias RAM Estáticas (SRAM) resultan ser las más apropiada para materializar la memoria de datos de los microcontroladores y es con la que están construidas por lo general estos dispositivos. Hay microcontroladores que aprovechan la característica de las memorias EEPROM de poder ser leídas y escrita de forma eléctrica y poseen parte de su memoria de datos implementada por una memoria de este tipo, de forma tal que cierta información, que no constituye programa pero si información muy importante para el trabajo del sistema, no se pierda producto de la perdida de la energía, pudiéndose recuperar dicha información una vez que esta es establecida permitiendo al sistema continuar con su tarea. Como hemos visto en epígrafes anteriores otros circuitos comparten el espacio interno de los microcontroladores con la memoria. Estos circuitos se incorporan en dependencia del microcontrolador que sea, reforzando la potencia del dispositivo para resolver determinadas tareas. A estos circuitos los llamaremos circuitos empotrados y a ellos estará dedicado el próximo epígrafe.

Microcontroladores. El 8051 de la INTEL.

27

Circuitos empotrados más comunes. Los circuitos empotrados constituyen aquellos dispositivos que el fabricante agrega a un microcontrolador dado con el objetivo de que contengan un conjunto de facilidades para realizar determinadas funciones que por lo general son las mas comunes encontrar en los sistemas para los que fue desarrollado dicho microcontrolador. Dado que la mayoría de los microcontroladores fueron concebidos por sus fabricantes para resolver aplicaciones dedicadas a la instrumentación y el control, estos han agregados a los mismos un conjunto de facilidades que se repiten mucho de un microcontrolador a otro. Entre las facilidades más comunes que se encuentran en muchos microcontroladores o en alguna de sus versiones podemos mencionar: •

Los Temporizadores.



El Perro guardián.



Los Módulos de Captura, Comparación y PWM.



Los Puertos Serie ya sean sincrónicos o asincrónicos.



Los Conversores A/D.

Como mencionamos anteriormente no todas estas facilidades tienen que estar presentes en un mismo microcontrolador. Por ejemplo el 8051 en su versión clásica cuenta con 2 Temporizadores y 1 Puerto Serie, no contando ni con Perro Guardián, ni con Modulo de Captura, Comparación y PWM, ni con Conversores A/D, sin embargo el 16F873 cuenta con 3 Temporizadores, Perro Guardián, 2 Módulos de Captura, Comparación y PWM, 2 Puertos Serie y un Conversor análogo Digital con 5 entradas analógicas. Poder conocer las facilidades que brinda al diseñador el contar con alguno de estos elementos en su microcontrolador somos del criterio de que nos permitiría tener una visión completa de que es lo que podemos hacer con un microcontrolador dado. Por lo que le proponemos que en a continuación le demos respuesta a las preguntas siguientes, ¿Qué función realiza cada uno de estos circuitos empotrados? ¿Para que tipo de operaciones me pudrieran ser útiles en una aplicación dada?

Microcontroladores. El 8051 de la INTEL.

28

Los Temporizadores. Son muchas las aplicaciones en las cuales los Temporizadores constituyen una ayuda valiosa e imprescindible para el diseño, ejemplos de ello son los siguientes casos: •

Determinar de forma automática el tiempo en ´1´ de un pulso generado por un circuito.



Determinar el valor que toma una determinada variable física con una periodicidad de 1 segundo.



Determinar la frecuencia de un tren de pulsos generado por un circuito.



Determinar la cantidad de productos terminados que se mueven por una cinta transportadora.

En los dos primeros casos se impone la necesidad de contar tiempo, mientras que en los dos últimos lo necesario es contar un determinado evento. En los cuatro casos los Temporizadores podrían ser utilizados como parte de la solución o como elemento fundamental de la misma. De los ejemplos anteriores podemos concluir las funciones fundamentales para las que están destinados los Temporizadores en un microcontrolador, las que las podemos resumir en los siguientes tres aspectos: •

Como reloj interno en la sincronización de eventos.



En la generación de intervalos de tiempo.



Como contador de eventos externos.

La pregunta aquí sería, ¿En qué consisten los Temporizadores?, que pueden realizar tareas tan disímiles. En esencia los Temporizadores consisten en un circuito contador, de 8 o de 16 bits, al que se le puede escoger mediante su programación, la fuente de conteo, la habilitación del conteo, la cantidad de bits y la base de conteo, lo que permite al diseñador moldear al temporizador en dependencia de las necesidades de su aplicación. Una vez programados, su operación es completamente por hardware, liberando al microcontrolador de la labor de supervisión por software de los mismos. Por ejemplo, si la fuente de conteo es la salida del circuito oscilador interno del microcontrolador, entonces el contador estaría contando tiempo y el Temporizador podría ser utilizado como reloj

Microcontroladores. El 8051 de la INTEL.

29

interno en la sincronización de eventos o como generador de intervalos de tiempo muy preciso. Por otro lado, si la fuente de conteo lo constituye una señal externa al microcontrolador que responde a la ocurrencia de un determinado evento, entonces el contador contaría eventos y el Temporizador estaría contando las veces que dicho evento ocurre. Estos contadores además, cuentan con una lógica que determina cuando el contador se desborda lo que genera la habilitación de una bandera propia de cada Temporizador y el pedido de interrupción al microcontrolador para ser atendidos. El Perro Guardián. En esencia es un temporizador, pero con la característica de que no se le puede cambiar ni la fuente de conteo ni la base de conteo. Todo lo que se puede decidir es cuando esta habilitado y cuando no, además, mediante instrucción se puede reiniciar su conteo cada vez que el programador lo entienda conveniente dentro del programa. De esta manera el Perro Guardián una vez habilitado se desborda, ladra de hay su nombre, siempre que transcurra el mismo intervalo de tiempo para un microcontrolador dado para una frecuencia de reloj dada, si no fue interrumpido su conteo mediante una instrucción de reinicio. La interrogante en este momento podría ser, ¿Cuál puede ser la función del Perro Guardián en una aplicación dada? En esencia su función es la de avisarnos que una determinada tarea se encuentra fuera de tiempo y por ende existe algún fallo en el sistema. Existen programas que una vez iniciadas una tarea dada, el microcontrolador espera por alguna respuesta antes de continuar con el resto del programa. Esto se implementa mediante un lazo de espera que pregunta constantemente por la ocurrencia de una condición dada y del cual no se saldrá hasta que dicha condición ocurra. Por ejemplo, se le da inicio de conversión a un Conversor Análogo Digital y el programa se queda esperando porque el Conversor le indique que termino con la conversión para efectuar su lectura, pero esta condición nunca se da, digamos que porque el Conversor esta roto o por cualquier otra causa. En este caso el programa quedaría en un lazo infinito del que no saldría, ya que la condición por la que espera nunca ocurre, no existiendo otra causa que lo haga salir. Ahora bien, si antes de iniciar la tarea se habilita el Perro Guardián, el programa se quedaría en el lazo infinito hasta que este se desborde y con ello sacaría al programa de esta condición. Si por el contrario todo ocurre bien, una vez leído el Conversor se reinicializa la operación

del Perro

Guardián, comenzando nuevamente con el conteo y por consiguiente no ocurriendo su

Microcontroladores. El 8051 de la INTEL.

30

desbordamiento y por tanto no interrumpiendo la operación normal del microcontrolador. De este forma el programa continuará con su secuencia de trabajo tal y como estaba establecido por el programador. Todo lo que debe tener en cuenta el programador es que el tiempo de respuesta de la condición por la que se pregunta sea menor que el tiempo en que se desborda el Perro Guardián. El Módulo de Captura, Comparación y PWM. Estas tres funciones por lo general vienen implementadas en un mismo dispositivo, a pesar de que realizan funciones diferentes, ya que utilizan los mismos recursos para efectuar su operación. Por lo general este recurso compartido es uno de los Temporizadores. Cada una de las funciones viene implementada mediante un Modo de operación específico. Estos Modos de Operación son: •

Modo de Captura.



Modo de Comparación.



Modo de Modulación de Ancho de Pulsos.

En el Modo de Captura la función fundamental es la de capturar la información que existe en uno de los Temporizadores al ocurrir una condición externa al microcontrolador. Para ello, en un registro interno del microcontrolador, por lo general de 16 bits, se almacena el valor en curso en el Temporizador siempre que ocurra dicha condición externa, introducida al microcontrolador a través de uno de sus terminales. Lo que puede constituir una condición, esta muy en dependencia del microcontrolador que sea, pero alguna de las más comunes resultan ser: •

Un flanco ascendente.



Un flanco descendente.



Cada 4 flancos ascendentes.



Cada 16 flancos ascendentes.

Al verificar el microcontrolador la ocurrencia de una de las posibles condiciones externas, este lleva a cabo una captura del valor en el Temporizador en cuestión y se activa una bandera interna indicando que es el momento de leer el valor en el registro de captura correspondiente. Esta bandera puede generar un pedido de interrupción, si esta habilitada, librando al programa de chequear mediante muestreo cuando dicha bandera se hace verdadera. Una aplicación del Modo de Captura puede ser la medición de los intervalos de tiempo que transcurre entre dos pulsos que ocurren externamente. Para ello el acontecimiento que se vigila es

Microcontroladores. El 8051 de la INTEL.

31

la ocurrencia del flanco de subida de la señal en cuestión y con ambos valores tomados del registro de captura se puede determinar el tiempo transcurrido entre uno y otro pulso. En el Modo de Comparación la función fundamental es la de comparar el valor de un registro interno con el contenido de uno de los Temporizadores. Para ello, cuando el Modulo trabaja de esta manera el contenido de dicho registro interno, previamente definido por el fabricante, se compara continuamente con el contenido de uno de los Temporizadores, cuando coinciden ambos valores, el microcontrolador lo puede indicar mediante el cambio del valor en un terminal de salida previamente configurado para esta tarea o mediante la activación de un pedido de interrupción. En el Modo de Modulación por Ancho de Pulsos la función fundamental es la de modular el intervalo de tiempo en el que cambia de ´1´ a ´0´ un determinado terminal de salida del microcontrolador. Para ello el contenido de un registro interno de este, por lo general de 8 bits, se compara con el valor almacenado en uno de los Temporizadores, enmarcando el tiempo de ´1´ y de ´0´ de una determinada señal que se genera externamente a través de uno de los terminales del microcontrolador. Este modo de operación puede ser de gran utilidad para el control de la velocidad de los motores de corriente directa. El Puerto Serie. La solución de la comunicación entre dispositivos separados entre si distancias relativamente largas, pasa hoy en día de forma insoslayable por la transmisión y la recepción de los datos de forma serie. Un ejemplo de lo anterior lo podría constituir la necesaria comunicación de un equipo construido en base a un microcontrolador y diseñado para la adquisición de datos de forma remota en un determinado proceso industrial con una microcomputadora donde se encuentra instalado el Programa Supervisorio de todo el sistema. La mejor solución en este caso, para la comunicación, lo constituiría la creación de un canal serie entre ambos dispositivos. Para ello se hace necesaria la existencia de un dispositivo interno en el microcontrolador que convierta los datos paralelos que se mueven dentro del microcontrolador a un formato serie que permita su transmisión hacia el dispositivo externo y lo inverso, la conversión de los datos que le llegan al microcontrolador serie del dispositivo externo en paralelo para que pueda ser utilizado internamente por el microcontrolador. Para el diseñador en este caso sería de gran utilidad el poder contar con un Puerto Serie que se encargue de estas dos tareas. Existen dos formas básicas de efectuar esta transmisión serie, conocidas como Sincrónicas y Asincrónicas. En la Comunicación Serie Sincrónica conjuntamente con los datos, el microcontrolador amo transmite una señal de reloj que es utilizada por el microcontrolador esclavo

Microcontroladores. El 8051 de la INTEL.

32

para la recepción de los mismos, los datos son transmitidos a la frecuencia de la señal de reloj. En el caso de la Asincrónica no existe esta señal de reloj independiente de los datos para sincronizar la recepción de los mismos, sino que la señal de sincronización viaja conjuntamente con el dato y constituye el primer bit de la transmisión. Los bits de datos que le siguen se transmiten a una determinada frecuencia de bits reconocida por el receptor, que le permiten a este sincronizar la recepción de los datos. De la explicación anterior podemos concluir que independientemente de la forma empleada para la transmisión serie de los datos, contamos con una cadena serie de bits que constituyen los datos y una determinada frecuencia a la que se transmiten dichos bits. Esto es lo que provoca que el circuito básico Puertos Serie lo constituyan los Registros Desplazamiento. Estos circuitos son capaces de desplazar de forma serie un dato a una frecuencia dada. Para ello cuentan con un conjunto de biestables internos concatenados de forma serie, la salida del biestable anterior constituye la entrada del biestable siguiente, con entrada de reloj común. Estos, además permiten cargar sus biestables con un dato que le llega de forma paralela y leer la información almacenada en estos de forma paralela. La señal de reloj a los biestables en muchos microcontroladores es entregada por uno de los Temporizador. El Conversor A/D. Son muchas las aplicaciones donde se emplea el microcontrolador para conocer el valor en unidades de ingeniería que tiene una determinada variable física, como puede ser la Temperatura, la Humedad Relativa, la Presión en una Tubería, etc. Para ello se hace necesario poder contar en el sistema con algún elemento transductor que convierta el valor de esta variable física en el valor de una determinada variable eléctrica, como puede ser un valor de Resistencia, un valor de Capacidad, etc. Por lo general estos dispositivos son conocidos con el nombre de Sensores. Generalmente los sensores vienen acompañados de otro circuito, que se conocen con el nombre de Transmisor, que convierte esta variable eléctrica en una señal eléctrica lista para ser transmitida. Esta señal eléctrica puede ser un voltaje o una corriente enmarcada en un intervalo de valores continuos. Esta señal es la que llega en la mayoría de las aplicaciones al microcontrolador para su procesamiento. La característica fundamental de esta señal es que la misma es analógica, no digital, por lo que seria muy útil poder contar en el microcontrolador con algunas entradas que aceptaran señales analógicas y con un circuito interno que convierta esta señal analógica en un número digital listo para ser procesado por el este. Muchos microcontroladores cuentan con estas entradas

Microcontroladores. El 8051 de la INTEL.

33

analógicas, por lo general más de una, y con estos circuitos conversores analógicos – digitales, ejemplo de ello son el 16F873 y algunas versiones del 8051. De esta manera todo lo que tiene que hacer el programador es dar inicio al proceso de conversión al conversor, esperar por que este concluya, para leer un número digital que estará relacionado con el valor de voltaje o de corriente impuesto por el transmisor del sensor en la entrada analógica correspondiente. La característica fundamental de estos Conversores Análogo - Digitales lo constituye el número de bits con que entregan el valor digital obtenido producto de la conversión de la señal analógica. Este número de bits esta relacionado con la precisión del conversor y con la posibilidad del microcontrolador de trabajar con valores más cercanos al valor real de la señal analógica. Por lo general estos conversores son de 8 o de 10 bits. Ya conocemos los elementos más comúnmente encontrados en los microcontroladores, su función, modo de operación y posibles aplicaciones a resolver con los mismos, pero, ¿Nos encontraremos todos estos circuitos empotrdos en el microcontrolador 8051? ¿Cómo trabajar con los que existen? ¿Qué posibilidades y qué limitaciones me brindan? Esperemos dar respuestas a estas interrogantes mediante el estudio del microcontrolador 8051 objetivo fundamental de los temas que aparecen a continuación en este material.

Microcontroladores. El 8051 de la INTEL.

34

Tema 2. El microcontrolador 8051. Se considera a INTEL como el "padre" de los microcontroladores. Este fabricante siempre ha ido por delante de los demás presentando los nuevos productos. El primer microcontrolador de 8 bits se considera al 8048 y lo fabricó esta compañía en la década de los 70. La siguiente generación, más evolucionada, fue la del 8051 / 8052 a la que ha seguido la de 16 bits, 80C196, que alcanza frecuencias de funcionamiento de hasta 50 Mhz. Con buen olfato comercial, INTEL ha lanzado versiones de microcontroladores basados en los microprocesadores 8088 y 8086. Se trata de los modelos 80188 y 80186. La misma política ha seguido con el 80386 creando el 80386EX. Estos últimos productos permiten trabajar con las herramientas clásicas desarrolladas para el entorno de la PC. 2.1 La Familia MCS-51. En el titulo de este epígrafe ha aparecido una palabra nueva, familia. Por su puesto que es nueva cuando estamos hablando de microcontroladores pero de la cual tenemos una definición en la vida social muy clara. La pregunta a contestar en este momento podría ser, ¿Qué constituye una familia de microcontroladores? Por regla los fabricantes cuando sacan al mercado un microcontrolador lo acompañan de un conjunto de versiones del mismo que son los que constituyen su familia. Estas versiones se caracterizan por tener un alto porciento de compatibilidad del punto de vista del hardware y del software entre si, pero presentan algunas diferencias como pueden ser: el tipo de memoria de programa que utilizan, la capacidad de la memoria de programa y de datos, el tipo y número de dispositivos complementarios que traen integrado, las posibles fuentes de interrupción, etc. Todos estos aspectos hacen que los microcontroladores que integran una familia sean similares pero no iguales. Con el nombre de MCS-51 se define a una familia de microcontroladores de 8 bits desarrollados originalmente por la INTEL, de la cual el microcontrolador 8051 es su principal representante.. Este microcontrolador de 8 bits, presenta un software orientado a facilitar el desarrollo de aplicaciones para la instrumentación y el control. Con una gran flexibilidad del punto de vista del hardware constituye un dispositivo ideal, del punto de vista económico y de tiempo de desarrollo para la solución de aplicaciones que demanden la necesidad de pocos recursos en su solución. Los primeros microcontroladores de esta familia que INTEL coloca en el mercado respondían a la tecnología de fabricación HMOS y llevaban el nombre de 8051AH, 8031AH y 8751H.

Microcontroladores. El 8051 de la INTEL.

35

¿Qué es lo que tenían de común estos dispositivos que posibilitaba su inclusión dentro de una misma familia de microcontroladores? ¿Qué es lo que los diferencia y les daba particularidades propias? Como características comunes estos tres dispositivos tenían las siguientes: •

Necesidad de una sola fuente de alimentación de 5 volts.



Unidad Central de Procesos de 8 bits.



Oscilador interno.



128 byte de Memoria de Datos interna.



Cuatro Bancos de Registros internos.



128 banderas posibles a definir por software por el programador.



Ciclo de Instrucción de un microsegundo a 12 Mhz.



Dos Temporizadores de 16 bits.



Una Unidad Asincrónica Serie Full Duplex.



Seis fuentes de interrupción vectorizada con cinco vectores, estructurada en dos niveles de prioridad.



Modos de Direccionado Directo, Indirecto, Inmediato, Extendido y de Bit en sus Instrucciones.



Instrucciones para la aritmética binaria y decimal, incluyendo instrucciones para la Multiplicación y la División.



Procesador Booleano integrado para las aplicaciones de control.



Modo Especial de Trabajo en el que se le pueden conectar al sistema de forma externa hasta 64 Kilobyte de Memoria de Programas y 64 Kilobyte de Memoria de Datos.

Un aspecto establecía la diferencia entre estos tres dispositivos. Este aspecto estaba relacionado con la existencia o no y el tipo de la Memoria de Programa interna para aquellos que la tuvieran. En el caso del 8031AH no tiene Memoria de Programa interna lo que imponía al diseñador siempre utilizarlo en el Modo Especial de Trabajo, conectándole la Memoria de Programa de forma externa. Esto a su vez condicionaba a que este microcontrolador tuviera que generar su propio Bus de Direcciones y de Datos externo lo que lo limitaba en cuanto al numero de terminales disponibles para líneas de entrada / salida, quedando limitado a solo 16 agrupadas en dos Puertos de 8 bits. Son estas las razones por la que muchos se cuestionan si esta versión de la familia constituye realmente un microcontrolador o es en realidad un microprocesador con dispositivos empotrados para realizar determinadas funciones.

Microcontroladores. El 8051 de la INTEL.

36

Por su parte las versiones 8051AH y 8751H cuenta con una capacidad de Memoria de Programas interna de 4 Kilobyte, lo que posibilitaba al usuario grabar sus programas de aplicación en el propio microcontrolador y no tener que utilizar las posibilidades que brinda el Modo Especial de Trabajo. Esto además permitió a los diseñadores contar con un número mayor de terminales disponibles para sus aplicaciones al contar con otros dos Puertos de entrada / salida de 8 bits con lo que elevaban a 32 el número de líneas con este fin. ¿Qué marcaba la diferencia entre estos dos últimos dispositivos? La diferencia venia dada por el tipo de memoria empleada para la materialización de la Memoria de Programa interna. Mientras que el 8051AH utilizaba un tipo de Memoria OTP, el 8751H utilizaba un tipo de Memoria EPROM. Estos elementos condicionaban la elección de uno u otro dispositivo en dependencia de la aplicación que se deseará resolver. Si su aplicación una vez puesta a punto no se previa un posible cambio en el software, escoger el 8051AH, si por el contrario era factible la ocurrencia de cambios en el software desarrollado inicialmente, entonces escoger el 8751H. De lo anterior nos queda una posible interrogante a responder, ¿Cuándo utilizar el 8031AH? La utilización del 8031AH es muy útil durante la fase de puesta a punto de los sistemas en que se hace necesaria la programación de diferentes versiones de programas ante de encontrar el definitivo. Esto permite que las versiones de prueba se programen en Memorias EPROM conectadas externamente y solo se lleve al microcontrolador escogido, la versión definitivamente probada con resultados satisfactorios. Después de este comienzo dado por la INTEL y ante el éxito del nuevo dispositivo en la solución de múltiples aplicaciones, muchas otras compañías productoras de circuitos integrados se dieron a la tarea de introducir al mercado sus propias versiones de los microcontroladores de esta familia, destacándose entre ellas a la compañía Analog Devices con su línea de microcontroladores ADUC8xx, las compañías Atmel y Philips con una variedad de microcontroladores de esta familia superior hoy en día a la que produce la propia INTEL, la compañía Dallas Semiconductor con su línea de Microcontroladores DS muy poderosos en cuanto a la ampliación de sus capacidades y la Texas Instruments con su línea de dispositivos TS entre otras.

Microcontroladores. El 8051 de la INTEL.

37

Las nuevas versiones se caracterizaban por agregar nuevas posibilidades al microcontrolador. Así aparecieron versiones que aumentaban la capacidad de Memoria de Programa hasta 8 Kilobyte, aumentaban la Memoria de Datos hasta 1 Kilobyte, agregaban otros dispositivos de interfaz como: otro Temporizador, Perro Guardián, entradas Analógicas, etc., que ya hacen verdaderamente difícil enmarcar a este microcontrolador en un conjunto de posibilidades fijas como ocurrió en las primeras versiones de INTEL. Otro aspecto que fue variando con el desarrollo de nuevas versiones lo constituye la tecnología de fabricación del microcontrolador. Después de las primeras versiones con tecnología HMOS aparecieron otros dispositivos con tecnología de fabricación CHMOS, lo que brindaba un microcontrolador de más bajo consumo que los anteriores y por lo tanto permitía el integrar en el circuito un número mayor de posibilidades o circuitos complementarios. Así surgieron los dispositivos 8XC51FA y 8XC51FB que incorporan un bloque PLA (Arreglo Lógico Programable) interno con lo que aparecieron en estos microcontroladores funciones tales como: •

Salida de Alta Velocidad.



Circuito de Comparación, Captura y PWM.

En su búsqueda por aumentar de forma cuantitativa las posibilidades de su microcontrolador de 8 bits, el 8051, la INTEL saca al mercado una nueva familia de microcontroladores a la que nombro MCs – 52 de la cual el microcontrolador 8052 es su principal representante. ¿Cuáles son las cosas comunes y cuales las diferencias entre estas dos familias de microcontroladores de la INTEL? 2.2 Los parientes cercanos, la Familia MCs - 52. Son pocas las diferencias que existen entre estas dos familias de microcontroladores, tan pocas que generalmente cuando se habla de una se menciona siempre a la otra. Entre las cosas comunes podemos mencionar: •

La existencia de las tres versiones, con Memoria de Programa OTP o EPROM o sin Memoria de Programa presente entre los miembros de la familia MCs - 51 están presentes también en la familia MCs - 52, por lo que nos encontramos: 8032. Sin Memoria de Programa interna. 8052. Con Memoria de Programa del tipo OTP. 8752. Con Memoria de Programa del tipo EPROM.

Microcontroladores. El 8051 de la INTEL. •

38

Los terminales de los microcontroladores de la familia MCs - 52 presentan las mismas funciones que la de los microcontroladores de la familia MCs - 51, razón por la cual son compatibles pin a pin.



Con respecto al Repertorio de Instrucciones, todas las instrucciones presentes en el repertorio de los microcontroladores de la familia MCs - 51 se encuentran presentes en el Repertorio de Instrucciones de los microcontroladores de la familia MCs- 52, razón por la cual los programas desarrollados para el primero pueden ser ejecutados por el segundo sin necesidad de efectuar ningún arreglo a los mismos.



Los microcontroladores de la familia MCs - 52 cuentan también con: Necesidad de una sola fuente de alimentación de 5 volts. Unidad Central de Procesos de 8 bits. Oscilador interno. Cuatro Bancos de Registros internos. 128 banderas posibles a definir por software por el programador. Ciclo de Instrucción de un microsegundo a 12 Mhz. Dos Temporizadores de 16 bits. Una Unidad Asincrónica Serie Full Duplex. Modos de Direccionado Directo, Indirecto, Inmediato, Extendido y de Bit en sus Instrucciones. Instrucciones para la aritmética binaria y decimal, incluyendo

instrucciones para

la Multiplicación y la División. Procesador Booleano integrado para las aplicaciones de control. Modo Especial de Trabajo en el que se le pueden conectar al sistema de forma externa hasta 64 Kilobyte de Memoria de Programas y 64 Kilobyte de Memoria de Datos. ¿Qué elementos los diferencia? En la práctica a los microcontroladores de la familia MCs - 52 los debemos ver como una ampliación cuantitativa de los microcontroladores de la familia MCs- 51 y en esto estriban sus diferencias, las que las podemos resumir en los siguientes tres aspectos: •

La capacidad de Memoria de Programas interna aumenta a 8 Kilobyte.



La capacidad de Memoria de Datos interna aumenta a 256 byte.



El número de Temporizadores de 16 bits aumenta a 3.

¿Qué consecuencias traen estas ampliaciones?

Microcontroladores. El 8051 de la INTEL.

39

El aumento en cantidad de las capacidades de memoria interna solo trae como consecuencias ventajas para el diseñador al contar con más espacio para sus aplicaciones ya desde el momento que coloca el microcontrolador en su sistema sin la necesidad de efectuar ampliaciones. En el caso de la Memoria de Programa el aumento de la capacidad permite el poder contar con más espacio de memoria para almacenar los códigos de los programas almacenados internamente y por lo tanto poder resolver aplicaciones con un grado de complejidad que demanden programas más extensos. En el aso de la memoria de datos aumenta de forma significativa, en el doble, el espacio para almacenar los datos temporales propios de cualquier aplicación. Por su parte el agregar un tercer Temporizador, además de la ventaja que nos da el contar con un circuito de estas características más, integrado en el propio microcontrolador para la solución de las aplicaciones, trae como consecuencia la necesidad de aumentar el repertorio de Instrucciones del microcontrolador con aquellas instrucciones destinadas para trabajar con este Temporizador, así como el aumento del número de fuentes de interrupciones posibles y de vectores de interrupción disponibles. Una vez conocidas las características principales del microcontrolador 8051 en cuanto a los dispositivos que lo componen enfrentémonos a la tarea de conocer como están distribuidos estos dispositivos internamente en el microcontrolador y para ello comencemos con el estudio de cómo esta estructurada internamente la memoria interna. Al finalizar el estudio del mismo debemos ser capaces de darle respuesta a preguntas tales como, ¿Cuál es la capacidad máxima de memoria para almacenar códigos de programa contamos internamente en el Microcontrolador? ¿Cuál es la capacidad máxima para el almacenamiento de datos? ¿Cuál es la estructura de almacenamiento tanto de datos como de códigos de programas en la memoria? ¿Cómo referirnos al contenido de una localización de memoria de programas? ¿Cómo almacenar un dato en la memoria de datos?, ¿Cómo recuperarlo? ¿Qué son los Registros de Funciones Especiales? 2.3 La Memoria Interna del microcontrolador 8051. Internamente el 8051 consta con 4 Kilobytes localizaciones para almacenar los códigos del programa y 128 bytes localizaciones para almacenar datos. Además existen un conjunto de localizaciones ubicadas en una zona conocida con el nombre de Registros de Funciones Especiales, la que se encuentra estrechamente relacionada con la programación de dispositivos

Microcontroladores. El 8051 de la INTEL.

40

internos del mismo, el estudio de estos tres bloques de memoria constituye el objetivo de este epígrafe. Localización, dirección y contenido. Como ya conocemos la arquitectura interna del 8051 responde a la arquitectura de Von Newman por lo que todos los tipos de memoria comparten un mismo bus para efectuar el movimiento de la información contenidos en ellos, ver Figura 2.3.1.

Figura 2.3.1 Memoria Interna del 8051. Esto impone que el tamaño de los datos a almacenar y los códigos de programa sean del mismo número de bits, en este caso 8 bits, de ahí que cuando se habla de capacidad de Memoria de Programa interna se habla de Kilobyte y cuando se habla de capacidad de Memoria de Datos se habla de bytes. Por lo tanto una localización de memoria, independientemente que sea de memoria de programa o de memoria de datos, contiene un número expresado en byte (8bits) y a la misma le corresponderá una dirección que será la forma de referirse a ella en el programa. Esta dirección vendrá dada por 16 bits. Observemos la Figura 2.3.2 tratemos de aplicar lo expresado hasta aquí de forma que nos sirva para una mejor comprensión.

Microcontroladores. El 8051 de la INTEL.

41

El contenido de la localización de memoria

de

programa

cuya

dirección es la 0010H en la Figura 2.3.2 se corresponde con el número en hexadecimal 30H, mientras que el

contenido

0011H número dirección

se

de

la

localización

corresponde

8DH,

mientras

0012H

el

con

el

que

la

dato

que

contiene es el 6AH.

Una pregunta interesante a responder en este momento sería, si los dos tipos de memoria comparten el mismo bus interno ¿Por qué cuando nos referimos a ellas las diferenciamos? La razón anterior se basa en que las instrucciones destinadas para trabajar con ellas son diferentes, existiendo instrucciones para leer de Memoria de Programas y existen instrucciones para leer o escribir en Memoria de Datos. A esta forma de trabajar las memorias se le conoce con el nombre de Memoria Segregada. De lo explicado hasta aquí se aparta un tanto el Microcontrolador 8031, al no contar con Memoria de Programa interna. En cuanto a la Memoria de Datos las características si son similares. La Memoria de Programas. En la Figura 2.3.3 se muestra la estructura interna de los 4 Kilobyte de Memoria de Programa básicos que contienen internamente los microcontrolador 8051. Observe que existen algunas localizaciones que se han destacado porque tienen un significado especial en la operación del mismo.

Microcontroladores. El 8051 de la INTEL.

42

La localización 0000H ya la habíamos estudiado, esta es la localización de memoria de programa donde se debe almacenar el código de la primera instrucción de nuestro programa. Observe que esta relacionada a la izquierda en la figura con la palabra RESET, palabra esta que esta relacionada a su vez con uno de los terminales externos del microcontrolador y que será el empleado por nosotros para indicarle que debe comenzar con la ejecución del programa almacenado. Por el momento, contentémonos con esta explicación la que será ampliamente debatida en el Tema 3. Las otras cinco localizaciones están relacionadas con las 6 fuentes posibles de interrupción con que cuenta este microcontrolador y representan las localizaciones donde se debe almacenar el código de la primera instrucción de las subrutinas de atención correspondiente. La 0003H esta relacionada con la Interrupción Externa 0, la 000BH con la interrupción que genera el Temporizador 0, la 0013H con la Interrupción Externa 1, la 001BH con la interrupción que genera el Temporizador 1 y la 0023H con el pedido de interrupción del Puerto Serie. Para los lectores que no estén relacionados con los microprocesadores dos aspectos tocados en el párrafo anterior les resultarán desconocidos, la interrupción y la subrutina. La interrupción es el proceso mediante el cual el microcontrolador podrá sincronizar la ocurrencia de eventos externos cuya ocurrencia le son impredecibles. Esta es una técnica que a estado presente desde los primeros microprocesadores y que las han heredados los microcontroladores. Por su parte la subrutina es un fragmento de programa concebido específicamente para la atención de un pedido de interrupción. Este fragmento de programa tiene características propias que lo diferencian del

Microcontroladores. El 8051 de la INTEL.

43

resto de los fragmentos que pueden existir en el programa. Estos dos aspectos los estudiaremos con más profundidad en el tema destinado al estudio de la Interrupción. Una preocupación de los productores de sistemas basados en este microcontrolador es la posibilidad de que intrusos puedan leer los programas grabados en la Memoria de Programa y con ello reproducir sus equipos. Para protegerse de esta situación los fabricantes han establecido dos niveles de protección, consistentes el primero, en una cadena de encriptación y el segundo, en dos bits de cerrojo. Dentro de la Memoria de Programa hay 32 localizaciones destinadas para conformar la cadena de encriptación, la que inicialmente esta desprogramada. Cada vez que una localización es direccionada durante el proceso de verificación, se utilizan 5 líneas de dirección para seleccionar una de las localizaciones de la cadena de encriptación. Su contenido es sometido a la operación lógica XNOR con el contenido de la localización que esta siendo grabada creando un byte encriptado. Si la cadena de encriptación esta desprogramada, todos los bits en ´1´, al efectuarse la operación XNOR con el contenido de la localización de memoria, este no resulta modificado y podría ser leído fácilmente. También en el circuito existen 2 bits, los que son conocidos como bits de cerrojo los que pueden ser programados (P) o desprogramados (D), obteniéndose los resultados que se indican en la Tabla 2.3.1. Bit 2

Bit 1

Característica

D

D

Funcionamiento sin protección.

D

P

No se permite acceder externamente los contenidos de la Memoria de Programa interna, además de no permitir ser programada.

P

P

Externamente no puede accederse a los contenidos de la Memoria de Programas interna. No permite ser programada. No permite la verificación del programa.

Tabla 2.3.1 Efecto de los bits de cerrojo sobre la Memoria de Programas. Al borrar la Memoria de Programa, en el caso de que la versión del microcontrolador, de ser posible, también se borra la cadena de encriptación y los bits de cerrojo permitiéndole al diseñador realizar una nueva programación de los mismos.

Microcontroladores. El 8051 de la INTEL.

44

La Memoria de Datos. En la Figura 2.3.4 se muestra la estructura de la Memoria de Datos interna. En total esta zona de memoria ocupa 256 localizaciones, 128 están destinadas al Área de Almacenamiento de Datos y el resto forma parte del Área de Registro de Funciones Especiales (SFR).

El acceso a las localizaciones ubicadas en el Área de Almacenamiento de Datos puede realizarse mediante el empleo de instrucciones con Modos de Direccionado Directo e Indirecto, mientras que las localizaciones ubicadas en el Área de los Registros de Funciones Especiales solo se puede acceder mediante instrucciones que utilizan Modos de Direccionado Directo. Quizás algunas dudas que pudieran surgir en este momento estarían relacionadas con las siguientes preguntas, ¿Qué diferencia existe entre estas dos Áreas? ¿Qué son los Registros de Funciones Especiales? Pasemos a estudiar cada una de estas áreas de forma independiente y esperemos poder encontrar las respuestas deseadas.

Microcontroladores. El 8051 de la INTEL.

45

El Área de Almacenamiento de Datos. El Área de Almacenamiento de Datos la podemos dividir en 3 segmentos atendiendo a la función para los que están destinados dentro del Microcontrolador, ver Figura 2.3.5:

El Segmento de Banco de Registros ocupa las 32 localizaciones bajas del Área de Almacenamiento de Datos, correspondiéndole las direcciones de la 00h a la 1Fh. Estas localizaciones se encuentran organizadas en 4 grupos de 8 localizaciones cada uno, los que son llamados Bancos de Registros 0, 1, 2 y 3 respectivamente, ver Figura 2.3.5. De forma tal que cada Banco de Registro consta de 8 localizaciones a las que se le asignan los nombre, R0, R1, R2, R3, R4, R5, R6 y R7, de las direcciones bajas hacia las altas, ver Figura 2.3.6. Estas localizaciones tienen algunas facilidades en el trabajo con ellas al ser tratadas como registros, permitiendo al programador referirse a las mismas en las instrucciones con solo declarar su nombre así como utilizarlas como puente en las

instrucciones

para

referirse

a

otras

localizaciones de memoria de datos. Uno solo de estos Bancos de Registros puede ser tratado como tal en un momento dado en la ejecución del programa, el que debe estar bien claro para el programador sino quiere cometer errores en su programa.

Microcontroladores. El 8051 de la INTEL.

46

Por ejemplo, si el Banco de Registros 0 es el que esta seleccionado, cada instrucción que en el programa se refiera a uno de estos registros se estará refiriendo a los registros de este banco, ver Figura 2.3.6 y los registros de los bancos restantes tienen que ser tratados como localizaciones de memoria normales y por lo tanto referirse a estos mediante sus direcciones. Una buena pregunta a hacerse en este momento sería, si solo puede estar activo uno de los Bancos de Registros, ¿De qué me sirve que existan cuatro Bancos de Registros? La repuesta a esta pregunta esta en la posibilidad mediante instrucciones de poder escoger cual es el Banco de Registro que yo quiero que se encuentre activo en un momento dado, por lo tanto puedo estar trabajando con más de uno o con los cuatro a la vez y escoger cual es el que es necesario que este activo en un momento determinado en la ejecución del programa. La pregunta a hacerse en este momento sería, ¿Cómo cambiar el Banco de Registros que esta activo en caso que sea necesario? Para poder explicar esto tenemos la necesidad de referirnos de forma momentánea al Banco de Registros Especiales que es la otra zona que comparte el espacio de la memoria de programa con esta área. Dos bits, los bits 3 y 4 del registro PSW ubicado en el Área de los Registros de Funciones Especiales definen cual de los Bancos de Registros se encuentra activo, ver Figura 2.3.7

El registro PSW es direccionable bit a bit, esto quiere decir que existen instrucciones que permiten poner a ´0´ o poner a ´1´ estos bits de forma independiente sin afectar el valor que tiene el resto de los bits en el registro. Estas instrucciones son CLR, pone a ´0´

al

bit

especificado

en

la

instrucción y SETB, pone a ´1´ al bit especificado en la instrucción.

Microcontroladores. El 8051 de la INTEL.

47

Por ejemplo, si el banco de registro que se encuentra activo es el 0, esto quiere decir que tanto RS0 como RS1 tienen el valor de ´0´, y se desea conmutar hacia el Banco de Registro 2 bastaría con hacer ejecutar al microcontrolador la instrucción, SETB RS1

; Pone a ´1´ al bit RS1 del registro PSW y con ello se conmuta al ; al banco de registros 2 ya que anteriormente RS0 estaba ya en ´0´.

A partir de esta instrucción en el programa, todas las instrucciones que se refieran a uno de los registros de R0 a R7 se estarán refiriendo a los registros correspondientes al Banco 2 que se encuentran ubicados en las localizaciones de Memoria de Datos de la 10h a la 17h, ver Figura 2.3.5. La información que se encontraba almacenada en los registros del banco 0 antes de conmutar de bancos no se pierde y para referirse a ellas solo basta direccionarlas a través de sus direcciones o conmutando nuevamente de banco. Existe una estructura de datos propia de los sistemas a microprocesadores para el trabajo con el mecanismo de Interrupción y que fue heredada por los microcontroladores, que se conoce con el nombre de Pila. La Pila es una estructura de datos en la cual el último dato que entra a la misma es el primer dato que esta disponible para ser sacado de esta. Es como lo que ocurre cuando se lavan los platos después de la comida, primero todos los platos son enjabonados uno a uno y puestos uno encima del otro hasta formar una pila de platos, una vez enjabonados todos, el último plato que se enjabono será el primero en ser enjuagado y así sucesivamente. Esta estructura es extremadamente importante para poder lograr el anidamiento de las interrupciones, aspecto que estudiaremos a profundidad en el tema dedicado a la interrupción. Esta zona de memoria destinada por el microcontrolador para almacenar la dirección a la que debe retornar la ejecución del programa, una vez que concluya con la atención del pedido de Interrupción. En el 8051, a diferencia de otros microprocesadores, la Pila solo puede ocupar una zona de memoria específica ubicada en el área de la memoria de datos y no cualquier zona como ocurre en la mayoría de los microprocesadores.

Esta zona de memoria tiene destinado un número de

localizaciones de memoria fija, 8, y una zona de memoria especifica de la dirección 08H hasta la 0Fh coincidiendo con las direcciones destinadas para los registros del Banco 1. Esto debe ser tomado en cuenta por el programador si en su sistema los servicios de Interrupción serán utilizados.

Microcontroladores. El 8051 de la INTEL.

48

El Segmento de Localizaciones direccionable bit a bit esta conformado por 16 localizaciones desde la localización 20h hasta la localización 2Fh, ver Figura 2.3.8.

¿Qué tienen de particular estas localizaciones? Como ya se explico anteriormente, existen instrucciones dentro del Repertorio de Instrucciones del microcontrolador que permiten accesar a los bits de cada una de las localizaciones de este Segmento de forma independiente. Es decir, estas localizaciones tienen la misma facilidad que alguno de los registros de funciones especiales. Es bueno aclarar que esto es solo posible en las localizaciones de memoria que se encuentran ubicadas en este segmento de la memoria de datos. Por ejemplo, el programador podrá poner a ´0´ o a ´1´ uno de los bits cualquiera de una de estas localizaciones mediante las instrucciones CLR y SETB sin afectar el valor del resto de los bits de la misma, tal y como hicimos con los bits RS0 y RS1 del registro PSW. Esta no es la única operación que podemos hacer mediante instrucciones sobre estos bits, por ejemplo podríamos preguntar el valor que tienen, ´0´ o ´1´, mediante las instrucciones JB y JNB la dirección del bit en cuestión.

Microcontroladores. El 8051 de la INTEL.

49

Esta posibilidad puede resultar muy útil en aplicaciones dedicadas al control automático ya que en dichos bits se puede almacenar el estado de elementos del tipo On – Off que funcionan en el sistema bajo control. En total son 16 localizaciones de 8 bits o lo que es lo mismo 128 bits que pueden ser utilizados como banderas en los programas para indicar estados de variables digitales, secuencias de programas, etc. Ahora bien, ¿Cómo especificar en la instrucción el bit con que queremos trabajar entre todos los que están en esta zona? Son dos las maneras: •

la primera declarando la dirección de la localización a la que pertenece el bit en cuestión, seguida de un punto y a continuación la posición del bit dentro de la localización. 20h.5



; bit 5 de la localización cuya dirección es 20h.

La segunda mediante la dirección directa que ocupa el bit dentro de todo el mapa de bits de esta zona, ver Figura 2.3.8. 05h

; se referencia al mismo bit.

Si no se desean accesar estos bits de forma independiente sino como parte del byte al que pertenece, el programador esta habilitado mediante el empleo de la dirección de la localización en la instrucción. Por su parte el Segmento de Trabajo lo ocupan las localizaciones restantes desde la 30h hasta la 7Fh. Este segmento se define como un área de memoria de poca capacidad pero de acceso rápido, muy útil para almacenar datos temporales de los programas. Para referirse a estas localizaciones de memoria se tiene que hacer mediante la declaración de la dirección de la localización en cuestión en la instrucción o refiriéndose a ella mediante el contenido de los Registros R0 y R1 del banco que se encuentre activo. El Área de Registros de Funciones Especiales. El Área de Registro de Funciones Especiales (SFR), como su nombre lo indica esta conformada por un conjunto de registros de 8 bits, que juegan diferentes papeles en la configuración de la

Microcontroladores. El 8051 de la INTEL.

50

operación del microcontrolador. Es un área que tiene 128 localizaciones reservadas para registros, desde la localización 80h hasta la FFh, no obstante, no todas están ocupadas quedando algunas disponibles para futuras ampliaciones del microcontrolador. Las localizaciones que no están ocupadas por registros no pueden ser accesadas mediante programa y por lo tanto son localizaciones no utilizables por el programador. En la Tabla 2.3.2 se muestra un listado de estos registros con su nombre y la dirección de la localización que ocupan dentro de la Memoria de Datos. Símbolo

Nombre del Registro

Dirección

Acc

Acumulador

0E0H

B

B

0F0H

PSW

Palabra de Estado

0D0H

SP

Puntero de la Pila

81H

DPL

bms del Puntero de Datos

82H

DPLH

Bms del Puntero de Datos

83H

P0

Puerto 0

80H

P1

Puerto 1

90H

P2

Puerto 2

0A0H

P3

Puerto 3

0B0H

IP

Prioridad de la Interrupción

0B8H

IE

Habilitación de la Interrupción

0A8H

TMOD

Modo de los Temporizadores

89H

TCON

Control de los Temporizadores

88H

TH0

Byte Alto del Temporizador 0

8CH

TL0

Byte Bajo del Temporizador 0

8AH

TH1

Byte Alto del Temporizador 1

8DH

TL1

Byte Bajo del Temporizador 1

8BH

SCON

Control del Puerto Serie

98H

SBUF

Almacenador Puerto Serie

99H

PCON

Control de la Alimentación

87H

Tabla 2.3.2 Registros de Funciones Especiales. Algunos de estos registros son direccionable bit a bit al igual que ocurre con las localizaciones del Segmento Direccionable Bit a Bit, ya habíamos conocido al PSW,

Microcontroladores. El 8051 de la INTEL.

51

¿Cuáles serán los otros? Todos aquellos registros cuya dirección termina en 0 o en 8, marcados en negritas en el Tabla 2.3.2, pueden ser direccionados bit a bit, el resto no. Sin pretender profundizar en el significado de cada uno de los bits de todos los registros, lo cual haremos en la medida en que vayamos estudiando las diferentes funciones del microcontrolador, daremos una definición resumida de cada uno de ellos, en algunos casos con más profundidad que en otros, que permita al lector tener una primera aproximación a los mismos. Para una mejor comprensión los registros los agruparemos según su función en los siguientes 4 grupos: •

De propósito general.



De control del procesador.



Punteros.



Relacionados con los puertos de entrada / salida paralelos.



Relacionados con el puerto serie.



Relacionado con los Temporizadores.



De control de la Interrupción.

Registros de Propósito General. ACC (Acumulador). Es un registro de propósito general de 8 bits, el que por su frecuencia de utilización en los programas lo hacen convertir en el más importante. Se acostumbra a hacer referencia a este como registro A solamente. Ampliamente utilizado en las instrucciones aritméticas, lógicas y de rotación, aportando uno de los operandos de las mismas y constituyendo el operando destino en la mayoría de los casos. B (Registro B). Es un registro de 8 bits de propósito general especializado en las instrucciones de multiplicación (MUL AB) y de división (DIV AB). Este microcontrolador esta capacitado para efectuar operaciones de Multiplicación y de División de números expresados en 8 bits, no obstante para poder efectuar estas operaciones impone como condición que para almacenar los operandos que participan en la instrucción y posteriormente almacenar los resultados de la ejecución de la misma solo están capacitados los registros Acumulador y el registro B. Esto será estudiado a profundidad en el tema dedicado a las instrucciones del grupo aritmético.

Microcontroladores. El 8051 de la INTEL.

52

Registros de Control del Procesador. PSW (Registro de Estado). Contiene información del estado de la Unidad Central de Procesos durante la ejecución de los programas. Como ya se vio anteriormente permite al programador escoger el Banco de Registro activo. El resto de los bits de este registro contiene los conocidos bits de banderas, ver Figura 2.3.9.

Figura 2.3.9 Estructura interna del Registro PSW. ¿Qué función hacen estos bits de banderas? ¿Qué utilidad pueden tener para el programador? Al ejecutar instrucciones aritméticas, lógicas o de rotación, existe información que podría resultar de gran interés para el programador en una aplicación dada. Por ejemplo, el poder conocer la paridad de ´1´ en el resultado, o si el resultado obtenido cabe en el registro destinado para ser almacenado, etc. Esta función, de brindar información de interés al programador como resultado de la ejecución de algunas instrucciones la cumplen los bits de banderas. Específicamente este microcontrolador cuenta con 5 bits de banderas, con los siguientes nombres y funciones, ver Figura 2.3.9:

Microcontroladores. El 8051 de la INTEL.

53

CY (Bandera de Acarreo). Es un bit que en muchas instrucciones del microcontrolador se incorpora como el noveno bit del registro Acumulador. Informa si como resultado de la ejecución de la instrucción se ha cambiado su contenido o si se mantiene en el valor inicial. Muy útil en las operaciones aritméticas y de rotación. La interpretación que le de el programador a esta información esta muy relacionada con la instrucción que se ejecutó y con la aplicación que se esta resolviendo. Por ejemplo analicemos que puede ocurrir con el bit CY en la siguiente instrucción de adición, ADD

A, #05H

; adicionar al contenido del registro A la constante 05H ; almacenar el resultado en el registro A. ;A

A + 05H

Por lo tanto el resultado almacenado en el registro A después de ejecutada la instrucción depende en gran medida del número almacenado en dicho registro antes de ejecutar la instrucción. Supongamos que el número almacenado se corresponde con el FDH. A

FDH + 05H

Pero para almacenar el resultado de esta operación no basta con los 8 bits del registro Acumulador sino que se hace necesario un noveno bit como se puede ver en la operación mostrada a continuación. 1111 1101

FDH

+ 0000 0101

+ 05H

1 0000 0010

102H

¿Quién aportará este noveno bit? Este noveno bit lo aporta el bit de bandera CY no permitiendo que se pierda. Pero en este caso, quizás más importante que almacenar este noveno bit lo constituye, que el bit de bandera CY le indica al programador de que el registro seleccionado como destino del resultado no es capaz de almacenar el mismo y que por ende el debe tomar alguna decisión en su programa al respecto.

bit bandera CY

1111 1101

FDH

+ 0000 0101

+ 05H

1 0000 0010

102H

Microcontroladores. El 8051 de la INTEL.

54

AC (Bandera de Acarreo Auxiliar). Muy utilizado por el procesador pero de poca utilidad para el programador. Hace un papel similar al bit de bandera CY pero considerando solo los 4 bits menos significativos del registro Acumulador. Por ejemplo en el caso anterior al sumar los bits 3 de ambos operandos el resultado da ´0´ acarreando un ´1´ para la suma de los siguientes dos bits. Este acarreo es indicado por el bit de bandera de acarreo auxiliar. 1

bit de acarreo auxiliar

1111 1101

FDH

+ 0000 0101

+ 05H

1 0000 0010

102H

Este bit de bandera de acarreo auxiliar es de mucha utilidad para el Procesador cuando efectúa las operaciones de Ajuste Decimal que estudiaremos más adelante. F0 (Bandera Definible por el usuario). Como su nombre lo indica la utilidad de este bit de bandera y lo que indique queda a la libertad del programador que lo emplea como un bit más. OV (Bandera de Desbordamiento). Muy útil en las operaciones aritméticas con signo. Indica que existió acarreo del bit 6 al 7 y del 7 al bit de bandera CY como producto de la ejecución de una instrucción aritmética, y por lo tanto el signo del resultado puede ser el no esperado. Esto lo indica poniéndose a ´1´. P (Bandera de Paridad). Mediante el valor almacenado en este bit el microcontrolador indica el tipo de paridad que esta presente en el resultado obtenido producto de la ejecución de una instrucción aritmética o lógica determinada. La paridad esta relacionada con el número de bits en ´1´ de dicho resultado. Por ejemplo, si el bit de bandera P esta en ´1´ después de la ejecución de una instrucción aritmética dada, esto indica que el número de bits en ´1´ en el resultado es impar, si por el contrario el valor es ´0´ indica que el número de bits en ´1´ en el resultado es par. Por su puesto que lo valioso del trabajo con los bit de banderas está en poder conocer el valor que tienen después de ejecutada una determinada instrucción, por lo tanto la pregunta a responder en este caso sería, ¿Cómo conocer el estado en que se encuentra un determinado bit de bandera?

Microcontroladores. El 8051 de la INTEL.

55

Todo lo que tenemos que hacer es encuestar el valor del bit de bandera específico que nos es de interés en el momento dado del programa. Para ello existen instrucciones que nos permiten preguntar por el valor de uno de un bit de bandera en particular, recordemos que el registro PSW es uno de los registros que puede ser direccionada bit a bit. Ejemplo de estas instrucciones son, JC

dir1

; Salta a la dirección dir1 si el Bit de Acarreo es ´1´.

JNC

dir2

; Salta a la dirección dir2 si el Bit de Acarreo es ´0´.

Existiendo instrucciones de este tipo para cada uno de los bit de banderas

especificados

anteriormente, con excepción del Bit F0 al que debemos. Sobre estos bits del registro PSW volveremos cuando estudiemos las instrucciones aritméticas y lógicas. PCON (Control de Alimentación). Es un registro estrechamente relacionado con la posibilidad de escoger los modos de trabajo de bajo consumo, IDLE y POWER DOWN que presentan las versiones a CHMOS de este microcontrolador. Registros Punteros. DPL (Parte Baja del Puntero de Datos). Es un registro de 8 bits que contiene los 8 bits menos significativos (bms) de la dirección a donde apunta el Puntero de Datos. Este registro conjuntamente con el DPH es muy útil para el direccionamiento de las localizaciones de la Memoria de Programa cuando se trabaja con Tablas y de las localizaciones de la Memoria de Datos externa. DPH (Parte Alta del Puntero de Datos). Es un registro de 8 bits que contiene los 8 bits más significativos (Bms) de la dirección a donde apunta el Puntero de Datos. Este registro conjuntamente con el DPL es muy útil para el direccionamiento de las localizaciones de la Memoria de Programa en el trabajo con Tablas y de las localizaciones de la Memoria de Datos externa. SP (Puntero de la Pila). Es un registro de 8 bits que contiene la dirección del último dato almacenado en la Pila. De gran utilidad para el trabajo con la Interrupción y con subrutina. Registros relacionados con los puertos de entrada / salida paralelos. P0, P1, P2 y P3 (Registros Almacenadores de los Puertos). Son registros de 8 bits que como su nombre lo indican son los almacenadores de los datos enviados hacia los puertos por programa en las operaciones de escritura de datos y de ellos se toman los datos en las operaciones de lectura de datos.

Microcontroladores. El 8051 de la INTEL.

56

Existen un conjunto de registros que están estrechamente relacionados con los circuitos complementarios con que cuenta el microcontrolador como son, el Puerto Serie, los Temporizadores y la Interrupción, a través de los cuales se efectuará su programación. Estos registros serán explicados en detalles en los Temas correspondientes a estos dispositivos, no obstante en este momento los mencionaremos para que el lector se vaya familiarizando con ellos. Registros relacionados con el Puerto Serie. SBUF (Buffer del Puerto Serie). Son dos registros de 8 bits vinculados con el Puerto Serie Asincrónico, USART, del microcontrolador. Aunque separados físicamente, el Buffer del Transmisor y el Buffer del Receptor, la forma de referirnos a ellos en el programa es mediante una única dirección simbólica, SBUF. El Buffer del Transmisor como su nombre lo indica esta relacionado con la transmisión de datos serie por parte del microcontrolador, mientras que el Buffer del Receptor esta relacionado con la recepción de datos serie. Esta característica es lo que permite que el Puerto Serie del 8051 sea ´Full-Duplex´. SCON (Control del Puerto Serie). Mediante este registro se establecen los parámetros para la transmisión y la recepción serie de los datos a través del Puerto Serie. Registros relacionados con los Temporizadores. Recordar que este Microcontrolador cuenta con dos Temporizadores los que son conocidos como Temporizador 0 y Temporizador 1. TH0-TL0, TH1-TL1 (Temporizador 0 y Temporizador 1). Cada uno son registros de 8 bits, aunque pueden operar en algunos modos de trabajo de los temporizadores como un par registro de 16 bits. Están relacionados directamente con los contadores de los Temporizadores internos del microcontrolador, indicando en cada momento el valor de conteo que tienen los mismos. Estos registros pueden ser leídos y escrito en cualquier momento durante la ejecución del programa. TMOD (Modo de los Temporizadores) Es un registro estrechamente relacionado con la configuración del Modo de Trabajo de los Temporizadores. TCON (Control de los Temporizadores). Es un registro que esta fundamentalmente relacionado con la habilitación del conteo de los contadores de los Temporizadores. Esta relacionado también con la elección del modo en que el microcontrolador va a activar los pedidos de interrupción externa.

Microcontroladores. El 8051 de la INTEL.

57

Registros relacionados con la Interrupción. IE (Control de Habilitación de la Interrupción). Es un registro estrechamente relacionado con la posibilidad de enmascarar por software las fuentes de interrupción. Contiene un bit por cada fuente posible de interrupción, considerando al Puerto serie como una sola fuente. IP (Control de Prioridad de la Interrupción). Es un registro estrechamente relacionado con la definición de uno de los dos posibles niveles de prioridad a seleccionar para las interrupciones que estén habilitadas por software. Si bien resulta interesante conocer como esta estructurada la memoria interna del microcontrolador, el objetivo final es el poder trabajar con ella, esto se traduce en el poder hacer operaciones de lectura de una localización o de escritura en una localización, de poder mover un dato de una localización a otra o de poder mover un bloque de datos de una zona de memoria a otra, etc. Por su puesto para poder efectuar estas operaciones con la memoria interna existen instrucciones dentro del repertorio de instrucciones del microcontrolador, por lo que debemos conocer, ¿Cuáles son estas instrucciones? para poder seguir adelante en nuestro estudio. 4.4 Las Instrucciones para trabajar con la Memoria Interna. El fabricante agrupa las instrucciones que forman parte del Repertorio de Instrucciones de este microcontrolador en 5 grupos tomando en cuenta el tipo de operación que estas realizan. Estos 5 grupos de Instrucciones son: •

Grupo de Transferencia de Datos.



Grupo de Operaciones Aritméticas.



Grupo de Operaciones Lógicas.



Grupo de Manipulación de Variables Boolleanas.



Grupo de Salto y Llamada a Subrutina.

Las instrucciones que nos interesan en este momento son las que permiten efectuar el movimiento de datos con la memoria interna, ya sea para leer datos de dicha memoria o para escribir datos en dicha memoria. Estas instrucciones se encuentran dentro del grupo de instrucciones de Transferencia de Datos.

Microcontroladores. El 8051 de la INTEL.

58

Como su nombre lo indica, las instrucciones de este grupo provocan la transferencia de un dato almacenado en una localización de memoria, tómese a los registros dentro de este grupo, hacia otra localización de memoria, por lo que al ejecutar dichas instrucciones el microcontrolador efectúa dos operaciones que resultan ser indispensables, primero una operación de lectura sobre la localización que contiene al dato que se desea mover y segundo una operación de escritura en la localización hacia donde se desea mover el dato. Como características comunes de este proceso podemos mencionar: •

El contenido de la localización que es leída se mantiene.



Estas instrucciones no afectan el contenido de los bits de banderas del registro PSW.



Todas las instrucciones de este grupo involucran a dos operandos, uno que tiene almacenado el dato a mover, al que a partir de este momento lo llamaremos fuente y otro que será el que recibirá el dato para su nuevo almacenamiento, al que llamaremos destino.

Tres instrucciones constituyen las básicas de este grupo: MOV

,

; para el trabajo con la memoria de datos interna ; y los registros de funciones especiales.

MOVC

,

; para el trabajo con la memoria de programa.

MOVX

,

; para el trabajo con la memoria de datos externa.

A modo de resumen podemos definir que la sintaxis de las instrucciones de este grupo, salvo muy contadas excepciones, es la siguiente: NEMOTÉCNICO

,

Y el movimiento del dato responderá al siguiente esquema:



Por ejemplo si queremos mover un dato almacenado en la localización de memoria de datos interna cuya dirección es la 10H hacia el registro Acumulador, tenemos que emplear la instrucción cuyo nemotécnico es MOV ocupando la posición del destino la letra A y la de la fuente el numero hexadecimal 10H.

Microcontroladores. El 8051 de la INTEL.

MOV

A, 10H

; A

59

(10H)

Quizás le surjan algunas dudas a partir del ejemplo anterior como pueden ser, ¿Por qué poner la letra A para indicar que se esta trabajando con el registro Acumulador? ¿Por qué poner el numero hexadecimal 10H para indicar que se desea que la instrucción actué sobre la localización de memoria de datos interna cuya dirección se corresponde con este número? ¿Serán solo estas las formas de referirnos a estos elementos en una instrucción? Para poder dar respuestas a estas preguntas y poder comprender las que siguen debemos dedicar un tiempo para estudiar los Modos de Direccionado. Los Modos de Direccionados del 8051. La pregunta a contestar en este momento sería, ¿Qué son los Modos de Direccionado? El Modo de Direccionado esta relacionado con las posibilidades que brinda el microcontrolador para referirse a sus operandos en una determinada instrucción. Todas las instrucciones tienen al menos un operando, que se declara en la propia instrucción, además la instrucción tiene una forma de expresar dicho operando que usted debe respetar o se arriesga a declarar instrucciones en su programa que no existen. ¿Cuáles son los Modos de Direccionado

que admite este microcontrolador en sus

instrucciones? Modo de Direccionado de Registro. Los 8 registros del Banco de Registro activo pueden ser accesados mediante ciertas instrucciones que simplifican sus códigos de operación y en la mayoría de los casos son más rápidas. Recordemos que existen 4 bancos de registros ubicados en las localizaciones bajas de la Memoria de Datos interna, cada banco contiene 8 registros conocidos con los nombres R0, R1, R2, R3, R4, R5, R6 y R7, que son los mismos nombres que utilizaremos para referirnos a ellos como operando en las instrucciones. Estos bancos son activados mediante los bits 3 y 4 del registro PSW. EJEMPLO: ADD

A, R7 ; Adiciona al contenido del registro A el contenido del Registro R7.

Microcontroladores. El 8051 de la INTEL.

60

; el resultado se almacena en el registro A. ; el contenido del registro R7 no se altera. A

(A) + (R7)

El Modo de Direccionado empleado en el segundo operando de la instrucción es del tipo Registro. Modo de Direccionado Directo. En este direccionamiento el operando es especificado por una dirección de 8 bits en la propia instrucción. Solamente las localizaciones de la memoria de datos interna y los registros pueden ser directamente direccionados mediante este Modo de Direccionado. EJEMPLO: ADD

A, 7FH

; adiciona al contenido almacenado en el registro Acumulador el ; el contenido de la localización de memoria de datos cuya ; dirección es la 7FH. ; el resultado se almacena en el registro Acumulador. ; el contenido de la localización de memoria 7FH no se altera.

A

(A) + (2EH)

En este caso los dos operandos utilizan el Modo de Direccionado Directo.

Modo de Direccionado Indirecto. En este Modo de Direccionado, como su nombre lo indica, no se declara directamente en la instrucción la dirección de la localización del operando implicado en la misma, sino, que se especifica el registro donde se encuentra almacenada dicha dirección. Pueden ser utilizados como registros para almacenar la dirección los registros R0 y R1 del Banco de Registros activo, pudiendo ser direccionadas de esta manera todas las localizaciones de Memoria de Datos interna. Para indicar que se esta empleando en al instrucción este Modo de Direccionado se debe preceder el nombre del registro utilizado para almacenar la dirección de la localización del operando el símbolo @. EJEMPLO: ADD

A, @R0

; Adicionar al contenido del registro Acumulador el contenido de la ; localización de Memoria de Datos cuya dirección se ; encuentra almacenada en el registro R0. ; el resultado queda almacenado en el registro Acumulador. ; el contenido de la localización de memoria de datos cuya

Microcontroladores. El 8051 de la INTEL.

61

; dirección se encuentra almacenada en el registro R0 no se altera A

A + ((R0))

El símbolo @ precediendo al nombre del registro R0 indica que se esta empleando el Modo de Direccionado Indirecto para direccionar al segundo operando de la instrucción. El doble paréntesis acompañando a R0 nos indica que lo que se le adiciona al contenido del registro Acumulador no es el contenido del registro R0, sino, que el contenido del registro R0 se toma como dirección y el contenido de la localización que le corresponde esta dirección en la Memoria de Datos es lo que se adiciona al contenido del registro Acumulador. El doble paréntesis indica el contenido del contenido. Modo de Direccionado Inmediato. Las instrucciones que acepten este Modo de Direccionado permiten declarar en la misma instrucción uno de los operando que esta implicado en la misma a modo de una constante. Este operando debe estar antecedido del signo #. Este Modo de Direccionado es utilizado para declarar constantes que serán utilizadas en el programa, estas constantes son de 8 bits. EJEMPLO: MOV

A, #64H

A

64H

; El registro Acumulador es cargado con la constante 64H.

El símbolo # antecediendo al numero 64H indica que este se tome como un dato y no como una dirección. Modo de Direccionado Inmediato Extendido. Ídem al anterior con la única diferencia de que las constantes declaradas en este Modo de Direccionado son de 16 bits, por lo que solo puede ser utilizado como destino en este caso el registro DPTR. EJEMPLO: MOV

DPTR, #1245H

; El Registro DPTR es cargado con la constante ;1245H.

DPTR

1245H

Microcontroladores. El 8051 de la INTEL.

62

Modo de Direccionado Indexado. Solamente las localizaciones ubicadas en la Memoria de Programa pueden ser accesadas mediante este modo de direccionamiento y sólo en operaciones de lectura. La dirección de la localización a la que se hace referencia en la instrucción, se obtiene mediante la suma del contenido de los Registros DPTR o PC, declarado en la propia instrucción, con el contenido del registro Acumulador. Como resultado de la ejecución de estas instrucciones el contenido de dicha localización es almacenado en el Registro Acumulador. Este modo de direccionado es muy útil para el trabajo con Tablas de constantes almacenadas en localizaciones ubicadas en la Memoria de Programa. El contenido de uno de los Registros DPTR o PC, apuntaría a la localización de inicio de la Tabla, mientras que el contenido del Registro Acumulador brindaría el desplazamiento dentro de la Tabla donde se ubica el dato deseado. EJEMPLO: MOVC

A,@A+DPTR

A

((A) + (DPTR))

Podría parecer un error que al contenido de un registro de 16 bits, como es el registro DPTR, se le este sumando el contenido de un registro de 8 bits, como es el registro Acumulador, pero no es así. No obstante, esto si limita a que el número máximo de datos que puede contener una Tabla que vayamos a manipular mediante instrucciones que utilicen este Modo de Direccionado es de 256 localizaciones. Una vez conocido las posibilidades que tengo para declarar los operando en las instrucciones de transferencias podríamos ejemplificar su utilización para realizar determinadas tareas con el microcontrolador. Leyendo datos de la Memoria de Programa. El objetivo fundamental de la Memoria de Programas es el de almacenar los códigos de las instrucciones que conforman los Programas. Estos códigos son extraídos de esta memoria de forma automática por parte del microcontrolador sin la intervención del Programa. No obstante, suelen formar parte también de los programas Tablas, que se desean almacenar de forma permanente ya que su contenido no va a cambiar durante el tiempo que se este resolviendo la aplicación en cuestión. El mejor lugar para almacenar estas Tablas Invariantes en su contenido lo constituye la Memoria de Programa.

Microcontroladores. El 8051 de la INTEL.

63

La razón de ser de estas Tablas es la de proporcionar datos en determinados momentos del programa de gran utilidad para el desarrollo de los mismos. Se acostumbra a utilizar Tablas para almacenar códigos numéricos que serán utilizados por el programa para llevar a cabo una conversión de códigos numéricos, como puede ser de binario a código de Lámpara de 7 Segmentos. Se puede utilizar también para evaluar funciones que dada su complejidad matemática es preferible almacenar los resultados para un juego de datos dados. En todos los casos lo que hace el programa es extraer el contenido de una determinada localización de memoria, el que será utilizado como un dato por el programa. ¿Cómo efectuar esta operación? Para ello contamos con la instrucción, MOVC

destino, fuente

Como ya se explico anteriormente, esta instrucción provoca que el contenido de la localización cuya dirección es declarada como fuente en la instrucción se transfiera a la localización cuya dirección aparece como destino en la instrucción. (destino)

(fuente)

Esta instrucción solo acepta el Modo de Direccionado Indexado por lo que a localización fuente, que obligatoriamente se tiene que corresponder con una localización de Memoria de Programa, solo se le puede direccionar mediante la dirección base almacenada en el registro DPTR o el registro PC y el desplazamiento almacenado en el registro Acumulador,

mientras que la

localización destino tiene que ser el registro Acumulador. Las dos posibles instrucciones son: MOVC

A, @A+DPTR

MOVC

A, @A+PC

En la primera para calcular la dirección de la localización fuente se le suma al contenido del registro DPTR el contenido del registro Acumulador y el resultado es la dirección de la localización de memoria de programa con que se desea trabajar. En la segunda todo es igual solo sustituyendo al registro DPTR por el Registro PC.

Microcontroladores. El 8051 de la INTEL.

64

Observe que estas instrucciones se corresponden de forma ideal con el formato que deben tener las instrucciones para el trabajo con Tablas de forma cómoda para el programador. Tanto en DPTR como en PC se pueden guardar las direcciones de inicio de la tabla correspondiente, mientras que en el Registro Acumulador estaría el desplazamiento dentro de la tabla correspondiente con la localización deseada. En ambas instrucciones una vez ejecutadas el contenido inicial del registro Acumulador es sustituido por el contenido de la localización de memoria de programa cuya

dirección fue

especificada en la instrucción. Leyendo y escribiendo datos en la Memoria de Datos interna. Como su nombre lo indica el objetivo de esta memoria es el de almacenar, por lo general de forma temporal, los datos que serán empleados por el programa. Esto hace que los contenidos de las localizaciones de esta memoria estén cambiando con relativa frecuencia por lo que resulta tan importante escribir en las localizaciones de esta memoria como de leer el contenido de las mismas. La pregunta a responder en este caso sería, ¿Existirá una instrucción para leer el contenido de las localizaciones de esta memoria y otra diferente para escribirlas? La respuesta a esta pregunta ya conocemos que es no, siendo la instrucción a emplear para ambas operaciones es, MOV

destino, fuente

¿Cómo indicarle al microcontrolador que la operación que queremos que haga sea la de leer el contenido de una localización de la Memoria de datos o escribir en ella? Todo depende de la posición en que pongamos la dirección en cuestión. Si esta ubicada en la posición destinada a la localización destino, lo que el Programador quiere hacer es escribir en la Memoria de Datos, por el contrario si esta ubicada en la posición destinada para la localización fuente lo que el Programador quiere hacer es una lectura de la Memoria de Datos. Analicemos lo anterior a la luz de los dos ejemplos siguientes

Microcontroladores. El 8051 de la INTEL.

65

Ejemplo. Se quiere mover el contenido de la localización de memoria de datos cuya dirección es 10H hacia el registro Acumulador. En este caso la fuente del dato es la localización de memoria de datos cuya dirección es 10H y el destino final de este dato es el registro Acumulador, por lo que la instrucción quedaría escrita de la siguiente forma: MOV

A, 10H

;A

(10H)

Si por el contrario el movimiento de la información fuera en el sentido inverso la instrucción a emplear sería: MOV

10H, A

; (10H)

A

¿Al igual que con la Memoria de Programa todas las transferencias de datos con la Memoria de Datos se tendrán que efectuar a través del Registro Acumulador? Por suerte no es así y en este caso la variedad es mucho mayor que con la otra memoria ya que esta instrucción admite otros modos de direccionado. ¿Cuáles modos de direccionado admite esta instrucción? Son 4 los Modos de Direccionado que se pueden utilizar con esta instrucción: •

Registro.



Directo.



Indirecto.



Inmediato.

Y todos son empleados para direccionar localizaciones de la Memoria de Datos interna, incluyendo dentro de estas a las localizaciones empleadas para almacenar los Registros de Funciones Especiales. Comencemos a analizar cada una de las variantes de este tipo de instrucción a partir de considerar los Modos de Direccionado que soportan. Direccionado Tipo Registro.

Microcontroladores. El 8051 de la INTEL. MOV

66

A, Rn

¿Quién es Rn? Uno cualquiera de los registros de R0 a R7 del Banco de Registro activo. Esta instrucción provoca que el contenido del registro Rn especificado en la instrucción se almacene en el registro Acumulador. El contenido del registro Rn se mantiene con el contenido que tenía antes de ejecutar la instrucción.

MOV

Rn, A

En este caso lo único que se ha hecho es intercambiar la posición de los operandos con lo que provocamos que el microcontrolador ejecute la operación en el sentido contrario.



Direccionado Directo. MOV

A, directo

¿Quién puede ser directo? Es la dirección, en 8 bits, declarada directamente en la instrucción de la localización de Memoria de Datos con que se desea trabajar. Esta instrucción provoca que el contenido de la localización de Memoria de Datos cuya dirección se declara en la instrucción se almacene en el registro Acumulador. El contenido de la localización de Memoria de Datos se mantiene en el valor que tenía antes de ejecutar la instrucción.

< (directo) >

Los paréntesis que encierran a directo nos indican que lo que se mueve hacia el registro Acumulador es el contenido de la localización y no la dirección declarada en la instrucción. MOV

directo, A

En este caso lo único que se ha hecho es intercambiar la posición de los operandos con lo que provocamos que el microcontrolador ejecute la operación en el sentido contrario.

Microcontroladores. El 8051 de la INTEL.

< (directo) > MOV

67

Rn, directo

En este caso sería interesante que usted tratara de explicar que es lo que hace esta instrucción y corrobore si coincide con nosotros.

< (directo) >

¿Que sucedería si intercambiamos la posición de los operandos? MOV

directo, Rn

Lo que sucedería es que surge una instrucción nueva, que realiza la operación contaría. < (directo) >

< Rn >

Siento que ya vamos entrando en confianza para definir nuevas instrucciones pero, esto lo debemos hacer con criterios sólidos sino podemos inventar nuestras instrucciones que el microcontrolador no va a ser capaz de entender. Por ejemplo veamos el siguiente caso, MOV

directo, directo

Estoy seguro que ya todos podrán identificar que operación realiza el microcontrolador cada vez que se encuentra con esta instrucción en un Programa. < (directo) >

< (directo) >

Por su puesto que en este caso no tendría sentido buscar la instrucción que realiza la operación inversa, aunque en la práctica si existe. Veamos las dos instrucciones siguientes y ustedes me darán la razón. MOV

2DH, 3DH

MOV

3DH, 2DH

Microcontroladores. El 8051 de la INTEL.

68

Las dos responden a la sintaxis de la instrucción que estamos estudiando y sin embargo hacen lo contrario y ambas son validas. Direccionado Indirecto. MOV

A, @Ri

¿Qué quiere decir Direccionado Indirecto? Esto se explico en detalles en el tema anterior, no obstante, expliquémoslo nuevamente a la luz de los ejemplos visto hasta aquí. En las instrucciones vistas hasta aquí el operando involucrado en la instrucción quedaba bien claro en la declaración de la misma. Podríamos decir que el operando aparece declarado en la instrucción de forma directa o bien mediante su dirección o bien mediante un nombre reservado que lo identifica. Sin embargo, los operando que utilicen el Modo de Direccionado Indirecto, como su nombre lo indica, no vienen declarados de forma directa en la Instrucción. Entonces, ¿Cómo el microcontrolador identifica en que dirección se encuentra el operando declarado por el Programador en la instrucción? La dirección de la localización del operando estará almacenada en el registro Ri, declarado en la instrucción precedido del signo @. ¿Quiénes pueden ser registro Ri en este tipo de instrucción? Como ya se explico anteriormente solo los registros R0 y R1 del Banco de Registro activo. Retomando la instrucción que nos ocupa, la operación en el Microcontrolador que provoca la misma es,

((Ri))

El doble paréntesis encerrando a Ri nos indica que lo que se mueve hacia el registro Acumulador es el contenido de la localización cuya dirección es el contenido del Registro Ri. Constituyen instrucciones de este tipo que emplean este mismo Modo de Direccionado las siguientes,

Microcontroladores. El 8051 de la INTEL. MOV

@Ri, A

< ((Ri)) > MOV

directo, @Ri

< (directo) > MOV

69

< ((Ri)) >

@Ri, directo

< ((Ri)) >

< (directo) >

Direccionado Inmediato. MOV

A, #dato8

¿Qué quiere decir Direccionado Inmediato? Hasta ahora en las instrucciones se declaraba directamente la dirección donde se encuentra el dato a mover o el registro donde se encuentra almacenada dicha dirección. No obstante, en este caso el dato a mover viene implícito en la propia instrucción, siendo el número en hexadecimal, binario o decimal que esta precedido del signo # en la instrucción. Por lo tanto en este tipo de instrucciones solo existe la localización ya que la localización lo constituye la propia instrucción. Es muy importante que el número de bits en que es declarado el dato a mover coincida con el número de bits de la localización . Retomando la instrucción declarada al inicio, la operación que ejecutaría el microcontrolador sería,



Donde dato8 es un número declarado en 8 bits. ¿Podría existir la instrucción inversa? Por su puesto que no, ya que el dato a mover declarado en la instrucción no puede ser destino de si mismo. Son instrucciones con este mismo Modo de Direccionado las siguientes: MOV

Rn, #dato < dato8 >

Microcontroladores. El 8051 de la INTEL. MOV

directo, #dato8

< (directo) > MOV

< dato8 >

@Ri, #dato8

< ((Ri)) > MOV

70

< dato8 >

DPTR, #dato16

< DPTR >

< dato16 >

Observe que en este último caso el dato a mover es declarado en 16 bits, dato16, no habiendo error ya que el registro DPTR al que se pretende mover con la instrucción en curso es el único de 16 bits del microcontrolador. Estas dos instrucciones no son las únicas presentes en este grupo de instrucciones del 8051, quedan un grupo que más que una transferencia de datos permiten efectuar un intercambio de datos, con lo que los operandos hacen el papel de fuente y destino en la misma instrucción. Instrucciones de intercambio de datos. Con estas instrucciones el Programador tiene la posibilidad de mover la información no solo en un sentido, de fuente hacia destino, sino, provocar un intercambio de la información entre los dos operandos, de forma tal que ambos operandos actúan como fuente y a su vez como destino. Tiene la característica que después de su ejecución el contenido de ambos operandos se ve afectado y que uno de los operandos es siempre el registro Acumulador. < operando1 > XCH

< operando2 >

A, origen

Carga en el registro Acumulador el contenido de la localización cuya dirección es origen y al mismo tiempo, el valor original almacenado en el registro Acumulador se copia en dicha localización de memoria. Por su puesto, en este tipo de instrucción solo se puede trabajar con localizaciones de la memoria de datos y con los registros ya que como la misma lleva implícita la escritura en ambas operandos no podría ser uno de ellos una localización de la memoria de programas la que no podría ser escrita. Son tres los Modos de Direccionado presentes en esta instrucción:

Microcontroladores. El 8051 de la INTEL. •

Registro.



Directo.



Indirecto.

71

Direccionado Tipo Registro. XCH

A, Rn

< (Rn) >

Direccionado Directo. XCH

A, directo

< (directo) >

Direccionado Indirecto. XCH

A,@Ri

< (Ri) >

XCHD A,@Ri Es una instrucción de intercambio al igual que la anterior, con la diferencia de que en este caso el intercambio es de nibles, 4 bits, y no de bytes como en el caso anterior. Intercambia los 4 bits menos significativos (b3- b0) del registro Acumulador con los de la localización de Memoria de Datos interna direccionada de forma indirecta por el registro R0 o R1. Los 4 bits más significativos (b7-b4) de ninguno de los dos operandos se alteran. < A 0 -3 >

< (Ri) 0 - 3 >

Ya conocemos un grupo de instrucciones del 8051 y de seguro que ya estamos deseosos de hacer nuestros primeros programas. No se sui ya estamos preparados para ello pero lo intentaremos en el próximo Tema.

Microcontroladores. El 8051 de la INTEL.

72

Tema 3. El Repertorio de Instrucciones del 8051. Las instrucciones que conocemos son las que nos permiten efectuar la transferencia de datos dentro de la memoria interna del microcontrolador, por lo que le proponemos que tratemos de hacer un programa que este relacionado con esto. 3.1 Moviendo un bloque de datos. La tarea que queremos que el programa ejecute es la siguiente, Ejemplo 3.1. Dado un conjunto de 100 datos tipo byte almacenados de forma consecutiva en la memoria de programas a partir de la dirección 1000H, mover dichos datos hacia la memoria de datos, almacenándolos a partir de la dirección 10H de forma ascendente y respetando su ordenamiento. La tarea aparenta ser sencilla y en la Figura 3.1.1 aparece reflejado de forma gráfica lo que ya se expreso en el texto del problema,

Figura 3.1.1 Movimiento de datos a efectuar por el programa. Todo lo que tiene que hacer el programa es mover los datos, de uno en uno, de una localización de la memoria de programas hacia una localización de la memoria de datos, y mediante un contador

Microcontroladores. El 8051 de la INTEL.

73

determinar cuando hemos terminado con esta transferencia. Que los datos se encuentren almacenados en la memoria de programa de forma consecutiva y que los tengamos que almacenar en la memoria de datos de la misma forma nos ayuda ya que podemos darle un tratamiento de Tabla y utilizar las posibilidades que nos dan algunas instrucciones de este microcontrolador para efectuar este tipo de tarea y que las estudiamos en el Tema anterior. En la Figura 3.1.2 brindamos un Diagrama en Bloques del algoritmo que tenemos que programar posteriormente para resolver la tarea que nos han asignado. Con

las

instrucciones

que

conocemos podemos efectuar las asignaciones iniciales de valores a los registros DPTR, R0 y R3 ya que esto no es más que una tarea de carga de una constante en un registro. De

igual

movimientos

forma

los

de

datos,

dos el

primero de registro a registro y el segundo de memoria de programas a memoria de datos también instrucciones

conocemos con

las

las cual

efectuarlos. Pero, ¿Cómo incrementar el contenido de los registros R0 y R3?, ¿Cómo conocer que el contenido de R3 es igual a 100? Son preguntas para las que no tenemos respuestas. Dentro del Grupo de Instrucciones Aritméticas se encuentra la instrucción incrementa que podría resultar útil para efectuar las operaciones de incremento de los registros R0 y R3 que nos hemos propuesto en el programa. ¿Qué nos permite hacer esta instrucción?, ¿Podrá ser utilizada para incrementar cualquiera de los registros del Banco de Registros activo?, ¿Cómo utilizarla de ser útil para este caso? INC

byte

Microcontroladores. El 8051 de la INTEL.

74

La variable especificada como operando es incrementada en uno. Si la variable a incrementar tiene el valor de 0FFH se convertirá en 00H debido al desbordamiento. No se modifican las banderas. < byte >

< byte + 1 >

Resulta evidente que esta es la instrucción que estamos buscando, lo interesante sería saber si pueden ser operando de esta instrucción los registros R0 y R3, por lo que intentemos darle respuesta a la pregunta siguiente, ¿Quiénes pueden ser byte? •

El registro Acumulador. INC

A



< (A) + 1 >

Una localización de memoria de datos. INC

directo

< (directo) > INC

@Ri

< ( Ri ) > •

< ( (Ri) ) + 1 >

El registro de 16 bits DPTR. INC

DPTR

< DPTR > •

< (directo) + 1 >

< (DPTR) + 1 >

Un registro cualquiera del Banco de Registros activo. INC < Rn >

Rn < (Rn) + 1 >

La última opción es la que estábamos buscando por lo que con esta instrucción podemos llevar a cabo en nuestro programa el incremento de los registros R0 y R3. Nos obstante nos queda pendiente la pregunta, ¿Cómo conocer que el contenido de R3 es igual a 100?

Microcontroladores. El 8051 de la INTEL.

75

Dentro del Grupo de Instrucciones de Salto se encuentra la instrucción Compara y Salta si no es igual, que como su nombre lo indica compara dos valores, declarados en los operandos de la instrucción y decide a que dirección debe continuar el programa en dependencia del resultado de la comparación. Evidentemente esto es lo que estábamos buscando para nuestro programa. CJNE destino, origen, rel Efectúa una comparación entre los contenidos de los operandos destino y origen y salta a la dirección indicada en el operando rel en caso de desigualdad. De ser iguales los contenidos de los operandos la próxima instrucción a ejecutar se corresponde con la almacenada en la localización inmediata superior a ella en la memoria de programas. El bit de bandera de Acarreo se pone a ´1´ si el valor almacenado en la localización destino es menor que el valor almacenado en la localización origen. En los demás casos, se pone a ´0´. La pregunta a contestar para saber como utilizarla en nuestro programa sería, ¿Quiénes pueden ser destino?, ¿Quiénes pueden ser origen? •

Comparando con el contenido del registro Acumulador. CJNE

A, directo, rel

Compara el contenido del registro Acumulador con el contenido de la localización de memoria cuya dirección esta especificada en el operando directo. Donde directo es una dirección de 8 bits correspondiente a una localización cualquiera de Memoria de Datos interna. CJNE

A, #dato8, rel

Donde dato8 es una constante de 8 bit declarada en la propia instrucción, que puede estar expresado en decimal, binario y hexadecimal. •

Comparando con una constante. CJNE

@Ri, #dato8, rel

Donde Ri puede ser uno cualquiera de los Registro R0 o R1 del Banco de Registro activo donde se encuentra almacenada la dirección de la localización cuyo contenido es el que se compara con el número de 8 bits declarado en la propia instrucción dato8. dato8 puede estar expresado en decimal, binario y hexadecimal.

Microcontroladores. El 8051 de la INTEL. CJNE

76

Rn, #dato8, rel

Donde Rn es uno cualquiera de los registro del Banco de Registro y dato8 es una constante en 8 bits que puede estar expresado en decimal, binario y hexadecimal. Evidentemente esta última es la instrucción que andamos buscando. Por lo que ya tenemos todas las instrucciones que nos son necesarias para efectuar la tarea que nos han asignado. A continuación presentamos el programa que materializa el algoritmo presentado en la Figura 3.1.2. ; Este fragmento de programas permite el movimiento de 100 datos tipo byte almacenados ; en la memoria de programas a partir de la localización 1000h, hacia la memoria de datos, ; a partir de la localización 10h. ; El orden de los datos en la tabla es respetado. ; Declarando las condiciones iniciales. mov

DPTR, #1000h

; DPTR

1000h

mov

R0, #10h

;

R0

10h

mov

R3, #0

;

R3

00h

A, R3

;

A

R3

movc A, @A+DPTR

;

A

(A+DPTR)

mov

@R0, A

;

(R0)

inc

R0

;

R0

R0+1

inc

R3

;

R3

R3+1

cjne

R3, #100, lazo

; R3 ≠ 100

; Lazo de movimiento de la Tabla de datos. lazo:

mov

; R3 = 100

A

PC

lazo

Ejecuta próxima instrucción.

; Fin del fragmento de programa. Del fragmento de programa anterior queremos llamar la atención en dos aspectos que resultan nuevos para ustedes: •

Todo lo que aparece a la derecha del signo punto y como (;) son simplemente comentarios agregados al programa para su mejor comprensión, por lo que no resultan indispensables para la ejecución del programa.



La utilización de la etiqueta lazo para referirnos a la dirección de una localización en memoria de programa. En este caso la etiqueta lazo fue empleada como operando en una instrucción de salto condicional, observe como aparece en el campo destinado a los operandos en esta instrucción, en especifico en el destinado para la dirección a donde saltar cuando la condición se cumpla y además aparece encabezando, precedido de un

Microcontroladores. El 8051 de la INTEL.

77

signo de dos puntos (:), la línea de la instrucción a ejecutar cuando ocurra el salto. Esto por su puesto que resulta una gran comodidad para el programador, pues cuando escriba sus programas no tiene que estar calculando exactamente la dirección en hexadecimal donde se encuentra

la instrucción ejecutar sino que deja esta tarea al Programa

Ensamblador que lo calculará en el momento de ensamblaje del programa. Le proponemos a modo de Trabajo Independiente que usted determine los cambios a efectuar al programa anterior si los datos en la memoria de datos se desearan almacenar en el sentido descendente de las direcciones a partir de la localización cuya dirección es la 70h. Una cosa nos ha quedado evidente de este primer programa que hemos hecho, por muy sencilla que sea la aplicación a la que nos estamos enfrentando, para poder realizar el programa que la resuelve de forma eficiente, debemos conocer primero todas las instrucciones que forman parte del repertorio de instrucciones del microcontrolador en cuestión y a esta tarea nos dedicaremos en los epígrafes siguientes antes de acometer la solución de otros problemas. 3.2 Repertorio de Instrucciones. El 8051 cuenta con un total de 111 tipos diferentes de instrucciones y mediante el empleo de los diferente Modos de Direccionado el Programador tiene la posibilidad de realizar 255 operaciones diferentes con el microcontrolador en el tiempo de un ciclo de instrucción. Este es un microcontrolador CISC y forman parte de su Repertorio de Instrucciones, instrucciones tan complejas del punto de vista matemático como son: MUL

AB

; multiplica el contenido del registro Acumulador con el del registro B.

DIV

AB

; divide el contenido del registro Acumulador con el del registro B.

Y tan complejas del punto de vista de su ejecución como son: CJNE A, #dato, rel

; compara y salta si no es igual

DJNZ Rn, rel

; decrementa y salta si no es ´0´.

Para su estudio, agruparemos las instrucciones que forman parte del Repertorio de Instrucciones de este microcontrolador en 5 Grupos tomando en cuenta el tipo de operación que estas realizan.

Microcontroladores. El 8051 de la INTEL.

78

Estos 5 grupos son: •

Grupo de Transferencia de Datos.



Grupo de Operaciones Aritméticas.



Grupo de Salto y Llamada a Subrutina.



Grupo de Operaciones Lógicas.



Grupo de Manipulación de Variables Boolleanas.

El Grupo de Transferencia de Datos ya lo estudiamos en el Tema anterior por lo que le propongo que comencemos el estudio de los restantes a partir del Grupo de Operaciones Aritméticas. Grupo de Operaciones Aritméticas. Las instrucciones de este grupo son las que permiten al Programador efectuar operaciones aritméticas en su programa tales como: la Adición, la Sustracción, la Multiplicación y la División. En estas instrucciones siempre están presentes dos operandos, siendo siempre uno de ellos el contenido del registro Acumulador. El resultado siempre es almacenado en este último registro, por lo que uno de los operandos se pierde después de efectuada la instrucción. Un caso particular lo constituyen las instrucciones Incrementar y Decrementar respectivamente, las que involucran a un solo operando, sobre el que actúan y al mismo tiempo el que afectan. Estas instrucciones tienen la característica común de que su ejecución puede afectar los bits de banderas presentes en el registro PSW. ¿Qué son los bits de banderas del registro PSW? En el Tema 2 ya se brindaron algunos elementos de lo que son y representan los bits de banderas, no obstante, nos parece adecuado que en este Tema profundicemos un poco más sobre este aspecto tomando en consideración la estrecha relación existente entre las instrucciones y estos bits del registro PSW. Los bits de banderas son bits del registro PSW que brindan información de importancia para el programador y para el microcontrolador sobre el resultado de determinadas operaciones. PSW es uno de los registros del SFR, y su distribución de bits y significado se mostraron en la Figura 2.3.9.

Microcontroladores. El 8051 de la INTEL.

79

No todos los bits de este registro constituyen bits de banderas, ni todas las instrucciones afectan a los mismos. Son Banderas los bits 0, 2, 6 y 7, con los nombres de Paridad (P), Desbordamiento (OV), Acarreo Auxiliar (AC) y Acarreo (CY) respectivamente. ¿Qué quiere decir que una operación afecta las banderas? Existen instrucciones que en su ejecución provocan que el valor que tome uno de los bits de bandera dependa del resultado de la ejecución de dicha instrucción. En este caso se dice que esta instrucción afecta las banderas y dentro de este grupo se encuentran, entre otras, las instrucciones Aritméticas. ¿Qué importancia puede tener esto para el programador? Para poder dar respuesta a esta pregunta primero repasemos a que responden los bits de banderas que tiene este microcontrolador. Paridad (P). Mediante el valor almacenado en este bit, el microcontrolador indica el tipo de paridad que esta presente en el resultado de una operación aritmética o lógica determinada. La paridad esta relacionada con el número de bits en ´1´ de dicho resultado. Por ejemplo, si el bit P esta en ´1´ después de la ejecución de una instrucción aritmética dada, esto indica que el número de bits en ´1´ en el resultado es impar, si por el contrario el valor es ´0´ indica que el número de bits en ´1´ en el resultado es par. Desbordamiento (OV). Indica que existió acarreo del bit 6 al bit 7 como producto de la ejecución de una instrucción aritmética, esto lo indica poniéndose a ´1´. Muy útil en los Programas que trabajen en aritmética con signo. Acarreo Auxiliar (AC). Es una bandera para ser utilizada fundamentalmente por el microcontrolador y no por el usuario. Indica que ha ocurrido un acarreo del bit 3 al bit 4 como producto de una operación aritmética. Esto resulta muy útil en el trabajo en BCD. Acarreo (CY). Lo que indica depende del tipo de instrucción que se haya ejecutado. Si es una instrucción que involucra una operación aritmética indica que para el resultado de la operación no le es suficiente con los 8 bits del registro Acumulador para su almacenamiento. En las instrucciones de Rotación este bit se concatena con el registro Acumulador tomando el valor del bit que lo antecede en la cadena de rotación. No todas las instrucciones del Grupo Aritmético afectan por igual a todos los bits de banderas, ni todas afectan por igual a los mismos bits de banderas. Que bit de bandera es afectado y de que

Microcontroladores. El 8051 de la INTEL.

80

manera depende en gran medida de la instrucción aritmética que se haya ejecutado. En la Tabla 3.2.1 se muestra los diferentes tipos de instrucciones aritméticas y los bits de banderas que afectan. Instrucción

Acarreo

Desbordamiento

Acarreo Auxiliar

ADD

X

X

X

ADDC

X

X

X

SUBB

X

X

X

MUL

0

X

DIV

0

X

DA

X

Tabla 3.2.1 Bits de Banderas que son afectadas por las instrucciones del Grupo Aritmético. Una vez aclarado lo anterior pasemos a estudiar cada una de las instrucciones de este Grupo con sus correspondientes variantes en dependencia del Modo de Direccionado que aceptan. Instrucciones de Adición. ADD

A, origen

Suma el contenido de la localización cuya dirección es origen con el contenido del registro Acumulador y almacena el resultado en este último registro.

< A + origen >

El bit de bandera de Acarreo (CY) y el de Acarreo Auxiliar (AC) se ponen a ´1´ si se produce un acarreo producto de la suma de los bits 7 o de los bits 3 de los operandos respectivamente y se ponen a ´0´ cuando no hay acarreo. El bit de bandera de Desbordamiento (OV) se pone a ´1´ si se produce un acarreo producto de la suma de los bits 6 de los operandos pero no de los bits 7 o viceversa. ¿Qué nos indica el bit de bandera CY en este caso? La respuesta es evidente, nos indica que el resultado de la operación de Adición de los dos números de 8 bits correspondientes a los operandos, no puede ser almacenado por completo en los 8 bits con que cuenta el registro Acumulador y que por ende hay un noveno bit del resultado que debe ser tomado en cuenta y que precisamente es el contenido de dicho bit de bandera.

Microcontroladores. El 8051 de la INTEL.

81

Auxiliémonos del ejemplo siguiente que ya lo utilizamos en el Tema anterior para comprender un poco más lo explicado anteriormente,

bit bandera CY

1111 1101B

FDH

+ 0000 0101B

+ 05H

1 0000 0010B

102H

253 +

5 258

En el ejemplo uno de los operandos es el número 253 correspondiente con el número FDH en hexadecimal y el otro es el número 5 correspondiente con el número 05H en hexadecimal. Ambos números pueden ser representados en 8 bits perfectamente, no obstante, el resultado de la suma de ambos, 258, necesita de 9 bits por lo menos para poder ser representado en binario, 102H, y por lo tanto no basta con los 8 bits del registro Acumulador para almacenarlo. En este caso ese 9 bit se almacena en el bit de bandera CY. ¿Qué nos indica el bit de OV en esta instrucción? Este bit de bandera es importante tomarlo en consideración si en nuestro Programa hacemos uso de números enteros con signo sobre los que efectuamos operaciones aritméticas. Por ejemplo, si al efectuar la Adición de dos números enteros con signo en nuestro programa, el bit de bandera OV se pone a ´1´, nos esta indicando que: •

La suma de dos números, de ser positivos, están generando como resultado un número negativo.



La suma de dos números, de ser negativos, están generando como resultado un número positivo.

En ambos casos, el resultado no se corresponde con lo esperado por lo que usted debe tomar algunas acciones en su Programa que corrijan este aparente error. Tratemos de aclarar lo anterior mediante un ejemplo. En un programa en el que se trabaja con números enteros con signo, el microcontrolador ejecuta una instrucción de Adición de dos números positivos almacenados en sendas localizaciones de la Memoria de Datos interna. Los números positivos a sumar se corresponden con el 40H y el 42H. Analizar el signo del resultado y que ocurre con la Bandera de OV. Si se esta trabajando aritmética con signo, los números 40H y 42H son positivos y se corresponden con los números decimales 64 y 66.

Microcontroladores. El 8051 de la INTEL.

82

¿Por qué podemos decir que los dos números anteriores son positivos?, ¿Cómo reconocemos que un número es negativo? La Unidad Aritmética y Lógica del microcontrolador no reconoce cuando un número es positivo o negativo, esta tarea corre por usted a la hora de representar los números. Para ello es práctica muy generalizada tomar el valor del bit más significativo del número como el signo y el resto de los bits se emplean para representar el valor del mismo. Por ejemplo si estamos trabajando con números enteros con signo en 8 bits, el bit 7 se utilizaría para declarar el signo del número y los bits del 6 al 0 para representar su valor. Si el número a representar es positivo el bit 7 toma el valor de ´0´ y si es negativo el bit 7 debe tomar el valor de ´1´. De forma tal que los números del ejemplo se corresponde con los números 64 y 66 en binario, 0

100 0000 b

+

64

0

100 0010 b

+

66

La suma de estos dos números debe dar un número positivo, o sea, un número que tenga al bit 7 en ´0´. Efectuemos la suma tal y como la haría el microcontrolador y veamos si el resultado obtenido se corresponde con el esperado. 0

100 0000 b

+ 0

100 0010 b

1

000 0100 b

Según lo que se había definido anteriormente el resultado se corresponde con un numero negativo ya que el bit 7 del resultado es ´1´ por lo tanto no es un resultado que se corresponde con el esperado. ¿Cómo el programa detecta que ha existido un problema en el resultado y que por tanto se deben hacer algunas operaciones que corrijan dicho resultado? Observe que en la operación anterior ocurrió un acarreo como resultado de la suma de los bits 6 de ambos números, sin embargo, no fue así para el caso de la suma de los bits 7. Este comportamiento se corresponde con las condiciones bajo las cuales el bit de bandera de OV se pone a ´1´ después de efectuada una instrucción de Adición, indicándonos el error en el resultado.

Microcontroladores. El 8051 de la INTEL.

83

Esta forma de representar los números con signos en las operaciones con los microcontroladores y los microprocesadores se conoce con el nombre de complemento a dos y es responsabilidad del programador representar los números de esta manera cuando en su programa esta trabajando con aritmética con signo si no quiere obtener resultados erróneos. Del ejemplo anterior creo que queda claro como representar un número positivo en 8 bits en complemento a dos, simplemente ponemos al bit 7 en ´0´ y el resto de los bits toman el valor de ´0´ o de ´1´ en dependencia del número que queramos representar. Por ejemplo el número +5 en quedaría representado en complemento a dos 0 000 0101B. +

5

La pregunta en este caso sería, ¿Como representar al número -5? El primer impulso sería representar al número -5 poniendo al bit 7 en ´1´ y poniendo en ´0´ o en ´1´ al resto de los bits de forma tal que representen el valor 5, 1 -

000 0101B 5

Si esto es correcto al efectuar la Adición del +5 con el -5 debe darnos 0, comprobemos si esto es cierto. 0

000 0101B = +5

1

000 0101B =

-5

1

000 1010B ≠

0

El error esta en la forma en que fue representado el número -5. Repitamos entonces la pregunta, ¿Cómo representar al número -5 en complemento a dos? El poner el bit 7 en ´1´ es solo una parte en la búsqueda de la representación de un número negativo cualquiera en complemento a dos, nos falta determinar el valor que deben tomar el resto de los bits del número, los que precisamente le dan el valor, para ello se procede de la siguiente forma: •

Representar el valor del número en binario.



Complementar todos los bits del número.

Microcontroladores. El 8051 de la INTEL. •

84

Sumarle 1 a los bits complementado.

Repitamos el ejemplo anterior ahora tomando en cuenta estos tres pasos para determinar la representación del número -5. •

Representar el valor del número en binario

000 0101B



Complementar todos los bits del número

111 1010B



Sumarle 1 a los bits complementado.

111 1011B

Por lo que el número -5 quedaría representado según la siguiente secuencias de ´0´ y de ´1´ 1111 1011B -5 Utilicemos la misma forma que en el caso anterior para verificar si es correcta la representación del número, CY 1

0

000 0101B = +5

1

111 1011B =

-5

0

000 0000B =

0

En este caso hubo acarreo producto de la suma de los bits 6 de los operandos y producto de la suma de los bits 7 de los operandos por lo que el bit de bandera de OV no toma el valor de ´1´ indicando que todo esta correcto. Después de explicar lo relacionado con la representación de los números cuando se trabaja en aritmética con signo retomemos la explicación de la instrucción de Adición. ADD

A, origen

¿Quiénes pueden ser origen? •

Uno de los registros cualquiera del Banco de Registro activo. ADD



A, Rn < (A) + (Rn) >

Una localización de memoria de datos.

Microcontroladores. El 8051 de la INTEL. ADD

A, directo

ADD

< (A) + (directo) > A, @Ri



85

< (A) + ((Ri)) >

Una constante declarada en la propia instrucción. ADD

A, #dato8

ADDC

< (A) + dato8 > A, origen

Lo único que la diferencia de la anterior es que además de sumar el contenido del registro Acumulador con el contenido de la localización cuya dirección es origen, se le suma el valor que tiene el bit de bandera Acarreo antes de ejecutada la instrucción.

< A + operando + C >

¿Quiénes pueden ser origen en este caso? Pueden ser origen los mismos que en la instrucción anterior. Veamos un ejemplo que nos ayude a comprender la diferencia entre estas dos instrucciones. Ejemplo 3.2. Sumar dos números de 16 bits almacenados en las localizaciones de Memoria de Datos interna 10H-11H y 12H-13H respectivamente. El resultado se desea almacenar en las localizaciones 14H-15H-16H de la misma Memoria. Dado que los números a sumar vienen expresados en 16 bits se necesitan 2 localizaciones de la Memoria de Datos para almacenar a cada uno, recuerde que esta memoria está organizada en byte. Hemos representado como bms a los 8 bits menos significativo del operando (de los bits del 0 al 7), mientras que hemos representado como BMs a los 8 bits más significativo (de los bits del 8 al 15). Atendiendo a esta misma razón, para el resultado se deben reservar como mínimo tres localizaciones de la memoria ya que la suma de dos números de 16 bits puede necesitar de 17 bits para poder expresar el resultado, ver figura 3.2.1.

Microcontroladores. El 8051 de la INTEL.

86

El Diagrama en Bloques del programa que les proponemos aparece en la Figura 3.2.2. y el fragmento de programa que lleva a cabo la suma de dos números de 16 bits respondiendo a este Diagrama en Bloques se lista a continuación.

; Este fragmento de programa suma dos números de 16 bits almacenados en ; las localizaciones de la Memoria de Datos 10-11H y en las localizaciones 12-13H. ; El resultado queda almacenado en las localizaciones 14H-15H-16H. mov

A, 10H

; carga bms del OPERANDO1 en el registro Acumulador

add

A, 12H

; suma los bms de ambos OPERANDOS.

mov

14H, A

; salva 1er byte del RESULTADO.

mov

A, 11H

; carga BMs del OPERANDO1 en el registro Acumulador.

Microcontroladores. El 8051 de la INTEL. addc

A, 13H

87

; suma los BMs de ambos OPERANDOS tomando ; en consideración el bit de bandera de ACARREO (CY) obtenido ; como resultado de la primera Adición.

mov

15H, A

; salva 2do byte del RESULTADO.

mov

A, #0

; prepara el registro Acumulador para sumarlo con ; el bit de bandera ACARREO (CY) obtenido como resultado de la ; segunda Adición.

addc

A, #0

; obtengo 3er byte del RESULTADO, tomando en ; consideración el bit de bandera de ACARREO (CY) obtenido de la ; segunda Adición.

mov

16H, A

; salva 3er byte del RESULTADO.

Observe como a partir de la segunda Adición se hace necesario utilizar la instrucción addc en lugar de la add utilizada en la primera para poder tener en cuenta si existió ACARREO producto de la operación de la Adición anterior. Le proponemos a modo de Trabajo Independiente que determinen cuales son los aspectos que debemos cambiar en el programa anterior si en la nueva tarea que nos proponemos los números a sumar son de 32 bits almacenados de forma consecutiva a partir de la localización de memoria de datos cuya dirección es 10h. El resultado lo deben almacenar en las localizaciones de memoria de datos continuas a las dedicadas para almacenar los números a sumar. Haga el nuevo programa. Instrucción de Sustracción. SUBB A, origen El contenido de la localización cuya dirección es origen y el bit de bandera de Acarreo (CY) se restan del contenido del registro Acumulador. El resultado se almacena en el registro Acumulador.

< A – origen - C >

Si como resultado de esta operación se produce un préstamo en la posición más significativa se pone el bit de bandera de Acarreo (CY) en ´1´. Esto permite realizar la substracción con precisión múltiple en la que se resta el acarreo resultante de la operación anterior. El bit de bandera Acarreo Auxiliar (AC) se pone a ´1´ si se produce un préstamo producto de la sustracción de los bits 3 de

Microcontroladores. El 8051 de la INTEL.

88

los operandos. El bit de bandera Desbordamiento (OV) se pone a ´1´ si se produce un préstamo del b6 pero no del b7 o viceversa. ¿Qué nos indica el bit de OV en este caso? Como se vio en la instrucción anterior, esta Bandera es importante tomarla en consideración si en nuestro Programa hacemos uso de números enteros con signo sobre los que efectuamos operaciones aritméticas. Por ejemplo, si al efectuar la substracción de dos números enteros con signo en nuestro programa, el bit de bandera OV se pone a ´1´, nos esta indicando que: •

Un valor negativo al ser restado de un valor positivo produjo un resultado negativo.



Un valor positivo al ser restado de un valor negativo produjo un resultado positivo.

Al igual que en el caso de la Adición el resultado obtenido no se corresponde con lo esperado por lo que usted debe tomar algunas acciones en su programa que corrijan este aparente error. ¿Quienes pueden ser origen? Los mismos que los de las instrucciones de Adición. SUBB

A, Rn

< (A) – (Rn) - C >

SUBB

A, directo

< (A) - (directo) - C >

SUBB

A, @Ri

< (A) – ((Ri)) - C >

SUBB

A, #dato8

< (A) - dato8 - C >

Instrucción de Multiplicación. MUL

AB

Realiza una multiplicación sin signo de los números enteros contenidos en los registros Acumulador y B. La parte menos significativa del resultado de 16 bits es almacenada en el registro Acumulador, mientras que los 8 bits más significativos son almacenados en el registro B.

Microcontroladores. El 8051 de la INTEL.





< A x B 8 - 15 >

89

Si el producto da un resultado mayor que 255, se pone a ´1´ la Bandera de Desbordamiento (OV) indicando que el valor almacenado en el registro B es diferente de ´0´, en caso contrario se pone a ´0´. El bit de bandera de Acarreo (CY) se pone a ´0´ en todos los casos. Instrucción de División. DIV

AB

Realiza la división del número entero sin signo almacenado en el registro Acumulador entre el número entero sin signo que se encuentra almacenado en el registro B. El Registro Acumulador recibe la parte entera del cociente y el registro B el resto de la división.

cociente < A / B >

resto < A / B >

Los bits de bandera de Acarreo (CY) y de Desbordamiento (OV) se ponen a ´0´. NOTA: Si el contenido del registro Acumulador vale ´0´ antes de la división, los valores devueltos no están definidos, indicándolo el microcontrolador poniendo a ´1´ el bit de bandera de Desbordamiento (OV). Las instrucciones de Multiplicación y División constituyen herramientas poderosas para el Programador no presente en muchos microcontroladores y microprocesadores de igual jerarquía que el 8051. Estas operaciones que por lo general requieren de un conjunto de instrucciones para poder ser efectuadas, en este caso solo con poner su nemotécnico en el programa, el 8051 es capaz de efectuarla. Veamos su potencialidad en el siguiente ejemplo. Ejemplo 3.3. Hacer un fragmento de programa que a partir de un número en hexadecimal entre 0 y 99 almacenado en la localización de la memoria de datos cuya dirección es 10H, obtenga el número equivalente en BCD empaquetado, almacenándolo en la localización de memoria de datos correspondiente con la dirección 11H.

Microcontroladores. El 8051 de la INTEL.

90

BCD viene de las siglas de las palabras Binary Code Decimal (Código Binario Decimal), el que constituye una manera de representar los números en el Sistema Numérico Binario bajo las mismas reglas empleadas en el Sistema Numérico Decimal. Por ejemplo, el número binario 0001 0001B es equivalente al número 17 en decimal, si lo fuéramos a expresar en Código BCD quedaría, 0001 0111, donde los 4 bits menos significativos representarían el valor de las unidades y los 4 bits mas significativos representarían el valor de las decenas, empleándose 4 bits para representar cada uno de los dígitos decimales. La pregunta a responder en este momento sería, ¿Qué quiere decir BCD empaquetado? Existen dos formas de representar los números en BCD: •

Mediante el empleo de un byte para representar cada digito decimal. A esta forma se le conoce con el nombre de BCD desempaquetado.



Mediante la representación de dos dígitos decimales en cada byte. A esta forma se le conoce con el nombre de BCD empaquetado y es como lo hemos venido representando hasta ahora.

Por ejemplo, representemos al numero en binario 0001 1000B en BCD desempaquetado y en BCD empaquetado. El

numero

en

binario

0001

1000B

representa al número 24 en decimal. Para representarlo en BCD desempaquetado necesitaríamos de dos byte, uno para representar a las unidades (4) y el otro para representar a las decenas (2), mientras que en BCD empaquetado solo necesitamos de un byte, representando a las unidades (4) en los 4 bits menos significativo y a las decenas (2) en los 4 bits mas significativos. En la Figura 3.2.3 se

representa

almacenadas

estas

como tres

representar al mismo número.

quedarían formas

de

Microcontroladores. El 8051 de la INTEL.

91

Con la explicación dada hasta aquí estamos ya en condiciones de hacer el fragmento de programa pedido y para ello emplearemos las instrucciones de Multiplicación y de División. El Diagrama en Bloques del algoritmo empleado se muestra en la Figura 3.2.4.

; Este fragmento de Programa obtiene el Código BCD Empaquetado de un número almacenado en ; Binario en la localización de Memoria de Datos cuya dirección es 10H, almacenándolo en la , localización de dicha memoria cuya dirección es 11H. mov

A, 10H

; Almacena en el registro Acumulador el número a convertir.

mov

B, #10

; Prepara la división entre 10.

div

AB

; En el registro Acumulador el BCD de las decenas ; y en el registro B el BCD de las Unidades.

mov

11H, B

; Almacena el Código BCD de las Unidades.

mov

B, #16H

; Preparo la multiplicación del registro Acumulador por 16H.

mul

AB

; Roto el contenido del registro Acumulador en 4 ; posiciones a la izquierda.

Microcontroladores. El 8051 de la INTEL. add

A, 11H

; Conformo el numero en BCD Empaquetado

mov

11H, A

; Almaceno el numero en BCD Empaquetado en 11H

92

Le proponemos a modo de Trabajo Independiente que determinen los cambios que hay que efectuar al fragmento de programa anterior si lo que quisiéramos obtener fuera la representación del número en BCD desempaquetado. Haga el nuevo programa. Instrucción Incrementa. Esta instrucción ya fue explicada en este propio Tema en el epígrafe 3.1. Instrucción Decrementa. DEC

byte

La variable indicada es decrementada en 1, haciendo el efecto contrario a la instrucción Incrementa. Un valor original de 00H se convertirá en 0FFH debido al desbordamiento. No se modifican las banderas. < byte >

< byte - 1 >

¿Quiénes pueden ser byte? Los mismos que en la instrucción Incrementa. DEC

A

DEC

< (A) - 1 > Rn

< Rn > DEC

< (Rn) - 1 > directo

< (directo) > DEC

< (directo) - 1 >

@Ri

< ( Ri ) >

< ( (Ri) ) - 1 >

Microcontroladores. El 8051 de la INTEL.

93

Instrucción de Ajuste Decimal. DA

A

Ajusta el valor de los 8 bits del registro Acumulador que resulta de la suma de dos números en formato BCD Empaquetado (instrucciones ADD o ADDC), obteniendo el resultado en BCD Empaquetado. ¿Cómo hace esto? Si como resultado de la ejecución de una instrucción aritmética en la cual se efectuó la adición de dos números en formato BCD empaquetado, los bits del registro Acumulador b3-b0 toman un valor superior a 9 o si el bit de bandera de Acarreo Auxiliar (AC) se pone a ´1´, el microcontrolador le adiciona 6 al valor almacenado en estos bits para provocar el ajuste decimal deseado. Esta suma puede poner a ´1´ el bit de bandera de Acarreo Auxiliar (AC) el que se propagaría a lo largo de los 4 bits más significativos b7-b4 del registro Acumulador. Si el bit de bandera de Acarreo (CY) se pone a ´1´ como resultado de la suma anterior o si los bits b7-b4 del registro Acumulador tienen un valor superior a 9, se suma 6 al valor almacenado en estos bits. Un acarreo desde el octavo bit pone a ´1´ el bit de bandera de Acarreo (CY) indicando que el número al que se le esta obteniendo el ajuste decimal no puede ser almacenado en los 8 bits del registro Acumulador. El bit de bandera de Desbordamiento (OV) no es afectada por esta operación. Veamos el efecto de esta instrucción en el siguiente ejemplo. Ejemplo 3.4. Se desea sumar dos números en formato en BCD Empaquetado almacenado en las localizaciones de memoria 10H y 11H. El resultado se desea almacenar en BCD Empaquetado en la localización de memoria 12H. En la Figura 3.2.5 se muestra el Diagrama en Bloques del fragmento de programa que ejecuta la tarea deseada.

Microcontroladores. El 8051 de la INTEL.

94

La pregunta en estos momentos podría ser, ¿Por qué se hace necesario convertir a BCD Empaquetado el resultado de la suma, si se sumaron dos números en BCD Empaquetado? Démosle respuesta a esta pregunta efectuando de forma manual la suma de dos números en BCD Empaquetado y veamos si el resultado es el esperado. Supongamos que sumaremos los números en BCD Empaquetados 45 y 37, por lo tanto el resultado esperado debe ser el numero 82. 45 =

0100 0101

+ 37 =

0011 0111

______________________ 82 ≠

0111 1100

Como se puede ver del ejemplo el resultado no se corresponde con el número esperado en BCD, es más el número obtenido como resultado no esta expresado en BCD. ¿Qué es lo sucedido? Lo que ha sucedido es que hemos efectuado la suma bajo las reglas de la adición binaria y no tomando en cuenta que los números están expresados en BCD Empaquetado, que es lo mismo que hace la Unidad Aritmético y Lógica del microcontrolador y por lo tanto el resultado obtenido

Microcontroladores. El 8051 de la INTEL.

95

no se corresponde con el esperado corroborando lo correcto de haber puesto en el Diagrama en Bloques del Programa, como un paso, la conversión del resultado a BCD Empaquetado. ¿Cómo efectuar esta tarea? Los pasos a seguir son los siguientes: •

Si la suma de los 4 bits menos significativa da como resultado un número mayor que 9, se debe sumar 6 a este numero.



Si hubo Acarreo Auxiliar (AC) de los 4 bits menos significativos, se le debe sumar al resultado de la suma de los 4 bits más significativo el número 6 tambien.



Repetir el primer paso para el resultado de los 4 bits más significativos.

Apliquemos estos 3 pasos al resultado obtenido en el ejemplo anterior, •

El resultado de los 4 bits menos significativos resulta ser mayor que 9, por lo que debemos sumarle 6. 1100 + 0110 1 0010 Con el quinto bit del resultado hemos querido representar que producto de la suma se produjo un Acarreo hacia el resultado de los 4 bits más significativos.



Como hubo Acarreo Auxiliar al resultado de la suma de los 4 bits más significativos se le debe incrementar en 1. 0111 + 0001 0 1000



Como el resultado obtenido es menor que 9 y no hubo Acarreo el numero se queda igual.

Por lo tanto el numero obtenido después de efectuados los tres pasos es el 1000 0010B = 82 en BCD Empaquetado que es el resultado esperado al efectuar la suma de los dos números propuestos. Si observamos nuevamente que es lo que hace la instrucción DA A

Microcontroladores. El 8051 de la INTEL.

96

veremos con sorpresa que se corresponde con los tres pasos que ejecutamos para obtener el resultado en BCD Empaquetado, por lo que en nuestro programa todo lo que tenemos que hacer es colocar esta instrucción inmediatamente después de efectuada la suma y con ello obtendremos el resultado como lo queríamos y listo para ser almacenado en la localización deseada. El fragmento de programa que lleva a cabo la tarea asignada en el ejemplo es el que se lista a continuación. ; Este fragmento de programa suma el contenido de las localizaciones de Memoria de Datos ; almacenadas en BCD Empaquetado cuyas direcciones son 10H y 11H ; almacenando el resultado obtenido en BCD Empaquetado en la localización cuya dirección es ; 12H. mov

A, 10H

; almacena en el registro Acumulador el primer operando.

add

A, 11H

; suma ambos operandos.

da

A

; convierte el resultado a BCD Empaquetado.

mov

12H, A

; almacena el resultado obtenido convertido a BCD Empaquetado ; en la localización 12H.

Le proponemos a modo de Trabajo Independiente que determine los cambios que hay que efectuar al fragmento del programa anterior si los operandos a sumar estuvieran almacenados en formato BCD desempaquetado y el resultado se lo quisiéramos tener en el mismo formato. Haga el nuevo programa. Con las instrucciones estudiadas hasta aquí estamos en capacidad de escribir Programas que efectúen operaciones de movimiento de datos entre las localizaciones de la memoria interna del microcontrolador y los registros del mismo, así como las tan populares operaciones aritméticas. No obstante, por lo general en los Programas se hace necesario tomar decisiones ante determinadas condiciones que se evalúan en un momento dado. Decisiones tales como, •

Si el número es par haz la tarea 1 pero si es impar haz la tarea 2.



Si el bit 7 del registro Acumulador es ´1´ haz la tarea 1 sino haz la tarea 2.



Decrementa un contador y repite la, operación anterior mientras sea diferente de ´0´.

A continuación estudiaremos las instrucciones del grupo de salto y llamadas a subrutinas que se caracterizan por tener la posibilidad de cambiar la secuencia lógica de ejecución del programa a decisión del Programador.

Microcontroladores. El 8051 de la INTEL.

97

Grupo de Salto y Llamadas a Subrutinas. Las instrucciones de este Grupo nos van a permitir cambiar, cuando lo queramos o cuando la ocurrencia de una determinada condición nos lo imponga, la secuencia natural del Programa. Todas tienen la característica común de que al ejecutarse provocan un cambio en la secuencia del programa, ya que afectan directamente el contenido del registro Contador de Programas. Dentro de este Grupo se encuentran las instrucciones más complejas en cuanto al número de operaciones que involucran del repertorio de Instrucciones del 8051. Para su estudio las instrucciones de este grupo las dividiremos en tres Subgrupos atendiendo a el porque de su uso en un programa. Estos dos subgrupos son: •

Instrucciones de Salto Incondicionales.



Instrucciones de Salto Condicionales.



Llamadas a Subrutinas.

Subgrupo de Instrucciones de Salto Incondicionales. Aunque todos los especialistas en la programación coinciden en que las instrucciones de salto deben ser evitadas al máximo en los programas, existen situaciones en los que es imprescindible utilizarlas. El objetivo fundamental que persigue el Programador al utilizar una de las instrucciones que conforman este Subgrupo en su programa es la de provocar un cambio en la secuencia de ejecución del mismo, haciendo que el microcontrolador ejecute la instrucción almacenada en la localización cuya dirección coincida con la dirección de salto declarada en la instrucción y no la que le sigue en la dirección consecutiva en la Memoria de Programa. Para ello, las instrucciones de este Subgrupo al ser ejecutadas afectan el contenido del registro Contador de Programas, sustituyendo en el mismo a la dirección consecutiva por la nueva dirección declarada en la instrucción. Otra características de las instrucciones de este subgrupo es que como su nombre lo indica la ejecución del salto se hace incondicional para el microcontrolador, en otras palabras, cuando el microcontrolador se tropieza con una de estas instrucciones no tiene otra alternativa que saltar a la a ejecutar la instrucción que se encuentra almacenada en la localización cuya dirección se declara en la instrucción. Veamos a continuación las instrucciones que conforman este Subgrupo. LJMP addr16

Microcontroladores. El 8051 de la INTEL.

98

Esta instrucción realiza un salto incondicional a la localización cuya dirección viene especificada por el operando addr16. addr16 es una dirección conformada por 16 bits, por lo que la dirección de destino del salto puede estar situada en cualquier punto de la Memoria de Programa, incluyendo la conectada externamente en el caso de que el microcontrolador este trabajando en el modo especial de trabajo. Esta es la razón por la que esta instrucción se conoce con el nombre de Salto Largo, permitiéndole al programador provocar un salto en la ejecución de su programa de una localización de memoria de programa cualquiera hacia una localización de memoria de programa cualquiera, no importando la distancia existente entre ambas localizaciones. SJMP rel Esta instrucción al igual que la anterior provoca un salto incondicional a la dirección declarada en la propia instrucción, la pregunta a contestar en este momento podría ser, ¿Qué la diferencia de la anterior? La diferencia viene dada por la longitud del salto, cantidad de localizaciones hacia delante o hacia atrás con respecto a la posición de la instrucción, que permite dar esta instrucción. Mientras que la anterior permitía dar un salto a cualquier dirección dentro de todo el espacio posible de direcciones de Memoria de Programa, con esta instrucción el espacio de salto está limitado a 128 byte hacia atrás y 127 byte hacia delante con respecto a la posición que ocupa la instrucción siguiente. Es por eso que esta instrucción recibe el nombre de Salto Corto. ¿En que radica esta limitación? La limitación en cuanto a la longitud posible del salto esta estrechamente relacionado con la forma empleada por el microcontrolador para calcular la dirección de salto cuando ejecuta esta instrucción. Si bien en la instrucción anterior de salto en el código de la misma están presentes los 16 bits de la dirección hacia donde se ordena efectuar el salto y por lo tanto todo lo que hace el microcontrolador para ejecutarla es cargar directamente en el registro Contador de Programa la dirección declarada en la instrucción, en esta instrucción lo que esta almacenado en el código es un valor, en 8 bits, que indica la distancia que existe entre la dirección de la localización donde esta almacenada la instrucción de salto y la dirección de la localización a donde se ordena efectuar el salto. Por lo tanto en este caso la dirección de salto es calculada por el microcontrolador sumando este valor de desplazamiento a la dirección de la localización que ocupa el primer código de la instrucción más 2.

Microcontroladores. El 8051 de la INTEL.

99

¿Por qué más 2? Esto es debido a que esta instrucción ocupa dos localizaciones en la memoria de programa, la primera para almacenar el código y la segunda para almacenar el byte de desplazamiento y cuando el microcontrolador haga el cálculo de la dirección a donde saltar para ejecutar la instrucción, ya el registro Contador de Programas se ha incrementado en dos con respecto a la dirección de la localización donde se encuentra almacenado el código de la instrucción de salto. ¿Cómo el microcontrolador determina si el salto es hacia delante o hacia atrás en las direcciones con respecto a la dirección que ocupa la instrucción de salto? El desplazamiento que se almacena en el código de la instrucción es un número entero con signo expresado en 8 bits en complemento a dos. Estar expresado el desplazamiento en complemento a dos posibilita que el microcontrolador pueda ejecutar saltos hacia delante (desplazamiento positivo) o hacia atrás (desplazamiento es negativo). Dado que el desplazamiento es un numero entero con signo expresado en complemento a dos, solo son empleados 7 bits para expresar el valor ya que el bit 7 es utilizado para indicar el signo, de ahí que los saltos puedan ser de 127 hacia delante (el 0 se toma como un numero positivo ya que tiene al bit 7 en 0 y no provoca salto) y 128 hacia detrás. Por suerte el Programador no tiene que calcular el valor del desplazamiento necesario a almacenar como parte del código de la instrucción, tarea esta que seria muy engorrosa. Si esta tarea no la hace el Programador entonces, ¿Quién hace esta tarea? De ello se encarga el Programa Ensamblador durante el proceso de ensamblaje del programa. No obstante, el Programador debe tener en cuenta que la dirección de salto que se ponga como operando de esta instrucción, rel, se encuentre dentro del espacio de salto máximo permisible por la misma, sino el Programa Ensamblador dará error. En la Figura 3.2.6 queda bien claro cual es la zona de salto valida mediante esta instrucción.

Microcontroladores. El 8051 de la INTEL.

100

Figura 3.2.6. Zona de salto valida con el empleo de la instrucción SJMP. ¿Por qué utilizar esta instrucción, corriendo el riesgo de cometer el error de ordenar un salto hacia una localización fuera de la zona valida con la misma y no utilizar una instrucción del tipo LJMP que permite saltar a cualquier dirección en la Memoria de Programa? La respuesta a esta pregunta esta relacionada con el número de localizaciones que ocupan estas instrucciones en la Memoria de Programa. Mientras que la instrucción del tipo LJMP ocupa tres localizaciones en la Memoria de Programa, código más dos localizaciones para los 16 bits de la dirección a donde saltar, la instrucción del tipo SJMP solo ocupa dos, código mas desplazamiento en complemento a dos, con lo que ahorra espacio en memoria. Si usted esta necesitado de ahorra espacio en la Memoria de Programa, utilice la instrucción del tipo SJMP cada vez que le sea posible, si no decida según su conveniencia. AJMP addr11 Esta instrucción se conoce con el nombre de Salto Incondicional Absoluto y en esencia es similar a la instrucción del tipo LJMP del punto de vista de cómo el microcontrolador determina la dirección de la localización hacia donde debe ejecutar el salto. Solo existen las dos diferencias siguientes:

Microcontroladores. El 8051 de la INTEL. •

101

addr11 es una dirección de 11 bits y no de 16 bits como es addr16, por lo que los saltos solo pueden ser dados en el entorno de las 2 k localizaciones de memoria con respecto a la dirección que ocupa la instrucción.



La instrucción ocupa dos localizaciones en la Memoria de Programa al igual que la instrucción SJMP.

Esta instrucción viene a ser como la intermedia entre las dos anteriores, permitiendo saltos más distantes que los que permite la instrucción SJMP, pero más cortos que los posibles con LJMP aunque ahorrando espacio en la memoria de programa. La pregunta a contestar en este momento sería, Si la dirección declarada en la instrucción es solo de 11 bits, ¿De donde obtiene el Microcontrolador los restantes 5 bits necesarios para completar la dirección de salto? Efectivamente, la dirección de una localización de Memoria de Programa esta conformada por 16 bits, recordemos que el registro Contador de Programas es un registro de 16 bits y es el que lleva la secuencia del Programa, por lo tanto a nuestra dirección en la instrucción le faltan 5 bits para completar los 16. Los 5 bits que faltan los aporta el propio registro Contador de Programas con sus bits del 15 al 11, ver Figura 3.2.7.

Figura 3.2.7. Conformación de la dirección de salto en la instrucción AJMP. Es como si la Memoria de Programa fuera dividida en 32 (25) paginas de 2 Kilo (211) localizaciones, Usted podría utilizar con plena libertad la instrucción AJMP para dar saltos a cualquiera de las localizaciones ubicadas dentro de la página en que se encuentra almacenada la instrucción. Si usted intenta dar un salto fuera de la página en cuestión mediante el uso de la instrucción AJMP el Programa Ensamblador se lo indicaría mediante un error en el proceso de ensamblaje.

Microcontroladores. El 8051 de la INTEL.

102

Una pregunta interesante a contestar en este momento podría ser, ¿Qué sucedería si en el proceso de ensamblaje uno de los byte de código de la instrucción AJMP cae en la última localización de una página y el otro cae en la primera localización de la página siguiente? El microcontrolador considera que la instrucción pertenece a la página donde se encuentra almacenado el segundo byte de código de la instrucción y por lo tanto los 5 bits que aporta el registro Contador de Programas para conformar la dirección efectiva de salto son los que le corresponden en este caso a la página siguiente. JMP

@A + DPTR

La dirección de salto dependerá de los valores almacenados en los registros Acumulador de 8 bits y DPTR de 16 bits. Para ello, el valor en 8 bits sin signo almacenado en el registro Acumulador se suma al valor en 16 bits almacenado en el registro DPTR, el resultado será la dirección de la próxima instrucción que será ejecutada. Esta instrucción se conoce con el nombre de Salto Incondicional Indirecto y solo ocupa una localización en la memoria de programas. Puede ser utilizada como una instrucción del tipo CASE del C++, ya que permitiría escoger, en dependencia del valor almacenado en el registro Acumulador, una instrucción a ejecutar dentro de un conjunto de ellas almacenadas en una tabla cuya dirección de inicio la aporta el contenido del registro DPTR. Ejemplo 3.5. Hacer el fragmento de programa que salta a localizaciones de memoria de programa diferentes en dependencia del valor almacenado en el registro Acumulador. El valor almacenado en el registro Acumulador debe ser un número entero sin signo ubicado entre los números del 0 al 9. Para la solución de este problema haremos uso de la instrucción, JMP

@A + DPTR

la que acompañaremos de un Tabla almacenada en memoria de programa justo en las localizaciones siguientes a las ocupadas por la instrucción anterior, cuyo puntero sea la dirección almacenada en DPTR y conformada por instrucciones del tipo, SJMP rel tendremos una instrucción de este tipo por cada posible a tomar por el registro Acumulador, por lo tanto serán 10 instrucciones de este tipo, cada una con una dirección de salto diferente.

Microcontroladores. El 8051 de la INTEL.

103

El Diagrama en Bloques del fragmento de programas es el que se muestra en la Figura 3.2.8.

Quizás la primera pregunta que se pueden hacer ustedes es, ¿Por qué multiplicar por 2 el contenido

del

registro

Acumulador? La razón es que el contenido del registro

Acumulador

será

el

desplazamiento para entrar en una Tabla de instrucciones que ocupan 2 localizaciones en la memoria de programas. Efectivamente la instrucción, SJMP rel ocupa 2 localizaciones en la memoria de programa cada vez que ella es colocada como parte de un programa en la misma. La primera localización es ocupada por el código de la instrucción y la segunda por el desplazamiento del salto. Por lo que en la Tabla la instrucción de salto que le corresponde al valor en el registro Acumulador igual a 0, ocupará las localizaciones de memoria (DPTR + 0) y (DPTR + 1), mientras que la que le corresponde a el valor en el registro Acumulador igual a 1 ocupará las localizaciones (DPTR + 2) y (DPTR + 3) y así sucesivamente. Observe, registro Acumulador = 0

(DPTR + (0*2)) = (DPTR + 0)

registro Acumulador = 1

(DPTR + (1*2)) = (DPTR + 2)

registro Acumulador = 2

(DPTR + (2*2)) = (DPTR + 4)

y así sucesivamente. El fragmento de programa sería el siguiente, ; Este programa salta a una localización en la memoria de programa en dependencia del ; valor almacenado en el registro Acumulador.

Microcontroladores. El 8051 de la INTEL.

104

; El valor almacenado en el registro Acumulador tiene que ser un numero entero sin signo entre ; el 0 y el 9. mov

DPTR, #TablaI

; carga en DPTR dirección inicio Tabla de Instrucciones

mov

B, #2

; prepara al registro B para multiplicar por 2 al registro ; Acumulador.

mul

AB

; multiplica por 2 el contenido del registro Acumulador.

jmp

@A+DPTR

; Salta dentro de la Tabla de Instrucciones.

; Tabla de Instrucciones. TablaI: sjmp

dir0

; salta si es 0 a dir0.

sjmp

dir1

; salta si es 1 a dir1

sjmp

dir2

; salta si es 2 a dir2

sjmp

dir3

; salta si es 3 a dir3

sjmp

dir4

; salta si es 4 a dir4

sjmp

dir5

; salta si es 5 a dir5

sjmp

dir6

; salta si es 6 a dir6

sjmp

dir7

; salta si es 7 a dir7

sjmp

dir8

; salta si es 8 a dir8

sjmp

dir9

; salta si es 9 a dir9

En las direcciones dir0, dir1, dir2, etc, podrían estar ubicados los fragmentos de programas que indican que operaciones hacer en dependencia del valor que tenia el registro Acumulador cuando entro a este fragmento de programa. Observe que sin preguntar por el valor del registro Acumulador hemos tomado una decisión a partir del valor que el mismo tenia. Les proponemos de Trabajo Independiente que hagan los arreglos pertinentes al programa anterior para que en el registro Acumulador en lugar de estar almacenados los números enteros sin signo del 0 al 9 lo que este almacenado sea el código ASCII de dichos números. Subgrupo de Salto Condicional. Es prácticamente imposible imaginarse un Programa en el que no se use una de las instrucciones de este Grupo. Por lo general en los programas se tienen que estar tomando decisiones constantemente en el sentido de efectuar una tarea u otra en dependencia del valor que toma una determinada condición. Las instrucciones de este subgrupo son las que ayudan al Programador a tomar estas decisiones. Por lo general estas instrucciones deciden ejecutar el salto a la dirección especificada en la propia instrucción o continuar la secuencia normal del programa en dependencia del estado en que se

Microcontroladores. El 8051 de la INTEL.

105

encuentra una de las banderas del Registro PSW. En el nemotécnico de la instrucción viene especificado si el salto se ejecutara cuando la bandera este en ´1´ lógico, verdadera, o cuando este en ´0´ lógico, falsa. Estas instrucciones responden a la caja de toma de decisiones en el Diagrama en Bloques del algoritmo del programa, ver Figura 3.2.9.

Figura 3.2.9 Diagrama en Bloques de las instrucciones de Salto CondicionalJC

dir

; Salta si el bit de bandera Acarreo (CY) esta en ´1´ lógico.

JNC

dir

; Salta si el bit de bandera Acarreo (CY) no esta en ´1´ lógico.

En la primera, si el bit de bandera de Acarreo (CY) está en ´1´ en el momento de ejecutarse la instrucción, la misma ejecuta un salto a la dirección especificada en dir, si no, se ejecuta la instrucción siguiente. En el caso de la segunda ocurre todo lo contrario, si el bit de bandera de Acarreo (CY) no esta en ´1´, o sea está a ´0´, en el momento de ejecutarse la instrucción, se ejecuta un salto a la dirección especificada por dir, en el caso contrario, se ejecutará la instrucción siguiente. Ninguna de las dos instrucciones afectan el contenido del bit de bandera de Acarreo (CY), por lo que este queda con el mismo valor que tenía antes de ejecutar la instrucción. ¿Existirá alguna restricción con respecto a la longitud del salto? Es imprescindible que el Programador garantice que la dirección dir, que constituye el operando de la instrucción, se encuentre en el intervalo de 2 Kilo localizaciones, hacia arriba en las direcciones o hacia abajo con respecto a la localización donde se encuentra almacenado el primer código de la siguiente instrucción a la de salto Condicional. Esto es debido a que en el código de la instrucción lo que se almacena no es una dirección absoluta de salto sino un desplazamiento con respecto al

Microcontroladores. El 8051 de la INTEL.

106

valor del registro Contador de Programa a la hora de ejecutar la misma. Esto no es nuevo para nosotros y ya lo habíamos visto en la instrucción de Salto Corto. Por lo tanto, la dirección de salto es calculada por el microcontrolador en esta instrucción a la hora de ejecutarla mediante la suma del valor del desplazamiento almacenado en la misma con el valor del registro Contador de Programas después de incrementarse en dos. ¿Por qué ± 2 Kilo localizaciones y no -128 y +127 localizaciones como en la instrucción de salto Corto? La diferencia esta en que mientras en la instrucción de Salto Corto solo se reservan 8 bits para almacenar el desplazamiento en esta instrucción se reservan 12 bits para el desplazamiento. ¿Por qué solo saltos de 2 Kilo localizaciones cuando se emplean 12 bits (212= 4 Kilo) para declarar el desplazamiento? Dado que se permiten dar saltos hacia arriba y hacia abajo en las direcciones en memoria, el desplazamiento tiene que ser un número con signo expresado en complemento a dos, por lo que uno de los bits, en este caso el más significativo, es destinado al signo y los 11 restantes al valor (211 = 2 Kilo). La operación que realiza el microcontrolador para calcular la dirección de salto no afecta las banderas. Al igual que en la instrucción de Salto Corto el Programador no tiene que calcular el valor del desplazamiento hasta la dirección de salto especificada por dir a cargar en el código de la instrucción ya que de esta tarea se encarga el Programa Ensamblador durante el proceso de ensamblaje del programa. No obstante si constituye responsabilidad del programador garantizar que el salto se encuentre dentro de los 2 kilo localizaciones permitido. Al igual que existe un par de instrucciones que permiten tomar una decisión en el programa en dependencia del valor que tenga el bit de bandera de Acarreo (CY), existen un par de instrucciones percápita con características similares para los bits de banderas de Paridad (P) y de Desbordamiento (OV). JP

dir

; Salta si el bit de bandera Paridad (P) esta en ´1´ lógico.

JNP

dir

; Salta si el bit de bandera Paridad (P) no esta en ´1´ lógico.

JO

dir

; Salta si el bit de bandera Desbordamiento (OV) esta en ´1´ lógico.

JNO

dir

; Salta si el bit de bandera Desbordamiento (OV) no esta en ´1 lógico.

Microcontroladores. El 8051 de la INTEL.

107

Existe una condición que aunque no esta relacionada con ningún bit de bandera de los existentes en el registro PSW es muy utilizada en los Programas. Esta condición es la que nos permite conocer si una determinada operación aritmética o lógica dio como resultado un ´0´. JZ

rel

; Salta si es cero.

JNZ

rel

; Salta si no es cero.

En este caso la primera instrucción ejecutara el salto si el valor del registro Acumulador, como resultado de la última operación aritmética o lógica ejecutada, se encuentra en 0, mientras en la segunda será lo contrario. Observe que la toma de la decisión por parte de la instrucción tiene validez si se pregunta por la condición después de ejecutada un instrucción aritmética o lógica, ya que su objetivo es el de poder contar con una instrucción que nos indique si el resultado de una de estos tipos de instrucciones fue 0 o no, no la de conocer si el registro Acumulador esta en 0. ¿Quién es rel en este caso? En esta instrucción se cumple lo mismo para el almacenamiento del desplazamiento y para el calculo de la dirección de salto que en la instrucción de Salto Corto. Dentro de este grupo existen instrucciones que resultan un tanto más complejas que las estudiadas. Estas por lo general no solo involucran el estado de un determinado bit de bandera, sino que en la instrucción viene implicitaza una determinada acción a ejecutar antes de tomar la decisión y en muchos casos se toma en cuenta el valor de varios bits de banderas. CJNE destino, origen, rel

; Compara y Salta si no es igual

Esta instrucción ya la estudiamos en el Tema anterior, no obstante repetiremos las características de la misma a modo de recordatorio para el estudiante. Si usted se recuerda bien de lo estudiado anteriormente, puede continuar con la próxima instrucción. Esta instrucción efectúa una comparación entre los contenidos de los operandos destino y origen y salta a la dirección indicada en caso de desigualdad. El bit de bandera de Acarreo (CY) se pone a ´1´ si el valor almacenado en la localización destino es menor que el valor almacenado en la localización origen. En los demás casos, se pone a ´0´. ¿Quiénes pueden ser destino?, ¿Quiénes pueden ser origen? CJNE A, directo, rel ; Compara el contenido del registro Acumulador con el ; contenido de una localización de memoria de datos.

Microcontroladores. El 8051 de la INTEL.

108

directo es una dirección de 8 bits correspondiente a una localización cualquiera de la memoria de datos. CJNE A, #dato8, rel ; Compara el contenido del registro Acumulador con una ; constante declarada en la propia instrucción. dato8 es una constante en 8 bit, declarado en la propia instrucción, que puede estar expresado en decimal, binario y hexadecimal. CJNE Rn, #dato8, rel ; Compara el contenido de uno de los registros cualquiera del ; banco de registros activo con una constante declarada en la ; propia instrucción. Rn es uno cualquiera de los registro del Banco de Registro activo. dato8 es una constante en 8 bits que puede estar expresado en decimal, binario y hexadecimal. CJNE @Ri, #dato8, rel

; Compara el contenido de una localización de memoria ; de datos con una constante declarada en la propia ; instrucción.

Ri puede ser uno cualquiera de los registro R0 o R1 del Banco de Registro activo. dato8 es una constante en 8 bits que puede estar expresado en decimal, binario y hexadecimal. Veamos el siguiente ejemplo donde se emplea esta instrucción con el objetivo de decidir entre tres posibles valores cual almacenar en la localización de memoria de datos 12H. Ejemplo 3.6. Dado dos números de 8 bits almacenados en las localizaciones de memoria de datos 10H y 11H, hacer un fragmento de programa que almacene en la localización 12H de dicha memoria el valor 00h si ambos números son iguales, el 01H si el numero almacenado en 10H es mayor que el almacenado en la 11H y el 02H en el caso contrario, ver Figura 3.2.10.

Microcontroladores. El 8051 de la INTEL.

109

Figura 3.2.10 ; El siguiente fragmento de programa compara los números almacenados en las localizaciones de ; Memoria de Datos 10H y 11H respectivamente almacenando en la localización de la Memoria de ; Datos 12H el número 00H si son iguales, el número 01H si el número en 10H es mayor que el ; número en 11H y el número 02H en el otro caso posible. mov

A, 10H

; cargo en el registro Acumulador uno de los números a comparar.

cjne

A,11H, caso1

; compara ambos números.

mov

12H, #00H

; iguales

sjmp

salir

; salida del programa

menor

; ¿es menor?

mov

12H, #01H

; mayor

sjmp

salir

; salida del programa

12H, #02H

; menor

caso1: jc

menor: mov salir:

nop

Les proponemos de Trabajo Independiente que hagan los cambios necesarios en el fragmento de programa anterior para resolver la misma tarea pero empleando la instrucción, JMP

@A+DPTR

Estudiada anterormente.

Microcontroladores. El 8051 de la INTEL.

110

En los programas en muchas ocasiones se hace necesario repetir la ejecución de una instrucción o de un grupo de instrucciones una cantidad de veces dadas. Para esto se hace necesario establecer en el programa un contador con la cantidad de veces que se desea ejecutar dicha tarea el que se decrementa cada vez que se ejecuta la misma. Este proceso se repite hasta que dicho contador se hace 0. Ejemplo 3.7. Llenar la zona de Memoria de Datos comprendida entre las localizaciones 20H hasta la 2FH con el numero 00H. En la Figura 3.2.11 se muestra el Diagrama en Bloques del algoritmo que nos

permitiría

encomendada.

efectuar El

la

tarea

fragmento

de

programa que permite realizar esta tarea

es

el

que

se

muestra

a

continuación. Observe que en este caso a diferencia del Ejemplo 3.2.1 el contador en lugar de incrementarlo y vigilar cuando llega al valor de localizaciones de memoria a llenar con el número 00H, este se inicializa

con

este

valor

y

se

decrementa y se vigila cuando llega al valor de 0. Por su puesto que son diferentes formas de hacer la misma cosa. A continuación se muestra el listado del fragmento de programas que hace la tarea que nos habíamos propuesto. ; Este fragmento de programa pone a 0 todos los bits de las localizaciones de Memoria de Datos ; comprendidas entre las localizaciones 20H y 2FH. mov

A, #16H

; numero de localizaciones a cargar con 00H, contador.

mov

R0, #20H

; primera localización a llenar con 00H

@R0, #00H

; cargo el 00H en la localización correspondiente.

inc

R0

; apunta a la próxima localización.

dec

A

; decrementa el Contador.

repite: mov

Microcontroladores. El 8051 de la INTEL. jnz

repite

111

; se termino de cargar 00H en la memoria.

Observe que lo que hemos hecho es poner a ´0´ a todos los bits del Segmento de Memoria de Datos direccionable bit a bit, lo que podría ser una forma de inicializar el trabajo con esta zona de memoria en un programa en caso de que fuéramos a trabajar con ella. Analicemos si existe alguna instrucción dentro del Repertorio de Instrucciones del microcontrolador que nos facilite esta tarea tan común en los Programas. DJNZ byte, rel

; Decrementa y Salta si no es cero.

Al ejecutar esta instrucción el microcontrolador decrementa en 1 el operando declarado como byte y si el resultado es diferente de 0, se ejecuta el salto a la dirección especificada por rel. La pregunta a dar respuesta en este momento sería, ¿Quiénes pueden tener almacenados el byte a decrementar? DJNZ Rn, rel Rn es cualquier registro del Banco de Registro activo. DJNZ directo, rel directo es una dirección en 8 bits de una localización cualquiera de Memoria de Datos. ¿Cómo quedaría el programa del ejemplo anterior si utilizáramos esta instrucción? ; Este fragmento de programa pone a ´0´ todos los bits de las localizaciones de ; Memoria de Datos Interna comprendidas entre las localizaciones 20H y 2FH. mov

R0, #16

; numero de localizaciones a cargar con 00H, contador

mov

R1, #20H

; primera localización a llenar con 00H

@R1, #00H

; cargo en ´0´ todos los bits de la localización correspondiente.

inc

R1

; apunta a la próxima localización.

djnz

R0, repite

; ¿Fin del lazo?

repite: mov

Nos parece conveniente aclarar que un valor original de 0 almacenado en byte provoca un desbordamiento del contador a 0FFH, no modificando el bit de bandera de Acarreo (CY).

Microcontroladores. El 8051 de la INTEL.

112

Le proponemos de Trabajo Independiente que analice los cambios que hay que hacer al fragmento de programa anterior si lo que quisiéramos poner todos los bits de esta zona de memoria con ´1´. Subgrupo de Llamadas a Subrutinas. Todo Programador cuando esta desarrollando una aplicación en particular se ha encontrado con el deseo de poseer una instrucción que el microcontrolador no tiene dentro de su Repertorio de Instrucciones. Esto por lo general viene dado por la cantidad de veces que un grupo de instrucciones se tiene que ejecutar en dicho programa. En estos casos el Programador tiene la opción de repetir en el programa este conjunto de instrucciones en tantos lugares como sea necesario. Esto por su puesto que resultaría engorroso para este y aumentaría la posibilidad de equivocación del mismo en la fase de Edición del Programa, además de provocar que el programa ocupara mucho más espacio que el necesario. Existe otra posibilidad, que consiste en darle a este conjunto de instrucciones la estructura de una Subrutina y mediante la instrucción correspondiente invocarla en el lugar necesario en el Programa con solo declarar su dirección de inicio en dicha instrucción. De esta forma el Programador no tiene que repetir el conjunto de instrucciones tantas veces como ocasiones en que se necesite su uso, escribiéndola una sola vez, con lo que ahorra tiempo, disminuye la posibilidad de equivocación y ahorra espacio en la Memoria de Programa. Se podría decir que a partir de este momento, el Programador cuenta con la instrucción que deseaba y que no se encontraba en el Repertorio de Instrucciones del microcontrolador. La preguntar a contestar en este momento sería, ¿Qué tiene de particular este fragmento de programa que le permite darle el nombre de Subrutina y emplearlo de esa manera? Los aspectos que lo particularizan y permiten llamarlo Subrutina son: •

Tienen un nombre que permite que lo invoquen desde cualquier lugar en el Programa Principal.



Tiene una instrucción de inicio y una instrucción final, que le permiten definirlo como un bloque.



Y quizás la más importante, son invocados mediante instrucciones del tipo de Llamadas a Subrutinas y su última instrucción se corresponde con una instrucción del tipo Retorno.

Microcontroladores. El 8051 de la INTEL.

113

¿Qué tienen de particular las instrucciones del tipo Llamadas a Subrutinas? ¿Qué tienen de particular las instrucciones del tipo Retorno? Las instrucciones del tipo Llamadas a Subrutina provocan un cambio en la secuencia del Programa al igual que las instrucciones del tipo de Salto ya estudiadas, por lo tanto su ejecución también alteran el contenido del registro Contador de Programas. Lo nuevo en estas instrucciones es que antes de provocar el cambio en la secuencia del Programa garantizan el retorno al Programa Principal una vez ejecutada la Subrutina. ¿Cómo garantizan esto? Para ello, la primera operación que ejecuta una instrucción de Llamada a Subrutina antes de provocar el salto es guardar en la Pila la dirección de la instrucción que sigue en secuencia en la Memoria de Programa, con lo que garantiza el posterior retorno al Programa Principal. Por su parte, las instrucciones del tipo Retorno como su nombre lo indican son las que garantizan el regreso al Programa Principal una vez concluida la ejecución de la Subrutina. Para ello la primera operación que realiza una instrucción del Tipo Retorno es, extraer de la Pila la dirección que previamente se había guardado en ella, que no era otra que la dirección de la próxima instrucción en secuencia a la instrucción de Llamada a Subrutina. Esta dirección se almacena en el registro Contador de Programa provocando que el Programa continué con la secuencia que traía antes de ejecutar la instrucción de Llamada a Subrutina, con lo que se completa el ciclo. En la Figura 3.2.12 se muestran los pasos que da el microcontrolador para ejecutar una instrucción de Llamada a Subrutina y en la Figura 3.2.13 se muestran los pasos que da el microcontrolador para ejecutar una instrucción del tipo Retorno.

Microcontroladores. El 8051 de la INTEL.

114

Figura 3.2.12 Pasos que da el microcontrolador para ejecutar una instrucción tipo Llamada a Subrutina.

Figura 3.2.13 Pasos que da el microcontrolador para ejecutar una instrucción del tipo Retorno. Tratando de establecer una comparación entre las instrucciones de Llamada a Subrutina y las instrucciones de Salto podemos plantear que mientras las primeras provocan un cambio en la secuencia del Programa con la intención futura de retomar al mismo una vez ejecutada la Subrutina, en la segunda se provoca también un cambio en la secuencia del programa pero no

Microcontroladores. El 8051 de la INTEL.

115

existe una Subrutina que ejecutar, ni una intención de retornar en el futuro a por donde iba el programa. ¿Cuáles son estas instrucciones de Llamada a Subrutina para el microcontrolador 8051? ACALL

addr11

; Llamada a Subrutina mediante dirección Absoluta.

La dirección de salto viene declarada en la propia instrucción, addr11, debiéndose corresponder con la dirección de la localización de la primera instrucción de la Subrutina en la memoria de programa. El Programador debe tener el mismo cuidado cuando emplea esta instrucción que cuando emplea una instrucción de Salto Absoluto y es que debe tener el cuidado de que, la primera instrucción de la Subrutina a la cual se invoca este situada en la pagina de 2 Kilo localizaciones en que se encuentra la instrucción siguiente a la dicha instrucción. LCALL

addr16

; Llamada a Subrutina mediante una dirección Larga.

Era de esperar que si existía una instrucción de Llamada a Subrutina con limitaciones en cuanto a la posición relativa entre la localización donde se almacena la instrucción y la localización de inicio de la Subrutina, existiera una instrucción donde esta restricción desapareciera, este es el caso de la Llamada a Subrutina Larga. ¿Cuáles son las diferencias entre una y otra? Son dos los aspectos que las diferencian: •

La dirección de inicio de la Subrutina declarada en la instrucción por addr16 esta almacenada en 16 bits en el código de la instrucción de ahí que la Subrutina puede estar ubicada en cualquier localización de la Memoria de Programas.



El número de localizaciones que ocupa esta instrucción en la Memoria de Programas es de 3, una para el código de la instrucción y los otros dos para los 16 bits de la dirección. Esto provoca que la dirección de la localización donde se encuentra almacenada la próxima instrucción en secuencia sea 3 localizaciones hacia abajo y no dos como en el primer caso. RET

; Retorno a una Llamada a Subrutina.

Ya conocíamos que existen instrucciones de Retorno que se deben ser ejecutadas una vez la ejecución de la Subrutina halla terminado. Estas instrucciones de Retorno que se corresponden

Microcontroladores. El 8051 de la INTEL.

116

siempre con la última instrucción en la Subrutina, como su nombre lo indica permiten el retorno de la secuencia natural hacia el Programa Principal. ¿Qué operaciones provoca esta instrucción que permite retomar la secuencia natural del programa Principal? Para ello recupera de la pila el valor de la dirección de la próxima instrucción a ejecutar según la secuencia natural del programa, previamente salvada en esta por la instrucción de Llamada a Subrutina, guardando este valor en el registro Contador de Programa con lo que se garantiza que la ejecución del programa Principal continúe con su secuencia natural. En esta operación el registro Puntero de la Pila (SP) se decrementa en 2. Como podemos ver la instrucción RET prácticamente ejecuta las acciones opuestas a las instrucciones de Llamada a Subrutina, para ello compare los esquemas que aparecen en las Figuras 3.2.11 y 3.2.12 respectivamente. Algo que el Programador debe tener en cuenta cuando trabaja con Subrutinas es que datos son los que se encuentran almacenados en la Pila en cada momento pues corre el riesgo de no regresar nunca a su Programa Principal sino se trabaja correctamente. RETI

; Retorno de una llamada a interrupción.

No existe una solo instrucción de retorno como nos podría haber hecho pensar la instrucción RET estudiada anteriormente. ¿Tendrá algo que ver cual fue la instrucción de Llamada a subrutina empleada para invocarla con respecto al uso de la instrucción de retorno a emplear? Por suerte, esto no tiene nada que ver y cualquiera de las dos instrucciones que se emplee para invocar a la subrutina la instrucción de retorno siempre será RET. ¿Cuándo usar la instrucción RETI? Conocimos la forma empleada para invocar una Subrutina mediante programa pero existe también la manera de invocar la ejecución de una Subrutina mediante hardware. Esto esta estrechamente relacionado con los servicios de la Interrupción que serán explicados más adelante en el material. Por lo que contentémonos con saber en este momento, que cuando la Subrutina es invocada por un pedido de interrupción al Microcontrolador la manera de retornar es mediante el empleo de la instrucción RETI.

Microcontroladores. El 8051 de la INTEL.

117

Veamos un ejemplo donde se hace uso de una Subrutina. Ejemplo 3.8. Diseñar un fragmento de programa en forma de Subrutina que cada vez que sea invocado provoque una demora de 120 microsegundos antes de regresar al Programa Principal. Son muchos los casos en que necesitamos una determinada demora en medio de la ejecución del programa, en estos casos poder contar con una Subrutina que cada vez que la invoquemos provoque la demora deseada sería de gran utilidad. Para esto nos basaremos en el tiempo de ejecución de la instrucción ya estudiada DJNZ. La ejecución de la instrucción DJNZ consume 2 microsegundo, por lo que si queremos provocar la demora de 120 microsegundos debemos ejecutar esta instrucción 60 veces. ; Subrutina demora120 que provoca una demora de 120 microsegundos. demora120:

mov

R0, #60

lazo:

djnz

R0, lazo

; cantidad de veces a ejecutar la instrucción, Contador.

ret Muchos Programas Ensambladores interpretan el símbolo $ como operando de las instrucciones de Salto como un salto a la misma instrucción, no siendo necesario en este caso declarar la etiqueta lazo. ; Subrutina demora120 que provoca una demora de 120 microsegundos. demora120:

mov

R0, #60

djnz

R0, $

; cantidad de veces a ejecutar la instrucción.

ret En muchas aplicaciones no resulta suficiente con un solo lazo, como en el ejemplo anterior, para provocar el tiempo de demora deseado. En estos casos se puede proceder a un doble lazo en el programa. Ejemplo 3.9. Diseñar un fragmento de programa en forma de Subrutina que cada vez que sea invocado provoque una demora de 51.2 milisegundos antes de regresar al Programa Principal. El tiempo máximo de demora que se puede lograr con un fragmento de programa como el del ejemplo anterior sería de 256 multiplicado por 2 microsegundos, que resultaría de cargar en R0 en

Microcontroladores. El 8051 de la INTEL.

118

la primera instrucción de la Subrutina el numero 00H. Pero este tiempo es solo de 512 microsegundos, por lo que, para obtener los 30 milisegundos deseados se hace necesario ejecutar esta Subrutina a su vez en 100 ocasiones. Por lo que una solución podría ser, haciendo dos lazos dentro de la Subrutina. El lazo interior se encargaría de provocar la demora de 512 microsegundos, mientras que el lazo externo se encarga de hacer ejecutar el lazo interno las 100 veces que se necesita para alcanzar los 51.2 milisegundos de demora deseados. ; Subrutina demora51 que provoca una demora de 51,2 milisegundos. demora51:

mov

R1, #100

; cantidad de veces a ejecutar el lazo interno

repite:

mov

R0, #0

; cantidad de veces a ejecutar DJNZ..

djnz

R0, $

; lazo interno.

djnz

R1, repite

; lazo externo.

Ret Le proponemos de Trabajo Independiente que empleando la Subrutina demora51, haga un fragmento de programa que alterne cada 51,2 milisegundos el valor almacenado en el registro Acumulador entre lo valores 00H y 0FFH. Con el estudio de este subgrupo de instrucciones hemos agregado a nuestros conocimientos para hacer programas para este microcontrolador las posibilidades de: •

Cambiar la secuencia natural de un programa.



Tomar decisiones a partir de la ocurrencia o no de una determinada condición.



Repetir tantas veces se desee la ejecución de un conjunto de instrucciones.



Trabajar con Subrutinas.

Continuemos con el estudio de los dos Grupos de Instrucciones que nos quedan para completar el Repertorio de Instrucciones de este microcontrolador. Grupo de Operaciones Lógicas. Este Grupo de instrucciones los podemos subdividir para su estudio en tres subgrupos atendiendo a las operaciones que las mismas efectúan. Estos subgrupos son: •

Subgrupo de Operaciones Lógicas.



Subgrupo de Rotación.



Subgrupo de Operaciones Especiales con el Acumulador.

Microcontroladores. El 8051 de la INTEL.

119

Subgrupo de Operaciones Lógicas. Dentro de este subgrupo se encuentran un conjunto de instrucciones que permiten efectuar entre dos operandos, las operaciones básicas del Álgebra de Boole, AND, OR y OR EXCLUSIVO. Si bien estas instrucciones tienen como operandos a estructuras tipo byte, ellas se ejecutan bit a bit dentro de dichos byte. Estas instrucciones no afectan los bits de banderas del registro PSW. Instrucciones del tipo AND. ANL

destino, origen

; AND lógico.

Realiza la operación lógica AND entre los bits de los operandos origen y destino, quedando el resultado almacenado en el operando destino. < destino >

< destino AND origen >

Resulta importante recalcar que la operación AND se efectúa entre los bits que ocupan la misma posición en los operandos que forman parte de la instrucción. Veamos lo anterior en el siguiente ejemplo. Supongamos que en el registro Acumulador se encuentra almacenado el número A = 0110 1100B mientras que en el registro R0 se encuentra almacenado el numero R0 = 0101 0110B. ¿Qué quedaría almacenado en el registro Acumulador después de ejecutada la instrucción ANL

A, R0 ?

La función lógica AND del Álgebra de Boole para dos entradas responde a la Tabla de la verdad que se muestra en la Figura 3.2.14, mostrándose a la derecha de dicha figura su representación esquemática.

Microcontroladores. El 8051 de la INTEL.

120

Observe que la salida solo tomará el valor de ´1´ lógico en el caso de que sus dos entradas se encuentren también en ´1´ lógico.

Atendiendo a esto hemos mostrado en la Figura 3.2.15 un esquema que nos ayude a comprender que es lo que ocurre dentro del microcontrolador cuando este efectúa la instrucción anterior.

Figura 3.2.15. La pregunta a responder en este momento podría ser, ¿Quiénes pueden ser origen y destino en esta instrucción?, ¿Solo podrá ser destino el registro Acumulador? •

Uno de los operandos es el registro Acumulador. ANL

A, Rn

Rn es cualquier registro del Banco de Registro activo.

ANL

< (A) AND (Rn) > A, directo

directo es la dirección de una localización cualquiera de Memoria de Datos.

Microcontroladores. El 8051 de la INTEL.

ANL

121

< (A) AND ( directo ) > A, @Ri

Ri puede ser uno cualquiera de los registro R0 o R1 del Banco de Registro activo.

ANL

< (A) AND ((Ri )) > A, #dato8

dato8 es un dato en 8 bits que puede estar expresado en decimal, binario y hexadecimal.

< (A) AND dato8 >

Dándole respuesta a la segunda pregunta, esta instrucción no solo acepta como localización destino al registro Acumulador, sino que también acepta como destino a una localización de la Memoria de Datos declarada en la instrucción empleando como Modo de Direccionado el Directo. •

Uno de los operandos es el contenido de una localización de memoria de datos. ANL

directo, A

A es el contenido del registro Acumulador. < (directo) > ANL

< (directo) AND (A) >

directo, #dato8

dato8 es un dato en 8 bits que puede estar expresado en decimal, binario y hexadecimal. < (directo) >

< (directo) AND dato8 >

Instrucciones del tipo OR y OR EXCUSIVO. Las funciones OR y OR EXCLUSIVO se corresponden con dos funciones lógicas del Álgebra de Boole al igual que la función lógica AND. Cada una tiene su propia Tabla de la Verdad que indica como responde la salida de la misma como consecuencia de la combinación impuesta en sus entradas. Estas con la representación esquemática de la compuerta se muestran en la Figura 3.2.16.

Microcontroladores. El 8051 de la INTEL.

122

Figura 3.2.16. ORL

destino, origen

; Instrucción OR Lógico.

Se realiza un OR lógico entre el origen y el destino. El resultado es colocado en el operando destino. No modifica las banderas. < destino >

< destino OR origen >

¿Cuáles son las diferentes combinaciones origen, destino que admite esta instrucción? Se pueden establecer las mismas combinaciones que origen, destino que las establecidas con la instrucción AND lógico. ORL

A, Rn

ORL

< (A) OR (Rn) > A, directo

ORL

< (A) OR (directo) > A, @Ri

ORL

< (A) OR ((Ri )) > A, #dato8

ORL

< (A) OR dato8 > directo, A

< (directo) > ORL

directo, #dato8

< (directo) OR (A) >

Microcontroladores. El 8051 de la INTEL. < (directo) >

123 < (directo) OR dato8 >

Otro tanto ocurre con la instrucción OR EXCLUSIVO. XRL

destino, origen

; Instrucción OR EXCLUSIVO.

Se realiza un OR EXCLUSIVO entre el origen y el destino. El resultado es colocado en el operando destino. No modifica las banderas. < destino >

< destino OR origen >

¿Cuáles son las diferentes combinaciones origen, destino que admite esta instrucción? Las mismas que en las anteriores. XRL

A, Rn

XRL

< (A) XOR (Rn) >

A, directo

XRL

< (A) XOR (directo) > A, @Ri

XRL

< (A) XOR ((Ri )) > A, #dato8

XRL

< (A) XOR dato8 > directo, A

< (directo) > XRL

< (directo) XOR (A) >

directo, #dato8

< (directo) >

< (directo) XOR dato8 >

Estas son las posibles funciones lógicas que aparecen representadas mediante una instrucción en el Repertorio de Instrucciones de este microcontrolador.

Microcontroladores. El 8051 de la INTEL.

124

Subgrupo de Rotación. Dentro de este subgrupo se encuentran un conjunto de instrucciones que permiten rotar el valor almacenado en los bits del registro Acumulador una posición hacia la derecha o una posición hacia la izquierda. Estas instrucciones son muy valiosas para detectar posición de un ´0´ o de un ´1´ dentro de un byte. Estas instrucciones pueden utilizar el bit de bandera de Acarreo (CY) como una prolongación del registro Acumulador. NOTA: estas instrucciones solo pueden realizarse con el registro Acumulador como operando, por lo que si usted en su programa necesita efectuar la rotación de un dato almacenado en una localización de la memoria o en un registro diferente del Acumulador, usted debe primero mover el dato de donde esta hacia el registro Acumulador y solo después podrá ejecutar la instrucción de rotación correspondiente. Instrucciones de Rotación hacia la Derecha. RR

A

; Rota el registro Acumulador un bit a la derecha.

Provoca que los valores almacenados en los bits del registro Acumulador se muevan una posición hacia la derecha dentro del registro. El valor almacenado en el bit 7 hacia el bit 6, a su vez el valor almacenado en el bit 6 se mueve hacia el bit5 y así sucesivamente. El valor almacenado en el bit0 se mueve hacia el bit 7. Ver Figura 3.2.17.

Figura 3.2.17. RRC

A

; Rota el registro Acumulador un bit a la derecha a través del bit de ; bandera de Acarreo (CY).

Microcontroladores. El 8051 de la INTEL.

125

Provoca que los valores almacenados en los bits del registro Acumulador se muevan una posición hacia la derecha dentro del registro. A esta cadena de bits se une el bit de bandera de Acarreo (CY) el que envía su valor hacia el bit 7, tomando el valor que envía el bit 0. Ver Figura 3.2.18.

Figura 3.2.18. Instrucciones de Rotación hacia la Izquierda. RL

A

; Rota el registro Acumulador un bit a la izquierda

Provoca que los valores almacenados en los bits del registro Acumulador se muevan una posición hacia la izquierda dentro del registro. El valor almacenado en el bit 7 se mueve hacia el bit 0. Ver Figura 3.2.19.

Figura 3.2.19. RLC

A

; Rota el registro Acumulador un bit hacia la izquierda a través del bit de ; bandera de Acarreo (CY).

Microcontroladores. El 8051 de la INTEL.

126

Provoca que los valores almacenados en los bits del registro Acumulador se muevan una posición hacia la izquierda dentro del registro. A esta cadena de bits se une el bit de bandera de Acarreo (CY) el que envía su valor hacia el bit 0, tomando el la información que envía el bit 7. Ver Figura 3.2.20.

Figura 3.2.20. Subgrupo de Operaciones Especiales con el registro Acumulador. Dentro de este subgrupo se encuentran tres instrucciones que dada la operación que realizan sobre los bits del registro Acumulador nos es difícil poderla enmarcar en uno de los subgrupos anteriores. Estas tres instrucciones son: CLR

A

; Limpia los bits del registro Acumulador.

Todos los bits del registro Acumulador se ponen a ´0´. No se modifican los bits de banderas.

CPL

< 0000 0000B > A

; Complementa los bits del registro Acumulador

Se invierten, complemento a 1, todos los bits del registro Acumulador, los bits que estan en ´0´ se ponen a ´1´ y viceversa. No se modifica los bits de banderas.

< NOT A >

SWAP A Intercambia los nibles del registro Acumulador. ¿Qué cosa es un nible?

Microcontroladores. El 8051 de la INTEL.

127

Un nible es un tipo de dato de longitud 4 bits, por lo que un byte lo podemos dividir en dos nibles, el menos significativo el formado por los bits del 3 al 0 y el más significativo el conformado por los bits de 7 al 4. ¿Qué es lo que hace entonces esta instrucción con los nibles que conforman el byte almacenado en el registro Acumulador? Intercambia los 4 bits más significativos (b7-b4) del registro Acumulador, nible más significativo, con los 4 bits menos significativos (b3-b0) del mismo registro, nible menos significativo, de forma tal que el contenido del bit7 pasa al bit3 y a su vez el contenido del bit3 pasa al bit7 y así sucesivamente. Ver Figura 3.2.21.

Figura 3.2.21. Con esta instrucción es como si se efectuaran 4 instrucciones de rotación o como si multiplicáramos por 16 un número de 4 bits. Veamos lo anterior en el siguiente ejemplo.

Ejemplo 3.9. Hacer una Subrutina que cada vez que se invoque permita multiplicar por 16 el byte almacenado en el registro Acumulador. El resultado debe quedar almacenado a la salida en los registros B y Acumulador. No emplear la instrucción de multiplicación.

Microcontroladores. El 8051 de la INTEL.

128

En la Figura 3.2.22 se muestra el Diagrama en Bloques de la Subrutina en cuestión y a su derecha aparece el listado de las instrucciones.

El nombre que le hemos dado a esta subrutina es el de mult16. ; Esta subrutina multiplica por 16 el dato que esta almacenado ; en el registro Acumulador. ; El resultado en 16 bits queda almacenado: ; el byte mas significativo en el registro B. ; el byte menos significativo en el registro Acumulador. mult16:

mov

R3,A

; Salvo el dato.

anl

A, #11110000B

; Me quedo con el nible alto

swap

A

; Multiplico por 16 al nible alto

mov

B, A

; Salvo el resultado en el registro B.

mov

A, R3

; Restablezco el dato a multiplicar

anl

A,#00001111B

; Me quedo con el nible bajo.

swap

A

; Multiplico por 16 al nible bajo.

ret

; retorno de la subrutina.

Le proponemos de Trabajo Independiente que mediante el empleo de esta instrucción haga un fragmento de programa que permita obtener el formato en BCD desempaquetado de cualquier numero almacenado en el registro Acumulador que venga expresado en BCD empaquetado.

Microcontroladores. El 8051 de la INTEL.

129

Una de las características más significativas de este microcontrolador es la de contar con un conjunto de instrucciones que permiten efectuar el tratamiento de bit. Operaciones tales como las aritméticas o las lógicas o las de salto condicional, etc., que antes hacíamos con un byte completo, existen instrucciones que nos van a permitir poderlas efectuar solo sobre un bit de un determinado registro o sobre un bit de una localización de memoria de datos. Estas instrucciones se encuentran dentro del grupo de Manipulación de Variables Booleanas. Grupo de Manipulación de Variables Booleanas. Las instrucciones de este Grupo declaran como operando a un bit de forma individual y no a un byte como había estado ocurriendo hasta aquí en las instrucciones estudiadas. Con estas instrucciones el Programador tendrá la posibilidad de fijar a ´0´ o a ´1´ un bit especifico sin afectar a los restantes bits que lo acompañan en el byte, podrá cambiar el valor almacenado en un bit, podrá efectuar las operaciones lógicas AND y OR estudiadas anteriormente pero solo para un par de bits específicos, podrá mover el valor almacenado en un bit hacia otro y podrá tomar decisiones en dependencia del valor almacenado en un determinado bit. ¿Estas instrucciones se podrán utilizar con cualquier bit independientemente de la posición que ocupe dentro del microcontrolador? Como era de esperar la respuesta a la pregunta anterior es no. En este caso, ¿En cuales se puede utilizar? Están autorizados a ser utilizados como operandos de estas instrucciones: •

Los bits ubicados en las localizaciones que pertenecen al Segmento Direccionable Bit a Bit en la Memoria de Datos Interna del Microcontrolador. Este Segmento, ya estudiado anteriormente, esta compuesto por 16 localizaciones ubicadas a partir de la dirección 20H hasta la 2FH en dicha Memoria.



Un conjunto de registro, de los Registros de Funciones Especiales, que se permite referirnos a sus bits mediante estas instrucciones.

¿Cuáles son estos registros? Aquellos registros cuya dirección termina con los números 0 y 8 y que ya fueron mostrados en la Tabla 2.3.2 marcados en negrita y que en la Tabla 3.2.2 los damos modo resumido.

Microcontroladores. El 8051 de la INTEL.

130

Símbolo

Nombre

Dirección

Acc

Acumulador

0E0h

B

Registro B

0F0h

PSW

Palabre de Estado

0D0h

P0

Puerto 0

80h

P1

Puerto 1

90h

P2

Puerto 2

0A0h

P3

Puerto 3

0B0h

IP

Prioridad de Interrupción

0B8h

IE

Habilitación de Interrupción

0A8h

TCON

Control de los Temporizadores

88h

SCON

Control de Puerto Serie

98h

Tabla 2.3.2. ¿Cómo referirnos a un bit específico en una instrucción? En el caso de los bits de las localizaciones de memoria del Segmento de memoria Direccionable Bit a Bit, a cada uno de sus bits le corresponde una dirección absoluta y una dirección relativa. Para el caso de emplear la dirección absoluta, todo el segmento se trata como bits, de esta forma al bit 0 de la localización cuya dirección es 20H le corresponde la dirección absoluta 00H, al bit 1 de la misma localización le corresponde la dirección 01H y así sucesivamente hasta llegar al bit 7 de la localización cuya dirección es la 2FH al que le corresponde la dirección absoluta 7FH, ver Figura 3.2.23. Por lo tanto una de las formas de declarar un bit determinado como operando de una instrucción de este grupo es declarando su dirección absoluta, como en la instrucción siguiente. CLR 00H

; Pone a ´0´ al bit 0 de la localización 20H.

Microcontroladores. El 8051 de la INTEL.

131

En el caso de la dirección relativa, cada bit de este segmento ocupa una posición dentro de una localización con dirección específica. El Programador podría declarar la dirección del bit, mediante la dirección de la localización a la que pertenece el bit, seguido de un punto y después la ubicación dentro de la localización del bit deseado, ver Figura 3.2.24.

La instrucción siguiente tendría el mismo efecto sobre el bit 0 de la localización 20H que la anterior, CLR 20H. 0 En el caso de los Registros que pueden ser direccionados bit a bit la manera de declarar el bit con que se desea trabajar es mediante el nombre del Registro al que pertenece el bit, seguido de un punto y seguido de la posición que ocupa el bit dentro del registro. SETB A.3

; Pone a ´1´ al bit 3 del registro Acumulador.

A continuación mostramos todas las instrucciones de este grupo. CLR

bit

Se pone a ´0´ el bit indicado por el operando. < bit >

´0´

Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. CLR C Se pone a ´0´ el bit de bandera Acarreo (CY). < Bit de Bandera Acarreo> SETB bit Pone a ´1´ el bit especificado por el operando.

´0´

Microcontroladores. El 8051 de la INTEL.

132

Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit >

´1´

SETB C Pone a ´1´ el bit de Bandera de Acarreo (CY). < Bit de Bandera Acarreo > CPL

´1´

bit

Se invierte, complemento a 1, el bit especificado en el operando. Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit > CPL

< NOT bit > C

Se invierte, complemento a 1, el bit de bandera Acarreo (CY). < bit de Bandera Acarreo > ANL

< NOT bit de Bandera Acarreo >

C, bit

Efectúa la aeración AND entre el contenido del bit de bandera de Acarreo (CY) y el bit especificado en el operando. El resultado se almacena en el bit de bandera de Acarreo (CY) Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit de Bandera Acarreo > ANL

< bit de Bandera Acarreo AND bit >

C, /bit

Efectúa la operación AND entre el contenido del bit de bandera de Acarreo (CY) y el negado del valor almacenado en el bit especificado en el operando. El resultado se almacena en el bit de bandera de Acarreo (CY). Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit de Bandera Acarreo > ORL

< bit de Bandera Acarreo AND bit/>

C, bit

Efectúa la operación OR entre el contenido del bit de bandera de Acarreo (CY) y el bit especificado en el operando. El resultado se almacena en el bit de bandera de Acarreo (CY)

Microcontroladores. El 8051 de la INTEL.

133

Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit de Bandera Acarreo >

< bit de Bandera Acarreo OR bit >

ORL C, /bit Efectúa la operación OR entre el contenido del bit de bandera de Acarreo (CY) y el negado del valor almacenado en el bit especificado en el operando. El resultado se almacena en el bit de bandera de Acarreo (CY) Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit de Bandera Acarreo > MOV

< bit de Bandera Acarreo OR bit/ >

C, bit

Mueve el valor almacenado en el bit declarado en el operando hacia el bit de bandera de Acarreo (CY). Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit de Bandera Acarreo > MOV

< bit >

bit, C

Mueve el valor almacenado en el bit de bandera de Acarreo (CY) hacia el bit declarado en el operando. Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. < bit > JB

< bit de Bandera Acarreo > bit, dir

Si el bit indicado como operando está a ´1´, se ejecuta un salto a la dirección especificada en dir. En caso contrario, se ejecuta la instrucción siguiente. El bit que se comprueba no se modifica. Tampoco se modifican los bits de banderas. Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. La distancia entre la dirección de salto y la dirección de la instrucción no puede ser mayor de -128 y +127. JNB

bit, dir

Si el bit especificado en el operando está a ´0´, se ejecuta un salto a la dirección especificada en dir, si no se ejecuta la instrucción siguiente. No se modifican los bits de banderas.

Microcontroladores. El 8051 de la INTEL.

134

Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. La distancia entre la dirección de salto y la dirección de la instrucción no puede ser mayor de -128 y +127. JBC

bit, dir

Si el bit indicado en el operando está a ´1´, se ejecuta un salto a la dirección indicada en dir. En caso contrario, se ejecuta la instrucción siguiente. Si el resultado de la comprobación es positivo, el bit es puesto a ´0´, como preparándolo para futuras encuestas. No se modifican los bits de banderas. Quienes pueden ser bit y la manera de definirlos en la instrucción, fue ampliamente debatido en los párrafos anteriores. La distancia entre la dirección de salto y la dirección de la instrucción no puede ser mayor de -128 y +127. Veamos a continuación un ejemplo donde empleemos instrucciones de este grupo. Ejemplo 3.10. Dada una Tabla conformada por 16 números enteros sin signos en 8 bits almacenada en memoria de datos de forma ascendente de las direcciones y a partir de la localización cuya dirección es 00H conformar dos Tablas, una que contenga los números pares de dicha Tabla y la otra los números impares. La primera almacenarla en memoria de datos a partir de la localización cuya dirección es la 20h y de forma ascendente de las direcciones y la segunda a partir de la localización cuya dirección es la 40h de forma descendente de las direcciones. En la Figura 3.2.25 se muestra el Diagrama en Bloques del programa que le proponemos para resolver la tarea asignada.

Microcontroladores. El 8051 de la INTEL.

135

Quizás la interrogante que nos puede surgir en este momento es, ¿Cómo conocer que el valor almacenado en el registro Acumulador traído de la Tabla original es par o impar? Si analizamos los 6 primeros números en binario pienso que podemos llegar a una conclusión sobre este aspecto,

Microcontroladores. El 8051 de la INTEL. NUMERO EN

136

NUMERO EN BINARIO

PAR O

DECIMAL

b7

b6

b5

b4

b3

b2

b1

bo

IMPAR

0

0

0

0

0

0

0

0

0

PAR

1

0

0

0

0

0

0

0

1

IMPAR

2

0

0

0

0

0

0

1

0

PAR

3

0

0

0

0

0

0

1

1

IMPAR

4

0

0

0

0

0

1

0

0

PAR

5

0

0

0

0

0

1

0

1

IMPAR

Si observamos el valor que toma el bit0 podemos llegar a la conclusión de que cuando el bit 0 toma el valor de ´0´ estamos en presencia de un numero par y cuando toma el valor de ´1´ estamos en presencia de un numero impar. En esto nos vamos a basar para desarrollar nuestro programa. El listado del fragmento de programa se muestra a continuación. ; Este programa a partir de una Tabla conformada por 16 números enteros sin signo en formato de ; byte, obtiene otras dos Tablas, una conformada con los números pares y la otra con los números ; impares.

lazo:

mov

R0, #00h

; puntero a la Tabla original.

mov

R3, #20h

; dirección de inicio de Tabla de los pares.

mov

R4, #40h

; dirección de inicio de Tabla de los Impares.

mov

R2, #16

; cantidad de datos en Tabla original.

mov

A, @R0

; traigo dato en curso de la Tabla original.

inc

R0

; actualizo el puntero a la Tabla original

jnb

A.0, par

; ¿el dato traído es par?

; El dato traído es impar. mov

R1, R4

; cargo en R1 puntero a la Tabla de los impares.

mov

@R1, A

; muevo el dato a la Tabla de los impares.

dec

R1

; actualizo al puntero de forma descendente de las direcciones.

mov

R4, R1

; guardo el puntero de la Tabla de los impares actualizado.

sjmp

salir

; El dato traído es par. par:

mov

R1, R3

; cargo en R1 puntero a la Tabla de los pares.

mov

@R1, A

; muevo el dato a la Tabla de los pares.

inc

R1

; actualizo al puntero de forma ascendente de las direcciones.

mov

R3, R1

; guardo el puntero de la Tabla de los impares actualizado.

; Chequeo si ya se paso por todos los datos de la tabla original. salir:

djnz

R2, lazo

Microcontroladores. El 8051 de la INTEL.

137

Les proponemos de Trabajo Independiente que analicen los cambios que hay que efectuar al programa para que el primer dato almacenado en la Tabla original sea el que indique la cantidad de datos que hay en la Tabla y que al mismo tiempo el primer dato en las Tablas de los impares y de los pares conformada indique la cantidad de datos que hay en la misma. En este momento ya conocemos todas las instrucciones que integran el Repertorio de Instrucciones de este microcontrolador, así como la sintaxis de las mismas por lo que somos del criterio de que deberíamos profundizar un poco más en los circuitos que resultan imprescindibles para que funcione un sistema basado en este microcontrolador antes de intentar desarrollar nuestras primeras aplicaciones, lo que constituirá el contenido del próximo Tema.

Microcontroladores. El 8051 de la INTEL.

138

Tema 4. Elementos imprescindibles en un sistema con el 8051. Ya conocemos del Tema 1 que una de las ventajas de los microcontroladores sobre los microprocesadores es que este por si solo puede resolver algunas aplicaciones, en dependencia del grado de complejidad de las misma. No obstante, aunque esto es cierto algunos elementos son imprescindibles que acompañen al microcontrolador para poder conformar el sistema. Estos elementos son: •

Una Fuente de Voltaje Regulada que brinde la alimentación que necesita el microcontrolador para trabajar.



Un elemento resonador externo a partir del cual se sincroniza toda la operación interna del microcontrolador.



Un circuito de RESET para la inicialización del microcontrolador y que permita ejecutar la primera instrucción del programa con el encendido del equipo.



Un programa que le indique al microcontrolador que es lo que tiene que hacer en cada momento.

Al estudio de estos elementos imprescindibles en todo sistema basado en el 8051 dedicaremos este Tema, de forma tal que cuando terminemos su estudio si estaremos listo para acometer nuestras primeras aplicaciones. 4.1 Conociendo al microcontrolador 8051. En la Figura 4.1.1 se muestra una representación del circuito integrado 8051, en su encapsulado de 40 terminales, especificándose la posición y la función básica de cada uno.

Figura 4.1.1 Terminales del Microcontrolador 8051.

Microcontroladores. El 8051 de la INTEL.

139

Observe que existen un conjunto de señales, en total 32, que su nombre viene precedido de la letra p, que no son más que terminales de entrada / salida digital. Estos son los terminales que el microcontrolador brinda para conectar diferentes circuitos al mismo como pueden ser: Interruptores, Diodos Emisores de Luz, Relay, Optoacopladores, Lámparas de 7 Segmentos, Teclados Matriciales, Display a Cristal Líquido, etc. Estas 32 líneas se agrupan en 4 grupos de 8 terminales cada uno conformando los llamados Puertos de Entrada / Salida que brinda el 8051, los que reciben el nombre de Puerto 0 (p0), Puerto 1 (p1), Puerto 2 (p2) y Puerto 3 (p3). Cada uno de los terminales de un mismo Puerto se diferencian entre sí a partir de la posición que los mismos ocupan, de forma tal que el Puerto 0 tiene un terminal que se conoce con el nombre de p0.0 que no sería más que el bit 0 de dicho Puerto. Así existirá un p0.1, p0.2, hasta el p0.7 y así para cada uno de los restantes tres puertos. Existen otro conjunto de terminales que no se encuentran dentro de estos grupos de líneas, ver Figura 4.1.1, que son utilizadas para conectarle circuitos indispensables para el funcionamiento del microcontrolador, como puede ser: la Alimentación, la Señal de Reloj, la Señal de Inicialización, etc. Comenzaremos estudiando estos terminales y conociendo estos circuitos para llegar en el próximo Tema a la conexión de diferentes elementos a los Puertos del microcontrolador. 4.2 Dándole alimentación al Microcontrolador 8051. Dos terminales están destinados para entregarle el nivel de voltaje y la corriente requerida por el microcontrolador para que alimente todos sus circuitos internos, ver Figura 4.2.1 Estos dos terminales son •

Vcc terminal 40.



Vss terminal 20,

La diferencia de voltaje a aplicar entre estos dos terminales es de +5 Volts regulado y referenciados a la tierra general del sistema. Al terminal Vcc se debe conectar el positivo y a Vss la referencia de tierra. El condensador de 0.1 µf a 16 Volts permite filtrar los posibles ruidos de la fuente de voltaje, y el diseñador del circuito impreso del sistema debe velar porque este conectado físicamente bien cerca del microcontrolador.

Microcontroladores. El 8051 de la INTEL.

140

Es común en los equipos a microcontroladores, que los +5 Volts se regulen en la propia tarjeta de circuito impreso en que este se encuentra a partir de un voltaje no regulado de directa que le es entregado. Esta señal de directa en los equipos modernos es por lo general de +12 Volts o de +24Volts. Un circuito útil para realizar esta tarea podría ser el que se muestra en la Figura 4.2.2.

Figura 4.2.2 Fuente regulada basada en el regulador de voltaje LM7805CT de la National Semiconductor. La componente principal del circuito lo constituye el Regulador de Voltaje LM7805CT de la National Semiconductor el que es capaz de entregar un voltaje fijo entre sus terminales 3 y 2 de +5 Volts a partir del voltaje no regulado aplicado entre sus terminales 1 y 2., el que según datos del fabricante puede estar entre 8 y 30 Volts. El condensador de entrada C1 cumple la función de disminuir las fluctuaciones del voltaje no regulado de entrada, mientras que el condensador de salida C2 ayuda a mantener fijo el voltaje de +5 Volts ante variaciones de la carga. Un Diodo Emisor de Luz, Led Rojo, conectado entre los terminales de +5 Volts y GND a través de la resistencia R1 podría indicar mediante su encendido que la fuente esta entregando el nivel de voltaje esperado. En muchas aplicaciones las funciones que el microcontrolador realiza en el sistema deben continuar funcionando aunque ocurra un fallo en la alimentación principal del sistema. Un circuito como el mostrado en la Figura 4.2.3, con Batería Externa podría ser la solución.

Figura 4.2.3 Circuito con fuente auxiliar de voltaje.

Microcontroladores. El 8051 de la INTEL.

141

Existen muchas aplicaciones donde el consumo del microcontrolador y del sistema en general constituye una preocupación para el diseñador. Para estos casos se han desarrollado las versiones a CHMOS del 8051. Estas versiones presentan dos Modos de Trabajo Especiales de bajo consumo, Modo IDLE y Modo POWER DOWN. Las preguntas que usted se podría estarse haciendo en estos momentos podrían ser: ¿Qué características tienen estos Modos de Trabajo?, ¿Cómo opera el microcontrolador bajo estos Modos de Trabajo?, ¿Cómo hacemos caer en estos Modos de Trabajo al microcontrolador? En la Figura 4.2.4 se muestra el circuito interno encargado de la generación de la señal de reloj, presente en las versiones CHMOS del 8051.

Este circuito esta conformado por un Oscilador el que alimenta con su salida al circuito responsabilizado con la generación de la señal de reloj que va a los diferentes circuitos internos del microcontrolador, como son: el Controlador de Interrupciones, el Puerto Serie, los Temporizadores y la Unidad Central de Procesos (CPU). Esta señal de reloj juega un papel fundamental en la sincronizar de las operaciones del microcontrolador, de forma tal que: •

Si la señal de reloj no llega al Controlador de Interrupciones, el microcontrolador no será capaz de reconocer y atender los pedidos de interrupción.



Si la señal de reloj no llega al Puerto Serie este no será capaz ni de recibir ni de transmitir datos.

Microcontroladores. El 8051 de la INTEL. •

142

Si la señal de reloj no llega a los Temporizadores estos detiene su operación si se encuentran trabajando en el modo Timer.



Si la señal de reloj no llega a la CPU, el microcontrolador detiene la ejecución del Programa.

Xtal1 (18) y Xtal2 (19) son las dos entradas destinadas para conectar de forma externa el elemento resonador para este oscilador. A este circuito nos referiremos más adelante en este mismo Tema. Lo realmente nuevo en este circuito, no presente en las versiones HMOS del 8051, son las dos compuertas lógicas conectadas una a la salida del Oscilador y la otra a la salida del Generador de Reloj. Estas compuertas lógicas son gobernadas por dos bits del registro PCON, uno de los Registros de Funciones Especiales de este microcontrolador. ¿Quiénes son estos dos bits y que funciones permiten realizar? Estos dos bits son conocidos con el nombre IDL (bit 0 del Registro PCON) y PD (bit 1 del registro PCON) configurables en ´1´ ó ´0´ lógico por el usuario mediante programa. Cada uno de estos bits están relacionados con uno de los modos de trabajo especiales de bajo consumo. El bit IDL esta relacionado con el Modo de IDLE y el bits PD con el Modo POWER DOWN, de forma tal que, si lo que se desea es poner al microcontrolador a operar en el Modo IDLE todo lo que hay que hacer es imponer por programa un ´1´ lógico en el bits IDL del registro PCON y si lo que se desea es poner al microcontrolador en el Modo POWER DOWN sería la misma operación pero ahora con el bit PD del mismo registro. Para efectuar las acciones anteriores basta con poner en su programa las instrucciones: ORL

PCON, #00000001B

; Pone en 1 lógico al bit IDL

ORL

PCON, #00000010B

; Pone en 1 lógico al bit PD

La ejecución de una de estas dos instrucciones hace que el microcontrolador caiga inmediatamente en el modo de trabajo correspondiente, por lo que las mismas son las últimas instrucciones ejecutadas, antes de caer en el estado especial de consumo seleccionado. Si el modo de trabajo al que se lleva al microcontrolador es el de IDLE las consecuencias en la operación de este serán las siguientes:

Microcontroladores. El 8051 de la INTEL. •

143

La señal de reloj interna queda bloqueada para el CPU, con lo que se detiene la ejecución del programa y con ello todas las operaciones inherentes al mismo, ver Figura 4.2.4.



El estado del CPU es preservado en su totalidad, manteniendo los registros internos y las localizaciones de Memoria de Datos los valores almacenados en ellos antes de caer en este estado, por lo que el microcontrolador queda preparado para continuar con el programa una vez restablecido el modo de operación normal del mismo.



La señal de reloj llega al Controlador de interrupción, al Puerto Serie y a los Temporizadores por lo que estos dispositivos continúan con su operación normal, ver Figura 4.2.4.



Los terminales de los Puertos retienen los estados lógicos que tenían en el instante en que fue activado el modo de IDLE.

Del análisis de la Figura 4.2.4 resulta evidente lo explicado en el párrafo anterior. El efecto de poner a ´1´ lógico el bit 0 del registro PCON provoca que la señal IDL/ se ponga a ´0´ lógico con lo que la compuerta AND a donde llega esta señal como una de sus entradas queda bloqueada manteniendo su salida en ´0´ lógico, bloqueando al CPU con lo que se detiene la ejecución de los programas. Sin embargo, esta señal de reloj si continúa llegando a los Temporizadores, al Puerto Serie y al Controlador de Interrupción, los que continúan trabajando independientemente de que el procesador se haya detenido. Todo esto indiscutiblemente redunda en una disminución significativa del consumo por parte del microcontrolador, disminuyendo hasta cerca del 66% el consumo con respecto a cuando se encuentra en el modo normal de operación. El poner al microcontrolador en el modo IDLE de trabajo se hace con la idea de que el consumo del microcontrolador disminuya cuando en una aplicación dada este se encuentra en espera de la ocurrencia, por hardware, de una determinada condición para continuar con la tarea a el encomendada. Por lo tanto en la idea del diseñador esta llevar al microcontrolador al estado de IDLE para que posteriormente salga y retorne al estado normal de trabajo. Ya conocemos la manera de llevarlo a este estado, pero, ¿Cuáles son las posibles causas que hacen salir del Modo de IDLE al microcontrolador? Son dos las posibles maneras de salir del Modo de IDLE: •

Mediante la activación de un pedido de interrupción que se encuentre habilitada.



Mediante la activación de la señal de RESET, terminal 9 del microcontrolador.

Microcontroladores. El 8051 de la INTEL.

144

Estas dos posibles acciones, un pedido de interrupción y la activación de la señal de RESET, son nuevas para los lectores y serán estudiadas a profundidad en Temas posteriores, por lo que nos contentaremos en este momento en conocer que: •

La interrupción es un mecanismo que tiene implementado el microcontrolador que le permite atender posibles pedidos de atención de eventos que resultan impredecibles conocer cuando ocurrirán. Por ejemplo, cuando será apretada por el usuario una determinada Tecla, cuando le llegará un dato por el Puerto Serie enviado por un dispositivo externo que este utilizando esta vía para comunicarse con el sistema, etc. Para que un pedido de interrupción sea atendido la misma tiene que estar habilitada en el microcontrolador, habilitación esta que se hace por software. El 8051 tiene capacidad para dar atención a 6 posibles fuentes de interrupción.



El RESET es un terminal que esta presente en el microcontrolador, terminal 9, el que esta estrechamente ligado con la inicialización de la operación del microcontrolador.



Ambos mecanismo tienen la características de que cuando son reconocidos por el microcontrolador provocan alteraciones en el contenido del registro Contador de Programas.

Ahora creemos que estamos en mejores condiciones de comprender el papel que juegan estos dos mecanismos presentes en el microcontrolador en sacar al mismo del estado de IDLE al que se había llevado con anterioridad por programa. Si la elección es la interrupción, la activación de una cualquiera de las 6 posibles fuentes, de encontrarse habilitada, provocará que el bit IDL en el registro PCON sea desactivado, con lo que el microcontrolador saldrá de este modo especial de operación. El pedido de atención de la interrupción será atendido mediante la ejecución de la Subrutina correspondiente. Una vez concluida la ejecución de la Subrutina correspondiente al pedido de interrupción atendido, la próxima instrucción que ejecuta el microcontrolador será la ubicada inmediatamente después de la que puso a este en el Modo de IDLE. Si la manera escogida es la activación de la señal de RESET, esta también provoca el borrado del bit IDL del registro PCON con lo que se saca al microcontrolador de este estado. En este momento la CPU reanuda la ejecución del programa ejecutando la instrucción siguiente a la instrucción que impuso al microcontrolador en este estado.

Microcontroladores. El 8051 de la INTEL.

145

¿Para que situación podría resultar útil llevar al microcontrolador al Modo IDLE en una aplicación dada? Supongamos que nos encontramos con una aplicación donde el microcontrolador después de ejecutar un conjunto de instrucciones que permitieron definir las condiciones iniciales del sistema, queda esperando por la ocurrencia de una determinada acción para continuar con su trabajo. Un modo efectivo del punto de vista de la disminución del consumo de potencia podría ser que este esperara por la ocurrencia del evento estando en el Modo IDLE, por su puesto, en este caso, la ocurrencia del evento que indica que el microcontrolador debe continuar con su trabajo se debe vincular con un pedido de interrupción, previamente habilitado. Veamos a continuación un Ejemplo que nos podría aclarar un poco más lo expresado anteriormente. Ejemplo 3.1. Supongamos que se desea diseñar un sistema remoto de adquisición de datos basado en el microcontrolador 8051. El valor de la variable física a monitorear se desea tomar

con

periodos

de

1

segundo.

Los

valores

tomados

se

enviaran

a

una

Microcomputadora cada vez que esta lo solicite a través de una comando enviada por el canal serie. Una representación esquemática de lo planteado se muestra en la figura 4.2.5.

Figura 4.2.5 Sistema remoto de adquisición de datos. El equipo remoto que en esencia sería un sistema de adquisición de datos, lo implementaríamos con un microcontrolador con tecnología de fabricación CHMOS como podría ser el 80C51BH. El sistema tiene que tomar el valor de la variable física cada 1 segundo, sin embargo esta tarea le toma solo varios microsegundo, quedando un tiempo grande entre cada una de las toma de muestras en las que el microcontrolador no realiza ninguna tarea. El concepto de remoto en nuestro caso esta relacionado con la no existencia de voltaje de la red comercial en el lugar donde se encuentra el equipo trabajando y por lo tanto la alimentación del

Microcontroladores. El 8051 de la INTEL.

146

mismo sería mediante una fuente alternativa. En este caso el ahorro de energía se convierte en una condición a imponer al diseño presentado. Una solución podría ser la de imponer el Modo de IDLE al microcontrolador cada vez que termine con la toma de una muestra de la variable a medir. Programaríamos a uno de sus Temporizadores, una de las posibles fuentes de interrupción con que cuenta el microcontrolador, para que interrumpa cada 1 segundo, acción esta que saca al microcontrolador del estado de IDLE para ejecutar la Subrutina de atención a la interrupción del Temporizador, que en este caso estaría relacionada con la toma del valor de la variable a medir. Una vez concluida con esta tarea se lleva al Modo de IDLE nuevamente al microcontrolador. Resulta muy importante que se mantenga en todo caso a la interrupción del Temporizador habilitada. Para la comunicación con la Microcomputadora se habilita la interrupción del Puerto Serie de forma tal que, una interrupción ocurra cada vez que llega un dato a este puerto previamente enviado por la Microcomputadora. Esta acción sacaría al microcontrolador del estado de IDLE el que pasaría a ejecutar la Subrutina de atención correspondiente la que se encargaría de leer el Puerto Serie y enviar como respuesta el dato correspondiente, que no sería más que uno de los valores tomados del sensor. Una vez concluida la ejecución de la Subrutina de atención, se vuelve a llevar al microcontrolador al estado de IDLE. Con toda esta operación se lograría una disminución significativa del consumo del sistema y un alargamiento de la vida útil de la Batería. ¿Qué sucederá si el microcontrolador es llevado al Modo de POWER DOWN en lugar que al Modo de IDLE? Si el microcontrolador es llevado al Modo de POWER DOWN las consecuencias en el modo de operación de este serán las siguientes: •

Se detiene por completo la operación del Oscilador y como consecuencia la operación del Generador de Reloj es detenida, ver Figura 4.2.4.



Con el Generador de Reloj detenido, no llega señal de reloj ni a la CPU, ni a los Temporizadores, ni a al Puerto Serie, ni al Controlador de Interrupción con lo que todas las operaciones del microcontrolador se detienen. Es esta la razón por la que en este modo de trabajo es el de menos consumo en el que se puede poner a trabajar al microcontrolador, consumiendo aproximadamente el 33% del consumo cuando opera en el modo normal.

Microcontroladores. El 8051 de la INTEL. •

147

La información almacenada en la memoria de datos interna y en los Registros de Funciones Especiales (SFR) se mantiene.



Los terminales de los Puertos de salida mantienen los valores que presentaban sus registros imagen en el SFR.

¿Cómo salir del Modo de POWER DOWN? Solo existe una manera de salir de este modo de operación, la activación de la señal de RESET. Esta acción redefine todos los valores almacenados en los registros pertenecientes al SFR incluyendo al registro PCON y con ello desactiva la acción del bits PD, con lo que el microcontrolador sale de este estado. No obstante, la información que esta almacenada en la memoria de datos interna se mantiene sin alteración con lo que se salva la misma de una posible perdida por fallo de la alimentación. La próxima instrucción que ejecuta el microcontrolador después de salir del POWER DOWN es la ubicada en la dirección 0000h en la Memoria de Programa. En este modo de trabajo el consumo de energía del microcontrolador es aún menor que en el Modo IDLE, se pude decir que es el mínimo posible, con lo que se protegería más la fuente de energía auxiliar, alargando su vida útil de trabajo. Por su puesto la idea no es caer en este Modo de Trabajo de forma intencional, como en el caso del Modo IDLE, sino tener preparado al microcontrolador para caer en este Modo producto de un fallo impredecible del fluido eléctrico que podría provocar la perdida de información valiosa y la imposibilidad de que el sistema continuara una vez restablecida la alimentación. Para ello en el sistema debe existir un circuito que detecte con suficiente tiempo el posible fallo de la energía eléctrica, de forma tal que le de tiempo al microcontrolador para salvar en memoria de datos la información valiosa y poner a este en el Modo de Trabajo POWER DOWN antes de que entre la fuente auxiliar a trabajar. Una propuesta de circuito se muestra en la Figura 4.2.6.

Microcontroladores. El 8051 de la INTEL.

148

Figura 4.2.6 Circuito para la detección de fallo en el sistema. ¿Cómo funciona el circuito de la Figura 4.2.6? En el circuito se vigila el fallo de la línea comercial de voltaje de forma tal que el microcontrolador pueda garantizar un paso ordenado hacia la fuente de energía de respaldo en caso de fallo. Se podría vigilar el fallo del voltaje después del rectificador o el fallo del voltaje después del regulador o directamente de la línea comercial de voltaje. De estas tres variantes la que da más tiempo al microcontrolador, para resguardar los datos de interés en la memoria de datos, desde que se detecta el fallo es la de vigilar el fallo sobre la línea comercial de voltaje, 110V/60hz, que se corresponde con el circuito mostrado en la Figura 4.2.6. Como funciona el circuito. En cada ciclo positivo de la señal de alterna de la línea comercial, el conjunto Zener-Transistor hace una solicitud de interrupción al microcontrolador a través de su terminal externo INT0/. Todo lo que tendría que hacer la Subrutina de atención al pedido de interrupción es reprogramar el tiempo de desbordamiento de uno de los Temporizadores de manera que este comience un nuevo ciclo de conteo. Si ocurre un fallo en el voltaje de la red comercial, el ciclo positivo de la señal de alterna no llegará y por ende el pedido de interrupción no es solicitada continuando el conteo el Temporizador el que al desbordarse le indicará al microcontrolador, mediante un pedido de interrupción, que un fallo de voltaje en la línea ha ocurrido y que por ende debe tomar todas las medidas necesarias para hacer el pase ordenado hacia el Modo Power Down. El circuito de la Figura 4.2.6 garantiza que el microcontrolador detecte un fallo de voltaje en la línea comercial, pero no garantiza el retorno al estado normal de operación una vez restablecida esta. Una propuesta de circuito que garantizaría esta operación sería el mostrado en la Figura 4.2.7.

Microcontroladores. El 8051 de la INTEL.

149

Figura 4.2.7 Circuito de detección de fallo y restablecimiento del voltaje del sistema. Aunque hemos incluido en este epígrafe los modos de trabajo especiales de bajo consumo IDLE y POWER DOWN, estos no son modos de trabajo muy utilizados en los equipos construidos en base al microcontrolador 8051. Por lo general en la mayoría de las aplicaciones basta con entregarle los +5 Volts entre los terminales Vcc y Vss y mantenerlo fijo durante todo el tiempo de trabajo del microcontrolador. 4.3 Sincronizando la operación del Microcontrolador. Todos los microcontroladores de la Familia del 8051 son dispositivos sincrónicos, utilizando una señal de reloj para sincronizar todas sus operaciones internas. Esta señal de reloj, como ya se vio anteriormente, es imprescindible para que la CPU pueda ejecutar los Programas, para que el Controlador de Interrupciones pueda atender los pedidos de interrupción, para que el Puerto Serie pueda recibir y transmitir datos, para que los Temporizadores puedan operar en el modo Timer, etc. Existen dos formas básicas de entregar esta señal de reloj al microcontrolador: •

Utilizando el Oscilador interno.



Entregando una señal generada por un Oscilador externo.

Los microcontroladores de la Familia del 8051 tienen un Oscilador interno que como ya se enuncio anteriormente puede ser utilizado como fuente de reloj. En este caso todo lo que hay que hacer es conectar un Cristal de Cuarzo entre los terminales XTAL1 (19) y XTAL2 (18) como se muestra en la Figura 4.3.1.

Microcontroladores. El 8051 de la INTEL.

150

Dos condensadores, c1 y c2, conectados a tierra colaboran con la estabilidad del circuito. Ambos condensadores deben ser del mismo valor y para Cristales de Cuarzo entre 10 – 12 Mhz se recomienda la selección del valor de estos condensadores entre 20 – 30 pf.

Si la opción escogida es la de entregar la señal de reloj mediante el empleo de un Oscilador Externo se debe tener en cuenta la tecnología de fabricación del microcontrolador. Para

microcontroladores

con

tecnología

de

fabricación HMOS como resultan las versiones 8051AH la señal de reloj generada por el Oscilador Externo es entregada al microcontrolador a través de su terminal XTAL2 (18), conectando el terminal XTAL1 (19) a tierra tal y como se muestra en la Figura 4.3.2.

Por su parte si la tecnología de fabricación del microcontrolador es CHMOS como resulta en las versiones 80C51BH la señal de reloj generada por el

Oscilador

Externo

es

entregada

al

microcontrolador a través de su terminal XTAL1 (19) quedando el terminal XTAL2 (18) sin conectar tal y como se muestra en la figura 4.3.3.

Existe una configuración que es valida tanto para las versiones HMOS como CHMOS que es la que se muestra en la Figura 4.3.4

Microcontroladores. El 8051 de la INTEL.

151 . En este caso la señal generada por el Oscilador

Externo

se

entrega

al

microcontrolador a través de su terminal XTAL1 (19), llevándose al terminal XTAL2 (18) la salida del Oscilador Externo negada a través de una de las compuerta lógica inversoras del circuito integrado 74HCT04, de tecnología de fabricación CMOS.

El Generador de Reloj, ver Figura 4.2.4, toma la señal entregada por el Oscilador, sea externo o interno, para definir la secuencia de Estados con que conforma los Ciclos de Máquina. En el párrafo anterior hemos hablado de dos unidades de tiempo básicas en la operación del microcontrolador de las cuales no conocíamos, el Estado y el Ciclo de Máquina. Un Estado coincide en tiempo con dos periodos de la señal entregada por el Oscilador, mientras que un Ciclo de Máquina consiste en la secuencia de 6 Estados. El microcontrolador va a dividir en tiempo todas sus operaciones tomando como base de tiempo a estos dos eventos, ver Figura 4.3.5.

Figura 4.3.5 Relación entre periodo de la señal de reloj del Oscilador, el Estado y el Ciclo de Maquina. Por ejemplo un microcontrolador que esta trabajando con un Cristal de Cuarzo de 12 Mhz como elemento resonador externo para su Oscilador Interno, todos sus Ciclos de Máquina consumen 1 µseg y la duración de un Estado será de aproximadamente 0.16µseg. Cada Estado, en este microcontrolador, está caracterizado por dos fases, a las que llamaremos P1 y P2, donde la duración de una fase coincide con el tiempo de duración del Periodo de la señal

Microcontroladores. El 8051 de la INTEL.

152

del Oscilador y todos los Ciclos de Máquina estarán caracterizados por 6 Estados, a los que llamaremos, S1, S2, S3, S4, S5 y S6, tal y como se muestra en la figura 4.3.6.

Figura 4.3.6 Estado y Ciclo de Máquina en el Microcontrolador. A modo de resumen podemos concluir: •

Un Estado esta conformado por dos periodos de la señal de reloj.



Un Ciclo de Máquina esta conformado por 6 Estados.



Un Ciclo de Instrucción esta conformado por uno o más Ciclos de Máquina.

Normalmente dos Ciclos de Búsqueda son ejecutados en cada Ciclo de Máquina, aún cuando no sean necesarios para la ejecución de la instrucción. Las preguntas en este momento podrían ser, ¿Qué es un Ciclo de Búsqueda?, ¿Por qué son dos en cada Ciclo de Máquina? La primera operación que debe efectuar el microcontrolador para poder ejecutar una instrucción constituye la búsqueda del código de la misma, ya que en este viene implícito el conjunto de operaciones que debe realizar este para ejecutar dicha instrucción. A este Ciclo de Máquina, que constituye el primero para toda instrucción, se le conoce con el nombre de Ciclo de Búsqueda. Existen instrucciones que no basta con el espacio destinado a una localización en Memoria de Programa para guardar todo su código, pudiendo necesitar dos y hasta tres, esta es una de las herencias de la Arquitectura Interna del tipo Von Newman que presenta este microcontrolador ya estudiado en el Tema 1. En este caso no basta con un Ciclo de Búsqueda para que el microcontrolador pueda ejecutar la instrucción. Por oro lado, son pocas las instrucciones que ocupan tres localizaciones de la Memoria de Programa para almacenar su código, la inmensa mayoría utilizan una o dos localizaciones. Atendiendo a esto se diseño a este microcontrolador para que efectúe dos búsquedas en un mismo Ciclo de Máquina con lo que se logra que la

Microcontroladores. El 8051 de la INTEL.

153

inmensa mayoría de las instrucciones estén listas para ser ejecutadas con solo un Ciclo de Máquina con lo que se ahorra tiempo de procesamiento. ¿Qué sucede con la segunda búsqueda en el caso de instrucciones cuyo código ocupan una sola localización en memoria de Programa? Simplemente el microcontrolador ignora la segunda búsqueda, no incrementando al registro Contador de Programa, pero si consumiendo el tiempo. ¿Quién es el registro Contador de Programa? Ya de este registro hemos hablado anteriormente, no obstante dada su importancia vamos a profundizar un tanto en su operación en este momento. El registro Contador de Programas es un registro interno de 16 bits el que almacena la dirección de la localización en Memoria de Programa donde se encuentra almacenado el próximo código a buscar y por ende a ejecutar por el microcontrolador. Este próximo código a buscar por lo general coincide con el código de la próxima instrucción a ejecutar, por lo que se dice que el registro Contador de Programa lleva la secuencia de ejecución del programa. Este registro se incrementa en uno cada vez que el microcontrolador efectúa una búsqueda en Memoria de Programa, con excepción de las búsquedas que son ignoradas. Veamos a modo de ejemplo la ejecución de una instrucción que solo consume un Ciclo de Máquina en su ejecución, como es el caso de la instrucción, MOV

A, R0

; A

R0

Esta instrucción provoca que el contenido almacenado en el registro R0 se almacene en el registro Acumulador. El código de la misma solo ocupa una localización en la Memoria de Programa por lo que basta con un Ciclo de Búsqueda para que el microcontrolador este listo para su ejecución, la segunda búsqueda que ocurre en el propio Ciclo de Máquina es ignorado y por ende el registro Contador de Programas solo se incrementa una vez. La ejecución de está instrucción consume solo un Ciclo de Máquina, con 6 Estados, ejecutándose, para el caso de que el microcontrolador este trabajando con un Cristal de Cuarzo de 12 Mhz, en 1 µseg. Veamos ahora el ejemplo de la instrucción, MOV

A, #05 H

;A

05h

Microcontroladores. El 8051 de la INTEL.

154

Esta instrucción provoca que la constante 05 en hexadecimal sea almacenada en el registro Acumulador. El código de esta instrucción ocupa dos localizaciones en la Memoria de Programa, uno para el código en si y el otro para almacenar la constante, por lo que el microcontrolador requiere de dos Ciclos de Búsqueda para poder ejecutarla y con ello el incremento en dos del registro Contador de Programas. Las dos búsquedas consumen el tiempo del primer Ciclo de Máquina, necesitando de un segundo ciclo para ejecutar la instrucción por lo que el tiempo consumido es de 2 µseg bajo las mismas condiciones del ejemplo anterior. No solo el número de localizaciones que ocupe en Memoria de Programa el código de la instrucción determina el tiempo que la misma consume. Veamos el ejemplo de la instrucción: MUL AB

; AB

AxB

Esta instrucción provoca que el contenido del registro Acumulador se multiplique con el contenido del registro B. El código de esta instrucción solo ocupa una localización en la Memoria de Programa por lo que basta con un Ciclo de Búsqueda para que el microcontrolador pueda ejecutar la misma, no obstante, dada la complejidad de la ejecución de esta instrucción el microcontrolador toma 4 Ciclos de Máquina para ejecutar la misma, consumiendo un tiempo de 8µseg bajo las mismas condiciones que las instrucciones anteriores. Esta constituye una de las instrucciones que más tiempo consume en su ejecución dentro del Repertorio de Instrucciones de este microcontrolador. Ya conocemos que existe un programa el que esta compuesto por un conjunto de instrucciones que responden a un algoritmo dado. Conocemos también el conjunto de instrucciones que conforman el Repertorio de Instrucciones de este microcontrolador así como la manera en que estas instrucciones son ejecutadas por el microcontrolador. Pero, ¿Cómo indicarle al microcontrolador en que localización de memoria de programa se encuentra almacenada la primera instrucción de nuestro programa a ejecutar por este? 4.4 Iniciando la operación del Microcontrolador. Es ya conocido que las operaciones que realiza el microcontrolador dependen de un Programa almacenado en la Memoria de Programa. Este Programa no es más que una secuencia de instrucciones que siguen una lógica determinada e impuesta por el algoritmo concebido para resolver la aplicación en cuestión. Este Programa tiene un comienzo, o sea, existe una instrucción que es la primera que debe ejecutar el microcontrolador.

Microcontroladores. El 8051 de la INTEL.

155

Las preguntas a responder aquí serían: ¿Cómo el microcontrolador sabe donde se encuentra almacenada la primera instrucción que debe ejecutar?, ¿Dónde almacenar el código, en Memoria de Programa, de la primera instrucción a ejecutar por el microcontrolador? Existe un terminal en el microcontrolador, el terminal de RESET (9), que al ser activado provoca que en todos los bits de los registros internos del microcontrolador se almacene el valor lógico de ´0´, con excepción de los registros Puntero de la Pila (SP) y el buffer del Puerto Serie (SBUF). Dentro de estos se encuentra el registro Contador de Programas (CP). Ya conocemos que el registro Contador de Programa almacena la dirección de la localización en Memoria de Programa donde se encuentra almacenado el código de la próxima instrucción a ejecutar. Si unimos estas dos consecuencias, la activación del terminal de RESET carga, entre otras cosas, la dirección 0000h en el registro Contador de Programas y que el registro Contador de Programas almacena la dirección de la localización donde se encuentra almacenado el código de la próxima instrucción a ejecutar por el microcontrolador, podemos concluir que, después de la activación de la entrada de RESET, la primera instrucción a ejecutar por el microcontrolador es la que se encuentra almacenada a partir de la localización de memoria cuya dirección es 0000 h, por lo que, cada vez que queremos que comience la ejecución del Programa por su primera instrucción, todo lo que tenemos que hacer es provocar que se active el terminal de RESET del microcontrolador. Claro esto sería valido si previamente, durante el proceso de grabación del Programa en la Memoria de Programa del microcontrolador, hicimos todo lo necesario para que se grabara en la localización cuya dirección es 0000 h el código de la primera instrucción de nuestro programa. Esta es la manera que se utiliza para garantizar que el microcontrolador ejecute el programa comenzando por la primera instrucción del mismo. Por lo general la activación del terminal de RESET se vincula con el encendido del equipo o con el apretar de una Tecla del tipo ´Push Button´. ¿Cómo el microcontrolador reconoce que la señal de RESET se esta activando?, ¿Cómo provocar que con el encendido del sistema se active la señal de RESET?, ¿Cómo provocar que con apretar una tecla del tipo ´Push Button´ se active la señal de RESET? Para que el microcontrolador reconozca que el terminal de RESET esta activado, el mismo debe permanecer en estado de ´1´ lógico por espacio de al menos 24 periodos de la señal de reloj, o sea 12 Estados. Si el microcontrolador esta trabajando con un Cristal de Cuarzo a 12 Mhz, el

Microcontroladores. El 8051 de la INTEL.

156

tiempo en ´1´ lógico debe permanecer por un espacio de tiempo no menor de 2 µseg para que el microcontrolador reconozca la activación del terminal de RESET. De cumplirse con esta condición, el microcontrolador responde cayendo en un estado de RESET interno el que provoca: •

Todos los registros internos ponen sus bits a ´0´ lógico con excepción de los registros, Puntero de la Pila (SP) el que se carga con el valor 07 H dejando todo preparado para comenzar el trabajo con la Pila vacía. Los buffer del Puerto Serie que toman valores indeterminados. Los Registros de los Puertos Paralelos de Entrada/Salida se cargan ´1´ lógicos en todos sus bits quedando preparados como puertos de entrada.



El contenido de las localizaciones de la Memoria de Datos interna no es afectada por lo que su valor es indeterminado.

Mientras que la entrada de RESET se mantenga en ´1´ lógico el microcontrolador se mantendrá en esta estado, no ejecutando instrucciones y no alterando el valor ni de la memoria de datos ni de los registros internos del microcontrolador, por lo que para que el microcontrolador comience con la ejecución del Programa hay que sacra al microcontrolador de este estado. ¿Cómo sacar al microcontrolador del estado de RESET? Basta con llevar nuevamente a ´0´ la entrada de RESET. Por lo que la secuencia de acciones a llevar a cabo para inicializar el trabajo del microcontrolador es la siguiente: 1. Poner a ´1´ lógico el terminal de entrada de RESET del microcontrolador, con lo que comenzamos con la inicialización. 2. Mantenerlo en estado de ´1´ lógico por un tiempo no menor que 24 periodos de la señal de reloj, con lo que damos el tiempo requerido para que el microcontrolador ejecute todas las acciones relacionadas con su inicialización. 3. Llevar el terminal de RESET a ´0’ lógico, con lo que terminamos con la inicialización. Una vez llevado a ´0´ el terminal de RESET el microcontrolador comienza a ejecutar el programa almacenado en la Memoria de Programas comenzando por la instrucción almacenada en la localización cuya dirección es 0000 h de esta memoria.

Microcontroladores. El 8051 de la INTEL.

157

Un circuito que provocará el pedido de RESET al Microcontrolador con el encendido del mismo para versiones con tecnología HMOS se muestra en la Figura 4.4.1. Este circuito se comporta como un circuito Pasa Alto al que se le aplica una señal Paso Escalón de 0 a 5 Volts en su entrada con el encendido del equipo.

Originalmente el Condensador (C1) se comportara como un corto circuito dejando pasar los +5 Volts hacia el terminal de RESET (9) del microcontrolador con lo que este ve un ´1´ lógico. Posteriormente el Condensador (C1) se comenzará a cargar con una constante de tiempo impuesta por los valores del propio condensador y de la Resistencia (R1), con lo que comienza a disminuir el voltaje aplicado en el terminal de RESET del microcontrolador, tendiendo este al valor de ´0´ lógico. En la Figura 4.4.2 se muestran las forman de onda ambos lados del circuito Pasa Alto.

Figura 4.4.2. Formas de onda a ambos lados del circuito Pasa Alto. De aquí la gran importancia de calcular correctamente los valores del Condensador (C1) y de la resistencia (R1) ya que, el voltaje en el terminal de RESET (9) debe permanecer por encima de 2.4 Volts, ´1´ lógico para el microcontrolador, durante un intervalo de tiempo que sobrepase los 24 periodos de la señal de reloj más el tiempo que demora la fuente en llegar al valor de +5 Volts estable desde el momento en que se dio la orden de energizar al circuito mediante un interruptor o simplemente conectando el circuito a la línea comercial de voltaje que puede llegar a ser de 10

Microcontroladores. El 8051 de la INTEL.

158

milisegundos si queremos que el microcontrolador reconozca que el terminal de RESET fue activado. Una pregunta interesante en este momento podría ser, ¿Cómo calcular el valor del Condensador (C1) y de la Resistencia (R1) en mi aplicación? Para lo anterior debemos partir de la ecuación que relaciona el Vent con el Vsal en un circuito Pasa Alto al que se le aplica ala entrada una señal Paso Escalón.

Vsal = Vent e −τ t

τ = R1C1 Lo que andamos buscando es un par de valores para R1 y C1 que satisfagan las condiciones que impone el microcontrolador para identificar que la entrada de RESET ha sido activada. Para ello pasemos dividiendo a Vent hacia el lado izquierdo de la igualdad y apliquemos logaritmo neperiano a ambos lados de la misma.

ln

Vsal = R1C1t Vent

R1C1 = (ln 2)t R1C1 = 0.69t El valor de t nos lo da el Cristal de Cuarzo con que este trabajando el microcontrolador en el circuito, escogemos un valor de R1 y despejamos el valor de C1 o viceversa y ya tendríamos la pareja de valores de R1 y C1 que andábamos buscando. Si el microcontrolador es de tecnología de fabricación CHMOS no es necesario conectar la Resistencia (R1) externamente ya que estos traen conectada internamente entre los terminales RESET (9) y Vss (20) una resistencia de 8.2K. En este caso basta con conectar el Condensador (C1) entre los terminales de RESET (9) y Vcc (40) como se muestra en la Figura 4.4.3 y la expresión para el calculo del valor de dicho condensador sería la que aparece a la derecha de dicha figura.

Microcontroladores. El 8051 de la INTEL.

159

C1 =

0.69t 8 .2 K

En muchas ocasiones se desea tener una Tecla del tipo ´Push Button´ en el equipo que permita activar el terminal de RESET cada vez que el operador quiera con solo apretar la misma y sin la necesidad de apagar el equipo y volverlo a encender. Un circuito que podría venir en nuestra ayuda en este caso se muestra en la Figura 4.4.4. Ahora las condiciones iniciales son diferentes ya que el equipo no se encuentra apagado sino que se encuentra funcionando y por ende en la entrada de RESET hay aplicado un ´0´ y por ende el Condensador (C1) se encuentra cargado al valor de la fuente aproximadamente. Al

apretar

la

Tecla,

el

Condensador (C1) se descarga a

Tierra

cortocircuito

a que

través provoca

del el

apretar la Tecla. Cuando el voltaje en el condensador cae por debajo de 0.4 Volts, el inversor impone un ´1´ lógico en el terminal de RESET (9), valor este que verá mientras la Tecla se encuentra apretada. Una vez que la Tecla es liberada comienza el proceso de carga del Condensador (C1) a través de la Resistencia (R1) aumentando el voltaje en el condensador de forma exponencial. Una vez que este voltaje llega al valor de 2.4 Volts el inversor impone un ´0´ lógico en la entrada de RESET del microcontrolador, sacando a este de este estado.

Microcontroladores. El 8051 de la INTEL.

160

La compuerta del tipo ´Smitch Trigger´ garantiza que el microcontrolador vea una señal mucho más definida en cuanto a los voltajes de ´0´ y de ´1´ lógico. El diodo es para garantizar que el condensador se descargue rápidamente y no a través de la Resistencia (R1) cada vez que se apague el equipo. Con los elementos vistos hasta aquí nos podemos proponer el diseñar un sistema mínimo basado en este microcontrolador, con el cual pudiéramos enfrentar la solución de aplicaciones que no fueran muy exigentes en cuanto a recursos. ¿Con que elementos contaría nuestro sistema mínimo? •

Circuito externo de RESET con el encendido y mediante Tecla del tipo ´Push Button¨.



Circuito Oscilador interno con Cristal de Cuarzo a 12 Mhz con lo que se logra que la instrucción más rápida se ejecute en 1 µseg.



Alimentación externa mediante voltaje no regulado de 12 Volts, con regulación interna.



4 Kilobyte de memoria para almacenar los Programas, aprovechando la propia del microcontrolador.



128 byte de memoria para almacenar los datos, aprovechando la propia del microcontrolador.



32 líneas de Entrada/Salida digitales agrupadas en 4 Puertos de 8 bits.



2 Temporizadores de 16 bits, aprovechando los propios del microcontrolador.



1 Puerto Serie Asincrónico Full Duplex, aprovechando el que trae implementado internamente el microcontrolador.



2 entradas externas para el pedido de interrupción con prioridad y habilitación por programas, aprovechando las propias del microcontrolador.

El esquema con el diseño del sistema propuesto se muestra en la Figura 4.4.5.

Microcontroladores. El 8051 de la INTEL.

161

Figura 4.4.5. Diseño de sistema mínimo basado en el Microcontrolador 8051. No obstante, para que el sistema anterior pueda resolver cualquier aplicación, por muy pequeña que esta sea, necesita de un Programa que almacenado en la memoria de programa del microcontrolador le indique a este que hacer. A aprender a hacer Programas para el microcontrolador 8051 dedicaremos el próximo epígrafe. 4.5 Haciendo Programas para el microcontrolador. Quizás se hallan sorprendido por el nombre de este epígrafe y del objetivo del mismo, ya que si conocemos todas las instrucciones que conforman el Repertorio de Instrucciones, si conocemos los Modos de Direccionado que es la forma de referirnos a los operandos en las instrucciones y si conocemos que un Programa es una secuencia de instrucciones que responden a un algoritmo dado y que la primera instrucción de este Programa se debe almacenar en la localización de memoria de programa cuya dirección es 0000 h, ¿Qué nos falta para poder hacer Programas para el 8051?

Microcontroladores. El 8051 de la INTEL.

162

A dar respuesta a esta pregunta dedicaremos este epígrafe, de forma tal que al terminar con el estudio del mismo podremos decir si realmente estábamos preparados completamente para hacer Programas para el microcontrolador o si todavía nos quedaban algunos aspectos de interés por conocer. El Lenguaje Ensamblador. Como toda máquina digital, el microcontrolador es capaz de entender exclusivamente el lenguaje binario grabado en su Memoria de Programa. A este código binario con que se representan en la memoria del microcontrolador las instrucciones que conforman un Programa dado, se conoce con el nombre de código de máquina. El Lenguaje Ensamblador, que utiliza palabras reservadas del idioma para representar las instrucciones, como lo hemos venido haciendo hasta ahora, es una forma más humana de escribir los Programas. A estas palabras reservadas, utilizadas para representar a las instrucciones del microcontrolador, se le conoce con el nombre de nemotécnico. No solo existen palabras reservadas para representar a las instrucciones, sino también para referirnos a los registros por sus nombres, a bits específicos de estos registros, etc. Todas estas palabras reservadas, conjuntamente con constantes, variables, símbolos, etc, constituyen los elementos que conforman una instrucción en el Programa. Por su puesto, a la hora de escribir una instrucción dada como parte de un Programa, el programador debe respetar la sintaxis de dicha instrucción, sino quiere cometer errores que provoquen el no entendimiento por parte de los Programas Traductores correspondientes. La sintaxis no es más que el conjunto de reglas que imponen los Programas Traductores a los programadores para que escriban correctamente los Programas en Lenguaje Ensamblador. Los Programas Traductores no son más que programas que vienen en ayuda del programador para llevar el Programa escrito por el en Lenguaje Ensamblador a un Programa entendible por el microcontrolador en código de máquina que es el objetivo final de cualquier trabajo. Existe una relación estrecha entre el nemotécnico, propio de las instrucciones en el Lenguaje Ensamblador y el código binario de las instrucciones, propio del código de máquina, de forma tal que cada instrucción perteneciente al Repertorio de Instrucciones del microcontrolador cuenta con su correspondiente código binario y a su vez con su correspondiente nemotécnico. Por ejemplo la instrucción ya estudiada cuyo nemotécnico es, MOV

A, R0

;A

R0

Microcontroladores. El 8051 de la INTEL.

163

Le corresponderá el código en binario, 1111 1000 B que es el que realmente entiende el microcontrolador, Por suerte, para nosotros y para los futuros usuarios de los sistemas, cuando escribimos los Programas lo hacemos con los correspondientes nemotécnicos de las instrucciones y no con los códigos binarios que las representan. De esa conversión se encargarán, como ya definimos anteriormente, programas ya desarrollados, fáciles en el uso y de fácil acceso que por lo general reciben el nombre de Programas Ensambladores. Esta es la razón por la que se conoce como programar en ensamblador cuando se desarrollan programas para un microprocesador o para un microcontrolador cualquiera escrito con los nemotécnicos de sus instrucciones. Existen otras formas de escribir los Programas para el microcontrolador, por ejemplo escribirlos empleando algún lenguaje de alto nivel como podría ser el C++. Hoy en día se han desarrollados programas que son capaces de convertir un programa desarrollado en C++ para un microcontrolador dado al programa en código de máquina correspondiente. Esto por su puesto que representa una comodidad grande y un ahorro en tiempo de desarrollo para el programador al poder contar con la potencia propia de las instrucciones de un lenguaje de alto nivel para escribir los programas. Sin embargo, estos programas traductores no son lo suficientemente eficientes en cuanto a la cantidad de código generado y por lo general provocan que los programas ocupen más espacio en la memoria de programa que lo que ocuparía si el programador los hubiera desarrollado en Lenguaje Ensamblador. Escribir lo Programas en Lenguaje Ensamblador permite hacer programas más eficientes en cuanto al uso de la memoria de programa, lo que redunda por lo general en lograr un uso más eficiente del tiempo de ejecución del microcontrolador. Por su puesto ambas ventajas dependen grandemente de la habilidad del programador para utilizar con eficiencia las instrucciones que brinda el microcontrolador. Si estos Programas no están bien confeccionados, pueden resultar de gran tamaño y lentos y por su puesto que el Programa Ensamblador no será capaz de corregir la ignorancia del programador, al menos hoy por hoy. Antes de continuar queremos dejar bien claro como hemos utilizado los nombres Lenguaje Ensamblador y Programa Ensamblador en el material. Para nosotros Lenguaje Ensamblador es el conjunto de instrucciones, representadas por su correspondiente nemotécnico, que brinda el fabricante de un determinado microcontrolador dentro del Repertorio de Instrucciones para hacer los Programas. Mientras que Programa Ensamblador, es el programa que nos ayuda a hacer la conversión del Programa desarrollador en Lenguaje Ensamblador a un Programa en Código de Máquina entendible por el microcontrolador.

Microcontroladores. El 8051 de la INTEL.

164

Este epígrafe lo dedicaremos ha brindar un conjunto de reglas a respetar al escribir un Programa en Lenguaje Ensamblador Escribiendo Programas en Lenguaje Ensamblador. Debemos tener en cuenta que cuando escribimos un programa en Lenguaje Ensamblador, lo estamos haciendo para que un Programa Ensamblador lo interprete y lo convierta en un conjunto de códigos binarios entendibles por el microcontrolador. Esto impone que usted debe respetar determinadas reglas, a la hora de escribirlos, impuestas por dicho Programa Ensamblador. Existen múltiples Programas Ensambladores para el microcontrolador 8051 desarrollados por las múltiples compañías que fabrican este microcontrolador o algunas de sus versiones, cada uno con sus particularidades propias a la hora de escribir los programas. Esto impone la necesidad de que si vamos a hacer un estudio de las reglas a cumplir a la hora de escribir un Programa en Lenguaje Ensamblador debemos tomar uno de los tantos Programas Ensambladores como referencia. En especifico nos basaremos en explicar las reglas que impone el Programa Ensamblador desarrollado por INTEL, ASM51. Por suerte la mayoría de los Programas Ensambladores presentan reglas similares para la escritura de los programas, por lo que si usted utiliza otro muchas de las explicaciones que daremos aquí le serán útiles. Los Programas están compuestos por un conjunto de líneas o sentencias de programas. Estas líneas pueden ser de tres tipos: •

Línea de instrucción.



Línea de pseudo - instrucción.



Línea de comentarios.

Una Línea de instrucción es aquella donde se declara una de las instrucciones que componen el Programa. Estas líneas generan código ejecutable por el microcontrolador y la estructura que presentan es la siguiente: [ETIQUETA]:

MNEMOTECNICO

OPERANDO

; [COMENTARIOS]

Como se puede observar una línea de instrucción esta conformada por 4 campos: •

el campo de ETIQUETA.



el campo de NEMOTECNICO.

Microcontroladores. El 8051 de la INTEL. •

el campo de OPERANDO.



el campo de COMENTARIOS.

165

Los [ ] indican que esos campos son opcionales, pueden estar o no estar formando parte de la sentencia, por lo que no resulta obligatorio que en una línea de instrucción estén presentes todos los campos. ¿Cuáles campos no pueden faltar? Los campos que no pueden faltar porque son los que le dan el nombre a esta línea de instrucción son los campos de NEMOTECNICO y de OPERANDO, ya que estos dos campos componen la Instrucción que usted desea declarar en dicha línea. El campo de ETIQUETA, que es opcional, posibilita poner nombres literales a direcciones de Memoria de Programa, lo que facilita la escritura de los programas y los hace reubicables. El Programa Ensamblador se encarga de darle el valor correspondiente a cada ETIQUETA. Observe que el literal puesto como ETIQUETA debe estar seguido por el signo (:). No pueden ser ETIQUETA las palabras reservadas para representar las instrucciones ni las reservadas para especificar a los registros internos del microcontrolador o los bits de los mismos. En el campo NEMOTECNICO se declara la instrucción a ejecutar por el microcontrolador como parte del programa. Estas instrucciones se declaran mediante literales reservados para las instrucciones por parte de los fabricantes y que componen el Repertorio de Instrucciones. El campo OPERANDO permite completar la instrucción y en el mismo se especifica quienes participan en la ejecución de la misma. En su declaración el programador debe tener en cuenta los Modos de Direccionado validos que tiene la instrucción. El campo COMENTARIO, también es opcional, posibilita que el programador ponga un conjunto de aclaraciones al programa que le sean de ayuda, tanto a él como a los futuros usuarios, para la comprensión del mismo. Observe que un comentario viene precedido del signo (;) extendiéndose hasta el carácter de retorno. Es una mala costumbre declarar como comentario lo que hace la instrucción, realmente el programador lo que debe declarar es la intención que el tuvo a la hora de emplear dicha instrucción en el programa. Este campo despreciado por muchos programadores, fundamentalmente los

Microcontroladores. El 8051 de la INTEL.

166

principiantes, constituye una muestra de la madurez que ha alcanzado el programador a la hora de hacer sus Programas. Una Línea de pseudo - instrucción presenta la misma estructura que la anterior con la diferencia fundamental de que en lugar de tener un campo nemotécnico, tiene en su lugar un campo de pseudo - instrucción. [ETIQUETA]:

PSEUDOINSTRUCCION

OPERANDO

; [COMENTARIOS]

¿Qué es una PSEUDOINSTRUCCION? El Programa Ensamblador brinda un conjunto de directivas que resultan de utilidad al programador a la hora de escribir su programa. Entre las cosas que permiten al programador definir en su programa se encuentran: •

declarar la dirección a partir de la cual se desea se almacene el programa en la Memoria de Programa del microcontrolador.



declarar una tabla de datos como parte del programa.



declarar valores a literales que serán utilizados posteriormente por las instrucciones del programa.



indicar el final del programa.

Estas directivas son las que reciben el nombre de PSEUDOINSTRUCCION. Estas no generan código ya que no forman parte en si del Programa, no forman parte de Repertorio de Instrucciones del microcontrolador y son propias Programa Ensamblador que se este utilizando. Si bien un comentario puede y debe como regla formar parte de una Línea de Instrucción, el programador puede utilizar solo una línea del mismo, Línea de Comentario, para declarar una oración o un conjunto de oraciones con el objetivo de documentar lo mejor posible su programa. A esta oración o conjunto de oraciones se le da el tratamiento de comentario dedicándole solo una línea a ella. Esta línea debe comenzar con el signo de puntuación (;). Ya conocemos algunas reglas que nos permiten estructurar correctamente del punto de vista formal un Programa que desarrollemos en Lenguaje Ensamblador con vista a su futura conversión a Código de Máquina mediante un Programa Ensamblador dado, en este caso el ASM51. No obstante, para poder hacer el Programa nos hace falta conocer,

Microcontroladores. El 8051 de la INTEL.

167

¿Cuales son las directivas o pseudoinstrucciones que nos brinda este Programa Ensamblador? Directivas del Programas Ensamblador ASM51. Como ya fue explicado, las directivas no son instrucciones en si presentes en el Repertorio de Instrucciones del microcontrolador, sino que son, comandos que le brindan información al Programa Ensamblador para que haga su tarea de conversión. Todo este proceso comienza cuando al diseñador se le plantea una aplicación dada a resolver y este toma la decisión de hacerlo con al empleo de un microcontrolador. A partir de este momento lo primero que ocurrirá será el diseño de un ´hardware´ que se ajuste a las necesidades de la aplicación y la escritura de un ´software´ que lleve implícito el algoritmo que permite resolver dicha aplicación. Si la decisión tomada es la de hacer dicho ´software´ en Lenguaje Ensamblador entonces todo lo que se explica a continuación se ajusta. A partir de este momento el diseñador necesita conocer si el ´hardware´

y el ´software´

desarrollado por el es correcto y resuelve de forma eficiente la aplicación a el encomendada. Por un lado comienza todo el trabajo de construcción de la tarjeta o de las tarjetas de circuito impreso que soportarán el ´hardware´ diseñado y por otro lado se comenzará con la tarea primero de liberar de errores de sintaxis el ´software´ desarrollado y por último liberar de errores de lógica dicho ´software´. Para la construcción de la tarjeta de circuito impreso se cuenta con herramientas de software que nos permiten llevar a cabo esta tarea de forma cómoda, rápida y confiable. Entre estas herramientas de software podemos mencionar el ORCAD, PROTEL, etc. Los errores más comunes en esta etapa del desarrollo de la aplicación están en errores humanos al equivocar las conexiones e inclusive a olvidarlas, esto tomando en consideración que quien esta haciendo el diseño del circuito impreso es un especialista que conoce muy bien todos los requerimientos que se deben tener en cuenta a la hora de enfrentar una tarea de este tipo. Para esto estas herramientas por lo general permiten trazar el circuito impreso mediante la opción de ´autoruting´ donde el propio software se encarga de la tarea del diseño del circuito impreso, esto en gran medida disminuye en un alto porciento los errores anteriores pero por lo general cuando los impresos son un poco complicados las soluciones propuestas no son del gusto de los diseñadores, los que, en la mayoría de las ocasiones, toman la decisión riesgosa de hacerlos ellos mismos. Una vez construido el circuito impreso de la tarjeta o las tarjetas se pasa al montaje en dichas tarjetas de los componentes que conforman el ´hardware´ diseñado. Los errores más comunes en

Microcontroladores. El 8051 de la INTEL.

168

esta etapa están relacionados con la existencia de malas soldaduras que provocan conexiones falsas entre los componentes. Para detectar esto solo contamos con un multimetro que nos permita medir continuidad eléctrica entre dos puntos y mucha paciencia. Por otro lado nos vamos enfrentando de forma paralela con la puesta a punto del ´software´ desarrollado. ¿Con que elementos cuenta el diseñador para enfrentar esta tarea? Para esta tarea el diseñador cuenta con un ambiente en su Computadora en el que se encuentra el Programa Ensamblador del que hemos hecho referencia anteriormente acompañado de otros Programas. Estos Programas son: •

Programas Enlazadores.



Programas Simuladores.



Programas Hexadecimal a Binario.

¿Cómo ocurre todo este proceso?, ¿Qué papel desempeña cada uno de estos Programas para la obtención del resultado final? El trabajo debe comenzar por introducir en la Computadora el ´software´ desarrollado. Para esto nos podemos apoyar en un Editor de Texto como podría ser el Notepad. A partir de este momento debe comenzar un trabajo con la ayuda de la Computadora y de las herramientas definidas anteriormente, Enlazadores, Simuladores, etc., para eliminar de errores el ´software´ El primer paso debe estar encaminado a eliminar del ´software´ todo tipo de errores cometidos durante la introducción del mismo en la Computadora mediante el empleo del Notepad. A este tipo de errores se le conoce con el nombre de errores de sintaxis y consisten por lo general en errores cometidos o bien por no conocer la forma correcta de declarar una determinada instrucción o por errores cometidos durante la entrada del programa mediante el Teclado de la Computadora. Para detectar estos errores viene en nuestra ayuda el Programa Ensamblador. Para esto, al Programa Ensamblador se le da como entrada el ´software´ que previamente habíamos introducido en la Computadora con la ayuda del Notepad. A este programa se le conoce con el nombre de programa fuente y el mismo lo debimos haber salvado con un nombre que lo identifica cuya extensión sea .asm. Esta extensión indica que es un programa escrito en Lenguaje Ensamblador y que debe ser manipulado con un Programa Ensamblador. A este proceso se le

Microcontroladores. El 8051 de la INTEL.

169

llama ensamblar el programa, que no es más que el proceso de conversión del ´software´ escrito en Lenguaje Ensamblador a Código de Máquina. Como resultado de este proceso, el Programa Ensamblador nos entrega dos nuevos programas, uno conocido como programa objeto con el mismo nombre pero con extensión .obj y otro conocido como programa ´listener´ con el mismo nombre pero con extensión .lst, conjuntamente con el número de errores de sintaxis cometidos. Mientras existan errores de sintaxis debemos seguir corrigiendo nuestro programa fuente y repetir el proceso. Pero, ¿Cómo conocer los errores de sintaxis cometidos? Como ya se explico anteriormente del proceso de ensamblaje conocemos la cantidad d errores de sintaxis cometidos, pero no conocemos ni ¿cuáles son?, ni en ¿Qué Línea de Instrucción se encuentran? Para llevar a cabo esta labor el programa ´listener´ nos es de gran ayuda ya que en este aparecen bien claro donde ocurrió el error y el tipo de error cometido. Por lo tanto con la ayuda del Notepad Abra el programa con extensión .lst, busque donde están y cuales son los errores, rectifíquelos en el programa con extensión .asm y comience el proceso nuevamente. Una vez logrado que el programa fuente se encuentre libre de errores de sintaxis estamos listos para empeños mayores. Ahora debemos verificar que el algoritmo diseñado y programado hace lo que exige la aplicación a resolver. Para ello viene en nuestra ayuda el Programa Simulador. Los Programas Simuladores, como su nombre lo indica, brindan todo un conjunto de facilidades al programador para poder simular el funcionamiento de su Programa como pueden ser entre otros: •

Ejecutar los programas instrucción a instrucción.



Declarar puntos de ruptura.



Chequear el estado de los registros después de ejecutada una instrucción.



Chequear el estado de la memoria de programa después de ejecutada una instrucción.



Forzar los registros a determinados valores antes de ejecutar una instrucción.



Forzar el valor de una localización de memoria antes de ejecutar una instrucción,

Claro que también existen algunas limitaciones a la hora de utilizar este programa, como pueden ser:

Microcontroladores. El 8051 de la INTEL. •

Dificultad para simular las tareas que involucran tiempo.



Imposibilidad para simular los posibles problemas de carga en el circuito.

170

No obstante, bien utilizado permiten verificar lo acertado o no del algoritmo diseñado, tarea fundamental en esta etapa de la puesta a punto de la aplicación. Los Programas Simuladores por regla trabajan con programas cuya extensión es .hex, que no son ninguno de los dos que nos entrega el Programa Ensamblador. ¿Cómo obtener el programa cuya extensión es .hex? En nuestra ayuda viene el Programa Enlazador. A este se le entra con el programa objeto, .obj, y el nos entrega el programa con el mismo nombre y extensión .hex listo para trabajar con el Programa Simulador. Una vez verificado que el algoritmo diseñado es correcto estamos listos para efectuar una última prueba ya con el ´hardware´ de la aplicación. Para ello debemos obtener el programa en código de máquina para su futura grabación en la Memoria de Programa del microcontrolador. En nuestra ayuda viene ahora el Programa Conversor de Hexadecimal a Binario el que se encarga de esta tarea. Para ello se le entra con el programa cuya extensión es .hex y nos da como salida un programa con el mismo nombre y con extensión .bin listo para ser grabado en la Memoria de Programa mediante un equipo Programador de la memoria del microcontrolador. Ahora digamos que comienza la tarea más ardua que constituye la de poner a punto tanto a ´hardware´ como ´software´ desarrollado funcionando como un todo. En nuestra ayuda vienen ahora equipos de laboratorio ya conocidos como lo son los Multimetros, Osciloscopios, Analizadores de Señales, etc. En esta etapa la experiencia del diseñador juega un papel fundamental. Ahora, cada vez que encontramos un error en el ´software´, tenemos que comenzar por la fase de rectificar y ensamblar el programa con extensión .asm, hasta llegar a la etapa de grabar nuevamente la memoria de programas del microcontrolador, para ver si la rectificación hecha resuelve el error encontrado. Este proceso lo tenemos que repetir hasta que el sistema funcione como un todo logrando resolver de forma eficiente la aplicación propuesta al principio. En la Figura 4.5.1 hemos querido mostrar de forma de diagrama de flujo el conjunto de tareas a llevar a cabo para la poner a punto nuestra aplicación y explicado anteriormente.

Microcontroladores. El 8051 de la INTEL.

171

Figura 4.5.1 Diagrama de Flujo a seguir para la puesta a punto de una aplicación basada en microcontroladores. Si bien este diagrama de flujo propuesto a desarrollar para poner a punto nuestra aplicación puede tener algunas modificaciones en dependencia de los programas utilizados, constituye una guía de gran utilidad para poder entender y adatarnos a cualquier modificación. Este ambiente de trabajo presenta la dificultad de que no se puede lograr el trabajo de simulación del algoritmo diseñado conjuntamente con el ´hardware´ propuesto para el circuito como ocurrirá en la realidad. Por lo que puede ocurrir que del trabajo de simulación lleguemos a la conclusión del que el circuito en conjunto funciona correctamente y cuando lo montamos en la placa definitiva no resulta así, haciendo muy dura la etapa final del trabajo.

Microcontroladores. El 8051 de la INTEL.

172

Existen equipos conocidos con el nombre de Emuladores que permiten el trabajo conjunto de ´hardware´ y ´software´ en tiempo real, tal y como va a ocurrir en el equipo final, durante la fase de simulación. Este proceso se conoce con el nombre de emulación, que no es más que crear un ambiente de trabajo que imite lo más posible al equipo que se esta desarrollando. Esta tarea de emular al circuito se hace bajo un ambiente controlado por el diseñador, en el que cuenta con información muy útil de lo que esta pasando dentro del microcontrolador para la puesta a punto del sistema. Ahora el diseñador puede emular directamente sobre el circuito final el ´software´ desarrollado para la aplicación. De esta forma usted va poniendo a punto el sistema poco a poco y tomando en cuenta la interrelación que existe entre ´hardware´ y ´software´ en los sistemas basados en microcontroladores. Lo mejor esta en que el diseñador tiene prácticamente las mismas posibilidades que las que brindan los Programas Simuladores ya mencionadas anteriormente pero en un ambiente en tiempo real. La única dificultad en este caso es que estos equipos resultan caros y en ocasiones ni los desarrolladores de circuitos basados en microcontroladores profesionales cuentan con ellos. En la actualidad se han desarrollados ambientes para la puesta a punto de circuitos basados en los microcontroladores que permiten hacer una aproximación bastante exacta durante la fase de simulación a lo que va a ocurrir en la realidad cuando el ´hardware´ diseñado se ponga a funcionar en conjunto con el ´software´ tal y como ocurre en el equipo definitivo. Estos sistemas aunque no llegan a ser emuladores, si brindan ambientes mucho más cercarnos a la realidad de los que brindaban los simuladores tradicionales. Un ejemplo de estos tipos de programas lo constituye el Proteus desarrollado por la compañía inglesa ´LabCenter´. El Proteus brinda un ambiente integrado donde el usuario encuentra desde un editor del ´hardware´ hasta los programas que permiten ensamblar el ´software´ desarrollado, depurarlo de errores de sintaxis, simularlo en conjunto con el ´hardware´ editado, depurarlo de errores de lógica y obtener el código de máquina que se grabara definitivamente en la memoria de programa del microcontrolador, haciendo más fácil la etapa final de puesta a punto del sistema al diseñador. El objetivo se este epígrafe no era el estudio de estas herramientas de software ni de los pasos a seguir para la puesta a punto de una aplicación dada, sino, el estudio de algunas de las directivas básicas para la escritura de un programa en Lenguaje Ensamblador, pero nos pareció oportuno explicarlo en este momento dada la relación que existen entre ellas. Las directivas le brindan información a todos estos programas, útiles para que puedan llevar a cabo con éxito sus tareas. Información tales como:

Microcontroladores. El 8051 de la INTEL. •

173

cual es la dirección de inicio a partir de la cual se debe comenzar a ensamblar el programa.



donde termina el ensamblaje del mismo.



valores tomados por variables simbólicas utilizadas en el programa a ser sustituidas por sus valores reales cuando vayan a ser programadas en el microcontrolador, etc.

Conozcamos un conjunto de estas directivas básicas que nos van a permitir comprender mejor a estas y comenzar a escribir nuestros primeros programas. Iniciando el Programa. Las instrucciones de un Programa son ubicadas en localizaciones de Memoria de Programa como ya conocemos, por lo general de forma consecutiva, a partir de una localización de inicio donde se debe almacenar el código de la primera instrucción. Para indicar la dirección que le debe corresponder a esta primera localización a partir de la cual se debe comenzar el ensamblaje del Programa existe la directiva, ORG

inicio

; inicio se corresponde con la dirección a partir de la cual se va a ; ensamblar el Fragmento de Programa que se encuentra a ; continuación de la directiva.

Por ejemplo ya conocemos que para este microcontrolador la localización donde se debe almacenar el código de la primera instrucción del Programa es a la que le corresponde la dirección 0000H, razón por la cual la mayoría de los Programas, por no decir todos comienzan con la directiva, ORG

0

; inicio del Programa Principal.

Si el programador estuviera obligado a que a partir de esta localización se tuvieran que colocar todos los códigos de las instrucciones que conforman el Programa de forma consecutiva parecería innecesaria esta directiva, no obstante esto no tiene porque ser así. Si bien, el programador tiene la obligación de que el código de la primera instrucción de su Programa este ubicado en la localización cuya dirección es la 0000H, el tiene posteriormente la libertad de ubicar el resto de las instrucciones a partir de la localización de Memoria de Programa que el considere oportuno, sin ninguna restricción, para ello cuenta con las instrucciones de Salto que permiten alterar la secuencia natural en la ejecución de un programa..

Microcontroladores. El 8051 de la INTEL.

174

Por ejemplo, supongamos que el programador quiere que la primera instrucción de su Programa Principal se encuentre almacenada en la localización cuya dirección es la 0010H y de esta manera reservar las localizaciones de la memoria de programa que la anteceden. Por su puesto que el microcontrolador será inicializado mediante la activación de la señal de RESET lo que provocará que la primera instrucción que ejecuta el microcontrolador sea la almacenada en la localización cuya dirección es la 0000h en la memoria de programa. No obstante, esta instrucción no tiene porque constituir la primera de su Programa Principal y ni siguiera tiene porque ser una instrucción que forme parte del mismo. Por ejemplo podríamos utilizar la instrucción de Salto Corto, SJMP

inicio

Y colocaríamos a la Etiqueta inicio en la próxima Línea de Instrucción a la ocupada por la directiva, ORG

0010h

; inicio del Programa Principal.

Por lo tanto para cumplir con lo pedido en el ejemplo procederíamos de la siguiente forma, ORG

Inicio:

0

; posición de la instrucción a ejecutar con la activación del RESET.

SJMP inicio

; salto a la dirección donde se encuentra la primera instrucción.

ORG

; posición de la primera instrucción del programa Principal.

0010H

; primera instrucción del Programa Principal.

Quedando el programa ensamblado para ser almacenado en la memoria de programa del Microcontrolador tal como se muestra en la Figura 4.5.2.

Microcontroladores. El 8051 de la INTEL.

175

Figura 4.5.2 Memoria de Programa del microcontrolador. Resumiendo, con la directiva ORG se le indica al Programa Ensamblador a partir de que dirección ensamblar el fragmento de programa ubicado inmediatamente debajo de la misma. Fin de Ensamblaje. La directiva que indica fin de ensamblaje es END. Esta debe estar ubicada después de la última línea o sentencia del Programa. Nos parece importante aclarar sobre este aspecto, la directiva END indica fin de ensamblaje, no fin del Programa, por lo tanto debe estar ubicada en la última línea o sentencia del mismo como ya se aclaro y no debajo de la última instrucción del Programa. La pregunta a responder en este momento sería, ¿A caso la última instrucción o sentencia del Programa no se corresponde con la última instrucción del mismo?

Microcontroladores. El 8051 de la INTEL.

176

La respuesta es que no necesariamente, es más, por lo general no ocurre así. Si analizamos la estructura de un Programa escrito en Lenguaje Ensamblador

para una

aplicación basada en el microcontrolador 8051 nos vamos a encontrar en que podemos subdividir al mismo en los siguientes bloques: •

Definición de Variables.



Saltos a Subrutinas de atención a la Interrupción.



Programa Principal.



Subrutinas.



Tablas.

Aunque obligatoriamente no tiene que ser así, un ordenamiento en el que aparezcan escritos en el Programa en el mismo orden en que los hemos enunciados sería una buena propuesta o guía a la hora de escribir nuestros programas. Por lo que estamos proponiendo que cuando usted escriba sus programas en Lenguaje Ensamblador siga la siguiente estructura: •

El primero bloque que usted escriba, es un bloque compuesto por un conjunto de directivas las que definan las variables y constantes que usted utilizará en el Programa. Estas variables y constantes las definimos mediante palabras escogidas por nosotros que le dan nombre.



El segundo bloque a escribir, estará conformado por un conjunto de instrucciones de Salto que permitan direccionar a las Subrutinas de Atención a las interrupciones presentes en la aplicación.



El bloque siguiente a escribir, estará compuesto por las instrucciones que permiten materializar el algoritmo escogido para resolver la aplicación a las que llamaremos Programa Principal.



El cuarto bloque a escribir, estaría compuesto por todas las Subrutinas que son utilizadas por el Programa Principal.



Y por último se escribiría un bloque conformado por todas las Tablas que son necesarias para el trabajo del Programa.

Todas las directivas y las instrucciones que conforman cada uno de estos bloques tienen que ser ensambladas por el Programa Ensamblador cuando se de la orden de ensamblar y por lo tanto se tienen que encontrar escritas en instrucciones o sentencias de programas ubicadas antes de la ocupada por la directiva END. De forma tal que el Programa quedaría escrito según la siguiente estructura:

Microcontroladores. El 8051 de la INTEL. •

177

BLOQUE DE DEFINICIÓN DE VARIABLES Y CONSTANTES. ORG

0000h

; dirección de inicio del ensamblaje.



BLOQUE DE SALTO A LAS SUBRUTINAS DE ATENCION A LA INTERRUPCION.



PROGRAMA PRINCIPAL.



BLOQUE DE SUBRUTINAS.



BLOQUE DE TABLAS. END

; fin de ensamblaje.

Declarando Variables y Constantes. Por lo general en los Programas se trabaja con muchas Variables y Constantes utilizadas para declarar, de una forma cómoda, algún recurso necesario para el trabajo o algún valor que en el programa se utilice con frecuencia. Por ejemplo, queremos tener una localización de Memoria de Datos destinada para almacenar el valor de una Variable que es utilizada para tomar determinadas decisiones. En el Programa podríamos trabajar directamente con la dirección de dicha localización, pero sería más cómodo para el programador y para el futuro usuario del Programa que nos pudiéramos referir a este localización mediante un nombre que en muchas ocasiones nos puede dar una idea de para que esta siendo utilizada la misma en el Programa. La directiva EQU nos permite esto. La sintaxis de esta directiva es la siguiente, VARIABLE

EQU

numero

La directiva lo que hace es asignarle, durante el proceso de ensamblaje, a VARIABLE el valor numérico numero, de forma tal que, cada vez que aparezca el nombre de dicha VARIABLE en el Programa este le asignara el número declarado en la directiva. VARIABLE

es un nombre conformado por letras, números y signos.

numero

es una constante escrita en binario, hexadecimal, decimal o ASCII.

Por ejemplo, Inicio EQU ORG

Inicio:

0010H

; VARIABLE Inicio igual al número hexadecimal 0010h

0

; dirección de inicio del ensamblaje en la 0000h

SJMP Inicio

; salto a la dirección 0010h

ORG

; dirección de inicio del ensamblaje en la 0010h

Inicio

Microcontroladores. El 8051 de la INTEL.

178

Hace el mismo efecto que en el caso anterior. Observe que en este caso tenemos la ventaja que podemos ubicar el inicio del Programa en cualquier dirección de la Memoria de Programa con solo cambiar el número en la directiva EQU. Al igual que hemos declarado una VARIABLE que va a ser utilizada por el Programa como una dirección, podemos declarar una VARIABLE que va a ser utilizada como un dato constante en el Programa. El procedimiento es el mismo, veamos el siguiente ejemplo. Supongamos que la primera instrucción del Programa es cargar en el registro Acumulador el valor constante 2AH. Inicio

EQU

0010H

; se le asigna a la VARIABLE Inicio el valor 0010h

Constante

EQU

2AH

; se le asigna a la VARIABLE Constante el valor 2Ah

ORG

0

; inicio de ensamblaje en la dirección 0000h

Inicio:

SJMP Inicio

; salto a la dirección 0010h

ORG

Inicio

; inicio de ensamblaje en la dirección 0010h

MOV

A, #Constante ; se carga en el registro Acumulador el valor 2Ah

Observe que el papel que juegue la VARIABLE declarada depende de cómo usted la utilice en el Programa. Declarando los datos de una Tabla. Conocemos que una Tabla es una estructura compuesta por un número n de datos almacenados de forma consecutiva. Cuando estas Tablas no cambian durante la ejecución del Programa por lo general se almacenan en la Memoria de Programa del microcontrolador como parte de este. ¿Cómo declarar los datos de la Tabla? Lo primero a declarar al Programa Ensamblador es la dirección de la localización a partir de la cual se quiere a almacenar la Tabla, esto lo podemos hacer mediante la directiva ORG ya estudiada. Esto nos da gran libertad para ubicar la Tabla en cualquier lugar en la Memoria de Programa. Una vez declarada la dirección de inicio de la Tabla los datos los podemos declarar empleando la directiva DB si los datos que conforman la Tabla son del tipo byte o DW si los datos que conforman la Tabla son del tipo word (16 bits).

Microcontroladores. El 8051 de la INTEL.

179

Un ejemplo de cómo declarar una Tabla conformada por datos del tipo byte y que contiene los 5 primeros números enteros sin signos a ubicar a partir de la localización de Memoria de Programa cuya dirección es la 1000H es el siguiente. ORG

1000H

; dirección de inicio de ensamblaje en la 1000h

Tabla DB

0

, primer dato de la Tabla.

DB

1

; segundo dato de la Tabla.

DB

2

; tercer dato de la Tabla

DB

3

; cuarto dato de la Tabla

DB

4

; quinto dato de la tabla.

El Programa Ensamblador al ensamblar el programa le asignara a la etiqueta Tabla el valor 1000H y por lo tanto el programador podrá referirse a esta mediante su nombre simbólico. Por ejemplo si queremos extraer el segundo dato de la Tabla lo podríamos hacer mediante el conjunto de instrucciones siguiente: MOV

A, #2

; carga en el registro Acumulador el numero 2

MOV

DPTR, #Tabla

; carga en el registro DPTR la dirección Tabla

MOV

A, @A+DPTR

; carga en el registro Acumulador el contenido de la ; localización de memoria de datos cuya dirección es ; Tabla + 2, en este caso el numero 2.

Ya conocemos algunas directivas que nos permitirán escribir nuestros primeros programas con vistas a ser ensamblados de una forma más cómoda y flexible. Existen otras pero que las iremos descubriendo en la medida que avancemos en el material. A manera de conclusión de este Tema ya conocemos como entregar la energía necesaria al microcontrolador para que funcione correctamente, como entregarle la señal de reloj para que el sincronice todas sus operaciones internas, como inicializar la ejecución del Programa y como hacer el Programa en Lenguaje Ensamblador. No obstante, cualquier aplicación que desarrollemos basada en un microcontrolador su objetivo fundamental será la de intercambiar información con el exterior. El microcontrolador esta concebido para que este intercambio de información lo haga básicamente a través de sus Puertos de Entrada / Salida, por lo que al estudio de los mismos dedicaremos el próximo Tema.

Microcontroladores. El 8051 de la INTEL.

180

Tema 5. Conectando dispositivos externos al microcontrolador. Una característica común a la mayoría de los microcontroladores es la de entregar un conjunto de líneas que operan de forma digital y que por lo general se organizan en grupos de 8 y toman el nombre de Puertos. A través de estas líneas es que el microcontrolador se comunica con el exterior, siendo común encontrarse conectadas a las mismas los diferentes elementos que apoyan a este en la solución de una aplicación dada. También resulta común que a través de estas líneas salgan al exterior los señales de los circuitos complementarios con que cuentan por lo general los microcontroladores, entiéndase, Controlador de Interrupciones, Temporizadores, Puerto Serie, etc. El 8051 no constituye una excepción, brindando 32 líneas de Entrada / Salida agrupadas en 4 Puertos de 8 líneas cada uno para efectuar la comunicación con los dispositivos externos. Al estudio de las características tanto lógicas como eléctricas de estos Puertos está dedicado este Tema, con el objetivo de conocer todos los elementos que nos permitan conectar diferentes tipos de dispositivos a los mismos. 5.1 Los Puertos del 8051. En la Figura 5.1.1 se muestran los terminales del microcontrolador que pertenecen a cada uno de los 8 bits de los Puertos. El nombre que reciben los 4 Puertos son: •

Puerto 0 (P0)



Puerto 1 (P1)



Puerto 2 (P2).



Puerto 3 (P3).

Los 4 Puertos tienen aspectos que son comunes a todos y peculiaridades propias de cada uno de ellos. Figura 5.1.1. Los Puertos del 8051 Entre las características comunes se encuentran: •

Cada uno cuentan con un registro Almacenador (Latch) de 8 bits entre los Registros de Funciones Especiales donde se almacena la información enviada a los mismos mediante programas. Para el Puerto 0 el nombre de este registro es P0, para el Puerto 1, P1, para el

Microcontroladores. El 8051 de la INTEL.

181

Puerto 2, P2 y para el Puerto 3, P3, por lo que en las instrucciones cuando nos queramos referir a uno de estos Puertos para efectuar una operación de escritura o de lectura lo haremos utilizando como operando en la instrucción el nombre del registro asociado a dicho Puerto. Por ejemplo si queremos poner a ´1´ todos los bits del Puerto 0 lo haríamos mediante la siguiente instrucción, MOV •

P0, #11111111B

; pone a ´1´ todos los bits del Puerto 0.

Los 4 Puertos son direccionables bit a bit, ya que los registros P0, P1, P2 y P3, se encuentran entre los registros que pueden ser trabajados de esta forma, ver Tabla 2.3.2, por lo que las instrucciones del grupo de Manipulación de Variables Booleanas pueden ser utilizadas para manipular la información que existe en los Puertos. Por ejemplo si queremos imponer un ´0´ en el bit 3 del Puerto 1, sin afectar a los demás, lo haríamos mediante la siguiente instrucción, CLR



P1.3

; pone a ´0´ el bit 3 del Puerto 1.

Las instrucciones que son validas para uno, son validas para todos. Cuando en las instrucciones vamos a trabajar con los Puertos le damos el mismo tratamiento que le damos a los registros que forman parte de los Registros de Funciones Especiales. Es más, P0, P1, P2 y P3, constituyen registros ubicados dentro de los Registros de Funciones Especiales, ver Tabla 2.3.2, por lo que todas aquellas instrucciones que pueden ser utilizadas para manipular estos registros pueden ser utilizadas para manipular a los Puertos. Por ejemplo si queremos sumar el contenido del registro Acumulador con el valor presente en cada uno de los terminales del Puerto 2, lo haríamos mediante la siguiente instrucción, ADD



A, P2

; A

A + P2

Para poder efectuar la lectura mediante programa del valor presente en uno de sus terminales es una condición imprescindible que el bit correspondiente en su registro Almacenador se haya puesto previamente a ´1´. Esta condición por lo general resulta transparente para el programador ya que, con la activación de la señal de RESET todos los bits de los registros Almacenadores son cargados con el valor de ´1´, con lo que quedan preparados para ser trabajados como de entrada. Como en la mayoría de las aplicaciones si usted decide que un Puerto será de entrada esta condición la va a mantener durante todo el tiempo pues usted no tendrá que preocuparse por esto ya que con la imprescindible activación de la señal de RESET del microcontrolador en su aplicación todo habrá quedado resuelto. No obstante, puede haber alguna aplicación en la cual un determinado Puerto pueda ser utilizado una parte del tiempo como Puerto de Entrada y otra parte del tiempo

Microcontroladores. El 8051 de la INTEL.

182

como Puerto de Salida, en este caso cada vez que usted vaya a conmutar el Puerto de salida hacia entrada lo primero que usted debe hacer el cargar en todos los bits del registro Almacenador un ´1´. Las causas de esto serán explicadas más adelante cuando estudiemos las características constructivas de cada uno de los Puertos. Ya conocidos los principales aspectos comunes entre los Puertos del 8051 por lo que le proponemos pasar al estudio de los aspectos particulares a cada uno de ellos. El estudio no lo haremos siguiendo el orden consecutivo del número de los Puertos como podría parecer lógico, sino que lo haremos tomando en cuenta su nivel de complejidad, de los menos complejos a os más complejos, para lograr una mejor comprensión de los mismos. 5.2 El Puerto 1. En la Figura 5.2.1 se muestra la estructura interna de uno cualquiera de los bits del Puerto 1, donde se destacan 4 elementos fundamentales: •

Un Biestable del tipo D.



El Buffer de tercer estado, de lectura del terminal.



El Buffer de tercer estado, de lectura del Biestable.



La Etapa de salida, conformada por un transistor MOS con una resistencia de RX conectada a Vcc.

Estos

elementos,

con

esta

misma

estructura se repiten para cada uno de los 8 bits del Puerto 1. De forma tal que el registro Almacenador de este Puerto, estará conformado por 8 Biestables tipo D, con sus correspondientes Buffer tercer estado y su Etapa de salida La pregunta a responder en este momento sería, ¿Cómo escribir un ´0´ o un ´1´ en uno de los bits cualquiera del Puerto 1?

Microcontroladores. El 8051 de la INTEL.

183

El objetivo, cuando trabajamos con un Puerto como salida, es el de imponer determinado valor lógico, de ´0´ o de ´1´, en los bits de dicho Puerto. Para ello utilizamos una instrucción del tipo MOV en la cual el operando destino sea el registro Almacenador correspondiente al Puerto y el operando fuente sea el dato o el lugar donde se encuentra almacenado el dato. Supongamos que estamos trabajando con el Puerto 1 como de salida y que deseamos poner a ´1´ los bits, 0, 3, 5 y 6 de este, mientras que al resto imponerles un valor de ´0´. Esto lo podríamos hacer mediante la instrucción, MOV

P1, #0110 1001B

; P1

01101001B

Observe la posición que ocupan los ´1´ y los ´0´ dentro del operando fuente, que no es más que el número que se va a escribir en el registro Almacenador P1 después de ejecutada la instrucción y compruebe que se corresponde con la combinación de ´0´ y ´1´ que nos habíamos impuestos en el ejemplo, si tomamos en cuenta que el digito que aparece escrito más a la derecha en el operando fuente de la instrucción se corresponde con el bit menos significativo y por lo tanto será el que se almacenara en el Biestable D correspondiente al bit P1.0, mientras que el digito escrito más a la izquierda en el operando fuente de la instrucción se corresponderá con el bit más significativo y por lo tanto será el que se almacenará en el Biestable D correspondiente al bit P1.7. Por lo tanto al ejecutar el microcontrolador la instrucción en cuestión en los Biestable D correspondientes a los bits 0, 3, 5 y 6 del registro Almacenador P1 se almacenará un ´1´, mientras que en los Biestable D correspondientes al resto de los bits de dicho registro Almacenador se almacenarán ´0´. ¿Cómo ocurre este proceso? En el caso particular del Puerto 1, cuando el programa ejecuta una instrucción de escritura en el registro Almacenador P1, como puede ser la instrucción anterior, el dato le llega a cada uno de sus Biestable a su entrada D a través del bus de datos interno del microcontrolador, ver Figura 5.2.1. Simultáneamente a las entradas CL, entrada de reloj del Biestable, de cada uno le llega la comando WRITE TO LATCH en forma de pulso, activando la entrada de reloj del Biestable con lo que el valor puesto en la entrada D es almacenado, tomando la salida Q del Biestable el valor escrito y en Q/ el valor invertido. ¿Qué influencia tendrá lo anterior sobre el transistor MOS de la Etapa de Salida? Observe de la Figura 5.2.1 que el valor en la Q/ del Biestable D es aplicado al terminal GATE del transistor MOS de la Etapa de Salida, cortándolo o saturándolo en dependencia del valor que

Microcontroladores. El 8051 de la INTEL.

184

tome dicha salida del Biestable. Si Q/ es ´0´, el transistor se cortará, si por el contrario la Q/ es ´1´, entonces el transistor se saturará. ¿Qué influencia tendrá sobre los terminales de salida del Puerto 1 la ejecución de la instrucción anterior? De la Figura, 5.2.1, parece evidente de que el valor que toma el terminal de salida del Puerto dependerá en gran medida del estado del transistor de la Etapa de Salida y por ende del valor que tome la salida Q/ del Biestable que no es más que la consecuencia del valor almacenado en el Biestable D. Analicemos todos los elementos de forma integral para los dos casos posibles, •

Cuando en el Biestable D se escribe un ´1´.



Cuando en el Biestable D se escribe un ´0´.

para así llegar a una conclusión definitiva. Si en el Biestable D se escribe un ´1´, la salida Q/ de dicho Biestable tomará el valor de ´0´ y como consecuencia el transistor MOS de la Etapa de Salida estará cortado. En este caso en el terminal de salida se verá reflejada la fuente Vcc a través de la resistencia Rx, con lo que se impone un valor lógico de ´1´ en el terminal, ver Figura 5.2.2.

El valor lógico de ´1´ está asociado a un intervalo de valores de voltaje, que hemos dado en llamar V0h, 2.4Volts < Voh < 5.0Volts que entrega el microcontrolador por el terminal correspondiente. Este intervalo de

valores

de

voltaje

de

´1´

se

corresponde con el establecido por la Familia de circuitos integrados TTL para el ´1´ lógico.

¿De qué depende que el valor tomado por el Voh sea uno cualquiera dentro del intervalo?

Microcontroladores. El 8051 de la INTEL.

185

Por su puesto que esto depende en gran medida de la corriente, Ioh, que demande la carga conectada a dicho terminal y que en la Figura 5.2.2 la hemos representado por RL. Ioh la entregará en este caso la fuente Vcc con que se alimenta al microcontrolador, esta corriente provocará una caída de voltaje en la resistencia RX que al restarse con Vcc nos dará el valor de Voh correspondiente Vcc es un valor constante y RX es un valor constante también por lo que el valor de Voh dependerá exclusivamente del valor de Ioh. El plantear una malla que vaya desde la fuente Vcc a través de la resistencia RX y la carga quizás nos podría ayudar a comprender un poco mejor lo anterior, para ello nos auxiliaremos de la Figura 5.2.2

VCC − VRx = Voh VRx = I X R X I X = I oh VCC − I oh R X = Voh Analicemos el caso en que no existe ninguna carga conectada al terminal del microcontrolador.

Voh = VCC − I oh R X I oh = 0 Voh = VCC O sea, si usted impone por programa un ´1´ en uno cualquiera de los terminales del Puerto 1 y no le conecta carga y conecta un Voltímetro entre este terminal y tierra, el valor de voltaje que el mismo nos indicará será aproximadamente el valor de la fuente con que se esta alimentando al microcontrolador. Por su puesto que este ejemplo no tiene mucha importancia del punto de vista práctico ya que si estoy trabajando con el terminal del Puerto es porque tengo alguna carga conectada al mismo, por lo que le proponemos que analicemos para comparar dos casos con demandas de corriente por las cargas diferentes. Consideremos el caso en que la carga nos demande 5 miliamperes y otro en el que la carga nos demande 10 veces esta magnitud.

Voh = VCC − I oh R x Necesitamos conocer el valor de RX para poder continuar con los cálculos. RX aunque la hemos representado por una resistencia, en si no es simplemente esto, realmente es un transistor MOS conectado entre el VCC y el DRAIN del transistor MOS de la Etapa de Salida, el que se encontrará

Microcontroladores. El 8051 de la INTEL.

186

en conducción cuando en el bit correspondiente del Puerto 1 se escriba un ´1´. Este efecto, de encontrarse en conducción, es lo que nos ha permitido poderlo representar como una resistencia ya que de esta forma lo vería la carga. El valor de la resistencia que este transistor impone cuando esta en conducción no es el mismo para todos los microcontroladores 8051 o versiones que nos encontremos. Efectivamente el valor de la resistencia dependerá en gran medida del fabricante del microcontrolador con que estemos trabajando y de la tecnología de fabricación con que ha sido diseñado el mismo, por lo que proponer un valor de RX que siempre será el mismo independientemente del tipo de microcontrolador con que estemos trabajando no lo podemos hacer y de hacerlo no resultaría útil para el diseñador ya que llegado el caso el tendría que ver en el manual del fabricante cual es el valor de RX para el microcontrolador con que este trabajando. Pero por lo general los manuales de los fabricantes no traen el valor de RX. ¿Cómo conocer el valor de RX del microcontrolador con que estemos trabajando? La idea que les propongo es determinar este valor de forma experimental y para ello les propongo que monten con el microcontrolador que van a trabajar el circuito de la Figura 5.2.3.

Microcontroladores. El 8051 de la INTEL.

187

Para buscar el valor de RX construyamos una grafica que relacione la corriente Ioh que entrega el microcontrolador por uno cualquiera de los terminales del Puerto 1 cuando esta en ´1´ lógico, con el voltaje Voh que el mismo es capaz de entregar. Para hacer esta labor nos auxiliaremos de un Potenciómetro que hemos conectado entre el terminal P1.0 del Puerto 1 y tierra para simular la variación de la carga, de un Amperímetro para medir la corriente Ioh y de un Voltímetro para medir el voltaje Voh. Los resultados del experimento son los mostrados en la Figura 5.2.4.

La pendiente de la ecuación mostrada en la Figura 5.2.4 no es más que el valor de RX que andábamos buscando, por lo que podemos llegar a la conclusión de que este valor para el microcontrolador con que estamos trabajando es de 20 ohms.

Voh = 5V − ((5mamp )(20Ω )) = 4.9V Voh = 5V − ((50mamp )(20Ω )) = 4.0V Como era de esperar, con el aumento de la corriente Ioh que demanda la carga el voltaje Voh disminuye y con ello el microcontrolador entregará un nivel de ´1´ lógico más deteriorado. Por su

Microcontroladores. El 8051 de la INTEL.

188

puesto que esto no es infinito y presenta sus limitantes, que sería cuando la Ioh que demanda la carga provoca una caída en el valor del voltaje Voh que este por debajo de 2,4 Volts, valor mínimo impuesto para el intervalo de valores posibles a tomar por el ´1´. Para nuestro caso,

5Volts − 2.4Volts 20Ω > 130mamp

I oh > I oh

¿Quiere decir esto que cuando en uno de los terminales del microcontrolador se impone un ´1´ no se pueden extraer valores de Ioh superiores a este valor? Si se pueden extraer valores de Ioh superiores, pero lo que va a ocurrir es que el valor del ´1´ lógico se deteriora tanto que si usted conecta una compuerta lógica a este terminal esta no reconocerá un ´1´ en su entrada. Analicemos el circuito mostrado en la Figura 5.2.4 a la luz de todo lo estudiado hasta aquí. En el circuito de la Figura pretendemos encender un LED conectado al terminal P1.0 del microcontrolador mediante la escritura de un ´1´ en dicho terminal. En este caso estamos trabajando con un bit del Puerto 1, el P1.0, sin importarnos el estado de los restantes bits para efectuar la tarea deseada.

La primera pregunta que nos puede venir a la mente en este caso podría ser, ¿Qué es un Diodo Emisor de Luz (LED)?, ¿Cómo es que se hace encender? Un LED es un dispositivo que presenta características similares a los Diodos, permitiendo la conducción de la corriente en un solo sentido, de Ánodo a Cátodo, cuando el voltaje que le esta siendo aplicado en el Ánodo es más positivo, en una cierta magnitud, que el que le esta siendo aplicado en el Cátodo. Tiene como característica que lo identifica que cuando conduce emite una luz cuya intensidad depende de la magnitud de la corriente que esta circulando por el. Por lo tanto,

Microcontroladores. El 8051 de la INTEL.

189

cuando el LED se enciende por el esta circulando una corriente y en el se cae un voltaje cuyo valor es el voltaje de conducción del mismo. En el caso del circuito de la Figura 5.2.4, el LED ha sido conectado de forma tal que su Ánodo esta conectado al terminal del Puerto 1 en cuestión a través de una resistencia que hemos llamado RL, mientras que su Cátodo esta conectado a la referencia de tierra (0Volts) del circuito. Por lo tanto, para que conduzca el LED, el voltaje que tiene que estar entregando el microcontrolador por su terminal P1.0 tiene que ser capaz de polarizar en directa al LED y esto sería posible si en el terminal se escribe un ´1´ lógico. De la conclusión anterior nos podría surgir la interrogante, ¿Para que esta la resistencia RL en el circuito? Cuando conectamos un LED en un circuito deseamos que, cuando este encienda, por el circule una determinada corriente que es la que va a permitir que la luminosidad del mismo sea la necesaria para la aplicación. Este valor de corriente (IL) conjuntamente con el voltaje de conducción de directa (VL) son los que definen el punto de operación en el que tiene que trabajar el LED cuando encienda. Por lo que cuando usted escoja un LED para conectarlo en su circuito debe antes que todo definir el punto de operación en el que el mismo va a trabajar cuando encienda. Para ello de los datos del LED entregados por el fabricante toma el VL y de estos mismos datos toma el intervalo de valores de IL permisibles a circular por el LED, entre los cuales se debe encontrar el necesario para tu aplicación. Supongamos que en nuestro caso el LED escogido tiene los siguientes datos tomados del fabricante,

V L = 2.2Volts 10mamp < I L < 30mamp y que el punto de operación necesario lo definen los valores de,

V L = 2.2Volts I L = 10mamp Ahora es que toma importancia la resistencia RL, permitiéndonos con su valor, imponer al LED el punto de operación deseado cuando a la salida del terminal del microcontrolador aparezca un ´1´ lógico en este caso. Para ello apliquemos las Leyes de Kirchoff a la malla donde se encuentran conectados el LED y la resistencia RL.

Microcontroladores. El 8051 de la INTEL.

190

VCC − I X R X − I L R L − VL = 0 I X = I L = 10mamp RL =

5Volts − ((10mamp )(20Ω )) − 2.2Volts = 260Ω 10mamp

Una vez conectado el LED al terminal P1.0 tal y como aparece en la Figura 5.2.4 y conectamos una resistencia RL de valor igual a 260Ω, si queremos encender el LED en el punto de operación escogido, todo lo que tenemos que hacer es imponer un ´1´ en el terminal P1.0 del Puerto 1. Como se explico en Temas anteriores los registros Almacenadores de los Puertos pueden ser direccionados bit a bit, por lo que podríamos aprovechar la comodidad que nos brindan las instrucciones del grupo de Manipulación de Variables Booleanas para el trabajo con un bit de un Puerto de forma independiente sin alterar el valor de los restantes. La instrucción que proponemos emplear en este caso sería, SETB P1.0

; P1.0

´1´, enciende el LED.

Por su puesto, cuando queramos apagar el LED todo lo que tenemos que hacer es utilizar la instrucción que provoca el efecto contrario en el terminal del Puerto. CLR

P1.0

; P1.0

´0´, apaga el LED.

Aprovechemos el ejemplo y analicemos nuevamente, con más detenimiento y a modo de resumen, todas las acciones que provoca la ejecución de la instrucción que impone un ´1´ en el terminal P1.0 y que por lo tanto enciende el LED. El microcontrolador al ejecutar la instrucción, SETB P1.0 pone un ´1´ lógico en el bit 0 de su bus de datos interno, llegando dicho valor a la entrada D del Biestable D correspondiente, el bit 0 en el registro Almacenador del Puerto 1. Un tiempo después el microcontrolador generará el comando WRITE TO LATCH con lo que se activa la señal de reloj de dicho Biestable. Con esta acción se impone en la Q del Biestable un ´1´ lógico, mientras que la Q/ toma el valor de ´0´ lógico. Este valor de ´0´ lógico es aplicado al GATE del transistor MOS de la Etapa de Salida, cortándolo, imponiendo la fuente de +5 Volts a través de la resistencia RX un ´1´ lógico en el terminal de salida, el que polarizará en directa al LED provocando su encendido en un punto de operación definido por el valor de la resistencia RL.

Microcontroladores. El 8051 de la INTEL.

191

Si por el contrario la instrucción ejecutada es, CLR

P1.0

el microcontrolador pone un ´0´ lógico en el bit 0 de su bus de datos interno, llegando dicho valor a la entrada D del Biestable D correspondiente, el bit 0 en el registro Almacenador del Puerto 1. Un tiempo después el microcontrolador generará la comando WRITE TO LATCH con lo que se activa la señal de reloj de dicho Biestable. Con esta acción se impone en la Q del Biestable un ´0´ lógico, mientras que la Q/ toma el valor de ´1´ lógico. Este valor de ´1´ lógico es aplicado al GATE del transistor MOS de la Etapa de Salida, saturándolo, imponiendo en el terminal de salida el voltaje DRAIN – SOURCE de un transistor MOS saturado lo que es interpretado como un ´0´ lógico. Este voltaje no será capaz de polarizar en directa al LED, no circulando corriente por el con lo que se apagará., ver Figura 5.2.4. ¿Cómo conectar al LED si lo que queremos es que el mismo se encienda cuando en el bit del Puerto 1 se escribe un ´0´? Tomemos como punto de partida en este caso lo expresado en el último párrafo donde se explico todo lo que ocurre dentro del microcontrolador cuando escribimos un ´0´ en uno cualquiera de los bits del Puerto 1. En este caso el microcontrolador entregará un voltaje bajo, al que llamaremos VOL, que no será más que el voltaje DRAIN – SOURCE típico de un transistor MOS saturado, ver Figura 5.2.5. Este voltaje se encuentra entre los valores,

0Volt < VOL < 0.4Volts Estos valores se corresponden con los valores de mínimo y de máximo del voltaje de salida de ´0´ de la familia de circuitos integrados TTL con lo que se garantiza el poder conectar directamente cualquier circuito de esta famosa familia de circuitos integrados a uno cualquiera de los terminales de este Puerto.

Observe que en este caso cuando hemos representado la carga lo volvemos a hacer mediante una resistencia a la que le hemos vuelto a llamar RL, pero en este caso en lugar de conectar el otro

Microcontroladores. El 8051 de la INTEL.

192

extremo de la misma a tierra lo hemos hecho a la fuente de alimentación VCC con lo que hemos querido representar que la carga no toma corriente del terminal del microcontrolador sino todo lo contrarío, entrega corriente al mismo. Esta corriente, a la que hemos llamado IOL, circula a través del transistor MOS de la Etapa de Salida del bit del Puerto 1 y esto constituye una de las primeras precauciones a tener en consideración cuando conectamos un circuito cualquiera a uno de los terminales de este Puerto y lo queremos activar poniendo en dicho terminal un valor de ´0´ lógico. El valor que puede tomar IOL, tiene sus limitaciones, las que el diseñador no debe violentar en sus diseños sino quiere correr el riesgo de que el microcontrolador entregue valores de voltaje mayores que los que se corresponden con el ´0´ lógico o en el peor de los casos, cuando este valor esta muy alejado del máximo permisible por encima, el poder dañar el circuito. Este valor máximo de IOL soportado por el terminal del microcontrolador depende de la tecnología de fabricación del mismo y de la versión de microcontrolador con que estemos trabajando por lo que siempre no tendremos otra opción que remitirnos a los datos del fabricante para conocerlo, no obstante, un valor bastante general es,

I OL max = −16mamp con el signo menos hemos querido representar que la corriente entra por el terminal y no sale. En la Figura 5.2.6 se muestra el circuito para conectar el LED al terminal P1.0 y provocar su encendido cuando en dicho bit del Puerto escribimos un ´0´ lógico. Como era de esperar el Cátodo del LED esta conectado al terminal P1.0 a través de la resistencia RL, mientras que el Ánodo esta conectado a VCC de forma tal que cuando en el terminal se imponga el voltaje bajo que caracteriza a VOL, el LED se polarice en directa y conduzca provocando su encendido, mientras que cuando en el terminal se imponga el voltaje alto que caracteriza a VOH el LED se polarice en inversa no conduciendo y apagándose. La función de RL es la misma que en el anterior, la de garantizar un determinado punto de operación al LED cuando se encienda. En este caso la ecuación nos queda,

VCC − VL − I L RL − VOL = 0

Microcontroladores. El 8051 de la INTEL.

193

Escogiendo el mismo punto de operación para cuando el LED este encendido que el del ejemplo anterior, pero, ¿Qué valor de Vol. tomamos? Efectivamente el valor de Vol no es único como ya se vio anteriormente, sino que se encuentra entre un intervalo de valores que dependen de la corriente Iol que entregue la carga al terminal en cuestión. Por su puesto, también depende, del microcontrolador con que estemos trabajando, por lo que les proponemos que procedamos de la misma forma que en el caso anterior, montemos un experimento y determinemos para nuestro microcontrolador cual es la relación existente entre el Vol y la corriente Iol. En este caso les proponemos que monten el circuito de la Figura 5.2.7.

Los datos obtenidos y la ecuación se muestran en la Figura 5.2.8.

Microcontroladores. El 8051 de la INTEL.

194

El objetivo inicial fue el de poder determinar el valor de Vol si la corriente Iol era igual a 10 mamp,

Vol = ((0.02 KΩ )(10mamp )) + (0.02volt ) = 0,22volts Sustituyendo en la ecuación obtenida al aplicar Kirchoff y despejando RL que es lo que queremos calcular obtenemos,

RL =

5Volts − 2.2Volts − 0.22Volts = 256Ω 10mamp

Una vez montado el circuito de la Figura 5.2.6 y sustituido RL por una resistencia cuyo valor sea 256 Ω, cada vez que queramos encender el LED todo lo que tenemos que hacer en nuestro programa es colocar la instrucción, CLR

P1.0

; P1.0

´0´, enciende el LED.

mientras que cuando o queramos apagar la instrucción en este caso será, SETB P1.0

; P1.0

´1´, apagar el LED.

¿Qué sucedería en este caso si el punto de operación necesario para cuando el LED se encienda sea con valor de IOL de 20 mamp?

Microcontroladores. El 8051 de la INTEL.

195

En muchas aplicaciones se hace necesario que la intensidad de la luz con que se encienda el LED sea alta para que se pueda divisar por el usuario. En estos casos no tenemos otra alternativa que aumentar la corriente que circula por el LED cuando esta encendido. Pero ya conocemos que este valor no puede ser todo lo grande que pudiéramos desear en una aplicación dada, sino que existe un límite el que no debe ser propasado por el diseñador en su circuito. En el ejemplo propuesto, si conectamos el LED directamente al terminal P1.0 como se hizo en el circuito de la Figura 5.2.6, nos encontraríamos en ese caso. Efectivamente la corriente por el LED cuando esta encendido y la corriente que entra al microcontrolador por su terminal P1.0 es la misma, por lo que,

I L = 20mamp I L = I OL = 20mamp I OL max = 16mamp I OL > I OL max ¿Cuál sería el circuito en este caso?, ¿Cuál de los dispositivos que conocemos podría venir en nuestra ayuda? Para dar solución al problema planteado nos auxiliaremos de un transistor npn, como podría ser el 2N697, tal y como se muestra en el circuito de la Figura 5.2.9. En este caso un ´1´ en el terminal P1.0 provoca que el transistor T se

sature,

aplicándose

entre

Ánodo y Cátodo del LED el voltaje colector emisor de saturación de un transistor bipolar, 0.2 Volts, con lo que

el

LED

no

conducirá

y

permanecerá apagado. Por el contrario un ´0´, provocará que el transistor T se corte, con lo que el Ánodo del LED queda conectado a VCC a través de la resistencia RC, mientras que el Cátodo estará conectado a tierra, estando el mismo polarizado en directa conduciendo y encendiéndose el LED. La resistencia RC garantiza el punto de operación para cuando el LED se enciende.

Microcontroladores. El 8051 de la INTEL.

RC =

196

VCC − VL 5Volts − 2.2Volts = = 140Ω IL 20mamp

Algo que debe verificar el diseñador es el valor de la corriente que circula por el colector del transistor, IC, cuando el mismo se encuentre saturado, tomando en consideración que la resistencia RC es la calculada anteriormente. Si este valor de IC es menor que la permisible por el transistor escogido, entonces no existe problema y ya tenemos nuestro circuito. De no ser así, se debe escoger otro transistor que soporte una corriente de colector mayor que IL cuando este saturado. Otra posible solución, la que en muchos casos resulta más económica y fiable, la constituye el utilizar uno de los Buffer No Inversores que vienen integrado en el circuito 74HCT125 en sustitución del transistor T, tal y como aparece en la Figura 5.2.10. Ahora

los

20

mamp

que

circulan por el LED cuando esta encendido, no entran al terminal

P1.0

microcontrolador

sino

del a

la

salida de uno de los Buffers No Inversores que integran al CI 74HCT125.

Los Buffers que conforman este circuito, aunque construidos con tecnología de fabricación TTL, soportan el doble de IOL, 32 mamp, antes de deteriorar el valor del ´0´ lógico, por lo que los 20 mamp que entraran al mismo cuando el LED se encienda, en nuestra aplicación, se encuentran por debajo del IOLmax de dicho circuito, lo que no traerá ningún problema. La carga del terminal P1.0 será la entrada del Buffer No Inversor, el que puede ser manejado sin dificultad por el microcontrolador. El Buffer No Inversor tiene salida con posibilidad de poner en tercer estado o estado de alta impedancia. Para ello cada uno de los mismos cuenta con una entrada negada la que en dependencia del valor lógico impuesto en la misma condicionará el estado de la salida, respondiendo a la Tabla de la Verdad que se muestra en la Figura 5.2.11.

Microcontroladores. El 8051 de la INTEL.

197

Es por esto que en el circuito de la Figura 5.2.10 la entrada de Habilitación (H) esta conectada de forma permanente a tierra, o sea, esta de forma permanente a ´0´, para que la salida siempre tenga el mismo valor lógico que el impuesto en su entrada, que no es otro que el valor lógico al que esta el terminal P1.0. Un Puerto puede ser utilizado también como de entrada. En este caso el interés del programador estará en conocer el valor lógico impuesto al terminal correspondiente por un dispositivo externo al microcontrolador. ¿Cuál será la instrucción a utilizar en este caso?, ¿Cómo funcionará todo este circuito cuando se ejecute esta instrucción? En este caso la instrucción a ejecutar debe ser una instrucción de lectura al registro Almacenador del Puerto 1, como podría ser, MOV

A, P1

;A

P1

Al ubicar en la instrucción al registro P1 en la posición que ocupa la localización fuente estamos indicando que la instrucción es de lectura sobre dicho registro, siendo el destino en este caso el registro Acumulador. Ahora cuando el microcontrolador ejecuta la instrucción anterior generará el comando READ PIN para todos los terminales de dicho Puerto, ver Figura 5.2.1, con lo que se habilita el Buffer de Lectura de todos los bits del Puerto, los que dejan pasar el valor que este impuesto en su terminal correspondiente hacia el bus de datos interno del microcontrolador el que lo toma y lo almacena en el registro Acumulador. Observe que los Buffer de Lectura son no inversores, al igual que los que componen el CI 74HCT125 que acabamos de estudiar, por la que el mismo valor lógico impuesto en el terminal, o sea en su entrada, será el impuesto en su salida, constituyendo el que llegará al bit correspondiente en el Bus de Datos interno y por ende al registro Acumulador como destino final. Estos Buffer de Lectura interpretaran que en el terminal correspondiente del Puerto hay un ´0´ lógico, al que llamaremos en este caso VOL, cuando el voltaje aplicado en su entrada, se encuentre entre los valores,

Microcontroladores. El 8051 de la INTEL.

198

0Volts < VIL < 0.8Volts e interpretará que es un ´1´ lógico cuando el voltaje impuesto, al que llamaremos en este caso VIH en su entrada se encuentre entre los valores,

2.0Volts < VIH < 5.5Volts Observe que los intervalos de voltaje tanto para el ´0´ como para el ´1´, son los característicos de la familia de circuitos integrados TTL por lo que circuitos construidos con esta tecnología de fabricación así como los construidos con tecnología de fabricación CMOS pueden conectar directamente sus terminales de salida a los terminales de dicho Puerto.. ¿Quién impone el valor lógico de ´1´ o de ´0´ en el terminal? Por su puesto lo debe imponer un elemento externo conectado al Puerto, como podría ser un conjunto de microinterruptores, como los que aparecen en la Figura 5.2.12 .

En la Figura, ocho microinterruptores que forman parte de un ´Dip Switch´ tienen uno de sus extremos conectados a terminales

diferentes

del

Puerto

1,

mientras que su otro terminal lo tienen todos unidos y conectados a la tierra del circuito.

Un microinterruptor es un dispositivo de dos terminales que puede encontrarse en dos posibles estados durante su operación, abierto y cerrado. Cuando se encuentra abierto la resistencia que existe entre ambos terminales es prácticamente de 0Ω, comportándose como un cortocircuito, por lo que el voltaje aplicado en uno de sus terminales se refleja íntegramente en el otro, mientras que cuando se encuentra abierto la resistencia entre ambos terminales es del orden de los MΩ, comportándose como un circuito abierto, por lo que un terminal se encuentra prácticamente aislado del punto de vista eléctrico del otro.

Microcontroladores. El 8051 de la INTEL.

199 Tomando en consideración lo anterior,

cuando

uno

de

los

microinterruptores de la Figura 5.2.12 se encuentre cerrado es como

si

el

terminal

correspondiente del Puerto 1 se conectara a la tierra del circuito y por lo tanto un valor de voltaje de 0 Volts es aplicado a la entrada del Buffer de Lectura de dicho terminal, lo que es reconocido como un ´0´ lógico, ver Figura 5.2.13.

Cuando se encuentre abierto es como si dicho terminal se encontrara sin

ningún

voltaje

aplicado.

No

obstante, del estudio de la estructura interna de los terminales de este Puerto conocemos que los mismos tienen su salida conectada a la fuente VCC a través de una resistencia RX, esto propiciará que en la entrada del Buffer de Lectura prácticamente este aplicado un voltaje de +5 Volts lo que será reconocido por este como un ´1´ lógico, ver Figura 5.2.14. ¿Por qué utilizamos la expresión de trataría de imponer un ´1´+ lógico? El valor lógico de ´1´ está relacionado con un nivel de voltaje en el terminal que permita al Buffer de Lectura interpretarlo como ´1´. Ya conocemos que para que el Buffer de Lectura interprete que tiene a su entrada un ´1´ el nivel de voltaje aplicado en la misma debe estar por encima de los 2.4 Volts. Pero si observamos la Figura 5.2.14, podemos concluir, para sorpresa nuestra, que el nivel de voltaje en la entrada del Buffer de Lectura no solo depende del valor del voltaje impuesto en el

Microcontroladores. El 8051 de la INTEL.

200

terminal del Puerto, sino que también depende del estado en que se encuentre el transistor MOS de la Etapa de Salida del terminal en cuestión y por lo tanto del valor en que se encuentre la Q/ del Biestable D, que a su vez es una consecuencia del valor lógico almacenado en el bit correspondiente del registro Almacenador del Puerto 1.

Esto es evidente ya que el voltaje en el DRAIN del transistor MOS de la Etapa de Salida se encuentra en AND Alambrado, en el punto A, con

el

voltaje

impuesto

en

el

terminal del Puerto. La salida de este AND Alambrado es el voltaje que llega a la entrada del Buffer de Lectura

del

Puerto,

ver

Figura

5.2.15.

Por lo tanto, si el valor lógico almacenado en el Biestable D es el de ´1´, la Q/ estará a ´0´ lógico y por ende el transistor MOS de la Etapa de Salida estará cortado y el valor de voltaje que se refleja en la entrada del Buffer de Lectura será igual al impuesto en el terminal y por lo tanto todo lo que vimos en las Figuras 5.2.13 y 5.2.14 es valido, pero ¿Que sucede si el valor almacenado en el Biestable D es el de ´0´ lógico? Si el valor almacenado es el de ´0´ lógico, la Q/ estaría en ´1´ lógico y con ello el transistor MOS de salida estaría saturado apareciendo un voltaje en el DRAIN de dicho transistor con respecto a tierra de aproximadamente 0.2 Volts. En un AND Alambrado el voltaje de salida será siempre el menor de los voltajes aplicados en las entradas del mismo, de hay su nombre, comportándose como una compuerta AND. Basta con que uno de los voltajes de entrada sea bajo, ´0´, para que a la salida obtengamos un voltaje bajo, ´0´.

Microcontroladores. El 8051 de la INTEL.

201

Por

lo

tanto

en

esta

situación

independientemente

del

voltaje

aplicado

terminal

del

voltaje

bajo

en

el

microcontrolador,

el

impuesto por el transistor MOS de la Etapa de Salida condiciona el voltaje de salida del AND Alambrado como un voltaje bajo, 0,2 Volts, que será el voltaje que llegará a la entrada del Buffer de Lectura del terminal, el que interpretará en todo momento que en el terminal

de

entrada

esta

siendo

aplicado un ´0´ lógico, ver Figura 5.2.15. Es por esto que cuando se vaya a utilizar el Puerto 1 completo o un bit de este como de entrada, el bit correspondiente del registro Almacenador tiene que tener almacenado un ´1´ lógico. Esta conclusión es valida para todos los Puertos del 8051, no solo para el Puerto 1. De esta tarea se debe ocupar el programador mediante una instrucción en su Programa. Observe que no existe un registro interno del microcontrolador donde usted seleccione si el Puerto o el bit en cuestión usted lo va a trabajar como de entrada o de salida como ocurre en otros microcontroladores, sino que es su responsabilidad en cada momento en el programa conocer como esta trabajando el Puerto o el bit y a partir de esto ser consecuente en el trabajo. Por suerte dos aspectos vienen en nuestra ayuda en este caso, •

En la mayoría de las aplicaciones, los Puertos que comienzan como de entrada son siempre de entrada y lo mismo con los de salida. Esto nos evita estar cambiando constantemente.



Con la activación del RESET, todos los bits de los Puertos del 8051 se cargan con ´1´ lógico quedando preparados para trabajar como de entrada.

Si regresamos al inicio del estudio del Puerto 1 y observamos la Figura 5.2.1 nos podrían surgir la siguiente pregunta,

Microcontroladores. El 8051 de la INTEL.

202

¿Qué diferencia existe entre el Buffer de Lectura del terminal y el Buffer de Lectura del Biestable? Una primera diferencia esta dada porque la entrada a ambos Buffer de Lectura no son las mismas. Al Buffer de Lectura del Terminal entra directamente el voltaje presente en el terminal externo del Puerto, siempre que en el Biestable D se encuentre almacenado un ´1´ lógico, siendo al que nos hemos estado refiriendo hasta ahora. Mientras que al Buffer de Lectura del Biestable entra, como su nombre lo indica, la salida Q del Biestable. Observe además que ambos Buffer de Lectura son no invasores y tercer estado, teniendo señales de habilitación diferentes, aunque la salida de ambos se unen en el bit del Bus de Datos interno correspondiente. Para el Buffer de Lectura del Terminal la señal de habilitación es la señal READ PIN, mientras que para el Buffer de Lectura del Biestable la señal de habilitación es la señal READ LATCH. Por lo tanto cuando el microcontrolador genere READ LATCH será la salida Q del Biestable la que impondrá el valor lógico en el bit correspondiente del Bus de Datos interno, mientras que cuando el microcontrolador genere la señal READ PIN será el voltaje impuesto en el terminal correspondiente el que impondrán el valor lógico en el bit del Bus de Datos interno. ¿En que puede ser útil esta diferenciación? Primero, si el Puerto esta siendo utilizado como de salida ambas lecturas, las del Buffer de Lectura del Terminal y la del Buffer de Lectura del Biestable, deben dar el mismo valor. Mientras que si el Puerto esta siendo utilizado como de entrada, la lectura del Biestable D es conocida de antemano y tiene que ser ´1´ lógico. ¿Cual es entonces la razón de ambos Buffer? Existen un conjunto de instrucciones que antes de modificar el valor de un bit cualquiera del registro Almacenador del Puerto deben efectuar su lectura. Estas instrucciones se conocen con el nombre de ´read (lee) – modif.(modifica) – write(escribe)´ y son las que generan el comando READ LATCH en lugar de generar el comando READ PIN, con lo que se leería el valor almacenado en el Biestable y no en el Terminal. Por lo tanto las instrucciones de este tipo trabajan con el valor almacenado en el Biestable y no con el valor impuesto en el Terminal. Ejemplo de estas instrucciones son, ANL, ORL, XRL, JBC, CPL, INC, DEC, DJNZ, CLR, SETB, cuando uno de sus operandos constituye uno de los Puertos. Veamos a modo de ejemplo la instrucción

Microcontroladores. El 8051 de la INTEL. ANL

203

P1, #11110000b

Esta instrucción ejecuta el AND lógico entre los bits del registro Almacenador P1 y los bits del número binario declarado en la propia instrucción. El resultado se almacena en el registro Almacenador P1. (P1)

(P1) AND 11110000B

Esta es una instrucción del tipo ´read – modify. – write´ por lo que para su ejecución el microcontrolador primero debe leer (read) el contenido del registro Almacenador P1 y para ello este genera el comando READ LATCH, posteriormente ejecuta el AND con la constante declarada en la instrucción (modify) y por último escribe el resultado en el registro Almacenador P1 (write). ¿Por qué no se lee directamente el Terminal del Puerto y se lee el valor almacenado en el Biestable si ambos valores deben ser iguales? Existe la posibilidad de que en una aplicación a uno de los terminales del microcontrolador que este siendo utilizado como de salida, se conecte algún elemento externo que, debido a la corriente que demanda cuando se escribe un ´1´, provoque que el voltaje que se impone en el terminal caiga a un valor VIh menor que, el mínimo permisible por el Buffer de Lectura el Terminal. En esta situación cuando se vaya a ejecutar la instrucción del tipo ´read – modify. – write´ el valor leído en dicho bit será erróneo. Sin embargo si la lectura se efectúa sobre el valor almacenado en el Biestable a través del Buffer de Lectura del Biestable, la lectura siempre será correcta independientemente de la carga conectada al terminal del Puerto. Veamos lo anterior a la luz del siguiente ejemplo. Ejemplo 5.1. Un dispositivo se encuentra conectado al terminal P1.0 del microcontrolador 8051 y se activa su funcionamiento cuando dicho terminal se encuentra en ´1´ y estará desactivado cuando dicho terminal se encuentre en ´0´. El dispositivo cuando esta activado representa una carga para el microcontrolador de 150 mamp., necesitando un voltaje de 1.0 volts. Haga una Subrutina que cada vez que se invoque cambie el estado en que se encuentra dicho dispositivo. En la Figura 5.2.16 se muestra el circuito donde aparece el dispositivo conectado al terminal P1.0. Como en el texto del ejemplo no se especifica cual es el dispositivo, lo hemos representado por una caja a la que hemos llamado CARGA.

Microcontroladores. El 8051 de la INTEL.

204 La resistencia RL, como ya conocemos, se encuentra en el circuito con el objetivo de

imponer

el

punto

de

operación

deseado para la CARGA cuando se encuentre activa. En la Figura 5.2.16 se muestra el estado de interés en este ejemplo que es cuando el terminal de salida se encuentra en ´1´. Aplicando Kirchoff en la malla donde se encuentra la CARGA obtenemos,

Voh = ((I oh )(RL )) + VCARGA Despejando de esta expresión el valor de RL que es el que nos interesa calcular nos queda,

RL =

Voh − VCARGA I oh

Para poder determinar el valor de RL se nos hace necesario conocer cual es el valor del Voh que entrega el microcontrolador por su terminal P1.0 cuando se le extrae una Ioh igual a 150 mamp. Para ello recurrimos a la característica de salida de los terminales del Puerto 1 cuando están en ´1´, ver Figura 5.2.4, para tomar la ecuación que relaciona el Voh con el Ioh.

Voh = −((0.02 KΩ )(I oh ) + 4.99volts ) Sustituyendo el valor de Ioh para cuando la CARGA se encuentra activa nos queda,

Voh = −((0.02 KΩ )(150mamp ) + 4.99volts = 1.99volts ) Con este valor ya estamos listo para calcular el valor de RL necesario,

RL =

1.99volts − 1.0volts = 6.66Ω 150mamp

Una vez sustituida la resistencia RL que aparece en el circuito de la Figura 5.2.16 por una resistencia cuyo valor sea el calculado, cada vez que escribimos un ´1´ en el terminal P1.0 la CARGA se activará en el punto de operación deseado y cuando se escriba un ´0´ dicha CARGA se desactivará.

Microcontroladores. El 8051 de la INTEL.

205

Esta no fue la tarea que se nos asigno en el texto del ejemplo, sino, la de hacer una Subrutina que cada vez que sea invocada provoque el cambio de estado de la CARGA. Para ello, la dicha Subrutina, debe provocar el cambio del estado lógico en que se encuentre el bit del registro Almacenador del terminal P1.0 cada vez que es invocada. En otras palabras, quizás un tanto más sencillas, •

Si el bit del registro Almacenador del terminal P1.0 se encuentra el ´0´, pasarlo a ´1´.



Si el bit del registro Almacenador del terminal P1.0 se encuentra el ´1´, pasarlo a ´0´.

Esto lo podríamos hacer, primero preguntando por el estado lógico en que se encuentra el bit del registro Almacenador P1.0 con el objetivo de, en dependencia de dicho valor tomar la decisión de escribir un ´0´ o un ´1´ en dicho bit. La Subrutina que responde a este algoritmo sería la siguiente, ; Subrutina que cambia de estado lógico al bit del registro Almacenador P1.0 ; cada vez que es invocada. ; la Subrutina se llama cambiaP10 cambiaP10:

jb

P1.0, diurno

; salta a dirurno si esta en ´1´ P1.0

setb

P1.0

, pone a ´1´ al bit P1.0

sjmp

salir

; buscar salida de la Subrutina

P1.0

; pone a ´0´ al bit P1.0.

; P1.0 esta en ´0´.

; P1.0 esta en ´1´. diurno:

clr

salir:

ret

; retorno al programa principal

Una forma quizás un poco más abstracta pero que ocupa menos espacio en la memoria de programa podría ser la que se muestra a continuación. ; Subrutina que cambia de estado lógico al bit del registro Almacenador P1.0 ; cada vez que es invocada. ; la Subrutina se llama cambiaP10 cambiap10:

xrl

P1, #00000001b

; cambia el estado del bit 0 del Puerto 1 ; el resto de los bits quedan como estaban.

ret Esta instrucción, xrl

P1, #00000001b

; retorno al programa principal.

Microcontroladores. El 8051 de la INTEL.

206

efectúa el OR Exclusivo de todos los bits del Puerto 1 con los bits del número 00000001b declarados en la propia instrucción. Esto debe provocar que los bits del 1 al 7 del registro Almacenador P1 se mantengan en el valor que tenían, mientras que el bit 0 cambia, que es lo que queremos que haga nuestra Subrutina. ¿Por qué fue este el número escogido por nosotros para efectuar el OR Exclusivo con el registro Almacenador del Puerto 1? Para poder dar respuesta a la pregunta anterior remitámonos a la Tabla de la Verdad de la función lógica OR Exclusivo, la que se muestra en la Figura 5.2. 17.

Observe de la Tabla de la Verdad que siempre que las dos entradas sean iguales la salida será ´0´ mientras que cuando las dos entradas sean diferentes la salida será ´1´.

Por lo tanto, aquel bit que queramos cambiar su estado mediante esta instrucción, debemos provocar que haga el OR Exclusivo con el digito binario ´1´, ya que si se encontraba en ´0´ pasara a ´1´ y viceversa si se encontraba en ´1´ pasará a ´0´. Por el contrarío, si queremos que el bit no cambie de estado producto de la ejecución de esta instrucción, debemos provocar que haga el OR Exclusivo con el digito binario ´0´, ya que si se encontraba en ´0´ permanecerá en ´0´ y si se encontraba en ´1´ permanecerá en ´1´. Como que en el ejemplo, el bit que queremos que cambie es el bit 0, en el número declarado en la instrucción en la posición de dicho bit ubicamos un ´1´, mientras que como queremos que el resto de los bits no cambie, en el resto de los bits del número declarado en la instrucción colocamos ´0´. La instrucción, xrl

P1, #00000001b

es una instrucción del tipo ´read – modif. – write´, que como ya conocemos, para ejecutarla el microcontrolador primero lee (read) el contenido del registro Almacenador P1, posteriormente efectúa el OR Exclusivo entre este registro y el numero declarado en la instrucción (modify) y finalmente escribe (write) el resultado en le registro Almacenador P1.

Microcontroladores. El 8051 de la INTEL. ¿Que sucedería, en este caso,

207

si el microcontrolador en lugar de leer en el Biestable

correspondiente al bit P1.0 en el registro Almacenador P1, leyera directamente del terminal P1.0? Analizar esto es el objetivo que perseguimos con este ejemplo. Si el microcontrolador para efectuar esta instrucción leyera el estado lógico del terminal P1.0 generaría la señal READ PIN con lo que se habilitaría el Buffer de Lectura del Terminal, ver Figura 5.2.18.

El voltaje que estaría aplicado a la entrada del Buffer de Lectura del Terminal, en este caso, cuando este se encuentre en ´1´, será de 1,99 volts como ya lo habíamos calculado anteriormente dentro de la resolución del propio ejemplo, no llegando al voltaje de uno mínimo (Vohmin) a aplicar a la entrada de dicho Buffer para que este pueda interpretar que tiene aplicado un ´1´. Esto provocaría una lectura errónea de este bit por parte del microcontrolador al efectuar la lectura del mismo, interpretando como un ´0´ lo que realmente debió haber sido la lectura de un ´1´. Al efectuar el OR Exclusivo con el ´1´ ubicado en el bit 0 del numero declarado en la propia instrucción, dará como resultado ´1´, no cambiando el estado que previamente estaba almacenado en el Biestable del terminal,

escribiendo nuevamente este valor en el bit 0 del registro

Almacenador P1 manteniendo a la carga activada, no ejecutándose lo esperado. Por suerte, el microcontrolador lee el Buffer de Lectura del Biestable generando en este caso la señal READ LATCH en lugar de la señal READ PIN. Ahora, el valor lógico leído será el almacenado en los Biestables del registro Almacenador, independizando esta lectura del Voh y de la corriente que demande la CARGA. Esta es la razón fundamental de la existencia del Buffer de Lectura del Biestable. Ahora al efectuar la lectura, el microcontrolador leerá de forma correcta el

Microcontroladores. El 8051 de la INTEL.

208

último valor escrito en el Biestable y por lo tanto el resultado de efectuar el OR Exclusivo será el esperado. A modo de resumen, •

El microcontrolador generara un comando del tipo READ PIN provocando la habilitación del Buffer de Lectura del Terminal, cada vez que ejecute una instrucción de lectura del Puerto. Ejemplo de este tipo de instrucciones son las del tipo MOV con el Puerto 1 ubicado en la posición del operando fuente.



Mientras que generará un comando del tipo READ LATCH provocando la habilitación del Buffer de Lectura del Biestable, cada vez que ejecute una instrucción del tipo ´read – modiy - write´.

5.3 El Puerto 3. En la Figura 5.3.1 se muestra la estructura interna del Puerto 3. Observe la similitud de uno cualquiera de los bits de este Puerto con los del Puerto 1. Como aspectos diferentes solo se encuentran: •

La

señal

FUNCION

DE

SALIDA ALTERNATIVA. •

La

señal

FUNCION

DE

ENTRADA ALTERNATIVA •

Una compuerta NAND de 2 entradas colocada entre la salida Q del Biestable y el transistor MOS de la Etapa de Salida.



La existencia de un Buffer No Inversor

ubicado

entre

el

terminal del Puerto y el Buffer de Lectura del Terminal. La pregunta a responder en este momento sería, ¿Qué son las FUNCIONES ALTERNATIVAS?

Microcontroladores. El 8051 de la INTEL.

209

Integrados en el 8051 se encuentran algunos dispositivos que le dan potencialidad y lo caracterizan como un microcontrolador. Estos dispositivos, a los que hemos llamados Circuitos Complementarios, son: •

Dos Temporizadores.



Un Puerto Serie Asincrónico Full – Duplex.



Un Controlador de Interrupción.

Estos dispositivos necesitaban tener habilitados algunos terminales que le permitan comunicarse con el exterior, por ejemplo, •

A cada Temporizador le es necesario contar con un terminal por donde le lleguen los pulsos a contar, cuando este funcione como Contador. Estos terminales se conocen con el nombre de Terminales de Entrada de Conteo, por lo que, para el 8051 se hacen necesarios dos terminales de entrada de conteo para los Temporizadores.



Dado que el Puerto Serie es full – duplex, o sea, esta habilitado para recibir y transmitir datos en serie de forma simultanea, se hacen necesario dos terminales, uno para ser empleado uno como de entrada de datos serie y el otro como de salida de datos serie.



El microcontrolador esta habilitado para poder atender el pedido de dos requerimientos de atención por Interrupción externos por lo que se hace necesario destinar dos terminales más para este empeño, que serán entradas al Controlador de Interrupción.

No obstante, no en todas las aplicaciones se utilizan todas estas señales, ya que su empleo no es imprescindible para la operación del microcontrolador, como lo son las señales de RESET, VCC, etc., por lo que su uso depende mucho de cada aplicación, es más depende de cómo el diseñador resuelva su aplicación. De ahí que a estas señales se le haya dado el nombre de FUNCIONES ALTERNATIVAS. Pero si bien, en alguna aplicación puede ocurrir que no se utilice ninguna de las FUNCIONES ALTERNATIVAS, puede ser que en otras se necesiten utilizar todas, por lo que estas señales deben estar al alcance del diseñador para ser utilizadas en su diseño. Pero si observamos los terminales ya estudiados del microcontrolador en su encapsulado de 40 terminales solo quedan disponibles dos, el 29 y el 30, lo que no cubre las necesidades de terminales, 6, FUNCIONES ALTERNATIVAS. ¿Cómo resolvieron esta aparente limitación los fabricantes?

de estas

Microcontroladores. El 8051 de la INTEL.

210

Los fabricantes ante la disyuntiva de mantener el encapsulado del Circuito Integrado del microcontrolador en el hasta ese momento chip de 40 terminales, común con los microprocesadores de aquellos tiempos, se vieron en la necesidad de hacer compartir a determinadas señales el mismo terminal. Para esto escogieron a los terminales del Puerto 3, ver Figura 5.3.2. RxD: entrada de datos serie al Puerto Serie interno. TxD: .salida de datos serie del Puerto Serie interno. INT0/: entrada de solicitud de Interrupción externa 0. INT1/: entrada de solicitud de Interrupción externa 1. T0: entrada de conteo al Temporizador 0. T1: entrada de conteo al Temporizador 1.

Observe que algunas de las FUNCIONES ALTERNATIVAS del Puerto 3 son de entrada y otras son de salida, por lo que en el esquema de la Figura 5.3.1 hemos hecho una representación genérica que se ajusta a cualquier terminal de dicho Puerto. Para poder representar esquemáticamente un terminal en particular debemos especificar si con lo que cuenta es con una señal del tipo FUNCIÓN DE SALIDA ALTERNATIVA y por lo tanto no contará con la bifurcación a la salida del primer buffer de entrada o contará con una señal del tipo FUNCIÓN DE ENTRADA ALTERNATIVA y por lo tanto la entrada al NAND estará fija a ´1´ lógico. A modo de ejemplo mostramos en la Figura 5.3.3 (a) y (b) respectivamente, los casos de los terminales P3.0 con su FUNCIÓN DE ENTRADA ALERNATIVA, RxD y a P3.1 con su FUNCIÓN DE SALIDA ALTERNATIVA, TxD. Observe que se corresponden con las dos señales externas que le son necesarias al Puerto Serie para poder ser full – Duplex.

Microcontroladores. El 8051 de la INTEL.

211

El utilizar el Pin del microcontrolador como una de las FUNCIONES ALTERNATIVAS o como uno de los terminales del Puerto en su aplicación es una decisión del diseñador y no hace falta programar ningún registro para asignarle al Pin una de las dos funciones. Por ejemplo, si en una aplicación dada se hace necesario comunicar el equipo diseñado en base al microcontrolador con una Microcomputadora, de seguro que el diseñador tomará la decisión de establecer dicha comunicación aprovechando uno de los Puertos Serie de la Microcomputadora, COM1, COM2, etc. De ser esta la decisión tomada, lo más sensato será utilizar al Puerto Serie interno del microcontrolador para esta tarea y por ende el terminal P3.0 hará la función de RxD y por el llegaran al microcontrolador los datos serie provenientes de la Microcomputadora y el terminal P3.1 hará la función de TxD y por este el microcontrolador enviara los datos serie hacia la Microcomputadora. Algo similar ocurrirá con los terminales P3.2 y P3.3 si el diseñador decide utilizar las fuentes de Interrupción Externa, INT0 e INT1 para la atención de algún dispositivo y con P3.4 y P3.5 si el diseñador decide utilizar los Temporizadores como contadores de eventos que estén ocurriendo fuera del microcontrolador. Cada una de estas FUNCIONES ALTERNATIVAS serán estudiadas a profundidad más adelante en este material cuando se estudien con detenimiento los Circuitos Complementarios del 8051, no obstante, si queremos dejar algo claro y es la razón por la que hemos tocado este aspecto en este momento, si usted decide utilizar alguna de la FUNCIONES ALTERNATIVAS en su diseño, garantice que este en ´1´ lógico el Biestable correspondiente al terminal de dicha función, sea de entrada o de salida.

Microcontroladores. El 8051 de la INTEL.

212

Analicemos lo expresado anteriormente de forma independiente para los Terminales que tiene FUNCIONES ALTERNATIVAS de entrada y para los que tienen FUNCIONES ALTERNATIVAS de salida. Para ello retomemos el ejemplo anterior y analicemos que sucede con los terminales que comparten las funciones con los bits del Puerto 3, P3.0 y P3.1 con RxD y TxD respectivamente. En la Figura 5.3.4 se muestra el estado de cada uno de los elementos que conforman el Pin 10 del microcontrolador, el que es compartido por P3.0 y RxD, cuando en el Biestable correspondiente se escribe un ´0´.

Si observamos la Figura 5.3.4, notaremos que la salida Q del Biestable esta conectada a una de las entradas de la compuerta NAND, la que tendrá su otra entrada fija a ´1´ al acoger este terminal una FUNCIÖN ALTERNATIVA DE ENTRADA, en este caso RxD. Si el Biestable tiene almacenado un ´0´ lógico, la salida del NAND estará a ´1´ la que saturará al transistor MOS de la Etapa de Salida con lo que el valor del voltaje a la salida del AND Alambrado formado en el punto A por el voltaje del DRAIN de dicho transistor y de la señal que envía la Microcomputadora y que llega al microcontrolador a través de RxD, siempre será el impuesto por el transistor MOS saturado independientemente del valor del voltaje que llegue de la Microcomputadora como consecuencia de la llegada de los datos series transmitidos por esta. Esto hace que a la entrada del Buffer siempre haya aplicado un ´0´ y por lo tanto al Puerto Serie del microcontrolador siempre estarán llegando ´0´ y no se podrá establecer correctamente la comunicación.

Microcontroladores. El 8051 de la INTEL.

213

Por su parte, en la Figura 5.3.5 se muestra el estado de cada uno de los elementos que conforman el Pin 11del microcontrolador, el que es compartido por P3.1 y TxD, cuando en el Biestable correspondiente se escribe un ´0´.

Nuevamente una de las entradas del NAND esta en ´0´ y por lo tanto su salida estará siempre en ´1´ independientemente del dato que el programa este transmitiendo a través de la línea TxD del Puerto Serie del microcontrolador. Esto provocará que siempre el transistor MOS de la Etapa de Salida este saturado y por ende el microcontrolador por su terminal 11 siempre estará enviando ´0. Por suerte con la activación del RESET en todos los Biestables del Puerto 3 se almacenan el un ´1´, por lo que quedan listos para que se puedan utilizar las FUNCIONES ALTERNATIVAS que sean necesarias. Con respecto al terminal como un bit del Puerto 3, todo lo que se explico para los terminales del Puerto 1 es valido en este caso y por lo tanto las mismas ecuaciones y características de salida con que trabajamos aquel Puerto pueden ser utilizadas para trabajar con este Puerto también. 5.4 El Puerto 2. Después de haber estudiado el Puerto 3, quizás una de las primeras preguntas que ustedes se deben estar haciendo es, ¿Tendrán FUNCIONES ALTERNATIVAS los terminales de este Puerto?

Microcontroladores. El 8051 de la INTEL.

214

De tenerlas, ¿Cuáles serán? Les propongo comenzar analizando los nombres que reciben los terminales de este Puerto para ver si encontramos algo que nos pueda ayudar a darle respuesta a estas dos preguntas, ver Figura 5.4.1. Como podemos ver de la Figura, los terminales destinados para que los bits del Puerto 2 salgan al exterior son los enumerados del 21 al 28 del microcontrolador, correspondiendo al terminal 21 el bit menos significativo del Puerto y al terminal 28 el bit más significativo. Observemos también que en cada terminal, acompañando al nombre del bit del Puerto 2 correspondiente,

aparece

otro

nombre

caracterizado por la letra A y un número de consecutivo que van del 8 al 15. ¿Qué representará esta A con un número en el nombre del terminal del Puerto? Una de las características del 8051 es el de presentar un Modo Especial de Trabajo en el que se comporta como un microprocesador de 8 bits al estilo del 8080, 8085 o Z80. En este Modo Especial de Trabajo al 8051 se le pueden conectar dispositivos externos, como pueden ser memorias, puertos programables u otro tipo de dispositivos que se fabrican específicamente para su conexión con los microprocesadores antes mencionados. Esto impone la necesidad de que el 8051 tenga que sacar al exterior sus Buses de Datos, Direcciones y de Control internos, para poder recibir o enviar los datos desde o hacia estos dispositivos externos, para poder generar las direcciones que permiten seleccionar el dispositivo con que se quiere trabajar y para poder enviar las señales de comando que permitan sincronizar las operaciones entre estos dispositivos y el microcontrolador. Dos de estas señales, las que se corresponden con las señales del Bus de Control que salen externamente, constituyen FUNCIONES ALTERNATIVAS del Puerto 3, que no las estudiamos en aquel momento porque nos parecía que no estaban creadas las condiciones para su comprensión por parte de ustedes. Efectivamente si ustedes observan la Figura 5.3.2 verán que dos de los terminales de dicho Puerto, los correspondientes a los bits P3.6 y P3.7, no tenían asociados

Microcontroladores. El 8051 de la INTEL.

215

FUNCIONES ALTERNATIVAS, sin embargo, si las tienen recibiendo el nombre de WR/ y RD/ respectivamente.

La señal WR/ es la que genera el microcontrolador para

sincronizar

con

el

dispositivo

externo

seleccionado las operaciones de escritura, mientras que, RD/ es la señal que genera el microcontrolador para sincronizar con el dispositivo seleccionado las operaciones de lectura. En la Figura 5.4.2 se muestra de forma completa al Puerto 3.

Como conocemos este microcontrolador es de 8 bits, de ahí que sus registros internos sean de 8 bits, que su memoria interna este organiza en localizaciones de 8 bits y que su Unidad Aritmético y Lógica este preparada para efectuar operaciones en las que intervienen operandos de 8 bits. Todo esto condiciona la necesidad de un Bus de Datos internos también de 8 bits por donde se muevan los datos dentro del microcontrolador de un lugar al otro. La prolongación de este Bus de Datos interno es lo que constituye el Bus de Datos externo de este microcontrolador a través del cual se mueven, como su nombre o indica, los datos entre el microcontrolador y los dispositivos que le son conectados externamente cuando este esta trabajando en el Modo Especial de Trabajo y por lo tanto su ancho también es de 8 bits. Cuando se definimos las características básicas de este microcontrolador en el epígrafe 2.1 del Tema 2 se planteo, •

Modo Especial de Trabajo en el que se le pueden conectar al sistema de forma externa hasta 64 Kilobyte de Memoria de Programas y 64 Kilobyte de Memoria de Datos.

Para poder conectar 64 Kilobyte de localizaciones de memoria diferentes al microcontrolador, este tiene que tener la capacidad de generar un numero igual de direcciones diferentes, una por cada localización de memoria, que será la que el envié al exterior a través del Bus de Direcciones externo cuando desea trabajar con una cualquiera de ellas. De lo anterior podemos sacar dos conclusiones:

Microcontroladores. El 8051 de la INTEL. •

216

Para poder generar 64 Kilo direcciones diferentes se necesitan 16 bits,

216 = 65535 = 64 K •

El Bus de Direcciones externo que saca este microcontrolador cuando trabaja en el Modo Especial de Trabajo es de 16 bits.

Ya conocemos por donde saca el microcontrolador las dos señales que conforman el Bus de Control externo de este cuando trabaja en el Modo Especial de Trabajo, pero, ¿Por qué terminales del microcontrolador se prolongan hacia el exterior las 8 líneas del Bus de Datos interno?, ¿Por qué terminales del microcontrolador se prolongan hacia el exterior las 16 líneas del Bus de Direcciones? Para nuestra tranquilidad, los Puertos 2 y 0, que aun no hemos estudiado, son los encargados de soportar estas dos funciones, por lo que no hay ningún otro cambio con respecto a lo estudiado anteriormente en los Puertos 1 y 3. Les propongo, concentrarnos en el Puerto 2 que es el que estamos estudiando en este epígrafe y veamos cuales de los buses se prolonga a través de el. Las líneas del Bus de Datos se acostumbran a identificar mediante la letra D, inicial de la palabra Data, mientras que las líneas del Bus de Direcciones se acostumbran a identificar mediante la letra A, inicial de la palabra Address. Un número siempre acompaña a la letra en cuestión, el que indica la posición que ocupa un bit en particular dentro del Bus. Por ejemplo si el Bus de Datos es de 8 bits, como el que nos ocupa, el bit menos significativo recibe el nombre de D0, mientras que el bit mas significativo recibe el nombre de D7, el resto de los bits reciben el nombre de D1, D2, D3, D4, D5 y D6. Algo similar ocurre con los nombres que reciben las líneas propias del Bus de Direcciones. Por ejemplo si el Bus de Direcciones es de 16 bits, como el que nos ocupa, el bit menos significativo recibirá el nombre de A0 y el más significativo el nombre de A15, el resto de los bits recibirán el nombre desde A1 hasta A14 consecutivamente. Con estos elementos observemos en la Figura 5.4.1 el nombre que reciben los terminales del Puerto 2. Además del que les corresponde por ser bit de un Puerto, el segundo nombre de cada terminal comienza con la letra A por lo que se corresponden con líneas del Bus de Direcciones externo del microcontrolador. Los números del 8 al 15 que acompañan a letra A en cada uno de los terminales de este Puerto indican que a través de ellos el microcontrolador saca los 8 bits más significativo de la dirección cuando esta trabajando en el Modo Especial de Trabajo, constituyendo estas las FUNCIONES ALTERNATIVAS de este Puerto.

Microcontroladores. El 8051 de la INTEL.

217

En la Figura 5.4.3 se muestra la estructura interna de uno de los bits con conforman al Puerto 2.

Observe de la Figura, que al Multiplexor, MUX, llegan como entradas Biestable

la

salida

Q

del

del

registro

Almacenador del Puerto 2 y la señal del Bus de Direcciones interno

correspondiente

al

terminal en cuestión, siendo la salida la que controla el estado del transistor MOS de la Etapa de Salida después de pasar por una compuerta inversora.

Este Multiplexor es controlado por la señal CONTROL generada por el microcontrolador en dependencia de la operación que este ejecutando. Si el microcontrolador esta ejecutando una operación con un dispositivo conectado externamente a sus buses en el Modo Especial de Trabajo, la señal CONTROL provocará que la línea correspondiente al bit del Bus de Direcciones interno sea la que se conecte a la salida del Multiplexor imponiendo su valor en el terminal de salida haciendo que los terminales destinados al Puerto 2 hagan la función de Bus de Direcciones externo. En cualquier otro caso, será la salida Q del Biestable la que se conectará a la salida del Multiplexor imponiendo esta el valor en el terminal, haciendo que los terminales destinados al Puerto 2 hagan la función de entrada o salida del Puerto. ¿Será necesario en este caso, como en el anterior, tener almacenado en el Biestable un ´1´ para que pueda la dirección como FUNCION ALTERNATIVA imponer su valor en el terminal? En este caso la respuesta es no, ya que cuando la señal CONTROL selecciona a la línea del Bus de Direcciones interna para que imponga su valor en el terminal del Puerto, el valor de la Q del Biestable queda aislado, no afectando el valor que toma la salida del Multiplexor y con ello del terminal. No obstante, si usted va a utilizar al Puerto 2 o a cualquiera de sus bits como entrada, si es imprescindible que la Q del Biestable correspondiente se encuentre a ´1´ como en los dos Puertos anteriores.

Microcontroladores. El 8051 de la INTEL.

218

Observe que la Etapa de Salida de los terminales de este puerto son iguales que las del Puerto 1 ya estudiado, por lo que todo lo que se vio cuando estudiamos el mismo es valido para el Puerto2 cuando trabaja como puerto de entrada / salida. Ya conocemos por donde salen los 8 bits más significativos de los 16 que conforman el Bus de Direcciones externo del microcontrolador cuando este esta trabajando en el Modo Especial de Trabajo, pero ¿Por donde salen el resto de los bits del Bus de Direcciones externo en este Modo de trabajo?, ¿Por donde salen o entran los 8 bits del Bus de Datos externo de este microcontrolador en este Modo de trabajo? Aunque todavía no nos proponemos estudiar a profundidad al 8051 en el Modo Especial de Trabajo al que le dedicaremos un Tema completo más adelante, al estudiar el Puerto 0 le podremos dar respuesta a las dos preguntas anteriores. 5.5 El Puerto 0. Este Puerto constituye el último que nos queda por estudiar de los 4 que contiene el 8051, por lo que todas aquellas señales que aún no le hemos encontrado un terminal por donde salir al exterior tienen que hacerlo a través de los terminales destinados para este puerto. Estamos hablando de las 8 líneas del Bus de Datos externo y de las 8 líneas del Bus de Direcciones externo que aun faltan, las que comparten con los bits del Puerto 0 los terminales del 32 al 39 del microcontrolador. Pero, estamos hablando de 8 bits para dirección, más 8 bits para datos, mas 8 bits para el puerto y solo contamos con 8 terminales disponibles en el microcontrolador, ¿Como los fabricantes resolvieron este problema? Les propongo que primero conozcamos el nombre que reciben cada uno de estos terminales, los que aparecen en la Figura 5.5.1, para poco a poco ir dándole respuesta a la pregunta anterior.

Microcontroladores. El 8051 de la INTEL.

219 De la Figura podemos observar que el primer nombre que recibe el terminal es el que caracteriza al bit del Puerto 0 que sale por el, mientras que el segundo

nombre,

como

ya

estábamos

acostumbrados de los Puertos 3 y 2, identifica a la FUNCION ALTERNATIVA que soporta. En este caso, este segundo nombre lo conforman dos letras y un número. Las letras son la A (Addrees) y la segunda letra es la D (Data), lo que nos indica que conjuntamente con el bit del Puerto 0 cada uno de los terminales es compartido con un bit del Bus de Direcciones y con un bit del Bus de Datos. Efectivamente el nombre AD0 que acompaña al P0.0 en el terminal 39, nos esta indicando que por este terminal salen al exterior el bit 0 del Bus de Datos y el bit 0 del Bus de Direcciones conjuntamente con el bit 0 del Puerto 0. Así podríamos hacer para los restantes 7 terminales, del 32 al 38, hasta completar el número de 8 que quedaban disponibles al comenzar el estudio de este epígrafe. Intentando resumir podemos plantear, que los 8 bits del Bus de Datos (D0-D7), más los 8 bits menos significativo del Bus de Direcciones (A0-A7), más los 8 bits del Puerto 0 comparten los mismos terminales en el microcontrolador, pero, ¿Cómo puede ser esto? Ya conocemos que este microcontrolador tiene un Modo Especial de Trabajo en el que se le pueden conectar diferentes dispositivos externamente, como pueden ser memorias, puertos de entrada / salida programables y no programables, conversores A/D, conversores D/A, etc. Usted me podría decir que en el modo normal de trabajo, a través de los bits de los puertos, también se pueden conectar estos dispositivos, entonces, ¿Qué tiene de particular este Modo Especial de Trabajo? La particularidad esta en que este modo de trabajo fue concebido por los fabricantes del 8051 para ser utilizados en aquellas aplicaciones donde se hacia falta ampliar las potencialidades del mismo en cuanto a:

Microcontroladores. El 8051 de la INTEL. •

Capacidad de almacenamiento de Programas.



Capacidad de almacenamiento de Datos.



Número de líneas destinadas para la entrada y/o salida de datos.



El numero de circuitos complementarios.



Agregar nuevos circuitos complementarios.

220

Para ello INTEL escogió la filosofía de que en estos casos el microcontrolador generara su propio bus externo (dirección, datos y control) para la comunicación con estos dispositivos tal y como lo hacían sus microprocesadores de 8 bits, aprovechando de esta manera un conjunto de circuitos ya construidos y existentes en el mercado, facilitando el trabajo para los diseñadores a la hora de conectar estos dispositivos al microcontrolador. Es por eso que en mucha bibliografía se dice que en este caso el microcontrolador se esta comportando como un microprocesador. Por lo tanto, es en este modo de trabajo que el microcontrolador saca hacia el exterior los bits antes mencionados de los Buses de Direcciones y de Datos a través de los terminales del 32 al 39 del microcontrolador, no permitiendo la salida de los bits del Puerto 0. Los bits del Bus de Direcciones se completan con los 8 que salen en este modo de trabajo a través de los terminales del 21 al 28, no permitiendo la salida de los bits del Puerto 2, ver Figura 5.5.2.

Figura 5.5.2 Los Buses externos en el Modo Especial de Trabajo.

Microcontroladores. El 8051 de la INTEL.

221

Cuando el microcontrolador no esta trabajando en este Modo Especial de Trabajo por los terminales del 32 al 39 tenemos los 8 bits del Puerto 0, los que podemos utilizar como entrada o como salida según sean las necesidades

de

la

aplicación

que

estemos

desarrollando, ver Figura 5.5.3.

Para poder comprender como es que el microcontrolador logra sacar por los mismo terminal los bits del Puerto 0(P0.0 – P0.7), los bits del Bus de Datos(D0-D7) y los bits de la parte baja del Bus de Direcciones(A0-A7) analicemos la estructura interna de uno cualquiera de estos terminales, ver Figura 5.5.4. Observe que la similitud con la estructura

interna

de

los

terminales del Puerto 2 es grande.

Esta

presente

el

Multiplexor de 2 a 1, al que llegan la Q/ del Biestable y el bit de dato o de dirección que llegan por la línea DIRECCIÖN / DATO después de pasar por una compuerta inversora, con la diferencia de que la Q/ llega directamente y no a través de una compuerta NAND. Sigue estando la señal CONTROL la que selecciona con su valor cual de las dos entradas conectadas al Multiplexor es la que se adueña de la salida del mismo y con ello impone la función que tendrá en ese instante el terminal. Por su puesto mientras que el bit del Bus de Datos interno que llega al Biestable así como los bits del Bus de Direcciones y de Datos que llegan al inversor son específicos y diferentes para cada terminal, la señal CONTROL es común a todos.

Microcontroladores. El 8051 de la INTEL.

222

Existe también un cambio en la Etapa de Salida, al ser otro transistor MOS el que esta conectado al DRAIN del transistor MOS de salida y no la resistencia RX a la que estábamos acostumbrados de los otros puertos. El estado en que se encuentre funcionando este transistor depende del valor que tome la salida de la compuerta AND, la que a su vez depende del valor que tomen las señales DIRECCIÖN /DATO y CONTROL. ¿Cómo funciona toda esta estructura? Cuando la señal CONTROL se encuentra en ´0´, la salida del Multiplexor es ocupada por la salida Q/ del Biestable, que a su vez se conecta al GATE del transistor MOS de la Etapa de Salida quedando todo preparado para que por los terminales del 32 al 39 salgan los bits del Puerto 0, mientras que cuando la señal CONTROL toma el valor de ´1´ indica que el microcontrolador se encuentra operando en el Modo Especial de Trabajo y por lo tanto el bit que venga por la línea DIRECCION / DATO es el que ocupa la salida del Multiplexor siendo el que impone su valor al GATE del transistor MOS de la Etapa de Salida quedando todo preparado para que a través del terminal salga el bit del Bus de Direcciones y el bit del Bus de Datos , pero, Tenemos dos bits y un solo terminal, ¿Cómo se resuelve este problema? Como especificamos anteriormente le dedicaremos un Tema al estudio del Modo Especial de Trabajo del microcontrolador 8051 y a la manera de expandir al mismo, por lo que no es objetivo en este Tema estudiar con más profundidad este modo de trabajo. No obstante, para poder dar respuesta a la interrogante anterior debemos dar algunos elementos que nos permitan adentrarnos un poco en el funcionamiento del microcontrolador en este modo de trabajo. En el Modo Especial de Trabajo el objetivo del microcontrolador es el de establecer el movimiento de la información, códigos de programa o datos, entre él y los dispositivos externos que le han sido conectados. Por su puesto que este movimiento de información se hace con solo uno de los dispositivos externos a la vez, el que tiene que ser seleccionado por el microcontrolador mediante el envió de su dirección, el que a su vez sincroniza sus operaciones de entrega de información o de entrega / toma de datos a partir de las señales de control que el microcontrolador genera. Por lo tanto lo primero que hace el microcontrolador es, enviar la dirección del dispositivo con que desea efectuar la transferencia de información y un instante de tiempo después, el necesario para que la lógica externa seleccione a dicho dispositivo, recibir el código o enviar / recibir el dato involucrado en dicha transferencia como respuesta del dispositivo seleccionado.

Microcontroladores. El 8051 de la INTEL.

223

Todo esto tiene que ocurrir en el intervalo de tiempo destinado a un Ciclo de Máquina. Con lo explicado anteriormente creo que estamos en condiciones para comprender como el microcontrolador resuelve el tener un solo terminal para sacar dos señales, bit de datos y bit de dirección. Cuando el microcontrolador decide que tiene que efectuar una transferencia de información con un dispositivo conectado externamente a través de sus buses, lo primero que hace es poner la señal CONTROL a ´1´, con lo que garantiza que la señal que venga por la línea interna DIRECCIÖN / DATO sea la que se adueñe de la salida del Multiplexor. Un instante de tiempo después por dicha línea se envía el bit correspondiente a la dirección del dispositivo externo con que se va a efectuar la transferencia de información, con lo que se garantiza que dicha dirección salga hacia el exterior, posibilitando que la lógica externa de selección, seleccione al dispositivo involucrado en la transferencia. Un tiempo después quita de la línea interna DIRECCIÖN / DATO el bit de dirección, convirtiendo a dicha línea en un bit del Bus de Datos, de forma tal que, si la transferencia consiste en enviar un dato hacia el dispositivo externo seleccionado, el bit del dato correspondiente será enviado por el microcontrolador a través de esta línea. Todo esto ocurre en el intervalo de tiempo en que el microcontrolador ejecuta un Ciclo de Máquina. En la Figura 5.5.5 mostramos el comportamiento de los terminales correspondientes al Puerto 0 y al Puerto 2 cuando el microcontrolador efectúa una operación de escritura de un dato en un dispositivo externo trabajando en el Modo Especial de Trabajo.

Si bien el comprender en toda su magnitud como opera el microcontrolador en el Modo Especial de Trabajo no constituye aún un objetivo fundamental para nosotros, si lo es profundizar en la

Microcontroladores. El 8051 de la INTEL.

224

operación del Puerto 0 como puerto, o sea, cuando el microcontrolador esta operando de forma normal como microcontrolador. Para ello retomemos la condición en que la señal CONTROL toma el valor de ´0´. Ya vimos que sucede con el Multiplexor y como la señal Q/ del Biestable es la que se conecta al GATE del transistor MOS de la Etapa de Salida en este caso. Hasta aquí no hay nada nuevo siendo lo mismo que sucedía con los otros puertos, pero, ¿Qué es lo que esta conectado al DRAIN del transistor MOS de la Etapa de Salida? Ya habíamos visto que, a diferencia de los otros tres puertos, al DRAIN del transistor MOS de la Etapa de Salida se encuentra conectado otro transistor MOS el que tiene conectado a su DRAIN la fuente Vcc y al GATE la salida de una compuerta AND la que tiene en sus entradas las señales DIRECCION / DATO y CONTROL, ver Figura 5.5.4. El estado en que se encuentre operando este transistor depende en gran medida del valor de la señal CONTROL, de manera que, •

CONTROL en ´0´, transistor en corte.



CONTROL en ´1´, transistor conduce.

Por lo tanto cuando el microcontrolador este operando en su modo normal y por ende por los terminales del 32 al 39 lo que tenemos son los bits del Puerto 0, este transistor se encontrará cortado y por lo tanto la fuente Vcc se encontrará aislada de la salida, ver Figura 5.5.6, quedando el transistor MOS de la Etapa de Salida en una configuración OPEN DRAIN.

¿Para qué los fabricantes hicieron esto?

Microcontroladores. El 8051 de la INTEL.

225

Cuando el microcontrolador se encuentra trabajando en el Modo Especial de Trabajo, a través de los terminales destinados a este puerto, salen multiplexados en el tiempo los bits del Bus de Datos y de la parte baja del Bus de Direcciones. Esta conmutación tiene que ocurrir en el intervalo de tiempo impuesto por el reloj del microcontrolador a un ciclo de máquina, por lo que el mismo debe consumir el menor tiempo posible. Esta situación se hace aún más critica cuando la operación que esta realizando el microcontrolador es de lectura de memoria de programa o de lectura en memoria de datos, ya que no solo los terminales tienen que conmutar de bits del Bus de Direcciones a bits del Bus de Datos, sino también, tienen que conmutar de bits de salida a bits de entrada, ver Figura 5.5.7.

Figura 5.5.7 Estado de los terminales del Puerto 0 y del Puerto 2 en una operación de lectura de datos en memoria. Efectivamente, durante una operación de lectura de un dato de la memoria del mismo nombre, lo primero que sale por los terminales del Puerto 0

son los bits menos significativos de la

dirección de la localización de memoria donde se quiere efectuar la lectura del dato, por lo que los terminales del puerto están de salida. Un instante de tiempo después el microcontrolador debe estar preparado para recibir a través de los terminales del mismo Puerto 0 el dato que le enviará como respuesta la memoria seleccionada, por lo que en este caso los terminales de dicho puerto se tienen que poner como de entrada. Esto queda bien representado en la Figura 5.5.7. Un intervalo de tiempo al que hemos llamado TCAMBIO en dicha Figura caracteriza este proceso, en el cual los terminales del Puerto 0 no están ni de entrada ni de salida, ni en ´0´ ni en ´1´. ¿En que estado están los terminales del Puerto 0 durante el intervalo de tiempo TCAMBIO? Están en un estado de Alta Impedancia, no representando ninguna carga para los dispositivos que le estén conectados. Con el objetivo de que este intervalo de tiempo fuera lo más corto posible es que los fabricantes sustituyen a la resistencia RX presentes en los otros puertos por un transistor MOS conectado como carga al DRAIN del transistor de la Etapa de Salida. Esto no debe ser motivo de

Microcontroladores. El 8051 de la INTEL.

226

preocupación para el diseñador cuando utiliza al Puerto 0 como Bus Multiplexado de Direcciones y Datos ya que la lógica de control del microcontrolador se encargara del buen funcionamiento del mismo y por lo general el microcontrolador se acompaña de una lógica externa que no deja ver este tiempo de cambio a los circuitos conectados a este puerto. No obstante, lo anterior puede levantar la siguiente duda entre ustedes, ¿Tendrá influencia esta situación en el comportamiento de los terminales del Puerto 0 cuando este trabaja como puerto de entrada o de salida y no como Bus Multiplexado? De entrada les puedo les puedo asegurar que si, ya que si cambia la Etapa de Salida es lógico que cambie el comportamiento de los terminales del puerto cuando opere como puerto en si. Para conocer cuanto influye comencemos dándole respuesta a la pregunta siguiente, ¿Cómo influye esto si al Puerto 0 lo ponemos a trabajar como de salida? Ahora el microcontrolador por si solo no será capaz de imponer los niveles de voltaje característicos del ´0´ y del ´1´. Efectivamente al quedar el transistor MOS de la Etapa de Salida aislado de la fuente, no habrá quien le entregue el voltaje necesario al DRAIN de dicho transistor. Es como si la Etapa de Salida no estuviera completa y necesitará del completamiento por parte del diseñador mediante la conexión externa de algún otro dispositivo al terminal. ¿Cómo resolver este problema? La primera idea puede resultar, repetir externamente la configuración que tenían los terminales de los puertos anteriores, conectando externamente el terminal a la fuente Vcc de alimentación del microcontrolador a través de una resistencia a la que llamaremos Rx, por similitud con los puertos estudiados anteriormente, ver Figura 5.5.8.

Microcontroladores. El 8051 de la INTEL.

227

Figura 5.5.8 Conectando una CARGA a uno de los terminales del Puerto 0. ¿De qué depende el valor de la resistencia Rx?, ¿Cómo calcular el valor de la resistencia Rx en una aplicación dada? Por su puesto que el valor de la resistencia Rx a colocar para completar la Etapa de Salida del Puerto 0 depende de la CARGA que se conecte a dicho terminal, ya que con su valor se deben garantizar los parámetros de voltaje y de corriente que necesite la misma para su buen funcionamiento, tanto para el caso en que el microcontrolador imponga un ´0´ lógico como para cuando imponga un ´1´ lógico, de forma tal que la CARGA vea los niveles de ´0´ y de ´1´ típicos para ella. Efectivamente, si el bit del puerto va a ser utilizado como de salida, es porque al terminal correspondiente se le va a conectar una CARGA, la que por lo general presenta dos comportamientos muy bien marcados, uno para cuando el bit del puerto tome el valor de ´0´ y otro para cuando el bit del puerto tome el valor de ´1´. Cuando calculemos el valor que debe tener la resistencia Rx debemos tomar en cuenta cual es el punto de operación, voltaje – corriente, de la CARGA cuando su entrada se pone a ´0´ y lo mismo para cuando su entrada se pone a ´1´, de forma tal que el valor de Rx garantice los valores de voltaje de ´0´ y de ´1´ necesarios por la CARGA tomando en cuenta su demanda de corriente en cada uno de los casos. Por ejemplo consideremos que se conecta como CARGA la entrada de una compuerta inversora de tecnología de fabricación TTL, tal y como se muestra en la Figura 5.5.9.

Microcontroladores. El 8051 de la INTEL.

228

Figura 5.5.9. Compuerta Inversora TTL conectada como CARGA a un terminal del Puerto 0. El valor de Rx debe ser tal que garantice a la entrada de la compuerta inversora los niveles de ´0´ y de ´1´ que define el fabricante para este tipo de compuertas si queremos que el circuito funcione correctamente. Los fabricantes de circuitos integrados TTL por lo general imponen como condición de entrada para sus compuertas,

0volts < VIL < 0,8volts 2.0volts < V IH < 5.0volts por lo que el valor de Rx debe ser tal que cuando el bit del Puerto 0 tome el valor de ´0´, el voltaje en el punto A, ver Figura 5.5.9, este entre el intervalo de valores definidos para VIL, mientras que cuando tome el valor de ´1´ el valor del voltaje en el mismo punto debe estar entre los valores definidos como intervalo para VIH. Para calcular el valor de RX el procedimiento a seguir sería el siguiente: •

Primero se calcula el valor necesario de Rx cuando el bit del Puerto 0 al que esta conectada la compuerta inversora tome el valor de ´0´. A este valor se le llama RXmin y para su calculo se impone un voltaje en el punto A que debe ser menor que el VILmax dado por el fabricante para la compuerta inversora.



Posteriormente se calcula el valor necesario de Rx cuando el bit del Puerto 0 al que esta conectada la compuerta inversora tome el valor de ´1´, a este valor se la llama RXmax y para su cálculo se impone un voltaje en el punto A que debe ser mayor que el VIHmin dado por el fabricante para la compuerta inversora.



Por último, el valor de Rx a conectar será escogido por el diseñador de forma tal que cumpla con la condición,

Microcontroladores. El 8051 de la INTEL.

229

R X min < R X < R X max Observe que el procedimiento es el mismo que se sigue cuando se esta trabajando con una compuerta lógica con tecnología de fabricación bipolar TTL, del tipo COLECTOR ABIERTO Una cosa diferente sería si al terminal lo que vamos a conectar como CARGA es un Diodo Emisor de Luz (LED), el que queremos que cuando el bit del Puerto 0 al que esta conectado tome el valor de ´0´ este apagado y que cuando tome el valor de ´1´ se encienda. El circuito que le proponemos en este caso es el que se muestra en la Figura 5.5.10 y escogeremos como punto de operación del LED para cuando este encendido, VL = 2.2volts e IL = 10 mamp.

Figura 5.5.10 LED conectado a uno de los terminales el Puerto 0 para ser encendido con la escritura de un ´1´. En este caso cuando el bit del Puerto 0 tome el valor de ´0´ el valor del voltaje en el punto A debe estar por debajo del voltaje de conducción del LED, con lo que garantizamos que el mismo este apagado, mientras que cuando tome el valor de ´1´ el valor del voltaje en dicho punto debe estar por encima de los 2.2 volts, con lo que se garantiza, si se calcula correctamente RL, que el LED se encienda con la intensidad deseada. En este caso no tenemos como condición intervalos de valores como en el ejemplo de la compuerta inversora, sino que tenemos valores muy bien definidos de voltaje en el punto A y de corrientes en el LED que deben ser garantizados por el diseñador en su circuito. Para seguir trabajando consideremos que el LED esta conectado al terminal que le corresponde al bit 0 del puerto, P0.0.

Microcontroladores. El 8051 de la INTEL. •

230

P0.0 en ´0´, entonces el LED apagado, el voltaje en el punto A igual a 0.4 Volts y la corriente que toma el LED sería 0.



P0.0 en ´1´, entonces el LED encendido, el voltaje en el punto A igual a 3.0 Volts y la corriente que toma el LED sería de 10 mamp.

¿Cómo proceder en este caso? Les propongo que primero calculemos el valor de RX que garantiza las condiciones que impone el LED cuando esta encendido y posteriormente comprobemos si el valor de RX calculado no viola ninguno de los parámetros del circuito cuando el LED este apagado. Para calcular el valor de Rx para cuando el bit del Puerto 0 tome el valor de ´1´, por lo tanto el LED esta encendido, nos auxiliaremos del esquema que aparece en la Figura 5.5.11.

Figura 5.5.11 P0.0 en ´1´, el LED encendido. En este caso el transistor MOS de la Etapa de Salida se encuentra cortado y por lo tanto podemos considerar que toda la corriente que circula por la resistencia RX, Ix, pasa a través del LED. Por su puesto, para que lo anterior se logre, debemos garantizar que el voltaje en el punto A, al que hemos llamado en este caso Voh, sea mayor que los 2.2 volts definidos como Voltaje de Conducción del LED. En este caso escogeremos 3.0 volts. Planteando Kirchoff por la malla correspondiente nos queda,

VCC − I X R X − I L RL − VL = 0

Microcontroladores. El 8051 de la INTEL.

231

De la expresión anterior aparentemente tenemos dos incógnitas, RL y RX al ser IL = IX = 10 mamp, pero contamos con una sola ecuación. No obstante, la ecuación anterior la podríamos dividir en dos ecuaciones con lo que quedaría resuelto dicho inconveniente,

VCC − I X R X = VOH VOH = I L RL + VL Con este par de ecuaciones podemos calcular el valor de RX y de RL, sustituyendo en las mismas los siguientes valores,

VCC = 5volts I X = I L = 10mamp VOH = 3.0volts Despejando RX, RL y sustituyendo los valores anteriores,

RX =

VCC − VOH 5volts − 3.0volts = = 200Ω IX 10mamp

RL =

VOH − VL 3.0volts − 2.2volts = = 80Ω IL 10mamp

Según el procedimiento a seguir, que se definió al empezar el calculo del RX en este ejemplo, lo que nos corresponde ahora es verificar si con estos valores de RX y RL calculados no se viola ninguno de los parámetros del microcontrolador y del circuito del LED cuando P0.0 este en ´0´. Como ya explicamos anteriormente bajo estas condiciones queremos que el LED este apagado por lo que el voltaje en el punto A debe estar por debajo del voltaje de conducción del mismo, el que proponemos que sea 0.4 volts, buscando similitud con el voltaje de ´0´ típico para este microcontrolador. En estas condiciones por el LED no debe circular corriente y por lo tanto toda la corriente que circula por Rx, la que hemos llamado Ix, entra al terminal del microcontrolador circulando a través de la unión DRAIN – SOURCE del transistor MOS de la Etapa de Salida, el que se encuentra en saturación. En la Figura 5.5.12 se muestra el estado del circuito cuando el bit del Puerto 0 toma el valor de ´0´.

Microcontroladores. El 8051 de la INTEL.

232

Figura 5.5.12 Estado del circuito cuando el bit del Puerto 0 toma el valor de ´0´. ¿Cuál sería el peligro en este caso? Al estar el LED apagado la corriente IX es la misma que la corriente Iol que entra por el terminal del microcontrolador y circula a través de la unión DRAIN – SOURCE del transistor de salida. El valor de esta corriente dependerá exclusivamente del valor de RX calculado. Al mismo tiempo el valor del voltaje VOL es el mismo que el valor del voltaje Vds, cuyo valor depende en gran medida del valor de la corriente Iol. Por lo tanto, el valor de VOL depende en gran medida del valor de RX calculado, La pregunta a dar respuesta en este caso sería, ¿Cuál es el valor de VOL si el valor de la resistencia RX es de 200Ω? La ecuación para el cálculo de Iol sería,

I ol =

VCC − Vol 5volts − 0.4volts = = 23mamp 200Ω RX

Con el valor de Iol y aplicando la ecuación de la Característica de Salida del puerto cuando esta en ´0´, que es la misma obtenida para el Puerto 1, ver Figura 5.2.8.

VOL = ((0.02kΩ )(I ol )) + 0.02volts = ((0.02kΩ )(23mamp )) + 0.02volts = 0.48volts Que es un valor muy cercano del valor deseado y con el cual el LED esta apagado tal y como se nos impuso en el problema, por lo que el valor de RX = 200Ω constituye una buena solución para la tarea propuesta.

Microcontroladores. El 8051 de la INTEL.

233

Otra posible solución al problema planteado es la que se muestra en la Figura 5.5.13.

Figura 5.5.13. Conexión de un LED a la salida del bit P0.0 sin necesidad de resistencia RL. Observe que en este caso no se ha conectado en el circuito la resistencia RL que acompañaba al LED en el caso anterior. Esto no trae ningún problema del punto de vista circuítal y es perfectamente valido, lo que indiscutiblemente varía es el valor de RX. Ahora el valor de RX será,

RX =

VCC − VOL 5volts − 2.2volts = = 280Ω IL 10mamp

Valor que era de esperar. Hasta ahora, el que no este completa la Etapa de Salida de los terminales correspondientes a los bits del Puerto 0 solo nos a traído inconvenientes al tener que conectar una resistencia externa a cada uno de ellos y tener que efectuar los cálculos de la misma. La pregunta podría ser, ¿Tendrá alguna ventaja para el diseñador este aparente inconveniente? Por lo general, cuando usted se enfrenta al diseño de un circuito para la solución de una aplicación dada no resulta una condición a cumplir que la CARGA que se conecte a uno cualquiera de los terminales de un puerto se active con ´0´ o con ´1´. Usted si tiene que decidir cual será el estado en el que la CARGA se activa y cual será el estado en el que la CARGA no se activa, pero esta decisión responde a la forma en que usted conecte la CARGA al terminal del puerto, aspecto que es de su libertad escoger.

Microcontroladores. El 8051 de la INTEL.

234

Veamos lo anterior a luz del propio ejemplo de conectar el mismo LED al terminal P0.0 y analicemos si esto nos trae alguna ventaje con respecto a los terminales de los otros puertos. En la Figura 5.5.14 aparece el circuito que les proponemos analizar.

Figura 5.5.14 LED conectado como parte del completamiento de la salida del terminal. Observe que en este caso hemos quitado la resistencia RX y la hemos sustituido por la resistencia RL y el LED. Ahora cuando en el bit del Puerto 0, P0.0, se escriba un ´0´ circulará corriente a través del LED y este se encenderá, mientras que cuando se escriba un ´1´, por el LED no circulará corriente y este se apagará, por lo que, aunque con valores lógicos en P0.0 diferentes provocamos el mismo efecto en el LED.. Los cálculos para el valor de RL en este caso se muestran a continuación,

RL =

VCC − V L − VOL 5volts − 2.2volts − 0.2volts = = 260Ω IL 10mamp

Este circuito resulta valido para cualquier CARGA y solo usted debe tener precaución con que la corriente de la CARGA cuando este activada no exceda el valor de IOLmax. Por ejemplo en este caso la corriente del LED cuando esta activado es de 10 mamp, mientras que el IOLmax para los terminales del Puerto 0 es de 32 mamp, por lo que no existe ninguna dificultad. Otra posible ventaje para el diseñador cuando trabaja con el Puerto 0 como de salida, esta relacionada con la posibilidad de efectuar la función AND Alambrado con sus terminales, ver la Figura 5.5.15.

Microcontroladores. El 8051 de la INTEL.

235

Figura 5.5.15 Conexión en AND Alambrado de las salidas del Puerto 0. Observe que lo que hemos hecho en este caso es conectar todas los terminales del Puerto 0 en un punto al que hemos llamado A y a este punto es que hemos conectado el circuito que completa la Etapa de Salida de los terminales de dicho puerto y que ya habíamos visto en el ejemplo anterior. ¿Qué sucede con el voltaje en el punto A?, ¿Bajo que condiciones se enciende el LED? Al unir todos los terminales del Puerto 0 en el punto A hemos provocado que el voltaje en este punto sea siempre el menor de los voltajes, impuestos por programa, en dichos terminales. En otras palabras, basta con que en uno de los bits del Puerto 0 se escriba un ´0´, para que en el punto A haya un ´0´. Es por esto que a esta configuración se conoce con el nombre de AND Alambrado ya que el comportamiento, del punto de vista lógico, de este punto es similar a si se hubiera colocado una compuerta AND en el mismo. Esto lo podemos hacer con este puerto ya que su Etapa de Salida es OPEN DRAIN. En el circuito de la Figura 5.5.15, cada vez que el LED se enciende nos indica que al menos uno cualquiera de los bits del Puerto 0 se encuentra en ´0´ y permanecerá apagado solo en el caso en que todos los bits del Puerto 0 estén en ´1´.

Microcontroladores. El 8051 de la INTEL.

236

En el circuito hemos conectados los 8 terminales del Puerto 0 al punto A, involucrándolos a todos en el AND Alambrado, pero esto no tiene que ser obligatoriamente así. Basta con que dos terminales cualquiera, los conectemos entre si para que ya este conformado el AND Alambrado. Supongamos que queremos conectar 8 LEDs, el mismo empleado en los ejemplos anteriores, a uno cualquiera de los puertos del 8051, la pregunta podría ser, ¿A cual de ellos conectarlos? En la Figura 5.5.16 mostramos las dos de las posibles propuestas, los LEDs conectados al Puerto 1 y los LEDs conectados al Puerto 0.

Figura 5.5.16. Conexión de 8 LEDs a los Puertos 1 y 0 del 8051, para que enciendan con ´1´. Hemos escogido el Puerto 1 para la comparación con el Puerto 0, pero a las conclusiones a las que arribemos serán las mismas si hubiéramos escogido al Puerto 2 o al Puerto 3 ya que la Etapa de Salida de los tres puertos, cuando están trabajando como tal, son iguales.

Microcontroladores. El 8051 de la INTEL.

237

En el circuito de la Figura 5.5.15 los LEDs se encienden cuando en su terminal correspondiente esta ´1´ lógico producto de escribir en el bit del puerto dicho valor. Esto es valido tanto para los bits del Puerto 0 como para los bits del Puerto 1. La diferencia en la forma de conectar los LEDs viene dada por la condición OPEN DRAIN de la Etapa de Salida del Puerto 0, ya estudiada. Para la comparación que queremos hacer analicemos el estado en que los LEDs están encendidos. En este caso, para el Puerto 1, la corriente que circula por el LED encendido viene de la fuente VCC a través de la resistencia RX conectada dentro del microcontrolador, mientras que, para el Puerto 0, la corriente que circula por el LED encendido viene igualmente de la fuente VCC, pero ahora es a través de la resistencia RX conectada fuera del microcontrolador. Por ejemplo, si estamos en la condición de que los 8 LEDs se encuentran encendido, caso peor, a través de cada una de las resistencias RX ubicadas dentro del microcontrolador circulan 10 mamp (10 mamp por cada LED) lo que hace una suma total de 80 mamp que traen consigo un aumento de la temperatura del microcontrolador por disipación en dichas resistencias. Sin embargo, la corriente de encendido de los LEDs para el caso del Puerto 0, circula íntegramente fuera del microcontrolador, a través de las resistencias RX conectadas externamente a los terminales, no aumentando la temperatura de este producto de este efecto. Esta es una de las razones que convierten al Puerto 0 en un puerto de salida por excelencia. Hemos hecho un estudio exhaustivo del comportamiento como puerto de salida de los terminales del Puerto 0, pero conocemos que también puede ser utilizado como puerto de entrada, ¿Qué sucede si el Puerto 0 es utilizado como puerto de entrada? En este caso, al igual que para el resto de los puertos, si queremos utilizar uno de los terminales del Puerto 0 como entrada en el Biestable correspondiente del registro Almacenador se debe escribir un ´1´. Con esto se garantiza que la Q/ de dicho Biestable se encuentre en ´0´ y con ello que el transistor MOS de salida se encuentre cortado. Por otro lado como la señal CONTROL tiene el valor de ´0´, el transistor de carga de la Etapa de Salida estará cortado también, quedando el circuito como se muestra en la Figura 5.5.17-.

Microcontroladores. El 8051 de la INTEL.

238

Figura 5.5.18 El terminal P0.0 como terminal de entrada. Cuando usted efectué, mediante programa, una lectura del Puerto 0, el microcontrolador genera la señal READ PIN con lo que se activa al Buffer de Lectura del Terminal pasando al Bus de Datos interno los valores lógicos impuestos por la CARGA en los terminales de dicho puerto. De lo explicado anteriormente, quien interpreta este valor lógico es el Buffer de Lectura del Terminal y dicha interpretación dependerá del voltaje que tenga impuesto la CARGA cuando se ejecute la instrucción de lectura del puerto. Para la explicación hemos dividido las posibles CARGAS a conectar a uno cualquiera de los terminales del puerto en, •

Activas. Generan, por si solas, un voltaje y una corriente que caracteriza el estado en que se encuentra.



Pasivas. No generan, por si solas, ni voltaje ni corriente que caracterice el estado en que se encuentran

Si la CARGA conectada es Activa, como puede ser la salida de una compuerta lógica, el nivel de voltaje en el terminal lo impondrá dicho circuito, solamente el diseñador debe tomar en cuenta los parámetros eléctricos de salida de la CARGA y los parámetros eléctricos de entrada de los terminales y efectuar los acoplamientos necesarios en caso de que haga falta. Pero, ¿Qué sucede si la CARGA conectada es del tipo Pasiva? Si la CARGA es Pasiva, como puede resultar un interruptor o una tecla, entonces esta por si sola no será capaz de generar los niveles de voltaje necesarios para que el Buffer de Lectura del

Microcontroladores. El 8051 de la INTEL.

239

Terminal interprete adecuadamente el estado en que se encuentra y por ende una lectura del puerto no reflejara dicho estado. Veamos lo anterior a luz del siguiente ejemplo. Supongamos que queremos conectar un Interruptor Simple Polo – Simple Tiro al terminal P0.0 del Puerto 0 del microcontrolador. Un posible circuito es el mostrado en la Figura 5.5.19.

Figura 5.5.19. Interruptor Simple Polo – Simple Tiro conectado al terminal P0.0. Cuando el Interruptor este cerrado a la entrada del Buffer de Lectura del Terminal esta aplicado un voltaje de 0 volts producto de conectar dicha entrada a la línea de tierra del circuito. En estas condiciones cuando el microcontrolador ejecute una instrucción de lectura del bit P0.0, este leerá un ´0´, por lo que para el programa la lectura de un ´0´ en este caso, es interpretado como Interruptor cerrado. Pero, ¿Qué sucede cuando el Interruptor este abierto y el microcontrolador ejecute una instrucción de lectura del bit P0.0? Ahora la entrada del Buffer de Lectura del Terminal estará abierta y por lo tanto no existe ningún dispositivo que imponga el nivel de voltaje que necesita dicho buffer para poder interpretar si a su entrada hay un ´0´ o un ´1´. En esta situación cuando el microcontrolador ejecute una instrucción de lectura del terminal P0.0 leerá nuevamente un ´0´ y por lo tanto para el programa el Interruptor continúa cerrado. Es evidente que el circuito propuesto, que funciono correctamente cuando conectamos el Interruptor Simple Polo – Simple Tiro al Puerto 1, no resulta si estamos trabajando con el Puerto 0.

Microcontroladores. El 8051 de la INTEL.

240

¿Cuál debe ser el circuito en este caso? Viene nuevamente en nuestra ayuda la resistencia RX conectada entre el terminal del puerto y la fuente VCC, como aparece en la Figura 5.5.20.

Figura 5.5.20 Resistencia RX a VCC para garantizar el nivel de voltaje del ´1´ cuando el interruptor este abierto. Ahora cuando el Interruptor este cerrado todo transcurre igual, con la novedad de que al terminal P0.0 entrara una corriente, a la que llamaremos IX, que le llega de la fuente VCC a través de la resistencia RX. Pero ahora cuando el Interruptor este abierto, el circuito formado por la resistencia RX y la fuente VCC se encargara de imponer el voltaje de ´1´ que necesita el Buffer de Lectura del Terminal para que el programa pueda diferenciar cuando el Interruptor esta cerrado y cuando esta abierto. Por su puesto que el valor que tome RX juega un papel determinante para el circuito funcione como se definió en el párrafo. RX debe garantizar que la corriente que entrega la fuente VCC a tierra cuando el Interruptor este cerrado sea pequeña y al mismo tiempo debe garantizar que cuando el Interruptor este abierto el Buffer de Lectura del Terminal vea un voltaje por encima del VIHmin, para que interprete correctamente a un ´1´. Un valor práctico para RX de 10 kΩ resulta una buena selección. En muchas aplicaciones algunos terminales de los puertos pueden quedar sin usar y por ende se acostumbra a dejarlos sin conectar, la pregunta en este momento podría ser, ¿Qué implicaciones podría tener esta costumbre si los terminales sin usar se corresponden con terminales del Puerto 0?

Microcontroladores. El 8051 de la INTEL.

241

En este caso la entrada de los Buffer de Lectura del Terminal quedan al aire al no tener ninguna CARGA conectada. A esto le debemos sumar, que con la activación de la señal de RESET al inicio del funcionamiento del circuito todos los Biestable del registro Almacenador del puerto toman el valor de ´1´, quedando preparados para operar como puertos de entrada. Esto provoca que estos buffers se encuentren trabajando en la zona intermedia entre el ´0´ y el ´1´ lo que causaría un incremento significativo de la corriente ICC que demanda de la fuente VCC que alimenta al microcontrolador. Esta es la causa por lo que no es recomendable dejar sin conectar los terminales del Puerto 0 que no sean utilizados ya que ocurriría un aumento innecesario del consumo por parte del microcontrolador. Basta con conectar una resistencia de 10 kΩ externamente entre el terminal del puerto y la fuente Vcc para minimizar este efecto. El efecto negativo de quedar las entradas de los Buffer de Lectura del Terminal del terminal en el aire también ocurre cuando los terminales del Puerto 0 son ocupados por las señales del Bus Multiplexado de Direcciones y Datos en el Modo Especial de Trabajo. No obstante, dado que los intervalos en que quedan en esta situación es muy corto, ver en la Figura 5.5.7 TCAMBIO, el efecto es despreciable. ¿Qué sucedería si en nuestra aplicación al microcontrolador se le impusiera el Modo de Trabajo IDLE y se dejara al Puerto 0 sin conectar CARGA? El efecto negativo sería similar, solo que en el estado de IDLE el tiempo en que quedan flotando los buses no es despreciable. Efectivamente, durante el estado de IDLE los buses del microcontrolador quedan detenidos y por ende los terminales del Puerto 0 flotarán, produciendo el efecto indeseado durante todo el tiempo en que el estado de IDLE se mantenga. De forma contraproducente, cuando tratamos de reducir el consumo al máximo, existe una causa que provoca un consumo al innecesario por parte del microcontrolador. Una solución a este problema seria el conectar una resistencia desde cada terminal del Puerto 0 a tierra de valor aproximado de 10 k, con lo que se minimiza este efecto negativo. Somos del criterio de que con los elementos que tenemos hasta este momento ya estamos en condiciones

de

poder

desarrollar

nuestras

primeras

aplicaciones

microcontrolador, tarea esta a la que le dedicaremos el próximo Tema.

basadas

en

este

Microcontroladores. El 8051 de la INTEL.

242

Tema 6. Desarrollando aplicaciones simples con el Microcontrolador 8051. Por lo general en los sistemas desarrollados a microcontroladores se encuentran un conjunto de elementos como son: Diodos Emisores de Luz (LED), Teclas, Interruptores, OptoAcopladores, Relay, Display a Lámparas de 7 Segmentos y a Cristal Liquido (LCD), etc., que en conjunto con sensores y actuadotes conforman la solución de una aplicación dada. Mientras que algunos de ellos son utilizados para enviar información al microcontrolador como son las Teclas y los Interruptores, otros son empleados para recibir información del microcontrolador como son los LED, las Lámparas de 7 Segmentos y los LCD. En el caso de los OptoAcopladores y Relay su función fundamental no es la de enviar información o recibir información del microcontrolador, sino más bien, la de aislar eléctricamente a este de las cargas que de alguna forma pueden resultar dañinas para el buen funcionamiento del mismo. El objetivo de este Tema es el de aplicar los conocimientos adquiridos por nosotros durante el estudio de los Temas anteriores, haciendo hincapié en el trabajo con los puertos del microcontrolador. Para ello analizaremos algunos ejemplos que nos permitan comprender como trabajar con los mismos cuando se le conectan alguno de estos dispositivos. Un conjunto de Ejercicios Propuestos aparecen en el epígrafe 9.4 como complemento para que usted de forma individual ejercite los conocimientos impartidos hasta aquí. 6.1 Tomando Decisiones. La toma de decisiones es una de esas tareas que prácticamente se encuentran presentes en todos los programas de aplicación que se hagan. Tomar la decisión de si ocurre una determinada condición hacer una cosa y si no hacer otra, por lo general se repite muchas veces dentro de un programa, por lo que somos del criterio de que bien puede constituir una de las primeras cosas que aprendamos a hacer. Si a esto le unimos el trabajo con Interruptores y Diodos Emisores de Luz(LEDs), conectados a los terminales de los puertos la tarea resulta más interesante. Estos son los aspectos que trataremos de resolver en el primer problema al que nos enfrentaremos en este Tema. Ejemplo 6.1 Se desean encender 8 LEDs enumerados de L0 a L7 con 4 Combinaciones diferentes. La selección de la Combinación con que se desea encender los LEDs es seleccionada abriendo o cerrando 2 Interruptores Simple Polo - Simple Tiro identificados como I0 e I1. En la Tabla 6.1 resume lo que se quiere que el microcontrolador haga. El punto de operación de los LEDs cuando se encuentren encendido debe ser de 2.0 volts y 15 mamp.

Microcontroladores. El 8051 de la INTEL.

243

Tabla 6.1 Aplicación del ejemplo 6.1 En la Figura 6.1.1 se brinda una propuesta del hardware de una posible solución al problema presentado, donde se han conectados los Interruptores I0 e I1 a los terminales P1.0 y P1.1 del microcontrolador respectivamente, mientras que los LEDs se han conectados a los terminales del Puerto 2.

Figura 6.1.1 hardware propuesto para la aplicación del Ejemplo 6.1 Observe que dada la conexión hecha de los Interruptores, cuando estos se encuentran abiertos, a la entrada de los Buffer de Lectura del Terminal de los terminales P1.0 y P1.1 se encuentra aplicado el voltaje que impone la fuente Vcc a través de una resistencia RX que forman parte de la Etapa de Salida de dichos terminales, voltaje este que será interpretado como un ´1´ lógico. Por otro lado, si el Interruptor esta cerrado el terminal correspondiente estará conectado a la tierra del circuito lo que será interpretado como nivel de ´0´ lógico. Esto será muy importante a la hora de toma la decisión de cómo encender los LEDs en el programa.

Microcontroladores. El 8051 de la INTEL.

244

Por su parte, los LEDs tienen el Ánodo conectado al terminal correspondiente del Puerto 2 a través de una resistencia que hemos llamado RL y el Cátodo a l tierra del circuito, por lo que estos se encenderán cuando en el bit del puerto se escriba un ´1´

y en el caso contrario estarán

apagados. El valor de la resistencia RL debe garantiza que el LED se encuentre en el punto de operación deseado cuando se encienda. Resumiendo lo planteado hasta aquí: •

Interruptor abierto, al terminal de entrada correspondiente del Puerto 1 se le impone un ´1´ lógico.



Interruptor cerrado, al terminal de entrada correspondiente del Puerto 1 se le impone un ´0´ lógico.



Terminal de salida del Puerto 2 en ´1´ lógico, LED encendido.



Terminal de salida del Puerto 2 en ´0´ lógico, LED apagado.

Para el cálculo de la resistencia RL nos auxiliaremos del circuito mostrado en la Figura 6.1.2 que muestra los voltajes y corrientes en la malla correspondiente al terminal P2.0, cuando el mismo se encuentra en ´1´.

Figura 6.1.2 Malla correspondiente al LED conectado al terminal P2.0.

RL =

VOH − V L IL

Los valores de VL y de IL los conocemos y constituyeron una condición del problema al ser definido el punto de operación en que se quería que operaran los LEDs cuando estuvieran encendidos. No

Microcontroladores. El 8051 de la INTEL.

245

obstante, el valor de VOH no es conocido y por lo tanto tenemos que proceder a su calculo antes de poder calcular el valor de RL. Para ello nos basamos en la característica de salida del Puerto 2 cuando esta en ´1´ calculada en el epígrafe 5.2 del Tema anterior, cuando estudiamos al Puerto 1.

VOH = −((0.02 KΩ )(I OH )) + 4.99volts En nuestro caso,

I OH = I L = 15mamp Por lo que sustituyendo en la expresión de VOH,

VOH = −((0.02 KΩ )(15mamp ) + 4.99volts ) = 4.69volts Sustituyendo en la expresión de RL,

RL =

VOH − V L 4.69volts − 2.0volts = = 180Ω IL 15mamp

Una vez completado el hardware de nuestra aplicación, pasemos a desarrollar el programa que garantizará la tarea asignada. Constituye una buena costumbre, fundamentalmente cuando se comienza a programar, organizar nuestras ideas de cómo resolver una aplicación dada mediante un Diagrama en Bloques, antes de comenzar a poner instrucciones en nuestro programa. Este Diagrama en Bloques, si bien no constituye una tarea imprescindible en la solución del problema, si constituye una gran ayuda para el programador. En este Diagrama en Bloques se encuentra recogido lo que se ha dado en llamar el Algoritmo del Programa, que no es más que la estrategia a seguir para resolver una tarea dada. Este Diagrama en Bloques debe ser lo más sencillo posible, tomando en cuenta de que el no constituye una meta en si, sino una manera de organizar el Programa para llegar a la meta deseada.

Microcontroladores. El 8051 de la INTEL.

246

El Diagrama en Bloques no debe ser una repetición instrucción a instrucción del Programa que se va ha desarrollar posteriormente, sino, un reflejo del Algoritmo con que vamos a enfrentar la solución de la tarea dada. En la Figura 6.1.3 se muestra el Diagrama en Bloques que proponemos para darle solución a la tarea que se nos ha planteado en el Ejemplo 6.1.

Figura 6.1.3 Diagrama en Bloques del Algoritmo propuesto para la solución del Ejemplo 6.1 El fragmento de programa que responde al Diagrama en Bloques desarrollado y que permite darle solución al problema planteado a partir del hardware propuesto es el que se lista a continuación. ; Programa ´´ Tomando Decisiones ´´. ; Este programa envía una Combinación de ´1´ y ´0´ previamente establecida al ; Puerto 2, en dependencia del estado de los Interruptores conectados a los ; terminales P1.0 y P1.1. ; Inicio del programa en la localización 0000h de Memoria de Programa. Org

0

; Directiva de Inicio del programa

; Apagar todos los LEDs conectados al Puerto 2. mov

P2, #00h

; Escribe un ´0´ en todos los terminales del Puerto 2

; Seleccionar los terminales del Puerto 1 como de Entrada. mov

P1, #0FFh

; Escribe un ´1´ en todos los Biestables del Puerto 1.

; Verifica si el Interruptor I0 esta cerrado inicio:

jnb

P1.0, cerrado

; Interruptor I0 abierto. ; Verifica si el Interruptor I1 esta cerrado jnb

P1.1,Comb_3

Microcontroladores. El 8051 de la INTEL.

247

; Los dos Interruptores están abiertos, Combinación 1. mov

P2, #11110000b

; Escribe Comb_1 en el Puerto 2.

jmp

inicio

; Repetir el proceso.

; El interruptor I0 abierto y el I1 cerrado, Combinación 3. Comb_3:

mov

P2, #01010101b

; Escribe Comb_3 en el Puerto 2.

jmp

inicio

; Repetir el proceso.

; El Interruptor I0 cerrado. ; Verificar si el I1 esta cerrado. cerrado:

jnb

P1.1, Comb_4

; Interruptor I1 abierto, Combinación 2. mov

P2, #00001111b

; Escribe Comb_2 en el Puerto 2.

jmp

inicio

; Repetir el proceso.

; Interruptor I1 cerrado, Combinación 4. Comb_4:

mov

P2, #10101010b

; Escribe Comb_4 en el Puerto 2.

jmp

inicio

; Repetir el proceso.

end

; Fin del programa.

Observe como hemos utilizado la instrucción jnb, para determinar el estado de los Interruptores. Esta es una instrucción del Grupo de Manipulación de Variables Booleanas que permite preguntar por el estado de los bits de los puertos, sin alterarlos. Si necesita más información sobre esta instrucción remítase al Tema 3, epígrafe 3.2, de este material donde la misma se trata en detalles. Al ejecutar esta instrucción, utilizando como operando un bit en particular de un Puerto 1, provoca: •

El microcontrolador censa el valor lógico impuesto en el terminal del Puerto por un elemento externo, en este caso un Interruptor.



En dependencia del valor censado en el terminal del Puerto toma dos posibles decisiones. Si el valor impuesto en el terminal es el ´0´ salta a la dirección especificada en la propia instrucción, si por el contrario es el ´1´ ejecuta la instrucción que sigue en la secuencia natural en la Memoria de Programa.

Esto es lo que necesitamos en este caso ya que el valor de ´0´ o de ´1´ impuesto en el terminal depende directamente del estado del Interruptor y con ello podemos hilvanar un conjunto de preguntas mediante esta instrucción que nos permita llegar a la conclusión de como se encuentran los mismos, que es lo que necesitamos para poder tomar la decisión correcta.

Microcontroladores. El 8051 de la INTEL.

248

El encendido y apagado de los LEDs lo hemos hecho mediante el empleo de la instrucción mov, no tratándolos como LEDs independientes sino como un byte completo ya que las combinaciones están definidas para los 8. Si necesita más información sobre las operaciones que provoca esta instrucción en el microcontrolador remítase al Tema 2, epígrafe 2.4, de este mismo material. Existen muchas aplicaciones que demandan la ejecución de una secuencia de eventos durante los procesos de Arranque y Parada. Un ejemplo de estos sistemas lo constituye una Caldera. Para controlar de forma automática estos procesos fueron desarrollados los Autómatas Programables en sus primeras versiones. Estos equipos eran de gran utilidad para llevar a cabo el Control Secuencial de aquellos procesos que lo demandaran. En el epígrafe siguiente enfrentemos la tarea de diseñar un Autómata Programable sencillo. 6.2 Secuencia de Eventos. En esencia un control secuencial constituye como su nombre lo indica en la ejecución de una secuencia de acciones en el tiempo. Generalmente entre la ejecución de una acción y otra media la ocurrencia de un determinado evento que indica que están las condiciones creadas para la ejecución de la acción siguiente, de forma tal que se establece una relación como la que se muestra en la Figura 6.2.1.

Figura 9.2.1 En la Figura 6.2.1 con el lazo alrededor de los cuadros CONDICION hemos querido representar la espera porque esta ocurra, antes de ejecutar la ACCION siguiente. Ejemplo 6.2. Diseñar un Autómata Programable con 4 Entradas para sensar la ocurrencia de un determinado EVENTO, una entrada por EVENTO, y con 4 salidas por donde dar la orden para ejecutar una determinada ACCIÓN, una salida para cada ACCIÓN. Las entradas de EVENTOS se encuentran enumeradas del 1 al 4 al igual que las salidas de ACCIÓN de forma tal que para que el Autómata de la orden de ejecutar la ACCIÓN1 debe haber verificado antes la ocurrencia del EVENTO1 y así sucesivamente. Una vez dada la orden de ejecutar la ACCIÓN4 el proceso debe comenzar nuevamente. Para el desarrollo de este ejemplo, aprovecharemos lo que ya aprendimos en el epígrafe anterior en el trabajo con los Interruptores y los LEDs de forma tal que asociaremos la ocurrencia de una CONDICIÓN con la doble acción de cerrar y abrir un Interruptor, mientras que simularemos las

Microcontroladores. El 8051 de la INTEL.

249

ACCIONES mediante el encendido de un determinado LED. El hardware propuesto es el mostrado en la Figura 6.2.2.

Figura 6.2.2. Observe que la forma de conectar los Interruptores es la misma de la del ejemplo anterior, con el elemento nuevo de ser 4 y por ende necesitar de 4 terminales del Puerto 1, los terminales P1.0 al P1.3, por lo que operarán de la misma manera. Mientras que los LEDs ahora tienen conectados el cátodo a los 4 bits menos significativos del Puerto 0 a través de las resistencias r5 a r8, con el Ánodo conectado a la fuente de 5 volts. Mediante esta conexión aprovechamos la condición de OPEN-DRAIN de este puerto, constituyendo la red conformada por la resistencia y el LED conectado a 5 volts la terminación de la etapa de salida de cada uno de los terminales del puerto. Ahora cuando se imponga un ´0´ lógico en el terminal correspondiente del Puerto 0, el LED se encenderá y con ´1´ permanecerá apagado. A modo de resumen, el hardware diseñado se comporta de la siguiente forma: 9

Interruptor abierto, al terminal de entrada correspondiente del Puerto 1 se le impone un ´1´ lógico.

Microcontroladores. El 8051 de la INTEL. 9

250

Interruptor cerrado, al terminal de entrada correspondiente del Puerto 1 se le impone un ´0´ lógico.

9

Terminal de salida del Puerto 0 en ´1´ lógico, el LED correspondiente apagado.

9

Terminal de salida del Puerto 0 en ´0´ lógico, el LED correspondiente encendido.

La pregunta a responder en este momento sería, ¿Por qué el valor de la resistencia en este caso es de 0.280K y no de 0.125K como en el ejemplo del epígrafe anterior? En este caso los LEDs se deben encender cuando el terminal correspondiente del puerto esta a ´0´ y no cuando esta a ´1´ lógico como ocurría en el ejemplo anterior. ¿Qué diferencia trae implicado esto? Ahora el transistor MOS de la etapa de salida del terminal del Puerto 0 esta saturado, cuando el LED se enciende, y no cortado como en el caso anterior por la que la carga lo que esta viendo es el voltaje DRAIN - SOURCE de un transistor MOS saturado. Esto es lo que garantiza el nivel de ´0´ en el terminal de salida y que en este caso el LED se encienda. Por lo tanto, en este caso al cátodo del LED se encuentra aplicado un voltaje bajo, VOL, mientras que al ánodo le esta aplicado un voltaje mucho más alto, +5 volts, lo que lo hará conducir y por ende encender con la luminosidad impuesta por la corriente que circule por el, dado el valor escogido de la resistencia, ver Figura 6.2.3.

Figura 6.2.3 Aplicando Kirchoff en la malla correspondiente para calcular el valor de r5 nos quedaría:

Microcontroladores. El 8051 de la INTEL.

r5 =

251

5volts − V L − VOL IL

Nuevamente VL e IL dependerán del punto de operación en que queramos que opere el LED cuando esta encendido, lo que dependerá del nivel de luminosidad deseado en la aplicación. Supongamos que el LED con el que estamos trabajando tiene un voltaje de directa VL = 2.0 volts y la corriente que queremos que circule por el cuando este encendido sea de IL = 10 mamp. Sustituyendo en la ecuación anterior nos queda,

r5 =

5volts − 2.0volts − VOL 10mamp

Pero, ¿Cuál debe ser el valor de VOL a sustituir en la ecuación? Del epígrafe 5.5 donde se estudio el Puerto 0 vimos como el voltaje VOL depende del valor de la corriente IOL que le este entrando de la carga al puerto por el terminal correspondiente. Esta relación viene dada por la ecuación,

VOL = (0.02 K )(I OL ) + 0.02v Sustituyendo en la ecuación anterior a IOL por el valor de IL deseado dada la intensidad de la luminosidad del LED necesitada en la aplicación nos queda,

VOL = (0.02 K )(10mamp ) + 0.02v = 0.22v Sustituyendo el valor de VOL obtenido en la ecuación de r5 nos queda,

r5 =

5volts − 2.0volts − 0.22volts = 0.278K 10mamp

El Diagrama en Bloques del Programa en cuestión se muestra en la Figura 6.2.4 y muestra el carácter secuencial de la operación del Autómata.

Microcontroladores. El 8051 de la INTEL.

252

Figura 6.2.4 El fragmento de programa que responde al Diagrama en Bloques diseñado y que permite darle solución al problema planteado a partir del hardware propuesto es el que se lista a continuación. ; Este programa ejecuta una secuencia de 4 ACCIONES a partir de la ocurrencia de 4 ; CONDICIONES. org 0

; Inicio del Programa en la dirección 0000h

; Se desactivan todas las ACCIONES posibles a ejecutar. ; Todos los LEDs son apagados. mov

P0, #0FFh

; Escribir ´1´ en todos los terminales del Puerto 0.

; Poniendo al Puerto 1 como Entrada, para atender los Interruptores. mov

P1, #0FFh

; Esperar porque ocurra la CONDICION 1. ; Inicio de Secuencia. cond1:

jb

P1.0, cond1

; ¿Interruptor 1 cerrado?

espe1:

jnb

P1.0, espe1

; ¿Interruptor 1 abierto?

; Ejecuta la ACCION 1. Encender el LED 0 y apagar los otros.

Microcontroladores. El 8051 de la INTEL. mov

253

P0, #11111110b

; Espera porque ocurra la CONDICION 2. cond2:

jb

P1.1, cond2

; ¿Interruptor 2 cerrado?

espe2:

jnb

P1.1, espe2

; ¿Interruptor 2 cerrado?

; Ejecuta la ACCION 2. Encender el LED 1 y apagar los otros mov

P0, #11111101b

; Espera porque ocurra la CONDICION 3. cond3:

jb

P1.2, cond3

; ¿Interruptor 3 cerrado?

espe3:

jnb

P1.2, espe3

; ¿Interruptor 3 abierto?

; Ejecuta la ACCION 3. Enciende los LEDs 1 y 2. mov

P0, #11111001b

; Espera porque ocurra la CONDICION 4. cond4:

jb

P1.3, cond4

; ¿Interruptor 4 cerrado?

espe4:

jnb

P1.3, espe4

; ¿Interruptor 4 abierto?

; Ejecuta la ACCION 4. Apagar el LED 2. mov

P0, #11110100b

jmp

cond1

; Repetir el Ciclo.

end

; Fin del Programa

Observe el conjunto de dos instrucciones consecutivas que se han utilizado para determinar la secuencia de eventos, Interruptor cerrado y posteriormente Interruptor abierto. ; Espera porque ocurra la CONDICION 2. Instrucción 1

cond2:

jb

P1.1, cond2

Instrucción 2

espe2:

jnb

P1.1, espe2

Con la primera instrucción garantizamos esperar porque el Interruptor, en este caso el 2, se cierre. Observe que el microcontrolador no saldrá del lazo que le impone esta instrucción hasta que al terminal P1.1, al que esta conectado el Interruptor 2 se la imponga un nivel de ´0´ lógico o lo que es lo mismo se cierre. Por su parte la instrucción 2 hace esperar al microcontrolador hasta que dicho Interruptor se abra. Para ello dicha instrucción se mantendrá ejecutándose constantemente hasta que el terminal P1.1 tome el valor lógico de ´1´ lo que indica que el Interruptor se ha abierto. Hasta aquí hemos trabajado con LEDs conectados de forma independiente para mostrar una información deseada, no obstante son más las aplicaciones donde por lo general la información a

Microcontroladores. El 8051 de la INTEL.

254

mostrar es una información numérica y por ende sería muy engorroso para el usuario trabajar con los LEDs montados de forma independiente para mostrar la información en binario. Existe otro tipo de dispositivo que no constituye más que un arreglo de LEDs conectados de forma tal que permita mostrar al usuario la información mediante números del Sistema Numérico Decimal al cual estamos acostumbrados. Uno de estos dispositivos lo constituyen las conocidas Lámparas de 7 Segmentos que será el dispositivo de salida que utilizaremos en el ejemplo del Epígrafe 6.3. 6.3 Trabajando con Tablas. En el trabajo con los microcontroladores es muy común efectuar la conversión de un número expresado en un código dado a su correspondiente equivalente en otro código. En muchas ocasiones no existe ecuación matemática que relacione a estos dos códigos o esta relación puede resultar muy compleja. En estos casos poder trabajar con Tablas podría ser de gran ayuda al Programador. La pregunta a responder en este momento podría ser, ¿Que es una Tabla? Definiremos como una Tabla a una secuencia de códigos, almacenados en memoria a partir de una dirección dada, de forma secuencial. Podríamos decir que son dos los elementos los que caracterizan una Tabla: la dirección de inicio y la longitud o cantidad de bytes que la integran. ¿Cómo se trabajaría con la Tabla? Para comprender la explicación partamos del siguiente ejemplo. Ejemplo 6.3 Mostrar a través de una Lámpara de 7 Segmentos el número decimal correspondiente al número Binario declarado mediante 3 Interruptores Simple Polo – Simple Tiro. Antes de poder encontrar una solución al problema planteado debemos darle primero respuesta a la siguiente pregunta, ¿Qué es una Lámpara de 7 Segmentos?

Microcontroladores. El 8051 de la INTEL.

255

Como ya se dijo anteriormente una Lámpara de 7 Segmentos no es más que un arreglo de LEDs conectados de forma que permita representar los números del Sistema Numérico Decimal, de forma tal que cada uno de los segmentos esta constituido por un LED, ver Figura 6.3.1.

En

dependencia

interconectados

de

estos

cómo LED

las

se

encuentren

Lámparas

de

7

Segmentos se clasifican en dos tipos: 9

Lámpara de 7 Segmentos de Ánodo Común.

9

Lámpara de 7 Segmentos de Cátodo Común.

La primera como su nombre lo indica todos los ánodos de los LEDs se encuentran interconectados internamente y el valor de voltaje impuesto en los cátodos correspondientes enciende o apaga el segmento en cuestión. Por lo general, en los sistemas a microcontroladores, estas Lámparas se le conectan los ánodos comunes al Vcc del sistema y al aplicar un ´0´ al cátodo correspondiente al segmento, este se enciende, de lo contrario se mantiene apagado. Por su parte las Lámparas de Cátodo común son todo lo contrario, conectándoseles el terminal común a la tierra del sistema y encendiendo el segmento correspondiente cuando se aplica un nivel de ´1´ en su ánodo. Hemos estado hablando de segmentos sin dejar todo lo claro que es necesario este concepto. La lámpara se llama de 7 Segmentos porque mediante 7 LEDs se conforman los arreglos que permiten indicar los números decimales. Cada LED esta relacionado con un segmento, ver Figura 6.3.1. De forma tal que si usted quiere que se muestre en la Lámpara el numero 0, todo lo que tiene que hacer es encender los LEDs correspondientes a los segmentos a, b, c, d, e y f, manteniendo al LED del segmento g apagado. Así sería como se conformarían todos los números decimales en la lámpara, ver Figura 6.3.2.

Microcontroladores. El 8051 de la INTEL.

256

Figura 6.3.2. De la Figura 6.3.2 podemos ver que si lo que queremos mostrar en la Lámpara de 7 Segmentos es el numero 0, tenemos que hacer encender los segmentos a, b, c, d, e y f, mientras que el segmento g se mantiene apagado. Para ello si la lámpara empleada es de Ánodo Común, como la que emplearemos en el ejemplo, debemos imponer por programa un nivel de ´0´ lógico en los terminales a, b, c, d, e y f de la lámpara y un nivel de ´1´ lógico en el terminal g de la misma. En la Tabla 6.3.1 se muestran todos los posibles códigos a enviar a la Lámpara de 7 Segmentos para mostrar los 10 dígitos decimales que aparecen en la Figura 6.3.2. Digito

Número

Segmentos

Decimal

g

f

e

d

c

b

a

hexadecimal

0

1

0

0

0

0

0

0

40h

1

1

1

1

1

0

0

1

79h

2

0

1

0

0

1

0

0

24h

3

0

1

1

0

0

0

0

30h

4

0

0

1

1

0

0

1

19h

5

0

0

1

0

0

1

0

12h

6

0

0

0

0

0

1

0

02h

7

1

1

1

1

0

0

0

78h

8

0

0

0

0

0

0

0

00h

9

0

0

1

0

0

0

0

10h

Tabla 6.3.1 El número de señales que tenemos que gobernar por programa para poder mostrar el número decimal que queramos en una Lámpara de 7 Segmentos es de 7 señales, una por cada

Microcontroladores. El 8051 de la INTEL.

257

segmento, de ahí que necesitemos prácticamente de un puerto completo para esta tarea (7 de las 8 señales). Por ejemplo podríamos conectar la Lámpara de 7 Segmentos del ejercicio que nos ocupa a los bits del 0 al 6 del Puerto 0 tal y como lo hicimos en el ejercicio anterior estableciendo un símil entre un LED y un segmento de la lámpara, ver Figura 6.3.3.

Figura 6.3.3 En este caso cuando los segmentos se encienden la corriente que circula por ellos es inyectada al terminal correspondiente del Puerto 0, la que circulará a través del DRAIN – SOURCE del transistor MOS de la Etapa de Salida, tal y como ocurría en el ejercicio anterior. Lo realmente nuevo en este caso es que la corriente que entra al Puerto 0 en su conjunto depende del número de segmentos que se encuentren encendidos y por ende del digito decimal que estemos representando en la misma, encontrándose entre los extremos del digito 1 que solo dos lámparas se encuentran encendida, mínima corriente y el digito 8 en que los 7 segmentos se encuentran encendido, máxima corriente. ¿Tendrá implicaciones para el Puerto 0 cuando todos los LEDs de la Lámpara de 7 Segmentos se encuentres encendidos?

Microcontroladores. El 8051 de la INTEL.

258

Esta situación que no la habíamos tocado antes porque no podía ocurrir en ninguno de los ejemplos anteriores si debemos tenerla en cuenta en este caso. Realmente los fabricantes dan dos datos con respecto a la corriente IOL permitida por un puerto: 9

La que soporta cada terminal del puerto por separado.

9

La que soporta el puerto en su conjunto.

Diferente a lo que podríamos esperar la segunda no se corresponde por lo general con la suma de las primeras, sino que por lo general es menor. Tómese en cuenta que esta corriente esta circulando dentro del microcontrolador con el consecuente calentamiento por disipación en la pastilla y el empeoramiento de las condiciones de trabajo del circuito. Es por eso que no se recomienda conectar directamente los terminales de la lámpara a los terminales de los puertos del microcontrolador, independientemente del puerto que sea. ¿Qué hacer en este caso? Una propuesta muy empleada en la práctica es la de conectar un circuito integrado buffer, como podría ser el 74HCT244 entre los terminales del puerto y los terminales de la lámpara de 7 segmentos, de forma tal que la corriente que circula por los segmentos de esta última entren al buffer y no al puerto, ver figura 6.3.4.

Figura 6.3.4 De la Figura 6.3.4 podemos observar que hemos sustituido al Puerto 0 en el circuito por el Puerto 2, esto es debido a que la ventaje que nos ofrece el Puerto 0 para conectar directamente los LEDs

Microcontroladores. El 8051 de la INTEL.

259

al terminal se pierde con la introducción del circuito buffer al demandar una resistencia cada uno de los terminales del puerto a Vcc con lo que se complicaría el circuito, encarecería y perdería en fiabilidad. El circuito buffer 74HC244 contiene 8 buffers no inversores con la posibilidad de ponerse en tercer estado, esta última posibilidad no la vamos a emplear en nuestro caso por lo que su terminal OE/ lo alambramos directamente a la referencia de tierra de nuestro circuito con lo que garantizamos que en todo caso se encuentre en ´0´ y por lo tanto los buffer habilitados. Los buffer no son almacenadores lo que no es necesario en este caso ya que el papel de almacenador lo hace el propio puerto. Somos del criterio de que ya estamos en condiciones de diseñar del punto de vista del hardware el circuito completo que se hace necesario para resolver el problema que nos han planteado en el ejercicio, ver Figura 6.3.5.

Figura 6.3.5. Observe que los Interruptores conectados al Puerto 1 están conectados de la misma forma que en el ejemplo anterior, por lo que Interruptor cerrado se corresponde con un ´0´ e Interruptor abierto se corresponde con un ´1´. Retomemos el programa que tenemos que hacer para resolver el problema planteado. En la Figura 6.3.6 se muestra una propuesta del Diagrama en Bloques del algoritmo propuesto.

Microcontroladores. El 8051 de la INTEL.

260

Lo realmente nuevo en este caso esta relacionado con la tarea de ´Buscar código de Lámpara de 7 Segmentos´. ¿Cómo hacer esta tarea? Para poder hacer esta tarea se nos hace necesario poder encontrar una relación entre el número binario que el usuario impone a través de los Interruptores, con el número decimal que este representa y el código de Lámpara de 7 Segmentos para poderlo mostrar a través de la lámpara. En el primero de los casos esta relación es directa, o sea, los números binarios del 0 al 9 se corresponden con los dígitos decimales directamente, por lo que no existe dificultad alguna en este caso. Pero, ¿Existirá alguna relación entre el número decimal y su correspondiente código de Lámpara de 7 Segmentos? Por desgracia, esta relación no existe, al menos de forma evidente, esto lo podemos corroborar en la Tabla 6.3.1. ¿Qué hacer en este caso?

Microcontroladores. El 8051 de la INTEL.

261

Lo único que podría venir en nuestra ayuda en este caso es una Tabla que nos ayude a efectuar la conversión correspondiente. Esta Tabla estaría almacenada en memoria de programa conjuntamente con el programa a partir de una dirección dada, la que llamaremos Puntero de la Tabla (PUNTERO). Los códigos de Lámparas de 7 Segmentos estarían almacenados en la Tabla, de forma consecutiva y ascendente de las direcciones, existiendo un código de lámpara por cada digito decimal a representar, por lo que para el ejemplo que nos ocupa serían 10 códigos en la Tabla, por lo que la Tabla tendrá una localización 0, que se corresponde con la dirección del PUNTERO, una localización 1 que se corresponderá con la dirección del PUNTERO + 1 y así sucesivamente hasta la localización 9 que se corresponderá con la dirección del PUNTERO + 9. ¿Cómo ubicar los códigos en la Tabla? La posición que ocupan los códigos en la Tabla no resulta aleatoria y de ello depende en gran medida la manera en que haremos los accesos a los códigos almacenados en ella. En nuestro caso las posiciones que ocupen los diferentes códigos dentro de la tabla vendrán dados por el numero decimal que el mismo representa, de forma tal que, el código de Lámpara de 7 Segmentos del numero decimal 0 debe ocupar la localización 0 en la Tabla, la del 1 la localización 1 y así sucesivamente hasta que el código de Lámpara de 7 Segmento del numero decimal 7 ocupa la localización 7. De forma tal que la Tabla quedaría almacenada en memoria tal y como se muestra en la Figura 6.3.7.

Figura 6.3.7.

Microcontroladores. El 8051 de la INTEL.

262

La pregunta a responder en este momento sería, ¿Cómo encontrar el código deseado a partir del número Binario declarado mediante los interruptores? Si tomamos al número Binario declarado mediante los Interruptores como el desplazamiento y lo sumamos al valor de la dirección de inicio de la Tabla, la nueva dirección obtenida se corresponde con la dirección de la localización donde se encuentra almacenado el código de Lámpara de 7 Segmentos correspondiente al numero decimal que se relaciona con el numero binario declarado, por lo que todo lo que tenemos que hacer en el programa es leer el contenido de la localización en cuestión y con ello tenemos el código de Lámpara de 7 Segmentos a escribir en el Puerto 2. A continuación se muestra el fragmento de programa propuesto para resolver este ejercicio.. ; Este programa toma el número Binario declarado a través de los Interruptores conectados al ; Puerto 1 y muestra el correspondiente numero decimal a través de la Lámpara de 7 Segmentos ; conectada al Puerto 2. org

0

; Dirección inicio programa 0000H.

; Apaga todos los segmentos de la Lámpara. mov

P2, #11111111b

; Selecciona al Puerto 1 como de Entrada. mov

P1, #0FFh

; Toma el número Binario. lazo:

mov

A, P1

; Lee el estado de los Interruptores

anl

A, #00001111b ; Se queda con los cuatro últimos bits.

; Busca código en la Tabla. mov

dptr, #Tabla

; Declara PUNTERO a la Tabla.

; La Tabla va a estar almacenada en Memoria de Programa. movc A, @A+dptr

; Toma el código deseado de la Tabla.

; Envía el código de LAMPARA DE 7 Segmento al Puerto 2. mov

P2, A

jmp

lazo

; Hace repetitivo el programa

; Declaración de la Tabla con los códigos de Lámpara de 7 Segmentos para una lámpara de ánodo ; común. La tabla se almacenará en memoria de Programa en las localizaciones siguientes al ; código del Programa principal. Tabla:

db end

40h, 79h, 24h, 30h, 19h, 12h, 02h, 78h, 00h ; Fin del programa

Microcontroladores. El 8051 de la INTEL.

263

Observe del programa que la Tabla se encuentra almacenada en la Memoria de Programa en las localizaciones inmediatas después al código de la última instrucción del mismo. Para declarar la tabla empleamos la directiva, db

numero

la que es utilizada para declarar datos del tipo byte en los programas. Que la Tabla se encuentre almacenada en la Memoria de Programa es la razón por la que en el dato es extraído de la misma mediante una instrucción del tipo, movc A,@A+DPTR destinada para efectuar la lectura del contenido de las localizaciones de Memoria de Programas. Si bien los display formados por Lámparas de 7 Segmentos llenaron una etapa relativamente grande de los sistemas basados a microcontroladores, en la actualidad estos están siendo desplazados por los Display a Cristal Liquido atendiendo a las mayores posibilidades que estos brindan y a los bajos costos a los que se pueden encontrar los mismos en el mercado. El objetivo del próximo ejercicio es el de presentarnos un fragmento de programa con su correspondiente hardware que le permite enviar carteles, almacenados en la Memoria de Programas en forma de Tablas, hacia un display de este tipo. 6.4 Trabajando con Display a Cristal Liquido. Diseñar un sistema donde al microcontrolador 8051 se le conecta un Display a Cristal Liquido de 2 Líneas y 16 Caracteres por Línea muy popular y fabricado por diferentes Empresas como la Philips, la Sharp, etc. Dos Interruptores Simple Polo-Simple Tiro le permiten al usuario escoger mediante la combinación de cerrado-abierto de los mismos, diferentes carteles a mostrar por el Display y previamente almacenados en la Memoria de Programas del microcontrolador. En la solución de este ejemplo aparece como elemento nuevo el trabajo con Display a Cristal Líquido, LCD, conjuntamente con un conjunto de aspectos que hemos ido enfrentando en la solución de los ejemplos anteriores como lo constituye, el trabajo con Interruptores, la Toma de Decisiones, el trabajo con Tablas almacenadas en la memoria de Programas, etc. El esquema del sistema que le proponemos es el que se muestra en la Figura 6.4.1

Microcontroladores. El 8051 de la INTEL.

264

Figura 6.4.1 No pretendemos dar todos los detalles sobre los LCD, esto usted lo puede encontrar en los manuales de los fabricantes o en diferentes materiales que estos publican en sus paginas Web, solamente daremos la información imprescindible para poder comprender el ejemplo. El LCD que vamos a utilizar para resolver el ejemplo es el LM016L, el que puede interconectarse directamente, con el bus de datos de cualquier microprocesador o microcontrolador, gracias a que tiene un bus de datos con tres estados. Además contiene una memoria RAM que le permite almacenar hasta 128 caracteres y una memoria ROM con 160 caracteres matriciales de 5x7 puntos, y 30 caracteres de 5x10 puntos. La ventana del display permite ver 32 caracteres a la vez, en 2 líneas de 16 caracteres cada una. El nombre de sus 14 terminales con su correspondiente número y función se muestra a continuación: TERMINAL

SEÑAL

FUNCION

1

GND

Voltaje de Referencia de Tierra o 0 Volt

2

VDD

Voltaje de Alimentación Positivo, 5 Volts

Microcontroladores. El 8051 de la INTEL. 3

Vo

Voltaje de Contraste.

4

RS

Selección del tipo de Dato enviado.

265

RS =1 Dato a Mostrar por el Display. RS =0 Comando. 5

R/W

Selección de operación sobre el Display. R/W =0 Escritura R/W =1 Lectura.

6

E

Habilitación del Display. E =0 Habilitado E =1 Deshabilitado

7

DB0

Bit Menos Significativo del Dato/Comando

8-13

DB1-DB6

Bits del 1 al 6 del Dato/Comando.

14

DB7

Bit Más Significativo del Dato/Comando.

Tomando en cuenta la distribución de los terminales y sus funciones es que se conecto el display al microcontrolador en el ejemplo que nos ocupa. El Bus de Datos del display se conecto al Puerto 1 y por lo tanto a través de este es que se generarán los datos y las comandos que se envíen al mismo por el programa. La entrada de habilitación del display se conectó al terminal P2.2 del microcontrolador y a través de la misma es que se controlará la habilitación o no del mismo imponiendo un ´0´ o un ´1´ en dicho terminal. La selección de si lo que se envía es un dato o una comando se efectuará imponiendo un ´0´ o un ´1´ en el terminal P2.0 del microcontrolador el que es conectado al terminal RS del display. Hemos considerado que solo sobre el display se efectuarán operaciones de escritura, razón por la cual el terminal R/W del LCD lo hemos conectado a GND del sistema. La pregunta a contestar en este momento podría ser, ¿Cómo trabajar mediante Programa con este display? Para dar respuesta a las preguntas anteriores conozcamos las principales comandos a enviar a este display para su programación. El procedimiento para inicializar el display es el siguiente: 1. Primeramente se establece el tamaño del Bus a través del cual se va a comunicar el LCD con el Microcontrolador. En nuestro caso, hemos escogido el Puerto 2 del Microcontrolador completo para establecer esta comunicación por lo que este Bus será de 8 bits. Para definir esto en la primera Comando enviada al Display (RS =0), los bits DB5 y DB4 deben

Microcontroladores. El 8051 de la INTEL.

266

ser puesto a ´1´, lo que se especifica que el tamaño del Bus de Datos es de 8 bits. En esta misma Comando el bit DB3 indica el número de líneas del Display con que se trabajará, en nuestro caso 2 por lo que este bit se debe poner a ´1´. Con lo que queda conformada la primera Comando a enviar al LCD en nuestra aplicación la que se corresponde con el número en hexadecimal 38H. NOTA: Ejecutar cada instrucción, toma un tiempo al LCD que puede variar entre 40 ms y 1.64 ms, en dependencia de la Comando que sea, por lo que se hace imprescindible esperar este tiempo como mínimo antes de enviar la próxima Comando. Para el caso particular de la primera Comando este tiempo a esperar es de 40 ms. 2. Como segundo paso se debe limpiar toda la memoria de Display del LCD y activar el Cursor. Para ello la Comando (RS =0) que se envía al Display es la correspondiente al numero en hexadecimal 01H. Esta instrucción toma un tiempo de 1.64 ms. 3. Lo próximo a definir al LCD está relacionado con el movimiento que se le establecerá a la información en el Display lo que se corresponde con la manera que irán apareciendo en este los caracteres alfanuméricos enviados. En nuestro caso estableceremos el movimiento del cursor de izquierda a derecha, lo que se corresponde con la Comando cuyo número hexadecimal es 06H. Esta instrucción toma un tiempo de 40 ms. 4. Ya en este momento se esta listo para encender la Pantalla del LCD y activar el cursor señalando la posición del próximo carácter de entrada. Para ello la Comando a enviar se corresponde con el número hexadecimal 0EH. Esta Comando también desactiva el parpadeo. Esta Comando toma 1.64 ms. 5. En la próxima Comando se debe definir la posición a partir de la cual se desea que comiencen a aparecer los caracteres enviados en el Display, esto esta estrechamente relacionado con el posicionamiento del Cursor. En nuestro caso posicionaremos el Cursor en el primer carácter de la primera línea, para ello la Comando a enviar se corresponde con el número hexadecimal 80H. Esta instrucción toma un tiempo de 40 ms. 6. A partir de este momento se puede comenzar a enviar los caracteres que se desean exhibir (RS =1) dejando un tiempo entre envío de 40 ms. La pregunta a responder en este momento sería, ¿En qué formato tengo que enviar los Datos a mostrar en el Display?

Microcontroladores. El 8051 de la INTEL.

267

Los caracteres a enviar deben estar representados por su correspondiente código ASCII. Por ejemplo si se desea enviar las letras A y B al Display, se debe enviar primero el código ASCII de la letra A (41H) esperar 40 ms y después enviar el código ASCII de la letra B (42H). De la manera en que hemos programado el Display, con cada escritura de un carácter en el Display el cursor se incrementará de forma automática en una posición hacia la derecha. Un aspecto de suma importancia en el trabajo con el LCD lo constituye de que el no es capaz por si solo de cambiar hacia la segunda línea una vez que la primera se encuentre completamente llena. Esto nos va a ocurrir con frecuencia en el trabajo con los LCD por lo que debemos estar claros como actuar en estos casos. Si usted quiere cambiar la línea donde están apareciendo los caracteres en el Display hacia la segunda usted debe enviar la Comando cuyo número hexadecimal es C0H, con lo que el cursor se posicionará en el lugar del primer carácter de la segunda línea. A continuación se muestra el Programa que permite mostrar en el Display los carteles ´hola a todos´ y ´MicroLab´ almacenados en forma de Tablas en la Memoria de Programas del Microcontrolador en dependencia del estado de los Interruptores conectados en P3.0 y P3.2. ; El siguiente fragmento de programa muestra por LCD dos carteles diferentes en dependencia del ; Interruptor que se encuentre apretado. org

0

; inicio del Programa

mov

P2, #0FFh

; deshabilita el LCD

mov

P3, #0FFh

; Puerto 3 como entrada

; Llamada a la Subrutina que garantiza la secuencia de comandos de inicio para la programación ; del LCD. call

lcd_ini

; secuencia de inicio del LCD

; Encuesta de los terminales P3.0 y P3.2 para escoger el cartel a mostrar. encuesta:

jnb

P3.0, mensaje1

jnb

P3.2, mensaje2

jmp

encuesta

; proceso cíclico.

; Se muestra el mensaje numero 1. mensaje1:

mov

R0, #0

mov

R4, #0

; declara el desplazamiento dentro de la tabla para recorrer ; todo el cartel.

clr

P2.0

; pone a RS en ´0´ (modo comando)

mov

P1, #00000001b ; borra LCD y Home.

Microcontroladores. El 8051 de la INTEL. call

lcd_e

; habilita al Display

call

delay_164

; demora de 1.64 ms.

mov

dptr, #tablad1 ; puntero de la Tabla del cartel 1.

jmp

otrod

; Se muestra el mensaje numero 2. mensaje2:

otrod:

mov

R0, #0

mov

R4, #0

clr

P2.0

mov

P1, #00000001b ; borra LCD y Home.

call

lcd_e

; habilita al Display

call

delay_164

; demora de 1.64 ms.

mov

dptr, #tablad2 ; puntero de la Tabla 2.

mov

a, R4

; pone RS en ´0´ (modo comando)

; carga desplazamiento en Tabla

movc a, @a+dptr

; extrae carácter a mostrar de la Tabla

jz

encuesta

; ¿ Fin del cartel?

clr

P2.0

; pone RS en ´0´ (modo comando)

mov

p1,a

; valor ASCII a sacar por Puerto1

setb

p2.0

; pone RS en ´1´ (modo dato).

inc

R0

inc

R4

call

lcd_e

; habilita al Display

call

delay_c

;demora de 0.4 ms.

jmp

otrod

; Subrutina para la inicialización del Display. lcd_ini: otroc:

mov

R1, #0

; desplazamiento en la tabla de Comandos

mov

dptr, #tablac

; puntero a Tabla de Comandos.

mov

a, R1

movc a, @a+dptr

; saca de la tabal la Comando a enviar.

clr

P2.0

mov

p1, a

inc

R1

call

lcd_e

call

delay_40

cjne

R1,#4, otroc

; ¿ Fin de programación del LCD?

clr

P2.0

; pone a RS en ´0´ (modo comando)

mov

P1, #00000001b ; borra LCD y Home.

call

lcd_e

call

delay_164

268

Microcontroladores. El 8051 de la INTEL.

269

ret ; Subrutina que genera el pulso de habilitación del Display. lcd_e:

setb

P2.2

; pone a E en ´1´

P2.2

; pone a E en ´0´

nop clr ret ; Subrutinas de demora de 40us y 1,64ms delay_40:

mov

R6, #40

lazo1:

djnz

R6,lazo1

ret delay_164:

mov

R7,#41

lazo2:

acall

delay_40

djnz

R7,lazo2

ret delay_c:

mov

R5,#100

lazo3:

acall

delay_164

djnz

R5,lazo3

ret salir:

jmp

$

tablac:

db

38h,06h,0Eh,80h,0fh

tablad1:

db

'hola a todos'

db

0

db

'MicroLab'

db

0

tablad2:

end En este ejemplo queremos destacar los seis aspectos siguientes: 1. El Programa trabaja con tres Tablas almacenadas en la Memoria de Programa, dos son para almacenar los códigos ASCII de los caracteres alfanuméricos que componen los dos carteles y la tercera contiene los números en hexadecimal de las Comandos a enviar al LCD para su programación. 2. Las Tablas con los carteles terminan con el número hexadecimal 00H, el que no se corresponde con ningún carácter ASCII posible a formar parte de los carteles. Es por esto que el programa para detectar que ya termino de enviar el cartel escogido hacia el LCD emplea la instrucción, jz

encuesta

; ¿ Fin del cartel?

cada vez que extrae un carácter de la Tabla.

Microcontroladores. El 8051 de la INTEL. 3.

270

Observe la forma de declarar las tablas con los carteles, tablad1:

db

'hola a todos'

db

0

el cartel entre apostrofe le indica al Programa Ensamblador que de cada carácter alfanumérico tome su número ASCII. 4. Por su parte la Tabla con las Comando se conoce su final, ya que se sabe el número de Comandos a enviar, en este caso son 4. Por o que para conocer que se ha terminado de enviar las Comandos almacenadas en esta Tabla y con ello terminada la programación del LCD se emplea un contador, el que es definido mediante la instrucción, lcd_ini:

mov R1, #0

; desplazamiento en la tabla de Comandos

este contador es incrementado cada vez que se envia una Comando al LCD y se conoce el final del proceso cuando este contador llega a 4, lo que se hace mediante la instrucción, cjne R1,#4, otroc

; ¿ Fin de programación del LCD?

5. Se emplean dos Subrutinas para generar las dos demoras necesarias de 40 milisegundos y 164 milisegundos con los nombres de delay_40 y delay_164. La segunda aprovecha que 40 milisegundos es la cuarta parte de 164 milisegundos para generar la demora. Ambas subrutinas se basan en el tiempo que le toma al Microcontrolador ejecutar la instrucción djnz. 6. Se hace necesario generar un pulso de habilitación al LCD por su terminal E, cada vez que se desea enviar una comando o escribir un carácter en el mismo. Este terminal normalmente se encuentra a ´0´, por lo que cuando se va a generar el pulso lo que se hace es llevarlo a ´1´ mantenerlo en este valor durante un tiempo y retornarlo nuevamente a ´0´. Para ello se emplea la Subrutina lcd_e, la que mediante el empleo de las instrucciones, setb

P2.2

; pone a E en ´1´

clr

P2.2

; pone a E en ´0´

ponen a ´1´ y a ´0´ respectivamente el terminal P2.2 del Puerto 2 al que esta conectado el terminal de entrada E del LCD. Existen eventos que ocurren de forma impredecibles en el tiempo y con un tiempo de duración finito, que si no son capturados por el microcontrolador en el momento oportuno, dicha información se pierde con el consiguiente mal funcionamiento del sistema. Un ejemplo de este tipo de dispositivo lo constituye una Tecla del tipo ´Push Botom´. Veamos un ejemplo donde utilizamos dispositivos de este tipo. 6.5 Trabajando con Teclas del tipo ´Push Botom´. Hasta ahora para introducir datos al Microcontrolador solo habíamos utilizado Interruptores del tipo Simple Polo-Simple Tiro, sin embargo existen otros dispositivos muy utilizados en estos sistemas

Microcontroladores. El 8051 de la INTEL.

271

como pueden ser las Teclas del tipo ´Push Botom´, a la que llamaremos a partir de este momento en el material como Tecla. ¿Qué diferencia existe entre un Interruptor y una Tecla? Del Interruptor ya conocemos que es un dispositivo que tiene dos estados estables, cerrado y abierto. Para moverse de un estado a otro se hace necesario de una acción mecánica, por lo general accionar una palanca, que lo haga salir del estado estable en que se encuentre. Por su parte la Tecla presenta un estado estable y otro estado cuasiestable funcionando de la siguiente manera: en el estado estable se mantendrá de forma indefinida hasta que una acción mecánica, por lo general presionar la Tecla, lo lleve a su estado cuasiestable. En este estado se mantendrá mientras la acción que lo llevo al mismo se mantenga, una vez que esta acción cese, la Tecla retornará por si sola a su estado estable. ¿Cuál es el estado estable de la Tecla, el cerrado o el abierto? ¿Cuál es el estado cuasiestable de la Tecla, el cerrado o el abierto? Se fabrican Teclas que indistintamente su estado estable puede ser el abierto mientras que el cuasiestable sea el cerrado y viceversa. En el caso de que el estado estable de la Tecla sea el abierto se dice que la Tecla es Normalmente Abierta (NA), en el otro caso se dice que la tecla es Normalmente Cerrada (NC). En la Figura 6.5.1 se muestra el modo de operación y de conexión de una Tecla del tipo NA. El terminal ´salida´ es el que se conectaría a uno de los terminales del Puerto del Microcontrolador seleccionado para tales fines.

Figura 6.5.1

Microcontroladores. El 8051 de la INTEL.

272

¿Qué es lo que provoca que la Tecla una vez liberada de la acción que la llevo a su estado cuasiestable retorne a su estado estable? Es una causa puramente constructiva, ya que las Teclas cuentan con un muelle que es el que provoca el retorno al estado estable. ¿Cómo atender dicha Tecla en el Programa? Supongamos que una Tecla de este tipo se encuentra conectada a un terminal cualquiera de un Puerto cualquiera del Microcontrolador. El Programa para conocer si dicha Tecla fue apretada la operación que efectuará será la de encuestar cada cierto tiempo el valor impuesto en dicha entrada de forma tal que, si el valor impuesto es el de ´1´ lógico es porque la Tecla no esta siendo apretada, pero si por el contrario el valor impuesto es el de ´0´ lógico es porque la tecla esta siendo apretada y por lo tanto el Programa podrá efectuar la operación que ordena dicha Tecla. Hasta aquí todo marcha bien pero, ¿Qué sucederá si el programa vuelve a encuestar el estado de la Tecla durante el tiempo que el usuario continua con la esta apretada? EL Programa detectará que en el terminal correspondiente esta impuesto un valor lógico de ´0´ y por tanto interpretará que la Tecla ha sido apretada nuevamente repitiendo la operación. Este efecto por su puesto seria indeseable para el buen funcionamiento del equipo. ¿Cómo eliminar este efecto indeseable? El Programa no debe validar nuevamente Tecla Apretada hasta que no detecte que se ha impuesto un valor lógico de ´1´ en el terminal lo que representa Tecla Liberada. Un Diagrama en Bloques de un posible fragmento de programa se muestra en la Figura 6.5.2.

Microcontroladores. El 8051 de la INTEL.

273

Figura 6.5.2. Resolvamos el siguiente ejemplo a modo de aplicar lo estudiado en este aspecto. Mostrar a través de una Lámpara de 7 Segmentos las veces que se aprieta una Tecla a la que llamaremos T. El efecto de apretar la Tecla provocará que el conteo sea ascendente o descendente, en dependencia del estado en que se encuentre un Interruptor al que llamaremos I. Si el Interruptor se encuentra abierto, incrementar el conteo, si el Interruptor esta cerrado, decrementar el conteo. Un posible hardware para el problema planteado podría ser el que se muestra en la Figura 6.5.3.

Figura 6.5.3

Microcontroladores. El 8051 de la INTEL.

274

Observe del hardware propuesto que la Lámpara de 7 Segmentos es conectada al Puerto 2 a través de ´buffer´ tres estados no inversores como son los que tiene el Circuito Integrado 74244. La razón de esto es porque hemos escogido Lámparas de 7 Segmentos de Ánodo Común, como las del último ejemplo del Tema anterior, pero, que para lograr la iluminación requerida necesitamos de una corriente IL a través de cada LED de al menos 15 mA, por lo que el Microcontrolador por si solo no sería capaz de garantizar los niveles de potencia requeridos para el buen funcionamiento de la Lámpara de 7 Segmentos. Recordemos que las Lámparas de 7 Segmentos de Ánodo Común los LED se encienden cuando en el correspondiente terminal al segmento se aplica un ´0´. El conjunto Interruptor-Tecla es a través del que el usuario interactúa para llevar a cabo la tarea que desea hacer. El interruptor es conectado al terminal P0.1 del Microcontrolador de forma tal que Interruptor Cerrado en P0.1 se impone un ´0´, mientras que Interruptor Abierto impone un ´1´. A través de este Interruptor es que el usuario define si la acción de apretar la tecla se toma como un incremento o como un decremento. Por su parte la Tecla esta conectada al terminal P0.0 de forma tal que Tecla apretada en el terminal se impone un ´0´ y Tecla no apretada se impone un ´1´ en el terminal. Resumiendo: 9

Un ´0´ en un terminal del Puerto 2, el segmento correspondiente se encenderá.

9

Un ´1´ en un terminal del Puerto 2, el segmento correspondiente se apagará.

9

Un ´0´ en el terminal P0.0, la Tecla esta apretada.

9

Un ´1´ en el terminal P0.0, la Tecla no esta apretada.

9

Un ´0´ en el terminal P0.1, el Interruptor esta cerrado.

9

Un ´1´ en el terminal P0.1, el Interruptor esta abierto.

El Diagrama en Bloques del software diseñado se muestra en la Figura 6.5.4.

Microcontroladores. El 8051 de la INTEL.

275

Figura 6.5.4 El Programa es el que se muestra a continuación. ; Este Programa incrementa o decrementa el número mostrado a través de la Lámpara de 7 ; Segmentos en dependencia del estado en que se encuentra el Interruptor conectado a P0.1 cada ; vez que la Tecla conectada a P0.0 es apretada. ; Para la obtención de los Códigos de Lámparas de 7 Segmentos se emplea una Tabla ; almacenada en la memoria de Programa del Microcontrolador conjuntamente con el Programa. org

0

; inicio del Programa en la dirección 0000H

mov

P2, #0FFH

; apaga todos los LEDs de la Lámpara.

mov

P0, #0FFH

; selecciona al Puerto 0 como de entrada.

; En el registro R3 se llevara el conteo de la cantidad de veces que la Tecla ha sido apretada. mov

R3, #0

; Inicializa el conteo en el número 0.

; Convierte el número binario almacenado en R3 a su correspondiente código de Lámpara de 7 ; Segmentos. inicio:

mov

A, R3

mov

DPTR, #Tabla ; carga en DPTR el puntero de la Tabla

movc A,@A+DPTR

; extrae de la tabla el Código de Lámpara.

; Escribe en la Lámpara de 7 Segmentos. mov

P2,A

; Espera por Tecla apretada. espera1:

jb

P0.0, espera1 ; ¿tecla apretada?

Microcontroladores. El 8051 de la INTEL.

276

; Chequea el estado del Interruptor. jnb

P0.1, decrementa ; ¿interruptor cerrado?

; Interruptor abierto, Incrementa el contador. inc

R3

; incrementa R3.

; Verifica si sobrepaso el número 9. ; Si lo sobrepaso, muestra el número 0 en la Lámpara. cjne

R3,#10,espera2

mov

R3,#0

; R3 igual a 10, ponlo a 0.

; Espera por Tecla Liberada. espera2:

jnb

P0.0, espera2

jmp

inicio

; muestra el numero en curso en Lámpara.

; Antes de decrementar verifica si el contador esta en 0. decrementa:

cjne

R3,#0,otro

; Contador el 0, carga el número 9 en el contador. mov

R3,#9

jmp

inicio

; muestra número en curso en Lámpara.

; Contador desigual de 0, decrementa el contador. otro:

dec

R3

jmp

espera2

; muestra número en curso en Lámpara.

; Tabla con los Códigos de Lámparas de 7 Segmentos. Tabla:

db

40h, 79h, 24h, 30h, 19h, 12h, 02h, 78h, 00h, 10h

End Quisiéramos llamar la atención en los tres aspectos siguientes: 1. Al no poder predecir cuando el usuario del sistema apretará la Tecla y al emplear como técnica para detectar esta acción la de Encuesta, hemos tenido que poner la instrucción, espera1:

jb

P0.0, espera1

; ¿tecla apretada?

que obliga al Microcontrolador a dedicar todo su tiempo en no hacer otra tarea que la de estar vigilando cuando el terminal P0.0 toma el valor de ´0´ para detectar que la Tecla ha sido apretada. En este ejemplo esto no es problema ya que el Microcontrolador no tiene nada que hacer hasta que la Tecla sea apretada, pero de hecho existen aplicaciones donde el Programador no se puede dar ese lujo de ineficiencia en el trabajo del Microcontrolador. 2. Antes de pasar a detectar si la tecla es apretada nuevamente, se hace necesario detectar que la tecla fue liberada ya que la acción mecánica de apretar y liberar la Tecla es mucho más lenta que la operación del Microcontrolador. Esto se logra con la instrucción,

Microcontroladores. El 8051 de la INTEL. espera2:

jnb

277

P0.0, espera2

3. El valor no se actualiza en la Lámpara hasta que la Tecla sea liberada. Esto se logra al poner la instrucción, jmp

inicio ; muestra el numero en curso en Lámpara.

Que llama al fragmento de programa que escribe en la Lámpara, a continuación de la Instrucción que detecta que la Tecla ha sido liberada. Existen Teclas que funcionan tal y como lo hemos explicado hasta aquí, estas Teclas por lo general utilizan un efecto magnético para detectar cuando la Tecla ha sido apretada. No obstante, existen otro tipo que realizan esta operación puramente de forma mecánica el que introduce en la operación de la Tecla un efecto indeseable conocido como Rebote. La pregunta a contestar aquí sería, ¿Qué es el Rebote? ¿Cuál es el efecto indeseado que introduce? A estas preguntas le daremos respuesta en el próximo ejercicio al enfrentar la solución de el mismo problema anterior pero ahora empleando una Tecla con Rebote. 6.6 Eliminando el efecto indeseable del Rebote. ¿Qué tienen de particular este tipo de Teclas? Cuando el usuario aprieta una Tecla de este tipo, lo que produce es que dos contactos se unan de forma mecánica, sirviendo la tecla como el puente que provoca esta unión. Esta característica constructiva es la que introduce la mayor dificultad a la hora de trabajar con este tipo de Tecla en un sistema a Microcontroladores, el Rebote. Tratemos de justificar lo anterior. El muelle es un elemento que se opone a la Fuerza que hace la persona sobre la Tecla, cuando la presiona, esto provoca un estado inicial transitorio en el que los contactos de la Tecla no quedan unidos de forma permanente. Este tiempo transitorio durará hasta que la Fuerza ejercida por la persona se imponga, ocurriendo durante este tiempo un efecto de cierre de los contactos y abertura de forma repetitiva como si la tecla rebotara de ahí el nombre de Rebote para este efecto. Un proceso similar ocurre cuando la Tecla es liberada por el usuario, por lo que el efecto de Rebote ocurre tanto cuando la Tecla es apretada como cuando la Tecla es liberada, ver Figura 6.6.1.

Microcontroladores. El 8051 de la INTEL.

278

Figura 6.6.1 ¿Qué efecto tiene este modo de operación para nuestras aplicaciones? Analicemos el efecto del Rebote a la luz del ejemplo anterior. Ahora al encuestar el Programa el terminal al que esta conectada la Tecla y detectar un ´0´ este identificará que la Tecla ha sido apretada pasando a ejecutar las operaciones correspondiente. Si al terminar con las operaciones propias de la Tecla e ir a identificar si la Tecla fue liberada, esto ocurre antes de que termine el tiempo propio del efecto de rebote, puede traer confusión al Programa al detectar un ´1´ propio del proceso transitorio y no porque la Tecla haya sido liberada que era el objetivo de esta acción del Programa provocando que se valide más de una vez la tecla como apretada y no una sola como realmente ha ocurrido. ¿Cómo solucionar esto? Para ello no basta con que esperemos porque la Tecla se libere para pasar a revisar si la tecla es apretada nuevamente. Ahora debemos agregar dos nuevas acciones que están relacionadas con esperar un determinado tiempo tanto al detectar que la Tecla fue apretada como cuando se detecta que la Tecla fue liberada. Este tiempo a esperar vendrá determinado por el tiempo propio de rebote de la Tecla que se este utilizando en la aplicación. Ahora el Diagrama en Bloques del Programa seria el que se muestra en la Figura 6.6.2.

Microcontroladores. El 8051 de la INTEL.

279

Figura 6.6.2. ¿Cuánto puede ser el tiempo de demora? Un valor que garantiza una operación correcta y eficiente para la gran mayoría de las Teclas de este tipo es de 10 milisegundos, demora esta que puede ser generada por software. Ahora el Programa con los arreglos correspondientes se muestra a continuación. ; Este Programa incrementa o decrementa el número mostrado a través de la ; Lámpara de 7 Segmentos en dependencia del estado en que se encuentra el ; Interruptor conectado a P0.1 cada vez que la Tecla conectada a P0.0 es apretada. ; Para la obtención de los Códigos de Lámparas de 7 Segmentos se emplea ; una Tabla almacenada en la memoria de Programa del Microcontrolador ; conjuntamente con el Programa. ; Este Programa toma en cuenta el efecto del Rebote en la Tecla. org

0

; inicio del Programa en la dirección 0000H

Microcontroladores. El 8051 de la INTEL. mov

P2, #0FFH

; apaga todos los LEDs de la Lámpara.

mov

P0, #0FFH

; selecciona al Puerto 0 como de entrada.

; En el registro R3 se llevara el conteo de la cantidad de veces que la Tecla ha sido apretada. mov

R3, #0

; Inicializa el conteo en el número 0.

; Convierte el número binario almacenado en R3 a su correspondiente código de Lámpara. inicio:

mov

A, R3

mov

DPTR, #Tabla ; carga en DPTR el puntero de la Tabla

movc A,@A+DPTR

; extrae de la tabla el Código de Lámpara.

; Escribe en la Lámpara de 7 Segmentos. mov

P2,A

; Espera por Tecla apretada. espera1:

jb

P0.0, espera1 ; ¿tecla apretada?

; Espera 20 milisegundos para dejar pasar el tiempo del Rebote acall

demora20

; eliminando rebote.

; Valida que la tecla fue realmente apretada. jb

P0.0,espera1 ; valida que la tecla ha sido apretada.

; Chequea el estado del Interruptor. jnb

P0.1, decrementa ; ¿interruptor cerrado?

; Interruptor abierto, Incrementa el contador. inc

R3

; incrementa R3.

; Verifica si sobrepaso el número 9. ; Si lo sobrepaso, muestra el número 0 en la Lámpara. cjne

R3,#10,espera2

mov

R3,#0

; R3 igual a 10, ponlo a 0.

; Espera por Tecla Liberada. espera2:

jnb

P0.0, espera2

; Espera 20 milisegundos para dejar pasar el tiempo del Rebote. acall

demora20

; elimina la rebote.

, Valida que la Tecla fue realmente liberada. jnb

P0.0, salir

; valida liberación de la Tecla.

jmp

inicio

; muestra el numero en curso en Lámpara.

; Antes de decrementar verifica si el contador esta en 0. decrementa:

cjne

R3,#0,otro

; Contador el 0, carga el número 9 en el contador. mov

R3,#9

jmp

inicio ; muestra número en curso en Lámpara.

; Contador desigual de 0, decrementa el contador. otro:

dec

R3

280

Microcontroladores. El 8051 de la INTEL. jmp

espera2

281

; muestra número en curso en Lámpara.

Subrutina que provoca una demora de 20 milisegundos. demora20:

mov

R0,#100

; declara contador externo.

otro1:

mov

R1,#50

; declara contador interno.

lazo:

djnz

R1,lazo

; decrementa lazo interno

djnz

R0,otro1

; decrementa lazo externo.

ret

; retorno al Programa Principal.

; Tabla con los Códigos de Lámparas de 7 Segmentos. Tabla:

db

40h, 79h, 24h, 30h, 19h, 12h, 02h, 78h, 00h, 10h

End En este Programa queremos destacar tres elementos: 1. Se ha introducido como elemento nuevo en el Programa la instrucción, acall

demora20

; elimina la rebote.

tanto cuando se ha detectado por primera vez que la Tecla ha sido apretada como cuando se ha detectado por primera vez que la tecla ha sido liberada. Esta instrucción invoca una Subrutina que lo que provoca es que transcurra un tiempo de demora de 20 milisegundos antes de retornar, con lo que se deja pasar un tiempo prudencial para garantizar que el efecto del rebote haya terminado. 2. Seguido de la instrucción anterior se encuentran las instrucciones, jb

P0.0,espera1

; valida que la tecla ha sido apretada.

jnb

P0.0, salir

; valida liberación de la Tecla.

que como los comentarios de las mismas lo indican lo que se busca es corroborar que ha ocurrido realmente la acción especifica sobre la Tecla. Esto le da más seguridad y robustez al Programa eliminando cualquier fallo por la ocurrencia de ruidos. 3. La Subrutina demora20, la que se muestra a continuación, demora20:

mov

R0,#100

; declara contador externo.

otro1:

mov

R1,#50

; declara contador interno.

lazo:

djnz

R1,lazo

; decrementa lazo interno

djnz

R0,otro1

; decrementa lazo externo.

ret

; retorno al Programa Principal.

se basa en el tiempo que demora el Microcontrolador en ejecutar la instrucción djnz. Los dos lazos son por la imposibilidad de hacerlo en uno dado el tiempo que hay que demorar.

Microcontroladores. El 8051 de la INTEL.

282

6.7 Ejercicios Propuesto. Ejercicio 6.4.1. Dado 8 Interruptores Simple Polo - Simple Tiro conectados al Puerto 1 del 8051, haga el circuito y el programa que permita mostrar a través de 8 LEDs conectados al Puerto 2 si el Interruptor se encuentra abierto o cerrado. Para ello establezca una relación donde cada Interruptor se encuentre representado por un LED. Interruptor cerrado se debe indicar mediante el encendido del LED y el Interruptor abierto se debe indicar mediante el apagado del LED. En una Lámpara de 7 Segmentos de Ánodo Común conectado al Puerto 3 se debe indicar el número de Interruptores cerrados. Punto de Operación del LED 1.8V, 15 miliamperes. Punto de Operación de la Lámpara 2.0V, 10 miliamperes. Ejercicio 6.4.2. Dada una Tecla conectada a uno de los terminales del Puerto 1 y un Interruptor Simple Polo – Simple Tiro conectado a un terminal del Puerto 2, hacer el circuito y el programa que permita contar el numero de veces que la Tecla es apretada. El sistema debe permitir que el conteo sea decreciente o en incremento, dependiendo esto de si el Interruptor esta cerrado (en incremento) o abierto (en decremento). Cada vez que la Tecla se aprieta una vez el valor del conteo se debe alterar en 1, mostrándose el mismo en una Lámpara de 7 Segmentos del tipo Ánodo Común conectada al Puerto 3 del Microcontrolador. Cuando el conteo llegue a 9 con el próximo apretado de la Tecla debe pasar a 0 si se encuentra el Interruptor en incremento, en el caso contrario si se encuentra en 0 con el próximo apretado de la Tecla si el Interruptor se encuentra en decremento se debe pasar a 9. Punto de Operación de la Lámpara 2.0V, 10 miliamperes. Ejercicio 6.4.3. Se cuenta con un sistema basado en el 8051 en el que 4 Interruptores Simple Polo – Simple Tiro se encuentran conectados al Puerto 1 y 8 LEDs se encuentran conectados al Puerto 3. Se desea hacer un programa que haga encender los LED de forma diferente en dependencia del Interruptor que se encuentre cerrado, según lo indicado a continuación, 9

Interruptor 1 cerrado Encender y apagar los LEDs de forma intermitente.

9

Interruptor 2 cerrado Encender los LED de izquierda a derecha.

9

Interruptor 3 cerrado Encender los LED de derecha a izquierda.

9

Interruptor 4 cerrado Encender los LED de adentro hacia fuera.

Microcontroladores. El 8051 de la INTEL.

283

En todos los casos las secuencias deben ser cíclicas y nunca debe haber dos Interruptores cerrados a la misma vez. Punto de Operación del LED 1.8V, 15 miliamperes. Ejercicio 6.4.4. Diseñar un dado electrónico basado en el 8051. Para ello cuenta con una Tecla conectada al Puerto 3 y una Lámpara de 7 Segmentos de Ánodo Común conectada al Puerto 1. El efecto de tirar el dado lo representa el apretar la Tecla y el número del dado que sale debe aparecer en la Lámpara de 7 Segmentos. Los números están comprendidos entre el 1 y el 6. Punto de Operación de la Lámpara 2.0V, 10 miliamperes. Ejercicio 6.4.5. Se desea diseñar un Generador de Secuencias de Códigos basado en el 8051. Para ello se cuenta con una Tecla conectada a uno de los terminales del Puerto 2, 2 Interruptores Simple Polo - Simple Tiro conectados a dos terminales del Puerto 3 y un conjunto de 8 LEDs conectados al Puerto1. Son dos las posibles secuencias a generar la de los números pares del 0 al 255 y la de los números impares del 0 al 255. La secuencia escogida se muestra a través del encendido y apagado de los LEDs y es escogida en dependencia de cual de los Interruptores es el que se encuentra cerrado, Interruptor 1 cerrado la secuencia de los números pares, el Interruptor 2 cerrado la secuencia de los números impares. El movimiento a través de una secuencia se hace apretando la Tecla y en caso de cambiar de secuencia esta debe comenzar por el número en que se había quedado. Las secuencias deben ser cíclicas de forma tal que una vez llegado a su número mayor comenzar por el número menor. Punto de Operación del LED 1.8V, 15 miliamperes. Ejercicio 6.4.6. Se desea diseñar un Codificador basado en el 8051. Para ello se cuenta con 8 Interruptores Simple Polo – Simple Tiro conectados al Puerto 2, con 4 LEDs conectados al Puerto 1 y con una Lámpara de 7 Segmentos de Ánodo Común conectada al Puerto 3. Los Interruptores son numerados del 1 al 8 y en los LEDs debe aparecer reflejado mediante su encendido el número en binario correspondiente al Interruptor que este cerrado. Un LED encendido representa un ´1´ y un LED apagado representa un ´0´. Al mismo tiempo en la Lámpara de 7 Segmentos debe aparecer reflejado el número en decimal correspondiente al Interruptor cerrado. En un instante de tiempo solo debe estar cerrado un Interruptor. Punto de Operación del LED 1.8V, 15 miliamperes.

Microcontroladores. El 8051 de la INTEL.

284

Punto de Operación de la Lámpara 2.0V, 10 miliamperes. Ejercicio 6.4.7. Se desea diseñar un Decodificador basado en el 8051. Para ello se cuenta con 3 Interruptores Simple Polo – Simple Tiro conectados al Puerto 2, con 8 LEDs conectados al Puerto 1 y con una Lámpara de 7 Segmentos de Ánodo Común conectada al Puerto 3. Los Interruptores son nombrados como A, B y C siendo A el bit menos significativo y C el bit más significativo del número binario que representan. Interruptor cerrado es un ´1´ y un Interruptor abierto es un ´0´. En los LEDs se debe encender el LED correspondiente al número binario declarado mediante los Interruptores. Al mismo tiempo en la Lámpara de 7 Segmentos debe aparecer reflejado el número en decimal correspondiente al número binario declarado con los Interruptores. Punto de Operación del LED 1.8V, 15 miliamperes. Punto de Operación de la Lámpara 2.0V, 10 miliamperes. Ejercicio 6.4.8. Se desea implementar un Circuito Combinacional Multiterminal de 4 entradas y 4 salidas con un 8051. Las entradas serán representadas mediante 4 Interruptores Simple Polo – Simple Tiro conectadas al Puerto 1 y serán nombradas como a, b, c y d, donde a constituye el bit menos significativo y d el bit más significativo. Por su parte el valor de las 4 salidas será mostrado a través de 4 LEDs conectados el Puerto 3. Las Funciones de Conmutación son las mostradas a continuación,

F1 (a, b, c, d ) = ∑ (0,3,5) + ∑ (7,9,10 ) Φ

F2 (a, b, c, d ) = ∑ (1,4,14) + ∑ (7,9,10 ) Φ

F3 (a, b, c, d ) = ∑ (3,5,11) + ∑ (7,9,10) Φ

F4 (a, b, c, d ) = ∑ (2,6,13) + ∑ (7,9,10 ) Φ

Punto de Operación del LED 1.8V, 15 miliamperes. Ejercicio 6.4.9. Se desea diseñar un circuito detector de secuencia con el 8051. La secuencia vendrá dada por un conjunto de 3 dígitos decimales entre los dígitos del 1 al 4. Para la entrada de los dígitos de la

Microcontroladores. El 8051 de la INTEL.

285

secuencia se cuenta con 4 Teclas conectadas al Puerto 1 del Microcontrolador, una Tecla para representar cada digito decimal. El resultado positivo o no de entrar la secuencia previamente definida se mostrara mediante el encendido de un LED conectado al Puerto 3 del Microcontrolador. Una Lámpara de 7 Segmentos conectada al Puerto 2 mostrará el digito decimal introducido al apretar la Tecla correspondiente. El sistema debe trabajar de forma cíclica. Punto de Operación del LED 1.8V, 15 miliamperes. Punto de Operación de la Lámpara 2.0V, 10 miliamperes. Existen aplicaciones con un mayor grado de complejidad que las que hemos enfrentado hasta aquí, que si bien podrían ser resueltas con lo que ya conocemos, podría resultar muy dificultoso y con una alta posibilidad de equivocarnos. El conocer otras posibilidades y potencialidades del microcontrolador, como podrían ser, el Temporizador, el Puerto Serie y la Interrupción, nos harían más sencilla esta faena. El estudio de estos tres elementos constituye el objetivo de los Temas que siguen.

Microcontroladores. El 8051 de la INTEL.

286

Tema 7. La Interrupción en el 8051. Con este Tema comenzamos una segunda etapa en el aprendizaje de las potencialidades del microcontrolador 8051, la que esta relacionada con lo que hemos dado en llamar los Servicios Adicionales del Microcontrolador o los Subsistemas Funciones Especiales o los Circuitos Empotrados. Por lo general, a los microcontroladores, se le adicionan un conjunto de servicios internos que amplían las capacidades de estos circuitos para resolver por si solos determinadas aplicaciones. Servicios tales como la atención de la Interrupción, la Temporización, la Comunicación Serie, la Conversión Análogo- Digital, etc., le dan un valor de uso superior a estos circuitos. En el caso particular del microcontrolador 8051, en su configuración básica, se le adicionan tres de estos servicios: 9

La Interrupción.

9

La Temporización.

9

La Comunicación Serie.

Este Tema tendrá como objetivo central, el estudio de la Interrupción como un servicio que brinda el microcontrolador para atender aquellos procesos cuya ocurrencia en el tiempo no puede ser predecible por el diseñador dentro de la aplicación. Al final del mismo debemos ser capaces de dar respuestas a preguntas tales como, ¿Qué es la Interrupción?, ¿En que casos es útil su utilización?, ¿Cómo tiene implementada la atención a la Interrupción el 8051? 7.1 Encuesta o Interrupción. Son dos las técnicas básicas para la atención de los eventos que su ocurrencia es impredecibles en el tiempo en los sistemas a microprocesadores y microcontroladores. Estas dos técnicas básicas se conocen con los nombres de Encuesta e Interrupción. En la técnica por Encuesta, ya abordada en el Tema anterior, el software juega un papel predominante ya que como su nombre lo indica, el microcontrolador se ocupa por programa de indagar constantemente la ocurrencia de dicho evento. Esta técnica, más económica del punto de vista de los circuitos necesarios para su implementación, ya que solo intervienen el microcontrolador y el dispositivo de Entrada/Salida que solicita su atención, por lo general ocupa

Microcontroladores. El 8051 de la INTEL.

287

mucho tiempo del procesador haciéndolo lento en la solución de determinadas aplicaciones y prohibitivo en algunos casos. En la técnica por Interrupción el microcontrolador se desentiende de si ocurre o no ocurre el evento, ya que una lógica adicional se encargará de vigilar su ocurrencia y emitirá un pedido de atención al Procesador cuando esta ocurra. Esta técnica libera al procesador de una gran cantidad de tiempo con lo que mejora su eficiencia y su velocidad en la solución de un problema en particular, quizás como desventaja tenga la necesidad de la existencia de la lógica que se encarga de vigilar de forma independiente la ocurrencia del evento. Analicemos estas dos técnicas a la luz de dos ejemplos de la vida cotidiana, con el objetivo de que nos ayuden a comprender mejor lo definido en los párrafos anteriores. Por lo general cuando usted esta esperando la ´guagua´, usted está constantemente mirando hacia la calle por donde debe venir la misma para poder determinar cuando la misma viene. En este caso, este evento que es bastante impredecible en el tiempo, usted está empleando una técnica de Encuesta para determinar la llegada de la ´guagua´. En este ejemplo usted esta haciendo el papel del Procesador, y durante el tiempo que usted esta esperando la llegada de la ´guagua´, una sola preocupación le ocupa todo su tiempo y es el de detectar la llegada de la misma, quedándole muy poco tiempo para desarrollar otras tareas, fundamentalmente cuando estas son un tanto complejas, so pena de no detectar su llegada. El ejemplo quizás es un poco exagerado, pero nos parece que ilustra bien como empleamos esta técnica de la Encuesta para detectar la ocurrencia de un evento impredecible en el tiempo. Un caso bien diferente lo constituye el siguiente, supongamos que nos encontramos en la sala de nuestra casa leyendo un libro que nos resulta interesante, nosotros, el Procesador, estamos absortos en la lectura del libro, que es nuestra tarea fundamental en ese momento, a la que le estamos dedicando todo nuestro tiempo. No obstante, llegan algunos amigos de visita a la casa, estos para llamar nuestra atención tocan a la puerta, requiriendo nuestra atención. Esta acción nos ´´interrumpe´´ de la tarea que estábamos haciendo, leer el libro, para pasar a otra tarea que es la de atender a nuestros amigos. Este constituye un buen ejemplo de cómo se emplea la técnica de Interrupción en nuestra vida cotidiana. Le propongo que tratemos de aplicar la técnica de la Interrupción al evento de esperar la ´guagua´ y la técnica de la Encuesta al evento de detectar cuando los amigos llegan a la casa. En el primer caso, nos podemos desatender de vigilar la llegada de la ´guagua´ y dejar que un amigo que al igual que nosotros espera su llegada, nos interrumpa de la tarea que estemos

Microcontroladores. El 8051 de la INTEL.

288

haciendo indicándonos la llegada de la misma. En este caso hemos necesitado de un elemento externo, nuestro amigo, que nos avise de la ocurrencia del evento al igual que ocurrió anteriormente con el ejemplo de la visita a la casa. En el segundo caso, al aplicar la técnica de la Encuesta para detectar la llegada de los amigos mientras leemos, nosotros debemos constantemente interrumpir la lectura para dirigirnos a la puerta de la casa, abrir y mirar para ver si los amigos han llegado. Esta manera de comportarnos, aunque posible, no resulta muy lógica y menos aún cómoda y eficiente para nosotros. No obstante, los ejemplos de la vida diaria nos han servido para corroborar lo que habíamos definido anteriormente y que queremos resumir en las siguientes plecas: 9

La técnica de la Encuesta para la atención de eventos que ocurren de forma impredecibles en el tiempo, ocupan en un porciento muy alto el tiempo de trabajo del Procesador, por lo que se recomienda su utilización solo cuando el Procesador no tenga otra tarea que ejecutar mientras espera la ocurrencia del evento.

9

La técnica de Interrupción libera en un gran porciento el tiempo de trabajo del Procesador, por lo que se recomienda su utilización en aquellos sistemas donde el Procesador tenga que realizar otras tareas importantes mientras espera por la ocurrencia del evento.

9

Cuando se emplea la técnica de la Interrupción se hace necesario la existencia de una lógica que se encargue de sustituir al Procesador en la vigilancia de la ocurrencia del evento.

Como era de esperar una técnica es recomendada su utilización para unos casos y la otra para los casos contrarios complementándose perfectamente. En el caso de los microcontroladores, por lo general, la lógica adicional necesaria es materializada mediante un circuito que se encuentra empotrado en el circuito integrado. Este circuito se encargará de traducir los pedidos de atención de los dispositivos en un conjunto de acciones que le permitirán al Procesador, detectar cuando ocurre una solicitud y quien la solicita, para así pasar a atender de forma eficiente dicho pedido de atención. El 8051 no es una excepción, contando con un Controlador Interno de Interrupciones al que dedicaremos este Tema.

Microcontroladores. El 8051 de la INTEL.

289

7.2 El Controlador Interno de Interrupciones del 8051. El 8051 cuenta con un Controlador Interno de Interrupciones, con posibilidad de atender hasta 5 fuentes de interrupción, las cuales pueden ser enmascaradas por software, así como establecer prioridades de atención por parte del Programador a las mismas en el caso de simultaneidad o anidamiento. Las 5 posibles fuentes de interrupción son: 9

2 Externas, INT0 e INT1.

9

3 Internas, Temporizador 0, Temporizador 1 y Puerto Serie.

Las dos externas llegan al Controlador de Interrupciones a través de los mismos terminales que ocupan las señales P3.2 (12) y P3.3 (13), por lo que constituyen ENTRADAS ALTERNATIVAS de estas, ver Tema 5, Epígrafe 5.3 de este material. Por su parte, las tres internas llegan al Controlador de Interrupciones a través de tres señales internas independientes, dos de ellas generadas por los Temporizadores, una por cada uno, y una generada por el Puerto Serie. Por el momento contentémonos con conocer esto. Cada una de estas fuentes de interrupción están relacionadas con un almacenador de 1 bit, el que recibe el nombre de Bandera de Interrupción. ¿Qué relación existe entre un pedido de interrupción y las Banderas de Interrupción? Cuando una interrupción es solicitada, la Bandera de Interrupción correspondiente es activada, puesta a ‘1’ de forma automática, indicándole al Procesador que una solicitud de interrupción esta en curso. Las Banderas de Interrupción con el correspondiente registro al que pertenecen, se relacionan en la Tabla 7.2.1: FUENTES DE INTERRUPCIÓN

BANDERAS

REGISTRO

INTERRUPCIÓN EXTERNA 0

IE0

TCON

INTERRUPCIÓN EXTERNA 1

IE1

TCON

TIMER 0

TF0

TCON

TIMER 1

TF1

TCON

TI y RI

SCON

PUERTO SERIE

Tabla 7.2.1

Microcontroladores. El 8051 de la INTEL.

290

TCON y SCON son dos registros de 8 bits ubicados en la zona de memoria dedicada a los Registros de Funciones Especiales, ver Tabla 2.3.2 del Tema 2. En el primer párrafo de este epígrafe se dan tres elementos que caracterizan a la Interrupción en el 8051 que quizás puedan traer dudas en este momento, 9

enmascaradas por software.

9

prioridades de atención.

9

simultaneidad o anidamiento.

Aunque el significado de las tres palabras en negritas es del conocimiento del lector, nos parece que resulta conveniente explicar como se interpretan estas cuando estamos hablando de la Interrupción en el 8051. Interrupción Enmascarables por Software. Como se explico anteriormente todas las fuentes de interrupción en el 8051 son enmascarable por programas, por lo que el programador tiene la posibilidad, mediante instrucciones, de habilitar o no un pedido de interrupción. Si al ocurrir un pedido de interrupción por una cualquiera de las 5 posibles fuentes, dicha fuente de interrupción no esta habilitada, el 8051 ignorará dicho pedido continuando con la tarea que esta realizando, por el contrario, si al ocurrir un pedido de interrupción por una cualquiera de las 5 posibles fuentes, dicha fuente de interrupción está habilitada, el 8051 atenderá dicho pedido interrumpiendo la tarea que esta realizando Por lo que no basta con que ocurra el pedido de interrupción por parte del dispositivo y que la Bandera de Interrupción correspondiente se active sino que además dicha interrupción tiene que estar habilitada para ser atendida. En esta posibilidad que tiene el programador de habilitar o no una determinada fuente de interrupción es en lo que consiste el Enmascaramiento de la Interrupción. Lo que nos corresponde saber en este momento será, ¿Como habilitar o inhabilitar las diferentes fuentes de interrupción? El registro IE ubicado en la zona de memoria dedicada a los Registros de Funciones Especiales, permite al programador realizar esta tarea, de forma individual para cada una de las fuentes de interrupción o en conjunto. Este registro es direccionable bit a bit, lo que permite el empleo de las instrucciones del Grupo de Manipulación de Variables Booleanas para manejar de forma independiente el valor de los bits que lo conforman. En la Tabla 7.2.2 se muestra de forma

Microcontroladores. El 8051 de la INTEL.

291

resumida el nombre, la función que realiza y el significada de escribir un ´0´ o un ´1´ en cada uno de los bits de este registro.

Tabla 7.2.2. Estructura del registro IE. Veamos el siguiente ejemplo para comprender mejor el trabajo con este registro. Ejemplo 7.2.1. Se desea programar al Registro IE, de forma tal que estén habilitadas las interrupciones: 9

Externa INT0.

9

La del TIMER0.

9

La del Puerto Serie.

Estando inhabilitadas: 9

La Externa INT1.

9

La del TIMER1.

La programación del registro IE para las condiciones deseadas sería la siguiente: b7

b6

b5

b4

b3

b2

b1

b0

1

x

x

1

0

0

1

1

Dada la programación del registro IE hecha en el ejemplo anterior, si se efectúa por un dispositivo externo un pedido de interrupción por su terminal de entrada INT0, la bandera correspondiente IE0

Microcontroladores. El 8051 de la INTEL.

292

se activa, se pone a ‘1’, y dado que el bit del registro IE correspondiente a esta fuente de interrupción, EX0, esta a ‘1’, el 8051 atiende la interrupción y con ello al dispositivo que solicita atención. Si por el contrario la solicitud de interrupción ocurre por el terminal externo INT1, la bandera correspondiente IE1, se activa, se pone a ‘1’, pero como el bit del registro IE, EX1, esta a ‘0’, la interrupción no será atendida. La pregunta a responder en este momento sería, ¿Por qué se puso el bit 7 del registro IE en ´1´ en el ejemplo anterior? De la Tabla 7.2.2 conocemos que a través de este bit el programador tiene la posibilidad de inhabilitar todas las fuentes de pedido de Interrupción del microcontrolador de forma simultánea. Basta con que se ponga a ´0´ este bit del registro IE para que el microcontrolador enmascare los pedidos de Interrupción de todas las fuentes, no reconociendo a ninguno. Por lo tanto, si usted desea no enmascarar algunas de las posibles fuentes, como ocurre en el ejemplo anterior, este bit no puede estar a ´0´, de aquí la razón del ´1´ en este bit en el ejemplo anterior. La Prioridad de las Interrupciones. El 8051 permite al programador establecer dos niveles de prioridad de la interrupción a cada una de las posibles fuentes, conocidos con los nombres de prioridad alta y prioridad baja. Como es de esperar las fuentes de interrupción a las que se defina prioridad alta tienen mayor prioridad que aquellas a las que se le defina prioridad baja. ¿Cómo seleccionar el nivel de prioridad de una determinada fuente de interrupción? Esto es posible mediante la programación del registro IP, otro de los registros de 8 bit ubicado en la zona de memoria dedicada a los Registros de Funciones Especiales, ver Tabla 7.2.3.

BIT

NOMBRE

b0

PX0

En ´1´ define alta prioridad a la interrupción INT0

b1

PT0

En ´1´ define alta prioridad a la interrupción del TIMER0

b2

PX1

En ´1´ define alta prioridad a la interrupción INT1.

b3

PT1

En ´1´ define alta prioridad a la interrupción del TIMER1.

b4

PS

En ´1´ define alta prioridad a la interrupción del Puerto Serie.

b5-b7

COMENTARIO

Reservada. Tabla 7.2.3 Estructura del Registro IP.

Microcontroladores. El 8051 de la INTEL.

293

El programador tiene la posibilidad de definir individualmente y mediante programa, la prioridad de cada una de las fuentes de interrupciones. Todo lo que tiene que hacer es programar según sus necesidades los bits del registro IE. Veamos esto reflejado en la solución del ejemplo 7.2.2. Ejemplo 7.2.2. Programar a los registros IE e IP del 8051 para lograr la habilitación de la Interrupción de las fuentes, INT0, Temporizador 0 y el Puerto Serie, deseando darle mayor prioridad de atención a las dos primeras sobre la última. La programación del registro IE y el registro IP que se corresponde con la solución de los requerimientos del ejemplo sería, Registro IE. b7

b6

b5

b4

b3

b2

b1

b0

1

x

x

1

0

0

1

1

b7

b6

b5

b4

b3

b2

b1

b0

x

x

x

0

0

0

1

1

Registro IP.

Queda evidente que si dos peticiones de interrupción de distintos niveles de prioridad son recibidas simultáneamente, la interrupción de nivel de prioridad mayor es la atendida antes que la de menor prioridad, por lo que, si en el sistema del ejemplo se solicita al microcontrolador de forma simultanea la atención por Interrupción las fuentes INT0/ y el Puerto Serie, se atiende primero la solicitud de interrupción externa INT0/ y después de finalizada su atención, si aun se mantiene la solicitud de atención por parte del Puerto Serie, se pasa a atender esta. La pregunta a contestar en este momento sería, ¿Como resuelve el 8051 la situación de que dos fuentes de interrupción de igual nivel de prioridad soliciten de forma simultanea atención? Para esto el 8051 tiene implementadas prioridades dentro de un mismo nivel las cuales no pueden ser alteradas por el programador, a las que recurre para tomar una decisión en este caso, como se muestra en la Tabla 7.2.4.

Microcontroladores. El 8051 de la INTEL.

294

PRIORIDAD ( más alta )

(más baja )

FUENTE

1

INT0

2

TIMER0

3

INT1

4

TIMER1

5

RI + TI ( PUERTO SERIE ) Tabla 7.2.4

La pregunta a responder en este momento sería, ¿Qué sucede si durante la ejecución de la subrutina de atención al Puerto Serie solicita interrupción el Temporizador 0? Estudiemos el significado dentro del microcontrolador de la tercera de las palabras en negritas definidas al inicio del epígrafe, Anidamiento. El Anidamiento de las Interrupciones. Empecemos el estudio del Anidamiento dándole respuesta a la pregunta con que termino el epígrafe anterior. ¿Qué sucede si durante la ejecución de la subrutina de atención al Puerto Serie solicita interrupción el Temporizador 0? Se interrumpe la ejecución de la subrutina de atención al Puerto Serie para pasar a atender la solicitud del Temporizador 0, una vez concluida la atención a este se continúa con la ejecución de la subrutina de atención al Puerto Serie, o sea, que una interrupción en curso puede ser a su vez interrumpida por una interrupción de mayor prioridad. A esto es lo que se llama Anidamiento de las Interrupciones y el 8051 esta capacitado para poder efectuar esto. Veamos un ejemplo de la vida cotidiana donde se refleje este mismo fenómeno y que quizás nos ayude a comprender mejor esto. Retornemos a la situación en que estamos leyendo un libro de mucho interés para nosotros sentados en la sala de nuestra casa y en ese momento suena el timbre del teléfono solicitando nuestra atención, como estamos solo en la casa no tenemos otra alternativa que dejar de leer e ir a tender la llamada telefónica, descolgamos el teléfono y comenzamos a hablar con la persona que llama y en ese mismo momento llega una vecina que quiere pedirnos un favor y toca a la puerta, no tenemos otra alternativa que pedirle al que nos

Microcontroladores. El 8051 de la INTEL.

295

llamo por teléfono que nos disculpe, que espere un momento que tenemos que atender el llamado de la puerta. ¿Qué es lo que ha ocurrido? Una primera interrupción, la llamada telefónica, fue interrumpida por una segunda interrupción que fue el toque de la puerta y nosotros como Procesadores hemos implementado un Anidamiento de ambas interrupciones. A modo de resumen podemos plantear, si una interrupción habilitada y de mayor prioridad que la que se esta siendo atendida solicita atención, el microcontrolador detiene la atención de la interrupción en curso para pasar a atender el nuevo pedido de interrupción, continuando con la Interrupción interrumpida una vez concluida la atención de la nueva interrupción. A este proceso se le llama Anidamiento de Interrupciones y el 8051 lo permite. Retornemos al ejemplo de la lectura, que fue interrumpida por la llamada telefónica, que a su vez fue interrumpida por el toque en la puerta. Sería interesante ver como nosotros resolvemos el proceso inverso en la medida que vamos resolviendo lo que nos imponen los pedidos de interrupción hasta que retornemos a la lectura del libro que es lo que realmente nos interesa y fue de donde partimos. De seguro que usted en la medida que fue siendo interrumpido, fue dejando marcas que le permitieran retomar el camino a la inversa. Por ejemplo cuando fue interrumpido por la llamada telefónica, usted de seguro hizo una marca en el libro que le permitieran conocer por donde iba su lectura en el momento que fue interrumpido. De igual manera cuando tocan a la puerta de seguro que usted dejo en una posición el teléfono que le permitiera retomar la llamada una vez concluyera con la atención del llamado a la puerta. Estas marcas que usted va dejando son las que le permiten que una vez concluida la atención de su vecina, usted retorne al teléfono a continuar con la atención de la llamada y que una vez que termine con esta usted pueda retornar a la lectura del libro en la página adecuada. De igual forma actúa el microcontrolador. La pregunta a contestar en este momento sería, ¿Cuáles son estas marcas?, ¿Dónde las deja? Para garantizar el retorno una vez concluida la atención de la nueva interrupción al igual que con la llamada a Subrutina por software mediante una instrucción del tipo ACALL, la dirección de retorno se guarda en la Pila, de manera que una vez terminada la atención de la interrupción el

Microcontroladores. El 8051 de la INTEL.

296

microcontrolador saca de la Pila la dirección de retorno y con ello garantiza el correcto regreso a al Subrutina interrumpida. Otro tanto hará cuando termine con esta interrupción y retorne al Programa Principal. Si tiene dudas con la instrucción ACALL y el concepto de Subrutina, remítase al Tema3, epígrafe 3.2. Una pregunta que puede resultar interesante contestar en este momento podría ser, ¿Será infinito el número de interrupciones que se pueden anidar? Como ya se explico, en la Pila se almacena la dirección de retorno a la Subrutina de atención a la Interrupción que fue a su vez interrumpida. Esta dirección de retorno es de 16 bits por lo que ocupa dos localizaciones de la Pila y aquí es donde se encuentra la limitación, dado que el número máximo de localizaciones que el 8051 dedica a la Pila es de 8, por lo que solo se garantiza el buen funcionamiento del Programa si el número de interrupciones anidadas no pasa de 4. Retornando al ejemplo 7.2.2, ¿Qué sucede si durante la atención a la interrupción del Temporizador 0 solicita interrupción el Puerto Serie? En este caso la solicitud de atención del Puerto Serie no es servida, ya que esta tiene menos prioridad que la del Temporizador 0. Si al terminar la atención a la interrupción del Temporizador 0 se mantiene el pedido por parte del Puerto Serie este será atendido. ¿Como el microcontrolador reconoce al terminar la atención a una interrupción, si un pedido, realizado por otra fuente de las habilitadas, no atendido por alguna causa aun se mantiene? Esto lo hace encuestando las correspondientes Banderas de Interrupción ya explicadas anteriormente. Estas banderas las cuales se activan cuando ocurre un pedido de interrupción no son borradas en algunos casos hasta que la interrupción sea atendida o hasta que el programador las borre por software en otros casos. ¿Cuáles son borradas de forma Automatica por hardware y cuales necesitan ser borradas por el Programa mediante una instrucción? Son borradas de forma automática por hardware una vez que son atendida, las banderas de INT0/ e INT1/ cuando son activadas por flanco y las banderas de los Temporizadores 0 y

Microcontroladores. El 8051 de la INTEL.

297

Temporizadores 1. Tienen que ser borradas por software las banderas del Puerto Serie (RI y TI) y las interrupciones externas INT0/ e INT1/ cuando son activadas por nivel. ¿Donde se encuentran las banderas del Puerto Serie y de INT0/ e INT1/ para poder ser borradas por software? Las banderas de INT0/ e INT1/ se encuentran en los bits 1 y 3 del registro TCON respectivamente, mientras que las banderas RI y TI del Puerto Serie se encuentran en los bits 0 y 1 del registro SCON respectivamente, ver Figura 7.2.1.

Figura 7.2.1. De lo definido anteriormente existen dos formas de ser reconocido por el microcontrolador los pedidos de interrupción a través de los terminales externos INT0/ e INT1/, por flanco o por nivel y esto un tanto define si la bandera se borra de forma Automatica o por Programa. ¿Como se define esto? Esto es definido por el programador mediante la programación de los bits 0 y 2 del registro TCON. Si el bit 0 es programado en ´0´ la interrupción INT0/ es activa por nivel, mientras que si es programado en ´1´ es activa con el flanco de bajada. Una situación similar ocurre con la interrupción externa INT1 con el bit 2 de este registro, ver Figura 7.2.1. El resto de los bits de estos dos registros tienen funciones de gran importancia para la programación de los Temporizadores y del Puerto Serie por lo que las estudiaremos en los Temas dedicados a estos dispositivos. Una vez definidos estos tres aspectos de la interrupción del 8051 nos parece que estamos en condiciones de pasar a ver como es que se atiende al dispositivo que solicita la interrupción.

Microcontroladores. El 8051 de la INTEL.

298

7.3 Atendiendo a los dispositivos que solicitan Interrupción. Un dispositivo interrumpe con el objetivo de que el microcontrolador ejecute un conjunto de operaciones especificas y definidas por el programador sobre él. Por ejemplo un Teclado interrumpe porque una Tecla ha sido apretada y solicita al microcontrolador que efectué la operación sobre él de lectura para entregarle el código de la Tecla apretada. Este conjunto de operaciones que debe realizar el microcontrolador como consecuencia del pedido de interrupción de un dispositivo dado, se traduce en un conjunto de instrucciones, agrupadas en forma de Subrutina, que se ejecutaran cada vez que el dispositivo interrumpa. Veamos el siguiente ejemplo. Ejemplo 7.3.1. Dada una Tecla conectada a la entrada de interrupción externa INT0, se desea que se complemente el valor del bit 0 del Puerto 1 del 8051, cada vez que la Tecla sea apretada. El hardware del sistema provoca que el efecto mecánico de apretar la Tecla se traduzca en un pedido de interrupción al microcontrolador a través de su terminal de interrupción externa INT0/. Si esta interrupción se encuentra habilitada, una vez concluida la instrucción en curso el microcontrolador buscará en la localización cuya dirección es 0003H el código de la primera instrucción a ejecutar como parte de la Subrutina de atención. La Subrutina sería en este caso la siguiente: DIREC.

INSTRUC.

0003 H

CPL

0005 H

RETI

P1.0

No. BYTES

COMENTRIO

2

; Complementa el bit 0 del Puerto 1.

1

; Retorno al Programa Principal.

La pregunta a responder en este momento sería, ¿Por qué el microcontrolador sabe que tiene que buscar el código de la primera instrucción de la Subrutina que atiende el pedido de interrupción de la Tecla, para este caso, en la localización cuya dirección es 0003H? Cada una de las 5 posibles Fuentes de Interrupción tiene asociada una localización con una dirección dada en la Memoria de Programa donde almacenar el código de la primera instrucción de la Subrutina que atiende su pedido. Estas localizaciones son fijas y se corresponden con

Microcontroladores. El 8051 de la INTEL.

299

direcciones de la zona baja de la Memoria de Programas donde de forma fija el programador debe almacenar las primeras instrucciones de las Subrutinas de interrupción de los dispositivos. Estas direcciones con su correspondiente fuente de interrupción se reflejan en la Tabla 7.3.1. FUENTES DE INTERUPCIÓN.

DIRECCIONES DE LAS LOCALIZACIONES

INTERRUPCION EXTERNA 0, INT0/

0003H

TIMER 0, TF0

000BH

INTERRUPCION EXTERNA 1, INT1/

0013H

TIMER 1, TF1

001BH

PUERTO SERIE, TI y RI

0023H Tabla 7.3.1

Observe que a la fuente de interrupción externa INT0/, le corresponde la localización cuya dirección es la 0003H con lo que se corrobora lo declarado en el ejemplo anterior. ¿Cuál sería la dirección de la localización primera si la Tecla se hubiera conectado a la entrada INT1 del 8051 en el ejemplo anterior? Buscando en la Tabla 7.3.1 veríamos que esta localización sería la que le corresponde la dirección 0013H y así sucesivamente lo podríamos ir haciendo con cada una de las posibles fuentes de interrupción. El programador no puede cambiar esto, ya que la búsqueda una vez que el microcontrolador decide atender el pedido de interrupción se hace de forma automática o sea por hardware a las direcciones definidas anteriormente. Estas direcciones se conocen también con el nombre de Vector de Interrupción, correspondiéndole a cada fuente de interrupción un único y mismo Vector. Por lo que se dice que el efecto de esta operación en el microcontrolador sería el mismo que si ejecutara una instrucción del tipo, LCALL Vector Observe de la Tabla 7.3.1 que existe una separación de 8 localizaciones entre cada una de las localizaciones correspondientes a los Vectores consecutivos. Esto permite, al programador, si la extensión de su Subrutina no es muy grande, poder cargar en dichas localizaciones la misma. Esto no constituyó un problema con la Subrutina del ejemplo 7.3.1 ya que la misma solo ocupa 3 localizaciones para almacenar los códigos de las instrucciones que conforman la misma. No

Microcontroladores. El 8051 de la INTEL.

300

obstante, en la mayoría de las aplicaciones no es suficiente con 8 localizaciones para almacenar las instrucciones que conforman estas Subrutina. ¿Qué hacer en estos casos? En estos casos el programador tiene la posibilidad de cargar en la localización correspondiente al Vector de interrupción, una instrucción de salto incondicional hacia cualquier localización de la memoria de programa, dirección a partir de la cual se almacenará la correspondiente Subrutina de atención a la interrupción del dispositivo en cuestión. Veamos el siguiente ejemplo a modo de esclarecer lo anterior. Ejemplo 7.3.2 Se desea que al apretar una Tecla del tipo ´Push – Botom´, el microcontrolador deje la tarea que se encuentra realizando y muestre en una Lámpara de 7 Segmentos conectada al Puerto 2 el número correspondiente al interruptor simple polo - simple tiro que se encuentre cerrado de los 8 conectados al Puerto 1. Si ningún Interruptor se encuentra cerrado mostrar en la Lámpara de 7 Segmentos el número 8. Los Interruptores los enumeraremos del 0 al 7 y este mismo número es el que corresponde mostrar en la Lámpara cuando el mismo se encuentre cerrado. La tarea de fondo que esta haciendo el microcontrolador y que solo será interrumpida cuando la Tecla sea apretada, será la de encender y apagar un LED conectado al terminal P0.7 a la frecuencia de 1Hz. El Hardware del sistema sería el que se muestra en la Figura 7.3.1.

Figura 7.3.1

Microcontroladores. El 8051 de la INTEL.

301

Del Hardware propuesto haremos los siguientes señalamientos: 9

Los Interruptores están conectados de forma tal que cuando estén cerrados, imponen un ´0´ en el terminal del puerto al que estén conectados y cuando estén abiertos se impone un ´1´ en dicho terminal (recordar la estructura interna de los terminales del Puerto 1).

9

La Tecla esta conectada de forma tal que cuando este sin apretar en el terminal del Puerto 3, INT0/, se ve un ´1´ y cuando se aprieta se impone un ´0´.

9

La Lámpara de 7 Segmentos empleada es de Ánodo Común por lo que los segmentos se encienden cuando se impone un ´0´ en el terminal de la lámpara correspondiente.

9

El Circuito Integrado 74HCT241 conectado entre el Puerto 2 y la Lámpara de 7 Segmentos realiza el papel de buffer para limitar la corriente que entra al puerto del microcontrolador cuando los segmentos de la lámpara se encienden.

La Subrutina de atención a la interrupción en este caso sería la siguiente, ; Subrutina de atención a la interrupción externa INT0/. org

0003H

mov

A, P1

; Buscar el primer bit de menor a mayor del Puerto 1 que esta en ´0´, cerrado. lazo1:

mov

R2, #0

rrc

A

jnc

encontre

inc

R2

cjne

R2, #8, lazo1

;declaro un contador

; Mostrar en la Lámpara de 7 Segmentos el número en decimal correspondiente al número binario ; almacenado en R2. encontre:

mov

A, R2

mov

DPTR, #Tabla1

movc A, @A+DPTR

; busca el código en la Tabla

; Enviar el código de Lámpara de 7 Segmentos del número decimal a la Lámpara. mov reti

P2, A

; envía el código de lámpara al Puerto 2. ; retorno al Programa Principal.

A partir de la dirección Tabla1 se encontrara una Tabla formada por los códigos de Lámpara de 7 Segmentos de los números del 0 al 8 en el sentido ascendente de las direcciones y consecutivos. ; Tabla con los códigos de Lámpara de 7 Segmentos. ; La Lámpara de 7 Segmentos es de Ánodo Común.

Microcontroladores. El 8051 de la INTEL. Tabla:

302

db

40h

; código del 0.

db

79h

; código del 1.

db

24h

; código del 2.

db

30h

; código del 3.

db

19h

; código del 4.

db

12h

; código del 5.

db

02h

; código del 6.

db

78h

; código del 7.

db

00h

; código del 8.

¿Qué diferencia existe entre la Subrutina de atención a la Interrupción INT0/ en este caso con respecto al caso del ejemplo 7.3.1? Los códigos generados por las instrucciones que conforman a la Subrutina en este caso ocupan más de 8 localizaciones de la Memoria de Programa, por lo que la misma no puede ser cargada en el espacio reservado para almacenar la misma, que se corresponde con las localizaciones que se encuentran entre la destinada para el Vector de interrupción INT0/ (0003H) y la destinada al Vector de interrupción correspondiente al Temporizador 0 (000BH) que es la que le sigue en orden ascendente de las direcciones. ¿Cuál fue la solución dada? La solución dada fue la de cargar en la localización correspondiente al Vector de interrupción de la interrupción externa INT0/ (0003H) una instrucción de salto incondicional a la dirección de memoria donde realmente se va a almacenar la primera instrucción de la Subrutina, en este caso iniciosub:, la que se convertirá en la primera instrucción que se ejecutará cuando al apretar la Tecla se provoque un pedido de interrupción al microcontrolador del tipo externa INT0/. Esto lo hicimos mediante la instrucción, ; Vector de la Interrupción Externa INT0/. org

0003H

; Salta a la dirección real de inicio de la Subrutina. ljmp

iniciosub

Quedando ahora la Subrutina a partir de la dirección inicio: de la forma siguiente, ; Subrutina de atención a la interrupción externa INT0/. iniciosub:

mov

A, P1

; Buscar el primer bit de menor a mayor del Puerto 1 que esta en ´0´, cerrado.

Microcontroladores. El 8051 de la INTEL.

lazo1:

mov

R2, #0

rrc

A

jnc

encontre

inc

R2

cjne

R2, #8, lazo1

303 ;declaro un contador

; Mostrar en la Lámpara de 7 Segmentos el número en decimal correspondiente al número binario ; almacenado en R2. encontre:

mov

A, R2

mov

DPTR, #Tabla1

movc A, @A+DPTR

; busca el código en la Tabla

; Enviar el código de Lámpara de 7 Segmentos del número decimal a la Lámpara. mov

P2, A

reti

; envía el código de lámpara al Puerto 2. ; retorno al Programa Principal.

Por su puesto para que todo esto funcione como se desea nos falta habilitar la interrupción externa INT0/ y decir de que forma será reconocido su pedido por el microcontrolador, si por nivel o por frente. Las instrucciones que permiten efectuar esta operación son las siguientes, ; Habilita la Interrupción externa INT0/. mov

IE, #10000001b

¿Cómo escoger que queremos que la interrupción INT0/ sea reconocida si el nivel lógico en su entrada correspondiente pasa de ´1´ a ´0´? Las formas en que el microcontrolador reconoce que se ha efectuado un pedido de interrupción externa de los tipos INT0/ o INT1/ pueden ser de dos tipos seleccionables por el programador: 9

Por nivel.

9

Por frente.

Por nivel, el microcontrolador reconocerá un pedido de interrupción cuando a la entrada de uno de los terminales que caracterizan a este tipo de interrupción INT0/ o INT1/ se ponen a nivel lógico ´0´. En este momento si la interrupción correspondiente se encuentra habilitada la misma es atendida. El diseñador debe tener cuidado ya que si cuando termina de ejecutarse la Subrutina de atención correspondiente continua la entrada en el nivel ´0´ la interrupción vuelve a ser atendida, por lo que se debe tener la precaución de que el valor lógico en el terminal retorne a ´1´ antes de que termine de ejecutarse la Subrutina de atención. Para ello se puede intercalar dentro de dicha Subrutina

Microcontroladores. El 8051 de la INTEL.

304

una instrucción que se encargue de avisar al dispositivo externo que interrumpe que la interrupción ya esta siendo atendida y que por ende quite el pedido. En el caso por frente, el microcontrolador reconocerá el pedido de interrupción cuando el nivel lógico en la entrada correspondiente pase de ´1´ a ´0´, o sea, con el frente negativo de la señal. Este pedido es almacenado en un Biestable interno del microcontrolador, el que toma el valor lógico de ´1´. Este Biestable se limpiara por hardware una vez que se pase a ejecutar la Subrutina de atención a la interrupción, o sea, en este caso no corremos el riesgo de que el pedido se atienda dos veces o más, cuando a ocurrido solo uno. ¿Cómo indicarle al microcontrolador que reconozca el pedido por nivel o por frente? Para ello están los bits 0 y 2 del registro TCON, ver Figura 7.3.2.

Figura 7.3.2 En este caso nos interesa seleccionar a INT0/ para que sea reconocida por frente por lo que impondremos por programa un 1 en el bit 0 de este registro. Para ello empleamos la instrucción, ; Selecciona reconocimiento de interrupción de INT0/ por frente. mov

TCON, #00000001B

Tomando en cuenta todos estos elementos el programa quedaría de la siguiente manera, ; Inicio del Programa Principal. org

0000H

Microcontroladores. El 8051 de la INTEL. sjmp

305

iniciopp

; Vector de Interrupción INT0/. org

0003H

; Salta a la dirección real de inicio de la Subrutina. ljmp

iniciosub

; Continúa el Programa Principal. iniciopp:

mov

P1, #0FFH

; Puerto 1 de entrada.

mov

P2, #0FFH

; apaga todos los segmentos de la lámpara.

dptr, #Tabla

; defino Puntero a la Tabla de conversión.

; Programando al Controlador de Interrupciones del microcontrolador. ; Habilita la Interrupción del Temporizador 0. mov

IE, #10000001b

; Selecciona reconocimiento de interrupción de INT0/ por frente. mov

TCON, #00000001B

; El microcontrolador se encuentra listo para atender los pedidos de interrupción cada vez que ; se apriete la Tecla. ; Continúa el Programa Principal. ciclo:

clr

P0.7

lcall

demora

setb

P0.7

lcall

demora

sjmp

ciclo

; Subrutina demora. Provoca una demora de aproximadamente 500 milisegundos a 12 Mhz. demora:

mov

R4, #50

ciclo2:

mov

R5, #200

ciclo1:

mov

R6, #250

djnz

R6, $

djnz

R5, ciclo1

djnz

R4, ciclo2

ret ; Dirección de inicio de la Subrutina de atención a la interrupción INT0/. iniciosub:

mov

A, P1

; Buscar el primer bit de menor a mayor del Puerto 1 que esta en ´0´, cerrado. lazo1:

mov

R2, #0

rrc

A

jnc

encontre

inc

R2

cjne

R2, #8, lazo1

;declaro un contador

Microcontroladores. El 8051 de la INTEL.

306

; Mostrar en la Lámpara de 7 Segmentos el número en decimal correspondiente al número binario ; almacenado en R2. encontre:

mov

A, R2

mov

DPTR, #Tabla1

movc A, @A+DPTR

; busca el código en la Tabla

; Enviar el código de Lámpara de 7 Segmentos del número decimal a la Lámpara. mov

P2, A

reti

; envía el código de lámpara al Puerto 2. ; retorno al Programa Principal

; Tabla con los códigos de Lámpara de 7 Segmentos. ; La Lámpara de 7 Segmentos es de Ánodo Común. Tabla:

db

40h

; código del 0.

db

79h

; código del 1.

db

24h

; código del 2.

db

30h

; código del 3.

db

19h

; código del 4.

db

12h

; código del 5.

db

02h

; código del 6.

db

78h

; código del 7.

db

00h

; código del 8.

end

; fin de compilación.

Hemos aceptado desde el inicio de este epígrafe, que al fragmento de programa donde se agrupan las instrucciones que indican las operaciones a ejecutar por el microcontrolador cada vez que un dispositivo dado interrumpe, como en los casos de los ejemplos 7.3.1 y 7.3.2, se le llame Subrutina. ¿Por qué? Podríamos decir que un elemento que lo caracteriza, es que dicho fragmento de programa termina con una instrucción del tipo reti, retorno de interrupción, lo que indica el interés del Programador en que una vez que dicho fragmento de programa termine de ejecutarse, el programa debe regresar a la dirección por donde se encontraba cuando fue invocado continuando con la tarea que venía realizando. Si necesita más información sobre las acciones que provoca la instrucción reti, remitirse al Tema 3, Epígrafe 3.2. Por lo tanto, a una Subrutina se puede llegar de dos formas diferentes, ambas reflejadas en el ejemplo 7.3.2,

Microcontroladores. El 8051 de la INTEL. 9

Por hardware.

9

Por software,

307

Por hardware se llega mediante una solicitud de interrupción bien externa o por uno de los dispositivos internos con posibilidades de interrumpir. Por software se llega mediante la ejecución de una instrucción del tipo CALL. ¿Qué diferencia existe entre ambas formas? Mientras que en la primera la llamada a la Subrutina ocurre de forma impredecible por el programador, en la segunda ocurre cuando este lo decide colocando la correspondiente instrucción CALL en el Programa Principal. Por lo general la Subrutina de atención a un pedido de interrupción como su nombre lo indica es un fragmento de programa que responde a las tareas que se deben realizar como parte de la atención al mismo. Por su parte las Subrutinas a las cuales se llega mediante una instrucción del tipo CALL, son fragmentos de programas que por su generalidad y frecuencia con que son ejecutados amerita que se encuentren separados del Programa Principal. Además de terminar con una instrucción del tipo retorno, reti para el caso de la interrupción y ret para el caso de una llamada mediante una instrucción CALL, los hace similar la manera en que reacciona el microcontrolador ante ambas causas, el trabajo con la pila y la estructura que deben tener dichos fragmentos de programas. Creo que en estos momentos estamos en condiciones de comprender, de forma integral, cuales son todos los pasos que provocan en el microcontrolador una petición de atención por interrupción de un dispositivo cualquiera. 7.4 El proceso de interrupción en el Microcontrolador. El microcontrolador cada cierto tiempo y de forma periódica, muestrea el estado de las Banderas de Interrupción, si alguna de ellas se encuentra activa, en ´1´, chequea en el registro IE si la misma esta habilitada. Si ambas condiciones se cumplen, están creadas las condiciones para la atención al pedido de interrupción, ver Figura 7.4.1.

Microcontroladores. El 8051 de la INTEL.

308

Figura 7.4.1 Bajo la óptica del circuito de la Figura 7.4.1 analicemos el ejemplo 7.3.2. En este ejemplo una Tecla del tipo ´Push Botom´ fue conectada al terminal INT0/ del microcontrolador, con el objetivo de que cada vez que se apretara dicha Tecla el microcontrolador interrumpiera la tarea que estaba haciendo para pasar a escribir en la Lámpara de 7 Segmentos conectada al Puerto 2 el digito decimal correspondiente al interruptor cerrado, de los conectados al Puerto 1. La acción de apretar la Tecla provoca que el valor lógico aplicado al terminal INT0/ pase de ´1´ a ´0´. Dado que cuando programamos al registro TCON se puso al bit 0 de dicho registro, IT0, en ´1´, la entrada INT0/ se conecto al detector de flanco negativo, ver Figura 7.4.1, el que detecta la transición de ´1´ a ´0´ ocurrida en dicha entrada poniendo a ´1´ a la Bandera de Interrupción de INT0/, IE0. Anteriormente habíamos programado al registro IE, poniendo en ´1´ a los bits 7, EA, y 0, EX0, con lo que se habilito la interrupción externa INT0/. Bajo estas condiciones la salida de la compuerta AND, a las que llega a sus entradas el valor lógico almacenados en IE0 y en EX0, será ´1´. El resto de las compuertas AND mantienen el valor de sus salidas en ´0´, independientemente de que sus correspondientes Bit de Banderas puedan tomar el valor de ´1´ ya que al programar el registro IE los bits del 2 al 5 se pusieron a ´0´. Todas las compuertas no inversoras tercer estado conectadas a las salidas de las compuertas AND se encuentran habilitadas ya que EA se encuentra en ´1´, por lo que la salida de la compuerta

Microcontroladores. El 8051 de la INTEL.

309

no inversora correspondiente a la compuerta AND ubicada en el camino de INT0/ se pone a ´1´, manteniéndose el resto en ´0´, con lo provoca la interrupción de las tareas que venia realizando el microcontrolador. ¿Qué sucede con las tareas que venia realizando el microcontrolador antes de la interrupción?, ¿Cómo pasa el microcontrolador a ejecutar la Subrutina de atención correspondiente a INT0/? A pesar de que el pedido de interrupción ya ha sido reconocido por el microcontrolador y que internamente ya esta dada la orden de que se interrumpa la tarea que este venia realizando, la interrupción no se procederá a atender hasta que la instrucción en curso no termine de ejecutarse. Con esto el microcontrolador garantiza la integridad del programa que se viene ejecutando al mismo tiempo que garantiza claridad con respecto a la dirección a donde debe retornar una vez terminada de ejecutarse la Subrutina de atención a la interrupción correspondiente. Una vez que la instrucción en curso termina de ejecutarse, el microcontrolador guarda de forma automática el contenido del registro Contador de Programas en la Pila con el objetivo de garantizar el retorno al programa principal una vez terminada la ejecución de la Subrutina de atención. ¿Qué se encuentra almacenado en el registro Contador de Programa cada vez que una instrucción ha terminado de ser ejecutada? En el registro Contador de Programa, se encuentra en ese momento la dirección de la localización de la próxima instrucción que le correspondería ejecutar al microcontrolador de no haber ocurrido una interrupción del programa. Esta no es más que la dirección a donde debe retornar cuando termine con la atención de la interrupción, para poder continuar con la tarea que venia realizando antes de ser interrumpido. ¿Como ocurre este proceso? Como ya se explico anteriormente, en el registro Contador de Programas del microcontrolador se encuentra almacenada la dirección de la próxima instrucción que debería ser ejecutada por este sino hubiera sido reconocido un pedido de interrupción. Esta dirección por lo general coincide con la dirección siguiente en la Memoria de Programa, a no ser que sea una instrucción interrumpida se corresponda con una instrucción de salto.

Microcontroladores. El 8051 de la INTEL.

310

Esta dirección, de 16 bits, se salva en la Pila en dos eventos. En el primero el Puntero de la Pila (registro SP) se incrementa en uno guardándose en la dirección de memoria a donde apunta, el Byte Menos Significativo (bms) del Contador de Programas, a continuación se incrementa nuevamente en uno el registro SP apuntando ahora a la dirección siguiente y guardando en esta dirección el Byte Más Significativo (BMs) del Contador de Programas. Analicemos lo explicado hasta aquí a la luz del siguiente ejemplo. Ejemplo 7.4.1. Supongamos que un pedido de interrupción producto del desbordamiento del contador del Temporizador 0 ocurre cuando el Programa Principal esta ejecutando la instrucción INC A la cual ocupa la localización de memoria cuya dirección es 0050 H en Memoria de Programa. Dado que el código de esta instrucción ocupa una sola localización, la instrucción siguiente a ejecutar por el microcontrolador estaría ubicada en la localización de memoria cuya dirección es 0051 H. Para el ejemplo no nos interesa cual es esta instrucción. Consideremos además, que el Puntero de la Pila esta cargado con la dirección 07 H, el que coincide con el valor que se carga en dicho registro producto de un reconocimiento de RESET por parte de microcontrolador. Bajo estas condiciones, la secuencia de acciones que ocurrirían serían las siguientes: 1. Una vez terminada de ejecutar la instrucción en curso, INC A, el registro Puntero de la Pila se incrementará en uno, tomando el valor 08H, apuntando a la dirección de Memoria de Datos correspondiente a esta dirección. 2. En esta localización se almacena el bms de la dirección de la instrucción siguiente a dicha instrucción, o sea, el valor 51 H. Recordemos que la zona de Memoria de Datos reservada por este microcontrolador para la Pila esta enmarcada entre las direcciones 08H y 0FH. 3. A continuación el registro Puntero de la Pila se vuelve a incrementar en 1, tomando el valor 09H apuntando a la dirección correspondiente a dicha dirección. 4. Pasando a almacenar en dicha dirección el BMs de la dirección de la instrucción siguiente, en este caso 00 H. Después de todo este proceso, el registro Puntero de la Pila y la zona de Memoria de Datos destinada a la Pila quedarían cargados con los valores que se muestran en la Figura 7.4.2.

Microcontroladores. El 8051 de la INTEL.

311

Figura 7.4.2 Quedando todo preparado para pasar a ejecutar la Subrutina de atención a la Interrupción. ¿Cómo ocurre este proceso? A continuación se carga en el registro Contador de Programas del 8051 la dirección del Vector de Interrupción correspondiente a la interrupción que va a ser atendida. El Vector de Interrupción no es más que un número de 16 bits, que el microcontrolador interpreta como una dirección en la Memoria de Programas, por lo que esta acción provoca que el control del microcontrolador pase a las instrucciones ubicadas a partir de esta dirección, las que se corresponden con la Subrutina de atención correspondiente. El proceso de atención a la interrupción no termina hasta que culmina de ejecutarse la Subrutina de atención al dispositivo que interrumpió, lo que es detectado por el 8051 por la ejecución de una instrucción del tipo reti, la que provoca que se extraiga de la Pila la dirección guardada cuando el microcontrolador fue interrumpido, la que se corresponde con la instrucción a ejecutar para poder continuar la tarea que fue interrumpida. Esta dirección es cargada nuevamente en el registro Contador de Programas, con lo que se garantiza la continuidad en la ejecución de la tarea interrumpida.

Microcontroladores. El 8051 de la INTEL.

312

¿Cómo se ejecuta todo este proceso? La ejecución de la instrucción reti es la que se encarga de desencadenar todas las acciones que garantizaran el retorno. Primero se extrae de la Pila el BMs de la dirección de retorno y se carga en el registro Contador de Programas. Como segundo paso el registro Puntero de la Pila es decrementado en 1, extrayéndose de la dirección a donde apunta el bms de la dirección de retorno cargándose el que es cargado en la parte baja del registro Contador de Programas, quedando todo listo para ejecutar un salto a esta dirección. Todo este proceso termina decrementando en uno nuevamente al registro Puntero de la Pila para que quede apuntando a la misma dirección a la que apuntaba antes de pasar a atender el pedido de interrupción, culminando de esta forma todo el proceso de atención a la Interrupción. A modo de resumen, la secuencia de pasos que da el microcontrolador desde que decide atender el pedido de Interrupción que le esta siendo hecho por cualquiera de las 5 posibles fuentes hasta que termina con dicha atención son los siguientes: 1. Termina de ejecutar la instrucción en curso. 2. Salva en la Pila, de forma automática, la dirección de retorno. 3. Carga en el registro Contador de Programas la dirección del Vector de Interrupción correspondiente a la fuente que esta solicitando atención. 4. Ejecuta la Subrutina de atención al pedido de Interrupción correspondiente. 5. Con la instrucción reti, última instrucción de la Subrutina, extrae de la Pila la dirección de retorno cargándola en el registro Contador de Programas. De lo visto hasta aquí podemos llegar a la conclusión de que la Interrupción constituye una técnica muy útil y muy importante para la atención de eventos que ocurren de forma impredecible en el tiempo en los sistemas construidos en base a los microcontroladores. Máxime tomando en cuenta que estos dispositivos traen empotrados, por lo general, un conjunto de circuitos que ayudan a llevar a cabo esta tarea, aliviando de forma significativa al microcontrolador de la carga en tiempo que significaría el estar pendiente de la ocurrencia de los mismos si empleáramos otra técnica como la encuesta. Tomando en cuenta lo expresado en el párrafo anterior, nos parece aconsejable que en este momento le dediquemos un tiempo a la solución de problemas donde empleemos la interrupción como técnica de atención a dispositivos conectados externamente al microcontrolador. A esto dedicaremos el próximo Tema.

Microcontroladores. El 8051 de la INTEL.

313

Tema # 8. Sincronizando eventos impredecibles en el tiempo. Existen muchos eventos en los sistemas a microcontroladores los que su ocurrencia en el tiempo no puede ser predecible con exactitud por parte del diseñador, ya que la ocurrencia de los mismos no responde a una periodicidad. Ejemplo de estos eventos pueden ser: 9

La acción de apretar una Tecla conectada a uno de los terminales de un Puerto del microcontrolador.

9

La llegada de un dato al Puerto Serie del microcontrolador.

9

El fin de conversión de un Conversor Análogo - Digital.

La pregunta que se haría el programador en este caso podría ser, ¿Cómo sincronizar en el tiempo la ocurrencia del evento con la ejecución del fragmento de programa que debe ejecutar el microcontrolador cuando este ocurre? Una forma de lograr esta sincronización como ya se ha visto en Temas estudiados anteriormente esta relacionado con la conocida técnica de Encuesta. Esta técnica constituye una solución basada fundamentalmente en el software, donde el tiempo de ejecución del microcontrolador se ve muy afectado por la tarea de determinar cuando ocurre el evento. Esta es la causa fundamental por la que el empleo de esta técnica se ve limitado para aquellas aplicaciones que demanden un tiempo alto de ocupación del microcontrolador. Una segunda técnica esta relacionada con la Interrupción. Esta técnica constituye una solución basada fundamentalmente en el hardware, donde el tiempo de ejecución del microcontrolador prácticamente no se ve afectado por la tarea de determinar cuando ocurre el evento. Para ello el microcontrolador debe contar con un mecanismo empotrado en el mismo que se encargue de esta tarea sin distraer al microcontrolador de su tarea fundamental. El 8051, como ya conocemos, cuenta con este mecanismo el que recibe el nombre de Controlador de Interrupciones, al estudio del cual dedicamos el Tema anterior. En este Tema pretendemos realizar a modo de ejemplo un conjunto de ejercicios donde la solución propuesta utilice de alguna manera el mecanismo de Interrupción del microcontrolador. Quizás los ejemplos podrían ser resueltos de otra manera pero el objetivo en este caso no es buscar la mejor solución a los problemas propuestos, sino la de brindar soluciones prácticas que permitan al estudiante vincularlas con los conocimientos adquiridos.

Microcontroladores. El 8051 de la INTEL.

314

8.1 Atendiendo una Tecla del tipo ´Push Botom´ por Interrupción. En este Epígrafe analizaremos dos ejemplos relacionados con Teclas del tipo ´Push Botom´ y su sincronización con el programa del microcontrolador mediante el empleo de la técnica de Interrupción. Ejemplo 8.1.1. Se desea diseñar un circuito basado en el microcontrolador 8051 que se comporte como un dado electrónico. Para ello el sistema contará con una Tecla del tipo ´Push Botom´ y de una Lámpara de 7 Segmentos de Ánodo Común. La acción de tirar el dado se relacionará con el apretar la Tecla y el número del dado que sale producto de la acción de tirar el mismo será el que se muestra en la Lámpara de 7 Segmentos. El circuito propuesto para la solución del problema anterior es el que se muestra en la Figura 8.1.1.1.

Figura 8.1.1.1. Observe que la TECLA se ha conectado al terminal del Puerto 3, P3.2, el que comparte dicho terminal con la entrada INT0/ del Controlador de Interrupciones empotrado en el microcontrolador. ¿Qué efecto provoca en el terminal INT0/ del microcontrolador la acción de apretar la Tecla?

Microcontroladores. El 8051 de la INTEL.

315

La TECLA a la que estamos haciendo referencia es del tipo Normalmente Abierta, por lo que en su estado estable sus dos contactos se encontrarán abiertos. La acción de apretar la TECLA provoca que ambos contactos se unan, permaneciendo en este estado mientras actué sobre ella la presión hecha por el usuario. Una vez liberada de dicha presión regresará por si sola a su estado estable, o sea, abierta. Tomando en cuenta el modo de operación de la TECLA explicado en el párrafo anterior y observando de la Figura 8.1.1.1 la forma en que esta conectada la misma al terminal INT0/, esta operación la podríamos explicar en términos de unos y ceros de la siguiente forma. Cuando la TECLA no este apretada en la entrada INT0/ lo que tenemos es un ´1´, impuesto por el pull-up interno propio de los terminales del Puerto 3, mientras que cuando este apretada en la misma entrada el valor que esta impuesto será de ´0´, impuesto por el terminal de la TECLA conectado al potencial de tierra del circuito. Cuando la TECLA sea liberada, nuevamente en el terminal INT0/ se impondrá un ´1´. De forma tal que el efecto de apretar la TECLA provoca que en la entrada INT0/ la señal pase de ´1´ a ´0´, mientras que el efecto de liberar la TECLA provocará que la señal pase de ´0´ a ´1´, tal y como se muestra en la Figura 8.1.1.2.

Figura 8.1.1.2 La acción de apretar la TECLA es la que debe provocar que en la Lámpara de 7 Segmentos se vea un nuevo digito decimal, correspondiente al número del dado que le corresponda salir. En otras palabras cuando la señal en la entrada INT0/ pase de ´1´ a ´0´ es que debe ocurrir esta acción. ¿Cómo implementar eso en nuestra aplicación?

Microcontroladores. El 8051 de la INTEL.

316

La solución que proponemos es la de que el microcontrolador este ejecutando como Programa Principal un contador ascendente del 1 al 6 constantemente y de forma cíclica, programa este que será interrumpido por la acción de apretar la TECLA. La Subrutina de atención a dicha Interrupción lo único que tendrá que hacer es tomar el valor binario por donde va el contador, cuando fue interrumpido, hacer la conversión a código de Lámpara de 7 Segmentos correspondiente y enviar el código obtenido hacia la Lámpara de 7 Segmentos, funcionando el sistema como un generador de números aleatorios entre los números 1 y 6. Para que el microcontrolador ejecute estas tareas de la forma descritas en el párrafo anterior, previamente debemos programar al Controlador de Interrupciones para que habilite la interrupción INT0/, terminal a donde es conectada la TECLA y que dicha interrupción se active con el flanco de caída de la señal en dicho terminal. Para ello debemos programar los registros IE y TCON tal y como se muestra a continuación. ; Programando al Controlador de Interrupciones. mov IE,#10000001b mov TCON,#00000001b Otro aspecto a tener en cuenta por el programador será, ¿A partir de que dirección se debe comenzar a cargar la Subrutina de atención a dicha interrupción? Para ello debemos considerar cual es el Vector de Interrupción correspondiente a INT0/, ya que es el terminal que estamos utilizando para detectar cuando la TECLA ha sido apretada. Esta dirección es la 0003H de la Memoria de Programa. Tomando en cuenta todas estas premisas el Diagrama en Bloques del algoritmo a programar será el que se muestra en la Figura 8.1.1.3.

Figura 8.1.1.3.

Microcontroladores. El 8051 de la INTEL.

317

El programa completo se muestra a continuación. ; Programa para el ejemplo 8.1.1. org 0 ; Reservando la zona de memoria para la INT0/ sjmp inicio org 0003h ; Subrutina de atención a la Interrupción INT0/ mov R7,A ; salva el contenido del registro A movc A,@A+DPTR ; obtiene código de lámpara de 7 segmentos. mov P2,A ; escribe en la lámpara de 7 segmentos. acall dem2 ; llamada a la subrutina de demora de 2 segundos mov A, R7 ; restablece el contenido del registro A. reti ; retorno al programa principal ; Subrutina que provoca una demora de 2 segundos a 12 Mhz. dem2: mov R6, #20 ldem2: mov R5, #200 ldem1: mov R4, #250 djnz R4, $ djnz R5, ldem1 djnz R6, ldem2 ret ; Inicio del Programa Principal. ; Apagando la Lámpara de 7 Segmentos. inicio: mov P2, #0ffh ; Declarando el Puntero a la Tabla de Conversión. mov DPTR, #TablaC ; Programando al Controlador de Interrupciones. mov IE, #10000001b ; habilitando la interrupción INT0/ mov TCON, #00000001b ; seleccionando activación con el flanco de caida ; Generador de números aleatorios. lazo1: mov A,#1 ; inicializa el contador nop nop lazo: inc A ; incrementa en 1 el contador nop nop cjne A,#6,lazo ; llego al conteo máximo sjmp lazo1 ; repite el proceso ; Tabla con los Códigos de Lámpara de 7 Segmentos de los dígitos decimales del 0 al 6. TablaC: db 40h,79h,24h,30h,19h,12h,02h end Observe en el listado del programa que tal como lo habíamos definido, la subrutina que atiende el pedido de interrupción a través de INT0/ producido por la acción de apretar la TECLA se coloca a partir de la localización en la memoria de programa cuya dirección es la 0003h. Esta es la razón por la que la primera instrucción del programa se corresponde con una instrucción de salto incondicional para reservar la zona de memoria a partir de esta dirección para colocar dicha subrutina. Observe también que dicha subrutina termina con la instrucción reti y no ret como estábamos acostumbrados terminar las subrutinas que invocamos mediante una instrucción del tipo call.

Microcontroladores. El 8051 de la INTEL.

318

¿A que se debe esto? De lo estudiado anteriormente sabemos que el objetivo al invocar cualquier Subrutina, sea por hardware o por software, es interrumpir la secuencia normal del Programa Principal para pasar a ejecutar un fragmento de programa, que es el que se conoce con el nombre de Subrutina, el que una vez terminado de ejecutar debe garantizar el retorno a la instrucción en el Programa Principal que se hubiese ejecutado de no haber ocurrido dicha interrupción. Esta es la causa por la que la última instrucción que se debe ejecutar dentro de una Subrutina debe ser una del tipo retorno. El 8051 cuenta con dos instrucciones de este tipo, ret y reti ambas utilizadas en el ejemplo anterior. La primera se debe utilizar como última instrucción de aquellas Subrutinas invocadas por software, o sea mediante una instrucción del tipo lcall, mientras que la segunda debe ser utilizada por aquellas Subrutinas que fueron invocadas por hardware, o sea debido a un pedido de interrupción atendido. Esto es así ya que mientras que la primera solo garantiza el retorno de una forma correcta y ordenada, la segunda además de garantizar esto, limpia el indicador interno de prioridad indicando que la atención a la interrupción en curso ha concluido y que por ende otra interrupción de igual prioridad, que se encuentre habilitada, puede ser atendida. Enfrentémonos a la solución del segundo ejemplo de este Epígrafe. Ejemplo 8.1.2. Dado un conjunto de 8 LEDs conectados al Puerto 2 del microcontrolador y nombrados de L1 a L8, se desea que el sentido de la rotación de uno de ellos encendido dependa de si un Interruptor simple polo – simple tiro conectado al terminal P1.0 del microcontrolador se encuentre cerrado o abierto. Si el Interruptor esta cerrado el LED encendido debe moverse en el sentido de L1 a L8 y si se encuentra abierto en el sentido contrario. Una Tecla del tipo ´Push Botom´ da la orden de cuando debe ocurrir el cambio en el sentido del movimiento del LED encendido. El intervalo de tiempo en el que cada LED debe permanecer encendido debe ser de 500 milisegundos. El circuito propuesto para la solución del problema anterior es el que se muestra en la Figura 8.1.2.1. ¿Qué encontramos de nuevo en este circuito con respecto al del ejemplo anterior? Observe que la TECLA, en este caso, la hemos conectado al terminal INT1/ del microcontrolador, a diferencia del ejemplo anterior, que fue conectada al terminal INT0/.

Microcontroladores. El 8051 de la INTEL.

319

Figura 8.1.2.1 ¿Qué implicaciones tiene esto para el programa ha desarrollar para solucionar esta aplicación? Primero, cuando programemos al Controlador de Interrupciones del 8051, la fuente de Interrupción a habilitar es la correspondiente a INT1/ y no ha INT0/ lo que provocará cambios en el bit del registro IE a poner en ´1´. Segundo, en el registro TCON al que hay que programar para que el microcontrolador reconozca un pedido de interrupción por el flanco de caída de la señal aplicada en su entrada correspondiente, al que hay que programar es a INT1/ no ha INT0/, lo que provocara cambios en el valor de los bits 0 y 2 de dicho registro. Tercero, la Subrutina de atención a la interrupción INT1/ se debe comenzar a cargar a partir de la localización de Memoria de Programa cuya dirección es 0013H y no la 0003H como ocurrió en el ejemplo anterior ya que los Vectores de Interrupción de ambas fuentes de interrupción son diferentes. ¿Cómo quedaría el programa tomando en cuenta estos tres aspectos nuevos en la solución de esta aplicación?

Microcontroladores. El 8051 de la INTEL.

320

; Inicio del Programa. org 0 ; Reservando el espacio para la Subrutina de Atención a la Interrupción. sjmp inicio ; Inicio de la Subrutina de Atención a la Interrupción. org 0013h jnb P1.0,L0L7 setb 20h.0 sjmp salir L0L7: clr 20h.0 salir: reti ;Inicio del Programa Principal. ;Imponer las condiciones iniciales. inicio: mov P0,#1 ; apagando todos los LEDs clr 20h.0 ; limpiando la bandera de sentido del movimiento. ; Programando al Controlador de Interrupciones. mov IE, #10000100b ; habilito a INT0/ mov TCON, #00000100b ; activa por frente. ; Rotando el encendido de los LEDs lazo3: jnb 20h.0, rotaba mov A, #01111111b mov R2,#8 lazo1: mov P0, A lcall demora rr A djnz R2,lazo1 sjmp lazo3 rotaba: mov A, #11111110b mov R2,#8 lazo2: mov P0,A lcall demora rl A djnz R2,lazo2 sjmp lazo3 ; Subrutina de demora. demora: mov R3,#5 lazo4: mov R4, #200 lazo5: mov R5, #250 djnz R5,$ djnz R4,lazo5 djnz R3,lazo4 ret end Observe en este caso el empleo del bit 0 de la localización de Memoria de Datos 20H para almacenar el valor de una Bandera que nos indicará el estado en que se encuentra el Interruptor cada vez que la TECLA es apretada. La parte del programa encargada de darle el valor adecuado a esta Bandera es la Subrutina de atención a la interrupción INT1/ y su valor es empleado por el Programa Principal para saber el sentido en que debe provocar el encendido de los LEDs La Subrutina ´demora´, simplemente esta puesta en el programa para establecer un tiempo entre el encendido de un LED y el encendido del siguiente en la secuencia, lo que permite que este

Microcontroladores. El 8051 de la INTEL.

321

proceso pueda ser visto por el usuario de una forma perceptible y periódica. Observe que a diferencia de la Subrutina de atención a INT1/ a la que se llega por hardware, a esta se llega por software producto de la ejecución de la instrucción, lcall demora 8.2 Termómetro Digital. Poder contar con un equipo que nos indique, cada vez que lo necesitemos, el valor de la Temperatura Ambiente podría resultar de gran utilidad en múltiples aplicaciones, por lo que les propongo que enfrentemos como aplicación a resolver, el diseño de un Termómetro Digital utilizando al microcontrolador 8051 como circuito fundamental de dicho equipo. Ejemplo 8.2.1. Diseñar un Termómetro Digital capaz de mostrarnos a través de un Display conformado por dos Lámparas de 7 Segmentos la temperatura ambiente que existe en un momento dado. La indicación del valor de la temperatura se efectuará cada vez que una TECLA presente en el Panel Frontal del equipo es apretada, manteniéndose dicha información por espacio de 5 segundos. El valor de la temperatura se debe mostrar en grados centígrados. La primera dificultad con la que nos tropezamos al enfrentar el diseño del equipo propuesto esta relacionada precisamente con la tarea que debe realizar el mismo, convertir la Temperatura Ambiente en un número decimal entendible por el operador del equipo. Efectivamente la temperatura es una variable física, mientras que el equipo basado en el 8051 trabaja con parámetros eléctricos, a esta situación no nos habíamos enfrentado todavía en ninguna de las aplicaciones que hemos ido resolviendo en el transcurso del presente libro. ¿Cómo lograr el entendimiento entre estos dos aspectos diferentes? En el mercado existen dispositivos, llamados Sensores, que son capaces de transformar el valor de una variable física en un valor de un determinado parámetro eléctrico como puede ser un valor de voltaje, un valor de corriente, un valor de resistencia, un valor de capacidad, etc. Existen diferentes principios de operación en los que estos se basan para llevar acabo esta tarea, no obstante en este momento esto no constituye de interés para nosotros. Un ejemplo de este tipo de dispositivo lo constituye el LM35 fabricado por la Nacional Semiconductor, el que es capaz de variar el valor del voltaje que entrega con respecto a la variación del valor de la temperatura que sense. En específico este Sensor, de alta precisión, varía en 10 milivoltios el valor del voltaje que entrega con cada variación de 1° Centígrado, brindando una salida lineal en todo el intervalo de temperatura que va desde los -55° C hasta +150° C.

Microcontroladores. El 8051 de la INTEL.

322

Este por su puesto que podría ser el Sensor que necesitamos para nuestra aplicación ya que como nos proponemos sensar temperatura ambiente, el intervalo de temperatura a medir se encuentra dentro del intervalo de temperatura que este es capaz de medir. La configuración típica que proponen los fabricantes para poner a sensar a este dispositivo la temperatura ambiente se muestra en la Figura 8.2.1, siendo la ecuación que relaciona el voltaje de salida con la temperatura en ° C la que aparece a su derecha.

Vsalida = 10 milivotls

°C

xT (°C )

La ecuación anterior es valida en todo el intervalo de valores de temperatura de nuestro interés para la aplicación, considerando que vamos a medir valores de temperatura entre 0° C y 50° C. La grafica que relaciona el voltaje de salida con la temperatura ambiente será la que se muestra en la Figura 8.2.2, obtenida de evaluar la expresión de Vsalida anterior para los valores de temperatura ambiente extremos que deseamos medir.

La pregunta a responder en este momento sería, ¿Cómo hacer que el microcontrolador, dispositivo digital, pueda trabajar con la señal analógica que entrega el Sensor LM35?

Microcontroladores. El 8051 de la INTEL.

323

En nuestra ayuda viene otro circuito integrado conocido con el nombre de Conversor Análogo – Digital, que como su nombre lo indica convierte los niveles de voltaje analógicos impuestos a su entrada en un número digital en n bits. Un ejemplo de este tipo de circuito lo constituye el TLC0820 fabricado por la ´Texas Instruments´, compatible con el ADC0820 de la ´Analog Device´, el que se muestra en la Figura 8.2.3.

El TLC0820 es un Conversor Análogo–Digital de aproximaciones sucesivas de 8 bits (n = 8), con posibilidad de trabajar con valores de voltaje analógico entre 0 y +5 volts con el empleo de una sola fuente de voltaje de + 5 volts conectada entre los terminales VCC y GND, ver Figura 8.2.3.

La señal analógica a convertir se debe conectar al terminal 1 del circuito integrado conocido con el nombre ANLG IN, ver Figura 8.2.3. El número binario obtenido por el conversor como resultado de la conversión es entregado a través de los terminales de salida D0 – D7, correspondiendo a D0 ser el bit menos significativo y a D7 el bit más significativo. Quizás la pregunta que se estén haciendo en este momento es, ¿Qué función entonces realizan el resto de los terminales del circuito? Los terminales REF+ y REF- están relacionados con el voltaje máximo y el voltaje mínimo de conversión respectivamente. Por ejemplo si los valores que puede tomar la señal analógica a convertir están enmarcados entre 0 volts y +5 volts, usted debe conectar al terminal REF+ los +5 volts de una fuente de CD mientras que a REF- debe conectar la tierra de dicha fuente. Con esto usted garantiza que si el voltaje aplicado en la entrada ANLG IN es de 0 volts, el conversor ponga a ´0´ todos sus bits de D0 a D7 (00h), mientras que si el voltaje aplicado es de +5 volts todos estos bits se ponen a ´1´ (0FFh). En ocasiones se desea restringir el intervalo de voltaje que puede tomar la señal analógica de entrada, por ejemplo entre 0 volts y +2.5 volts, en este caso, ponga el terminal REF+ a +2.5 volts y el terminal REF- a la tierra del circuito.

Microcontroladores. El 8051 de la INTEL.

324

En los dos ejemplos que hemos puesto se ha considerado que la señal analógica a convertir solo puede tomar valores de voltaje positivos, no obstante, pueden existir aplicaciones donde dicha señal puede tomar valores positivos y negativos, por ejemplo, consideremos una aplicación donde el intervalo de valores que puede tomar la Temperatura pudiera estar entre -50° C y 50° C. En este caso la configuración que proponen los fabricantes para conectar al lm35 es la mostrada en la Figura 8.2.4.

Como podemos ver ahora la señal que entrega el lm35 puede tomar valores positivos y negativos. En este caso REF+ lo podríamos conectar a un voltaje positivo como podría ser +5 volts mientras que a REF- lo conectaríamos a un voltaje negativo como podría ser -5 volts con lo que garantizamos que la señal analógica pueda tomar valores positivos y negativos de voltaje en el intervalo entre +5 volts y – 5 volts. En este caso cuando la entrada analógica toma el valor de -5 volts todos los bits de D0 a D7 se ponen a ´0´ (00h), mientras que cuando la señal analógica toma el valor de +5 volts todos los bits se ponen a ´1´ (0FFh). La pregunta en este caso podría ser, ¿Qué valor toman los bits de D0 a D7 cuando la señal analógica tome el valor de voltaje de 0 volts? 0 volts se correspondería con el valor de voltaje que se encuentra justo en el medio del intervalo de medición por lo que el número binario que entrega el conversor a través de los terminales de D0 a D7 se debe corresponder con el valor medio entre 00h y 0FFh, por lo que todos los bits de D0 a D6 tomarían el valor de ´1´, mientras que el bit D7 tomaría el valor de ´0´, 7Fh.

Microcontroladores. El 8051 de la INTEL.

325

Retornemos al ejemplo inicial ya que como podemos apreciar en la Figura 8.2.2 en nuestro caso todos los valores de voltaje que puede entregar el lm35 se corresponden con valores por encima de 0 volts. ¿Qué sucede si la señal analógica toma valores por encima de máximo permisible? Por ejemplo consideremos que REF+ lo hemos conectado a +5 volts y REF- a tierra de la misma fuente de CD y que la señal analógica toma el valor de +6 volts. Esto lo indicaría el conversor llevando a ´0´ su terminal 18, OFLW/, ver Figura 8.2.3. Esto puede ser utilizado para conectar varios conversores en cascada. ¿Cómo trabajar desde la posición del microcontrolador con este conversor? Son tres las operaciones básicas que ocurren entre un microcontrolador y un conversor análogo – digital: 1. Inicio de Conversión (IC) 2. Fin de Conversión (FC) 3. Lectura de la Conversión (LC). El Inicio de Conversión (IC), como su nombre lo indica, es la acción que efectúa el microcontrolador cada vez que quiere que el conversor análogo – digital obtenga el número binario correspondiente al valor de voltaje que tenga en ese momento la señal analógica que llega al conversor. Este proceso de conversión no es un proceso instantáneo, si no que toma un tiempo que depende en primer lugar de la velocidad de conversión del conversor. Por lo general, los conversores indican cuando han concluido el proceso de conversión mediante una señal, indicando que están listos para entregar el número binario correspondiente. A este proceso es al que llamaremos Fin de Conversión (FC). Muchos conversores tienen su salida de datos con posibilidad de ponerse en tercer estado, esto facilita su conexión a sistemas basados en microprocesadores. En estos tipos de conversores no basta con que se halla terminado la conversión y que por lo tanto tenga el número binario correspondiente listo para ser tomado, sino que hay que efectuar sobre ellos una operación de Lectura de la Conversión (LC) para que estos entreguen el número binario correspondiente. ¿Cómo indicarle al TLC0820 que queremos dar inicio a un proceso de conversión (IC)? ¿Cómo nos indica el TLC0820 que ha concluido con la conversión y que por lo tanto tiene un dato listo para ser leído (FC)? ¿Cómo efectuar una Lectura de la Conversión (LC) al TLC0820?

Microcontroladores. El 8051 de la INTEL.

326

Esto depende de 4 señales del TLC0820, tres de ellas de entrada y una de ellas de salida. Estas señales son: 9

CS/ (13)

ENTRADA.

9

RD/ (8)

ENTRADA.

9

WR/ (6)

ENTRADA

9

INT/ (9)

SALIDA.

El modo de combinar estas señales para producir la operación deseada depende de otro terminal de entrada del circuito el que recibe el nombre de MODE (7). En dependencia del nivel lógico impuesto en este terminal el conversor estará trabajando en uno de los dos posibles modos de trabajo con que cuenta, MODE = ´0´

MODO READ.

MODE = ´1´

MODO READ – WRITE.

Analicemos cada uno de estos modos de trabajo por separado para poder dar respuesta a las 4 preguntas que nos habíamos formulado anteriormente. MODO READ. En este modo de trabajo el conversor esta convirtiendo constantemente, razón por la cual no se hace necesario dar una orden de Inicio de Conversión (IC), ni esperar por un Fin de Conversión (FC). Todo lo que tiene que hacer el programador es dar Lectura del Conversor (LC) cada vez que quiera tener el número binario que corresponde con el valor de voltaje de la señal analógica. Para ello basta con imponer un ´0´ lógico en la entrada CS/ del conversor y un instante de tiempo después imponer un ´0´ lógico en la entrada RD/ del conversor. La lectura en este momento de los terminales de D0 a D7 del conversor nos traerá al microcontrolador el número producto de la conversión deseado. En la Figura 8.2.5 se muestran las formas de ondas correspondientes.

Figura 8.2.5. Modo Read.

Microcontroladores. El 8051 de la INTEL.

327

MODO READ – WRITE. En este modo de trabajo si están presentes todas las operaciones del conversor tal y como las explicamos en párrafos anteriores. ¿Cómo operar en este caso? En este caso podríamos poner de forma fija un nivel lógico de ´0´ en la entrada CS/, esto lo conseguiríamos conectando este terminal mediante un cable al terminal GND del conversor. Ahora todo lo que tenemos que hacer cuando queramos dar inicio de conversión (IC) es llevar a ´0´ lógico a la entrada WR/ y cuando queramos efectuar una Lectura del Conversor (LC) llevaríamos a RD/ a ´0´ lógico. El Fin de Conversión (FC) nos lo indicaría el conversor llevando a ´0´ su terminal de salida INT/. La forma de onda de las señales las mostramos en la Figura 8.2.6.

Figura 8.2.6 Modo Read – Write. Con los elementos que hemos dado hasta aquí somos del criterio de que estamos en condiciones de poderles proponer un hardware para nuestro Termómetro Digital, el que aparece en la Figura 8.2.7.

Microcontroladores. El 8051 de la INTEL.

328

Figura 8.2.7 Observe que hemos escogido el MODO 1 para trabajar con el TLC0820, esto lo logramos al imponer un ´1´ al terminal MODE de este circuito al conectarlo directamente a la fuente de voltaje de +5 volts, por lo que debemos darle Inicio de Conversión mediante la puesta a ´0´ de sus terminales WR/ y CS/, Leeremos el Conversor mediante la puesta a ´0´ de sus terminales RD/ y CS/ e indicara Fin de Conversión llevando a ´0´ su terminal INT/. Para generar las señales WR/, RD/ y CS/ emplearemos los terminales P3.5, P3.6 y P3.7 respectivamente, mientras que la salida INT/ del conversor la conectaremos a la entrada de interrupción INT1/. Por otro lado, la TECLA que permite al usuario pedir cuando desea conocer la Temperatura Ambiente la conectamos a la entrada de interrupción INT0/ del microcontrolador, por lo que las dos fuentes de interrupción externa deben ser habilitadas y ambas las habilitaremos para que el microcontrolador las reconozca con el frente de caída. El algoritmo que debe seguir el programa dado este hardware podría ser el siguiente, una vez programado el Controlador de Interrupciones, de poner los terminales del TLC0820 en el valor de no activación y de borrar ambas Lámparas de 7 Segmentos, el programa se queda esperando porque la TECLA sea apretada. Esta acción provocará la activación de la interrupción INT0/, encargándose la Subrutina de atención a esta interrupción de provocar el Inicio de Conversión en el conversor. El proceso de conversión le tomará un tiempo al conversor el que indicará cuando ha terminado y por ende cuando esta listo para ser leído mediante la activación de su terminal INT/ el que provocará un pedido de interrupción del tipo INT1/ en el microcontrolador. La Subrutina de atención a esta interrupción leerá el conversor a través del Puerto 1 quedando listo para

Microcontroladores. El 8051 de la INTEL.

329

determinar el valor de la Temperatura Ambiente y mostrarla a través de las Lámparas de 7 Segmentos. Pero, ¿Qué relación existe entre el número binario leído del conversor a través del Puerto 1 y el valor de la Temperatura a ser mostrada en las Lámparas de 7 Segmentos? Por su puesto que lo ideal sería poder encontrar una expresión matemática entre el número binario leído y la Temperatura Ambiente que nos permita ser representada mediante un fragmento de programa que ejecutaremos cada vez que tengamos que mostrar la medición en las Lámparas de 7 Segmentos. ¿Como proceder para determinar esta expresión matemática? En la Figura 8.2.2 se muestra la relación existente entre la Temperatura Ambiente y el voltaje de salida entregado por el lm35. Esta relación viene dada por la ecuación:

Vsalida = 10 milivotls

°C

xT (°C )

Podríamos buscar también una relación entre el voltaje en la entrada ANLG IN del conversor y el número binario que este entrega. Dado que REF+ esta conectado a +5 volts y REF- esta conectado a GND y a que el conversor es de 8 bits podemos plantear que la relación entre ambos es la que se muestra en la Figura 8.2.8 y la ecuación que las relaciona es la que se presenta a la derecha.

1 ⎞ ⎛ # binario = ⎜ 51 ⎟(V ANLGIN ) ⎝ volts ⎠

Microcontroladores. El 8051 de la INTEL.

330

Si encontramos una relación entre el voltaje aplicado en la entrada ANLG IN del conversor y la Temperatura Ambiente tendríamos lo necesario para encontrar la ecuación buscada. No obstante, entre el lm35 y el conversor hemos conectado un Amplificador Operacional lm2902. ¿Con que interés hemos hecho esto? El problema esta en que la salida del lm35 esta en el intervalo de voltaje de 0 a 0.5 volts el que resulta estrecho si tomamos en cuenta que el intervalo de voltaje con que puede trabajar el conversor esta entre 0 y 5 volts, dada la configuración que hemos escogido para el mismo. Efectivamente si conectamos directamente la salida del lm35 al conversor solo estaríamos aprovechando la décima parte de la resolución del conversor y por lo tanto perderíamos en posibilidad de discernir entre valores de temperatura cercanos. Una solución a este problema sería tratar de ocupar todo el intervalo posible de voltaje a la entrada del conversor de forma tal que pudiéramos aprovechar todas las posibilidades de resolución que me brindan sus 8 bits. Para ello la solución que hemos propuesto ha sido la de colocar un operacional, el lm2902, en su configuración como amplificador con ganancia 10. Ahora cuando el lm35 producto de la temperatura este dando 0 volts al conversor por su entrada ANLG IN esta llegando 0 volts y cuando el lm35 este dando 0.5 volts, producto de la temperatura, a la entrada ANLG IN están llegando 5 volts. ¿Cómo quedaría ahora la grafica que relaciona el voltaje a la entrada ANLG IN del conversor con la temperatura que esta sensando el lm35? Todo lo que tenemos que hacer es multiplicar por 10 la grafica que habíamos obtenido anteriormente que relacionaba la Temperatura con el voltaje de salida del lm35, que aparece en la Figura 8.2.2. La nueva grafica aparece en la Figura 8.2.9 y la ecuación que la caracteriza es la que aparece a la derecha de la Figura.

(

VSAL = 0.1 volt

°

C

)(T ) a

Microcontroladores. El 8051 de la INTEL.

331

De las tres ecuaciones obtenidas anteriormente y recogida en el sistema de ecuaciones que aparece a continuación, obtenemos la ecuación que buscamos.

1 ⎞ ⎛ # binario = ⎜ 51 ⎟(V ANLGIN ) ⎝ volts ⎠

(

VSAL = 0.1 volt

°

)(T ) C

⎛ # binario ⎞ Ta = ⎜ ⎟°C 5 ⎝ ⎠

a

VSAL = V ANLGIN Por lo tanto todo lo que tiene que hacer nuestro programa, cuando desee obtener el valor de la Temperatura Ambiente a partir del número binario leído del conversor, consiste en dividir entre 5 este número y el resultado ya nos da en grados centígrados que es lo que queremos. El programa en ensamblador

para resolver la aplicación que nos estamos proponiendo en

consecuencia al hardware definido seria el que se muestra a continuación. ; Programa para el Termómetro Digital org

0

sjmp

inicio ; salva el espacio en memoria de programa para Subrutina INT0/

; Subrutina de atención a TECLA apretada. org

0003h

clr

p3.5

; dando Inicio de Conversión.

reti ; Subrutina de atención a Fin de Conversión. org

0013h

setb

p3.5

clr

p3.6

lcall

dem1 ; espera por respuesta del buffer de salida del conversor.

mov

a,p1

setb

p3.6

mov

20h,a ; salva el valor leído del conversor.

setb

21h.0 ; pone en ´1´ la bandera de medición a mostrar.

; habilita la Lectura del Conversor. ; lee el buffer del conversor

reti ; Subrutina de demora de 20 microsegundos a 12 Mhz. dem1: mov djnz

r7, #10 r7,$

ret ; Programa Principal inicio: mov

p0, #0ffh ; apaga la Lámpara de 7 Segmentos de las decenas.

Microcontroladores. El 8051 de la INTEL.

lazo:

mov

p2, #0ffh ; apaga la Lámpara de 7 Segmentos de las unidades.

mov

dptr, #tablac

; puntero a la Tabla de código de Lámpara de 7 Segm.

mov

ie,#10000101b

; habilita las interrupciones INT0/ e INT1/.

mov

tcon, #00000101b ; ambas interrupciones activas por el flanco de caída.

clr

21h.0

; limpia bandera de dato a mostrar.

jnb

21h.0,$

; espera por un dato a mostrar.

mov

a, 20h

; carga en el reg. A el número leído del conversor

332

; Convirtiendo a unidades de ingeniería. mov

b, #5

div

ab

; Convirtiendo a BCD Empaquetado. mov

b, #10

div

ab

mov

r2, a

; en R2 las decenas.

; Validadando el valor medido subb

a, #5

jnc

nmos

; las decenas mayor que 5 no mostrar.

; Determinando el código de Lámpara de 7 Segmentos de las decenas. mov

a,r2

movc a, @a+dptr

; extrayendo el código Lámpara de 7 Segmentos de la tabla.

mov

; escribiendo en la Lámpara de 7 Segmentos.

p0,a

; Determinando el código de Lámpara de 7 Segmentos de las unidades. mov

a, b

movc a, @a+dptr

; extrayendo el código de Lámpara de / Segmentos de la tabla

mov

p2,a

; escribiendo en la Lámpara de 7 Segmentos.

nmos: sjmp

lazo

; hacer cíclico el programa.

; Tabla con los códigos de Lámparas de 7 Segmentos. tablac: db

40h,79h,24h,30h,19h,12h,02h,78h,00h,10h

end 8.3 Sincronizando la llegada de datos desde un Teclado ASCII - Paralelo. Quizás la primera pregunta que ustedes se estén haciendo es, ¿A qué llamamos un Teclado ASCII - Paralelo? Existen Teclados del tipo alfa – numéricos, como el de su Microcomputadora, que el código correspondiente a la Tecla que ha sido apretada lo transmite de forma paralela, por lo general en 8

Microcontroladores. El 8051 de la INTEL.

333

bits. El código generalizado para indicar la Tecla apretada es el conocido como ASCII. Estos dos elementos son los que caracterizan al Teclado al que haremos referencia en el ejemplo que resolveremos en este Epígrafe. Además de los 8 bits correspondientes al código de la Tecla apretada, estos Teclados transmiten y reciben otras señales que le permiten sincronizar su operación con el dispositivo al que ellos se encuentren conectados. Podríamos decir que de estas señales dos que podemos considerar de las más importante para la sincronización lo constituyen la señal de STROBE/(STB/) y la señal de ACKNOLEGMENT/(ACK/). La primera constituye una señal de salida del Teclado, a través de la cual este indica que una Tecla ha sido apretada y que el código ASCII correspondiente a dicha Tecla se encuentra de forma estable y lista para ser leído en las líneas de salida de código del mismo. Por su parte la segunda señal es de entrada y a través de la misma el dispositivo receptor le indica al Teclado que el código de la Tecla apretada ha sido tomado de forma satisfactoria y que se encuentra listo para recibir un nuevo código. La Figura 8.3.1 los ayudara a comprender mejor la explicación dada.

Figura 8.3.1. Las Teclas que conforman a este Teclado son del mismo principio de operación que las que utilizamos en los dos ejemplos anteriores, claro esta, en este caso esto no resulta tan importante para la solución de la aplicación ya que el Teclado tiene su propio circuito que se encargará de detectar cuando una Tecla ha sido apretada y determinar el código ASCII que le corresponde para su posterior transmisión. Somos del criterio que con los elementos dados podemos enfrentar la solución de la aplicación que se nos propone resolver en el Ejemplo 8.3.1.

Microcontroladores. El 8051 de la INTEL.

334

Ejemplo 8.3.1. Diseñar una interfaz basada en el microcontrolador 8051 entre un Teclado ASCII y un Display a Cristal Líquido (LCD) de 2 renglones y 16 caracteres del tipo LM016L, de forma tal que cada vez que se teclee un número o una letra en el Teclado la información aparezca en el Display. Para cambiar de renglón utilizar la Tecla ENTER y para indicar nuevo cartel apretar la Tecla ESC. En la Figura 8.3.2 se muestra un esquema en bloques de la aplicación que nos piden resolver empleando al microcontrolador 8051.

Figura 8.3.2. Para poder definir un hardware del sistema necesitamos conocer primero cuales son las señales que brinda el Display a Cristal Liquido para comunicarse con el. En la Figura 8.3.3 se muestra un esquema donde aparecen los terminales del LM016L. La función de cada uno de los terminales es la siguiente: D0-D7 Bus de datos. A través de estas 8 líneas se le envían al LM016L los códigos ASCII de los caracteres a mostrar y la comandos. RS

A través de este terminal se le indica al LM016L si el código enviado a través de los terminales D0-D7 se corresponde a una comando o a un carácter a mostrar. ´0´

comando.

´1´

carácter a mostrar.

Microcontroladores. El 8051 de la INTEL. R/W

335

A través de este terminal se le indica al LM016L si la operación que se desea efectuar con él, es de lectura o escritura.

E

´0´

escritura.

´1´

lectura.

Este terminal debe estar a ´0´ para que el LM016L este habilitado para efectuar una cualquiera de las operaciones definidas anteriormente.

VSS Terminal de tierra. VEE Terminal de + 5 volts. VDD Terminal para aplicar un voltaje entre +5 volts y tierra que garantice el contraste necesario Entre los caracteres y el fondo de la pantalla. Con estos elementos podemos intentar diseñar un hardware para la aplicación que nos ocupa, ver Figura 8.3.4.

Figura 8.3.4. Observe que hemos utilizado la INT1/ del 8051 para conectar el terminal de salida STB/ del TECLADO ASCII. Con esto logramos sincronizar la acción de apretar una Tecla por parte del usuario con la operación del programa en el microcontrolador. Ahora cuando el usuario apriete una Tecla, el TECLADO ASCII enviará el código ASCII correspondiente al carácter asociado a dicha Tecla a través de sus terminales D0-D7,

Microcontroladores. El 8051 de la INTEL.

336

conjuntamente con la señal STROBE a través del terminal de salida STB/, ver Figura 8.3.1. Este frente de caída de la señal que sale por el terminal STB/ es el que aprovecharemos para Interrumpir la operación del 8051 y que de esta forma detecte que el TECLADO ASCII le esta enviando el código ASCII de la Tecla apretada. El código ASCII de la Tecla apretada le estaría llegando al 8051 a través del Puerto 1 según el hardware diseñado, ver Figura 8.3.4, por lo que para su captura solo se hace necesario ejecutar una instrucción de lectura de dicho Puerto y ya tendríamos en el registro Acumulador del microcontrolador dicho código. Todo lo que resta sería reconocer que tipo de Tecla es la que ha sido apretada, de carácter o de comando, para que el programa tome la decisión correcta, enviar el código ASCII del carácter a mostrar o el comando adecuado para ejecutar la orden enviada por el usuario. Pero, ¿Cómo enviar un carácter a mostrar en el LM016L? , ¿Cómo enviar una comando al LM016L?, ¿Cuáles son los posibles comandos a enviar al LM016L? Tanto los códigos de los caracteres a mostrar en el LM016L así como los comandos que controlan su operación le llegan a este dispositivo a través de sus terminales D0-D7, en un formato de 8 bits. Es imprescindible, para que el LM016L pueda recibir esta información, que su terminal E se encuentre en ´0´ con lo que se esta habilitando al dispositivo. Esta señal la controlaremos en nuestra aplicación con el terminal P3.2 del 8051. La pregunta a responder en este momento sería, ¿Cómo el LM016L sabe que lo que le están enviando es el código ASCII de un carácter a mostrar en su display o es el código de un comando? Como se explico cuando se definió la función de cada uno de los terminales de este circuito, para ello esta el terminal RS. Si lo que se esta enviando es el código de un carácter a mostrar en el display, conjuntamente con el ´0´ en el terminal E, se debe poner un ´1´ en el terminal RS. Si por el contrario lo que se envía es el código correspondiente a una comando, entonces conjuntamente con el ´0´ en el terminal E se debe poner un ´0´ en el terminal RS. Esta señal la controlaremos con el terminal P3.0 del 8051. A la operación de enviar el código ASCII de un carácter a mostrar en el display o la de enviar el código de un comando se conoce con el nombre de que el LM016L ha sido escrito. Para ello el terminal R/W debe estar a ´0´. No obstante, el LM016L permite también ser leído.

Microcontroladores. El 8051 de la INTEL.

337

¿Qué leemos del LM016L? Efectivamente las operaciones anteriores eran las de esperar que se pudieran efectuar sobre el LM016L ya que este dispositivo lo podemos clasificar como un periférico de salida, no obstante, operaciones tales como leer el estado en que se encuentra el dispositivo y el valor almacenado en una localización de su memoria de datos son también posibles de efectuar. Para ello el terminal R/W se debe poner a ´1´. Este terminal lo controlaremos con el terminal P3.1 del 8051. A continuación mostramos una Tabla donde resumimos la operación del LM016L y el valor en los terminales P3.0, P3.1 y P3.2 del 8051 en nuestra aplicación. Puerto 3 – LM016L

Operación

P3.0-RS

P3.1-R/W

P3.2-E

X

X

1

Deshabilitado el LM016L para recibir códigos de caracteres a mostrar y de comandos.

0

0

0

Escritura de una comando.

1

0

0

Escritura de un carácter a mostrar.

0

1

0

Lectura de la palabra de estado del LM016L

1

1

0

Lectura de una carácter almacenado en la memoria de display del LM016L

Por ejemplo como sería una Subrutina que podríamos invocar cada vez que queramos escribir un carácter a mostrar en el LM016L en el caso que nos ocupa. ; Esta Subrutina permite escribir el código de un carácter que se desea mostrar en el LM016L. ; P3.0 del microcontrolador esta conectado al terminal RS del LM016L. ; P3.1 del microcontrolador esta conectado al terminal R/W del LM016L ; P3.2 del microcontrolador esta conectado al terminal E del LM016L. ; El Puerto 2 del microcontrolador esta conectados a los terminales D0-D7 del LM016L ; En el registro Acumulador el código ASCII del carácter que se desea enviar al LM016L esccar:

mov

P2, A

; envía el código del carácter a mostrar al LM016L

setb

P3.0

; indica al LM016L que le van a enviar un carácter.

setb

P3.2

; habilita al LM016L.

nop clr ret ; Fin de la Subrutina.

P3.2

Microcontroladores. El 8051 de la INTEL.

338

Por su parte la Subrutina a invocar cada vez que queramos enviar el código de un comando al LM016L podría ser la siguiente. ; Esta Subrutina permite escribir el código de un comando en el LM016L. ; P3.0 del microcontrolador esta conectado al terminal RS del LM016L. ; P3.1 del microcontrolador esta conectado al terminal R/W del LM016L ; P3.2 del microcontrolador esta conectado al terminal E del LM016L. ; El Puerto 2 del microcontrolador esta conectados a los terminales D0-D7 del LM016L ; En el registro Acumulador el código del comando que se desea enviar al LM016L esccom:

mov

P2, A

; envía el código del carácter a mostrar al LM016L

clr

P3.0

; indica al LM016L que le van a enviar un comando.

setb

P3.2

; habilita al LM016L.

nop clr

P3.2

ret ; Fin de la Subrutina. Otro aspecto importante a tomar en consideración cuando se esta trabajando con un Display a Cristal Líquido del tipo LM016L esta relacionado con el tiempo que debe mediar entre cada una de las escritura, tanto de una comando como de un carácter, que se haga sobre el mismo. Efectivamente la respuesta del LM016L no es instantánea y los fabricantes recomiendan dejar pasar un tiempo, en algunos casos de 40 microsegundos y en otros casos de 1,64 milisegundos, después de cada escritura, si se quiere que este dispositivo trabaje correctamente. ¿Cuándo dejar pasar 40 microsegundos?, ¿Cuándo dejar pasar 1,64 milisegundos? Cada vez que usted escriba el código de un carácter a mostrar en el LM016L, el tiempo recomendado dejar pasar es de 40 microsegundos antes de escribir otro, mientras que si es el código de una comando un tiempo prudencial es el de 1,64 milisegundos. Aunque no es así para el caso de las comandos en todos los casos seguir este consejo siempre que sea posible es saludable. Esto lo podemos resolver en nuestro programa mediante dos Subrutinas como las que mostramos a continuación. ; Subrutina que demora 40 microsegundos. ; Considerando que el cristal de cuarzo conectado al 8051 es de 12 Mhz. dem40:

mov

R2,#20

djnz

R2,$

ret

Microcontroladores. El 8051 de la INTEL.

339

; Subrutina que demora 1,64 milisegundos. ; Considerando que el cristal de cuarzo conectado al 8051 es de 12 Mhz. dem164:

mov

R7,#41

lazo2:

acall

demo40

djnz

R7,lazo2

ret Definir los comandos fundamentales para programar al LM016L nos puede dar todos los elementos para comenzar a enfrentar el diseño del programa de la aplicación que nos ocupa. Estos comandos son: 38H

Escoge el tamaño del bus de datos y comandos para el LCD de 8 bits. Escoge que el número de renglones con que va a trabajar el LCD es de 2.

01H

Limpia todas las localizaciones de memoria del LCD. Lleva al puntero de memoria del LCD a la posición inicial (80H).

06H

Movimiento del cursor hacia la derecha.

0EH

Se enciende el LCD. Se activa el cursor. Se elimina el estado de parpadeo.

80H-8FH C0H-CFH

Dirección de la localización de memoria del LCD. Primer renglón Segundo renglón.

Con los elementos que hemos definido tanto del Teclado ASCII como del Display a Cristal Líquido LM016L podemos proponernos hacer el programa de la aplicación que nos ocupa. En la Figura 8.3.5 se muestra en Diagrama en Bloques el algoritmo a programar.

Figura 8.3.5.

Microcontroladores. El 8051 de la INTEL. El listado del programa es el que mostramos a continuación. ; Este programa controla la operación del circuito interfaz entre un Teclado ASCII y un ; Display a Cristal Líquido del tipo LM016L de forma tal que la información entrada por ; el Teclado ASCII se muestre en el Display a Cristal Líquido. ; La Tecla ENTER provoca un cambio en el renglón del display donde se escribe. ; La Tecla ESCAPE provoca que se preparen las condiciones para recibir un cartel nuevo. ; La atención del teclado ASCII se hace por Interrupción. ; Inicio del texto del programa. org 0 ; Resguarda la zona de memoria para almacenar la Subrutina que atiende a la interrupción ; externa INT1. sjmp inicio ; Subrutina que lee el código ASCII de la tecla apretada. org 0013h mov A, P1 ; leo el código ASCII de la tecla apretada clr P3.7 ; indico al teclado que ya se tomo la letra. acall dem40 ; provoco una demora de 40 microsegundos. setb P3.7 ; restablezco la señal de reconocimiento. acall tecla reti ;Inicio del Programa Principal. ;Habilitando la interrupcion externa INT1 y reconociéndola con el frente de caída. inicio: mov ie,#10000100b mov tcon,#00000100b ; Habilita al LM016L para escribirlo. clr P3.1 ;Programando al LCD. mov P2,#38h ; bus de 8 bits, 2 renglones. acall esccom ; escribe comando acall dem164 ; demora de 1.64 milisegundos mov P2,#06h ; mueve el cursor a la derecha. acall esccom ; escribe la comando acall dem164 ; demora de 1.64 milisegundos mov P2,#0eh ; enciende el display y activa el cursor. acall esccom ; escribe comando acall dem164 ; demora de 1.64 milisegundos mov P2,#80 ; primer carácter de la primera línea. acall esccom ; escribe comando acall dem164 ; demora de 1.64 milisegundos mov P2,#01b ; limpia LCD, puntero a posición inicial. acall esccom ; escribe comando acall dem164 ; demora de 1.64 milisegundos. ; Esperando por Tecla apretada. espera: sjmp $ ; En el Registro Acumulador el código ASCII de la tecla apretada. ; Determinando si el código se corresponde con una Tecla de Carácter o con las Teclas ; ESCAPE o ENTER. tecla: cjne A, #27 ,noesc ; el número 27 es el código ASCII de la tecla ESCAPE sjmp escape noesc: cjne A, #13 , caract ; el número 13 es el código ASCII de la tecla ENTER sjmp enter

340

Microcontroladores. El 8051 de la INTEL.

341

; Escribe un carácter en el LM016L caract: acall secar acall dem40 ret ; Envía el comando que prepara las condiciones para recibir un nuevo cartel. escape: mov P2,#01h acall esccom acall dem164 ret ; Envía el comando que provoca un cambio de línea de un cartel. enter: mov P2,#0c0h acall esccom acall dem40 ret ; Subrutina que escribe un comando en el LCD. esccom: clr P3.0 setb P3.2 nop clr P3.2 ret ;Subrutina que escribe un carácter en el LCD esccar: mov P2,A setb P3.0 setb P3.2 nop clr P3.2 ret ; Subrutinas de demora de 40 microsegundos. dem40: mov R2,#20 djnz R2,$ ret ; Subrutina de demora 1,64 milisegundos dem164: mov R7,#41 lazo2: acall dem40 djnz R7,lazo2 ret end 8.4 Generador de Avisos. Poder contar con un equipo manuable, que permita enviar mensajes con determinada longitud hacia una pequeña pantalla o hacia otra persona puede resultar muy útil. Intentemos diseñar este equipo con el empleo del microcontrolador 8051. Por supuesto que nuestro equipo necesitara de un Teclado por donde introducir el mensaje a mostrar y/o transmitir y algún elemento indicador que actué como Display y muestre los mensajes enviados, de forma tal que, el que envía el mensaje tenga una manera de realimentarse y conocer si el mensaje que esta enviando es el correcto. Un dibujo donde se muestra una propuesta del equipo a diseñar es el que se muestra en la Figura 8.4.1.

Microcontroladores. El 8051 de la INTEL.

342

Figura 8.4.1. Como Display podríamos utilizar a otro de los LCD de la misma familia del LM016L estudiado en el ejemplo anterior, el LM032L. ¿En que se diferencian estos dos dispositivos? Podríamos decir que las únicas diferencias entre ellos están en cuanto a sus capacidades para mostrar caracteres de una vez en la pantalla. Mientras que el LM016L solo puede mostrar 16 caracteres en un renglón y dos renglones en su pantalla, el LM032L puede mostrar 32 caracteres por renglón y también dos renglones en su pantalla. En

cuanto

a

sus

terminales

para

su

conexión

al

microcontrolador, su modo de operación y sus comandos son las mismas. En la Figura que se muestra a la derecha aparece un esquema del LM032L donde se puede ver su similitud en cuanto a los terminales para su conexión con el LM016L. Con esta selección estamos limitando el tamaño de los mensajes a enviar a 64 caracteres, 32 por cada renglón, considerando que el cartel se debe visualizar completamente en la pantalla.

Microcontroladores. El 8051 de la INTEL.

343

Los mensajes a enviar pueden estar constituidos por letras y números por lo que el Teclado debe permitir la entrada de estos caracteres. Ya esto impone aparentemente la necesidad de 37 teclas en el Teclado, 10 para los números y 27 para las letras. Por otro lado, sería conveniente que se pudieran utilizar algunos caracteres especiales para poder escribir los mensajes como pueden ser: 9

Los signos de interrogación (¿), (?)

9

Los signos de admiración (¡), (!)

9

Los signos de puntuación (,), (.)

Con lo que el Teclado podría estar constituido por más de 40 teclas, esto atenta con el tamaño del equipo. ¿Cuál podría ser una solución para disminuir el número de teclas en el Teclado? Una solución podría estar relacionada con darle varios significados a la misma tecla. Por ejemplo en una misma tecla podrían coexistir los caracteres A, Q y /. La pregunta en este momento podría ser, ¿Cómo el microcontrolador puede conocer la intención del usuario al apretar esta tecla? Para ello podríamos agregar otras dos teclas a las que podemos llamar F1 y F2 de forma tal que si la tecla anterior se aprieta y ninguna de estas dos teclas están apretadas la intención del usuario fue la de introducir al mensaje la letra A, pero si estaba además apretada F1 la intención fue introducir la letra Q y si la que estaba apretada era la F2 la intención fue la de introducir el símbolo /. Con esto indiscutiblemente que complicamos el trabajo del usuario a la hora de componer el mensaje pero disminuimos significativamente el número de teclas que conforman el Teclado. Por ejemplo con un Teclado conformado por 16 teclas tenemos 48 caracteres diferentes para componer nuestros mensajes. Un teclado con este número de teclas es el que proponemos para construir nuestro equipo, tal y como se muestra en la Figura 8.4.2.

Microcontroladores. El 8051 de la INTEL.

344

Figura 8.4.2. La pregunta a contestar en este momento sería, ¿Cómo construir este Teclado?, ¿Cómo conectarlo al microcontrolador? Por su puesto que una solución sencilla podría ser conectar una tecla a un terminal de uno de los Puertos del microcontrolador de forma tal que para conectar las 16 teclas necesitamos de dos Puertos completos (8 terminales cada puerto). Esta forma aunque sencilla en cuanto al hardware y al software necesario para atender el Teclado ocupa muchos recursos del microcontrolador. Intentemos conectar las 16 teclas a los terminales de un solo Puerto del microcontrolador, ¿Cómo podríamos hacer esto? Observen la propuesta que le hacemos en la Figura 8.4.3.

Microcontroladores. El 8051 de la INTEL.

345

Figura 8.4.3. Hemos hecho una matriz de 4 x 4 con las 16 teclas de forma tal que la posición de una tecla en el teclado viene dada por las coordenadas que imponen dos de los terminales del Puerto 2 en este caso. Esto queda resumido en la Tabla que se muestra a continuación. POSICIÓN DE LA TECLA

COORDENADA X

COORDENADA Y

0

P2.4

P2.0

1

P2.4

P2.1

2

P2.4

P2.2

3

P2.4

P2.3

4

P2.5

P2.0

5

P2.5

P2.1

6

P2.5

P2.2

7

P2.5

P2.3

8

P2.6

P2.0

9

P2.6

P2.1

10

P2.6

P2.2

11

P2.6

P2.3

12

P2.7

P2.0

13

P2.7

P2.1

14

P2.7

P2.2

15

P2.7

P2.3

Microcontroladores. El 8051 de la INTEL.

346

Pero, ¿Cómo el programa que esta siendo ejecutado por el microcontrolador detecta cual tecla ha sido apretada? La acción de apretar la tecla provoca que los dos terminales que conforman sus coordenadas se unan de forma tal que el nivel lógico que hay en uno se pase al otro terminal. Por ejemplo, si por el terminal P2.4 el programa que se esta ejecutando en el microcontrolador envía un ´0´ y al leer el Puerto 2 en el terminal P2.0 hay un ´0´ es porque la tecla que hemos dado la Posición 0 fue apretada, pero si el que esta en ´0´ es el terminal P2.1 la tecla que fue apretada fue la que le hemos dado la Posición 1. Esto lo podríamos hacer para cada una de las teclas del Teclado obteniendo pares de terminales diferentes para cada una de ellas, de forma tal que, cuando por P2.4 se envía un ´0´ al leer el Puerto 2 podemos determinar si fue apretada alguna de las teclas que le hemos dado la Posición desde la 0 hasta la 3, pero si el ´0´ se envía por P2.5, ahora las teclas encuestadas son las que tienen la Posición de la 4 a la 7 y así sucesivamente. Este es el algoritmo que debemos implementar en nuestro programa para atender al Teclado matricial conformado con las 16 teclas del equipo. Todo lo que nos queda por hacer es asociar a cada tecla del equipo una Posición dentro del Teclado de forma tal que cuando determinemos la Posición de la Tecla que fue apretada podemos deducir cual fue la intención del usuario. Esta asociación para nuestro caso se muestra en la siguiente Tabla. Posición 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Ni F1 ni F2 A B C D E F G H I J K L M N O P

F1 Q R S T U V W X Y Z , ! @ # $

F2 / * ( ) + = 0 1 2 3 4 5 6 7 8 9

Microcontroladores. El 8051 de la INTEL.

347

Del ejemplo anterior ya conocemos que cuando se desea escribir un determinado carácter en la pantalla de un display del tipo LM032L, ya sea letra, número o carácter especial, lo que tenemos que enviar hacia el mismo es el código ASCII de dicho carácter. Por lo que no basta en nuestro caso con determinar la Posición de la tecla apretada y de esta forma conocer la intención del usuario al apretar la tecla, sino que tenemos que convertir esta Posición en un código ASCII a transmitir hacia el LM032L. Lo que tenemos que hacer es una conversión de códigos, de código de Posición a código ASCII. Este tipo de operación ya la hemos efectuado otras veces y para ello hemos empleado una Tabla que se almacena en la Memoria de Programa junto con este y que contiene el código destino de la conversión, en este caso el ASCII y a la que se entra con el código fuente de la conversión en este caso la Posición de la tecla. Por lo que debemos conocer cual es el código ASCII de los caracteres que aparecen representados en el Teclado. Pienso que este es un buen momento dentro del libro para hablar sobre el código ASCII. El código ASCII es el código más empleado para representar los caracteres cuando estos se transmiten entre las diferentes partes que componen la microcomputadora y cuando estos se transmiten a otros dispositivos fuera de la microcomputadora. Es un código que emplea 7 bits para la representación de los diferentes caracteres, de forma tal que a cada carácter le corresponde un número en binario que lo identifica. En total se pueden representar 128 caracteres diferentes entre los que se incluyen los dígitos decimales, las letras en mayúsculas y minúsculas, los símbolos especiales y algunos caracteres que hacen función de comandos. En la siguiente Tabla se muestran los 127 caracteres posibles a representar en código ASCII, divididos en caracteres no imprimibles y caracteres imprimibles con sus correspondientes códigos.

Microcontroladores. El 8051 de la INTEL.

348

Todo lo que tenemos que hacer es seleccionar de la tabla anterior cuales son los códigos de los caracteres que aparecen reflejados en la teclas y colocarlos en la Tabla de Conversión del programa ordenados tomando en cuanta la Posición que ocupe la tecla en cuestión dentro del Teclado. En la Figura 8.4.4 se muestra la propuesta de hardware que hacemos para materializar el equipo que nos hemos propuesto construir.

Microcontroladores. El 8051 de la INTEL.

349

Figura 8.4.4. A continuación se lista el programa en lenguaje ensamblador del 8051 que da solución a la aplicación que nos habíamos propuesto tomando en cuenta el hardware de la figura anterior. ; Este programa permite conformar mensajes de hasta 64 caracteres que se entran a través ; de un Teclado Matricial de 16 teclas en una matriz de 4 x 4. ; Los mensajes se muestran a través de un Display a Cristal Líquido del tipo LM032L. ; Dos teclas fuera de la matriz permiten escoger diferentes símbolos para la misma tecla. ; Dos teclas fuera de matriz permiten enviar dos comandos al microcontrolador. ; Teclado Matricial conectado al Puerto 2. ; Display a Cristal Líquido conectado al Puerto 1. ; Las señales de control del Display a Cristal Líquido, P3.6 y P3.7. ; Las teclas no conectadas a la matriz a los terminales P3.4 (F1) y P3.5 (F2). ; Se emplea la interrupción externa INT0/ para detectar nuevo cartel, (NC). ; Se emplea la interrupción INT1/ para detectar nueva línea (NL). ; Inicio del listado del programa. org 0 ; Inicio del Programa. ; Resguardando la zona de memoria para la Subrutina de INT0/ sjmp inicio ; Subrutina que atiende el inicio de un nuevo cartel. org 0003h mov P1,#01h acall esccom acall dem164 reti ; Subrutina que atiende el cambio de línea de un cartel. org 0013h mov P1,#0c0h acall esccom acall dem40 reti

Microcontroladores. El 8051 de la INTEL. ; Inicio del Programa Principal. ; Habilitando la interrupción. inicio: mov ie,#10000101b mov tcon, #00000101b clr 20h.0 ; Programando al LCD. mov P1, #38h ; Bus de 8 bits, 2 renglones. acall esccom ; Escribe comando acall dem40 ; Demora de 80 microsegundos mov P1, #06h ; Mueve el cursor a la derecha. acall esccom ; Escribe la comando acall dem40 ; Demora de 80 microsegundos mov P1, #0eh ; Enciende el display y activa el cursor. acall esccom ; Escribe comando acall dem40 ; Demora de 80 microsegundos. mov P1, #80 ; Primer caracter de la primera linea. acall esccom ; Escribe comando acall dem40 ; Demora de 80 microsegundos. mov P1, #01b ; limpia LCD, puntero a posicion inicial. acall esccom ; Escribe comando acall dem164 ; Demora de 3.2 milisegundos. ; Atención a Teclado. lazo: acall teclad ; Convierte a ASCII jnb P3.4,mayor jnb P3.5,numero conv: mov dptr, #tabla movc A, @A+dptr mov P1,A acall esccar acall dem164 sjmp salir mayor: add A,#16 sjmp conv numero: add A,#32 sjmp conv salir: sjmp lazo ; Subrutina que escribe un comando en el LCD. esccom: clr P3.6 setb P3.7 nop clr P3.7 ret ; Subrutina que escribe un carácter en el LCD esccar: setb P3.6 setb P3.7 nop clr P3.7 ret ; Subrutinas de demora de 40 microsegundos. dem40: mov R2,#20 djnz R2,$ ret ; Subrutina de demora 1,64 milisegundos dem164: mov R7,#41 lazo2: acall dem40

350

Microcontroladores. El 8051 de la INTEL.

351

djnz R7,lazo2 ret ; Subrutina que atiende al Teclado. teclad: mov r6, #11101111b ;Patrón de búsqueda original. mov r5,#4 ;Numero de líneas de búsqueda. mov r7,#0 ;Contador de posición repite: mov P2,r6 ;Envío patrón de búsqueda mov A, P2 ;Leo las líneas de retorno ; Buscando tecla apretada. mov r4,#4 ;Numero de líneas de retorno. lazo1: rrc A jnc encont inc r7 djnz r4,lazo1 mov A,r6 rl A mov r6,A djnz r5,repite clr 20h.0 sjmp teclad encont: jb 20h.0,teclad setb 20h.0 mov A, r7 ret ; Tabla con los códigos ASCII de los caracteres. tabla: db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ,!@#$/*()+=0123456789' ; Fin del listado del programa. end En estos dos últimos programas hemos tenido que diseñar diferentes Subrutinas para provocar demoras imprescindibles en los mismos. Esta manera de generar una espera tiene el inconveniente de que el microcontrolador se encuentra totalmente ocupado en ejecutar este fragmento de programa y por ende mientras espera no puede ejecutar ninguna otra tarea. Esto no siempre es posible hacerlo en todas las aplicaciones. Como una manera de ayudar al diseñador el 8051 tiene empotrado dos circuitos Temporizadores que nos auxilian en este tipo de tareas. Dediquemos el próximo capitulo al estudio de estos dispositivos.

Microcontroladores. El 8051 de la INTEL.

352

Tema 9. Los Temporizadores del 8051. Son muchas las aplicaciones en las cuales los Temporizadores constituyen una ayuda valiosa e imprescindible para el diseñador. Veamos los siguientes casos a modo de ejemplo de lo planteado anteriormente. Ejemplo 1. Determinar de forma automática el tiempo en ´1´ de un pulso generado por un circuito. Ejemplo 2. Determinar el valor que toma una determinada variable física con una periodicidad de 1 segundo. Ejemplo 3. Determinar la frecuencia de un tren de pulsos generado por un circuito externo. Ejemplo 4. Determinar la cantidad de productos terminados que se mueven por una cinta transportadora. En los dos primeros ejemplos se impone la necesidad de contar tiempo, mientras que en los dos últimos lo necesario es contar la ocurrencia de un determinado evento. En los cuatro casos los Temporizadores del 8051 podrían ser utilizados como parte de la solución o como elemento fundamental de la misma. El estudio de estos circuitos es el objetivo fundamental de este Tema. 9.1 Los Temporizadores por dentro. El 8051 consta de 2 Temporizadores conocidos con los nombres de Temporizadores 0 y 1 respectivamente, los que pueden ser usados fundamentalmente en ayuda del microcontrolador como reloj interno en la sincronización de eventos o en la generación de intervalos de tiempo 0 como contador de eventos externos. Estos dispositivos, una vez programados, su operación es completamente por hardware, liberando al microcontrolador de la labor de supervisión por software de los mismos, aunque esta última posibilidad el programador la tiene a su alcance. La pregunta a contestar en este momento sería, ¿En qué consisten los Temporizadores del 8051? Para su estudio, los elementos que conforman a cada uno de los Temporizadores los podemos dividir en tres bloques atendiendo a la función que realizan dentro del mismo. Estos tres bloques son:

Microcontroladores. El 8051 de la INTEL. 9

Bloque Contador.

9

Bloque Generador de la Señal de Conteo.

9

Bloque de Habilitación del Contador.

353

En la Figura 9.1.1 se muestra la estructura interna de uno cualquiera de los dos Temporizadores del 8051.

Figura 9.1.1. Bloque Contador. En esencia los Temporizadores del 8051 consisten en un circuito contador de 16 bits, al que se le puede escoger la fuente del conteo, la habilitación del conteo y la base de conteo, lo que permite al diseñador moldear al Temporizador en dependencia de las necesidades de su aplicación. Este contador de 16 bits, realmente esta conformado por dos contadores de 8 bits separados, los que pueden ser interconectados de diferentes formas en dependencia del Modo de Trabajo que se seleccione para el Temporizador. Estos contadores pueden ser leídos y escritos mediante Programa direccionandolos como TLx para los 8 bits menos significativos del contador y THx para los 8 bits más significativos del contador. La x indicaría con cual de los dos Temporizadores se desea trabajar. Por ejemplo, si lo que queremos es leer el valor almacenado en los 8 bits menos significativo del Temporizador 0, nos referiríamos a él como TL0, mientras que si lo que deseamos es cargar nuevos valores en los bits más significativos del Temporizador 1 nos referiremos a él como TH1.

Microcontroladores. El 8051 de la INTEL.

354

Formando parte de este boque también se encuentra la Bandera de Interrupción propia del Temporizador, TF0 para el Temporizador 0 y TF1 para el Temporizador 1, las que constituyen los bits 5 y 7 respectivamente del Registro TCON, el que a su vez constituye, uno de los Registros de Funciones Especiales del 8051. Esta Bandera de Interrupción se hace verdadera, toma el valor de ´1´, cada vez que el contador se desborda, generando un pedido de atención por Interrupción al microcontrolador el que será atendido de estar habilitado. La pregunta a responder en este momento sería, ¿Qué significa que el contador se desborda? Ambos contadores en los Temporizadores son crecientes, o sea, con cada pulso a contar el valor en el contador se incrementa en 1. Esto ocurrirá de esta forma hasta que todos los bits del contador tomen el valor de ´1´, o sea, el contador llega a su valor máximo, en este momento con el próximo pulso a contar todos los bits del contador pasan a ´0´, valor mínimo de conteo, comenzando con una nueva secuencia de conteo. A este paso del contador de su valor máximo de conteo a su valor mínimo de conteo es a lo que se llama que el Temporizador se ha desbordado, indicándolo poniendo a ´1´ la bandera TFx correspondiente. Si el circuito fundamental de este bloque lo constituye un contador, la pregunta a responder en este momento sería, ¿Qué señal es la que cuenta este contador? Bloque Generador de la Señal de Conteo. Son dos las posibles fuentes de conteo de los Temporizadores, ver Figura 9.1.1: 9

La señal del Oscilador Interno dividida entre 12.

9

Las señales aplicadas en las entradas Tx, T0 para el Temporizador 0 y T1 para el Temporizador 1, donde, T0 y T1 comparten el mismo terminal que los bits P3.4 y P3.5 del Puerto 3 respectivamente.

De la propia Figura 9.1.1 se puede observar que a la salida de este bloque se encuentra un Interruptor Electrónico Doble Polo-Simple Tiro que se encarga de escoger cual de las dos posibles fuentes de conteo es la que se le entregará al contador. A este Interruptor le llegan por uno de sus terminales la salida de un circuito divisor entre 12 interno del microcontrolador conocido con el nombre de Pre-Escalador el que entrega a su salida un tren de pulsos cuya frecuencia es la

Microcontroladores. El 8051 de la INTEL.

355

frecuencia del Oscilador Interno del microcontrolador dividida entre 12 y por la otra le llega directamente la señal aplicada al terminal T0 para el Temporizador 0 y T1 para el Temporizador 1. La pregunta a responder en este momento sería, ¿Cómo escoger la fuente de conteo? El escoger una u otra define si el Temporizador va a trabajar como Timer (contador de tiempo) o como Contador (contador de eventos), no confundir el nombre que le dimos para el segundo caso con la acción de contar que tienen los Temporizadores independientemente de la fuente de conteo escogida. La elección de una fuente de conteo u otra se hace mediante la programación del bit C/T del Registro TMOD, Registro de Modo del Temporizador, que se corresponden con los bits b2 y b6 de este registro respectivamente. Si usted pone a ´0´ mediante programa el bit C/T correspondiente a uno de los Temporizadores este operará como Timer y la señal de conteo será la salida del Pre-Escalador o lo que es lo mismo, la salida del Oscilador Interno dividida entre 12. En este caso se puede decir que el Temporizador cuenta tiempo. Si por el contrario, el bit C/T correspondiente a uno de los Temporizadores se pone a ´1´, este operará como Contador siendo la fuente de conteo la señal aplicada a los terminales T0 para el Temporizador 0 y T1 para el Temporizador 1. En este caso el Temporizador cuenta eventos externos. La pregunta a contestar en este momento sería, ¿Tenemos la posibilidad de decidir cuando el Contador del Temporizador cuenta y cuando no? Bloque de Habilitación del Contador. Poder contar con la posibilidad de decidir cuando el contador cuenta y cuando no es muy importante para la solución de muchas aplicaciones y para facilitar las cosas del programador. Por ejemplo usted podría programar el Modo de Trabajo del Temporizador al inicio del Programa y este no comenzaría su operación hasta que usted no la habilite en el momento preciso. Esta facilidad nos la brindan los elementos que conforman el Bloque de Habilitación del Contador, ver Figura 9.1.1. Si observamos en esta Figura, existe un circuito interno, conformado por compuertas lógicas del tipo AND, OR e INVERSORES, que es el encargado de generar la señal control que provoca que

Microcontroladores. El 8051 de la INTEL.

356

se cierre o permanezca abierto el Interruptor Electrónico, del que ya habíamos hablado, que deja pasar la señal de conteo o no hacia el contador. De forma tal que: 9

Si el Interruptor Electrónico se cierra, el contador esta habilitado y por lo tanto cuenta la señal que usted le haya seleccionado como señal de conteo.

9

Si el Interruptor Electrónico se abre, el contador se inhabilita deteniéndose el conteo del Temporizador.

Por su puesto para que el Interruptor Electrónico se cierre es necesario que la señal control tome el valor de ´1´, en el caso contrario estará abierto. Esto depende del valor que tengan las señales internas TR0, GATE0 y la señal externa INT0 para el Temporizador 0 y TR1, GATE1 e INT1 para el Temporizador 1. Por ejemplo analicemos el caso del Temporizador 0. Si TR0 tiene el valor de ´0´, la salida del AND es ´0´ independientemente del valor que tengan las señales GATE0 y la señal externa INT0/ y por lo tanto la señal control estará en ´0´ y el Interruptor Electrónico estará abierto y al contador no llegará la señal de conteo, estando inhabilitado el conteo. Si por el contrario, TR0 tiene el valor de ´1´, la salida del AND dependerá del valor de la salida del OR al que llegan las señales GATE0 negada e INT0/. Si la salida del OR es ´1´, la señal control toma el valor de ´1´, provocando que el Interruptor Electrónico se cierre llegando al contador la señal de conteo seleccionada, estando habilitado. Si por el contrario la salida del OR es ´0´, la señal control tomará el valor de ´0´ con lo que el Interruptor Electrónico se abrirá no llegando al contador la señal de conteo, estando inhabilitado. Al ser los circuitos de ambos Temporizadores iguales esto lo podemos generalizar para el Temporizador 1. Observe el papel preponderante que juega la señal TR0 para el Temporizador 0 y TR1 para el Temporizador 1 en la habilitación o no del conteo del contador. Si esta señal es puesta a ´0´, el conteo del contador se encuentra inhabilitado independientemente del valor en que se encuentren las otras dos señales de control. Si por el contrario, es puesta a ´1´ la habilitación del conteo del contador depende del valor que tengan las otras dos señales de control. Por lo que estas dos señales pueden jugar el papel de señal de habilitación del conteo de los contadores. Analicemos un poco más en detalle la conclusión anterior. Supongamos que la salida de la compuerta OR se encuentra en ´1´, en este caso el valor que tome la señal control depende únicamente del valor que tome la señal TR0 para el Temporizador 0 y TR1 para el Temporizador 1. Concentrándonos en el Temporizador 0, si TR0 se pone a ´0´, el conteo se inhabilitará y por lo tanto el contador dejara de contar, si por el contrario TR0 se pone a ´1´, el conteo se habilitará.

Microcontroladores. El 8051 de la INTEL.

357

La pregunta a contestar en este momento sería, ¿Cómo poner a ´0´ o a ´1´ las señales de control TR0 y TR1? Tanto TR0 como TR1 son dos bits del Registro TCON, específicamente los bits 4 y 6, los que se ponen a ´0´ o a ´1´ mediante instrucciones. El Registro TCON, Registro de Control del Temporizador, es un Registro de Funciones Especiales, el que puede ser manipulado mediante las instrucciones del grupo de Tratamiento de Bits. Por lo tanto, tengo la posibilidad de habilitar o inhabilitar el conteo del contador mediante una instrucción en el programa que ponga a ´1´ o a ´0´ el correspondiente bit TRx en el Registro TCON. Por ejemplo para el Temporizador 0 estas instrucciones serían, setb

TR0

; habilita el conteo.

clr

TR0

; inhabilita el conteo.

A esta posibilidad que tiene el programador de habilitar o inhabilitar el conteo de los contadores de los Temporizadores mediante programa se le conoce con el nombre de Control del Conteo por Software o Disparo por Software. De la lectura del párrafo anterior nos pueden surgir las interrogantes siguientes, ¿Existirá otra manera de controlar la habilitación del conteo de los Contadores? ¿Existirá un Control de Conteo por Hardware? Para dar respuesta a las dos interrogantes anteriores pasemos a analizar el papel encomendado a las otras dos señales presentes en esta lógica, las señales GATE0 e INT0 para el Temporizador 0 y las señales GATE1 e INT1 para el Temporizador 1. Concentrémonos en el Temporizador 0, las señales GATE0 e INT0 son las dos señales de entrada a la Compuerta OR de la que ya habíamos hablado anteriormente, ver Figura 9.1.1. INT0 es una señal que le llega a la compuerta OR de forma directa y el valor lógico que tenga se corresponderá con el valor lógico impuesto en el terminal del mismo nombre del microcontrolador. Por lo que, si en el terminal INT0/ se encuentra aplicado un ´0´ a la entrada de la compuerta OR del mismo nombre le estará llegando un ´0´, pero si lo que esta aplicado es un ´1´, lo que estará llegando será un ´1´.

Microcontroladores. El 8051 de la INTEL.

358

Por su parte GATE0 es una señal que le llega a la compuerta OR después de pasar por una compuerta Inversora, ver Figura 9.1.1, de forma tal que si GATE0 se encuentra en ´0´ a la entrada de la compuerta OR correspondiente estará aplicado un ´1´ y en el caso contrario estará aplicado un ´0´. Las preguntas a responder en este momento serían, ¿Quién es GATE0? ¿Cómo poner a GATE0 en ´0´? ¿Cómo poner a GATE0 en ´1´? La señal GATE0 se corresponde con el bit 3 del Registro TMOD (GATE1 se corresponde con el bit 7 del mismo registro) y el programador la podrá poner a ´0´ o a ´1´ efectuando una operación de escritura sobre este Registro.. Lo mismo lo podríamos generalizar para el caso de GATE1 del Temporizador 1 pero ahora la escritura es sobre el bit 7 del mismo Registro. Concentrando nuevamente nuestra atención en la compuerta OR. Como sabemos del análisis de la Tabla de la Verdad de la compuerta OR, para que a la salida de esta se encuentre un ´1´ basta con que una cualquiera de sus entradas se encuentre en ´1´, mientras que para que a su salida se encuentre a ´0´ las dos entradas tienen que tener aplicado un ´0´. Por lo que si GATE0 se pone mediante programa a ´0´ la salida de la Compuerta OR estará a ´1´ independientemente del valor que tome la señal que viene del terminal del microcontrolador INT0/. Por el contrario, si GATE0 se encuentra en ´1´, el valor que tome a su salida la compuerta OR dependerá del valor que tenga aplicado en su terminal INT0/ el microcontrolador, si el valor aplicado es ´1´ la salida de la compuerta OR estará a ´1´, mientras que si es ´0´ la salida tomará el valor de ´0´. Por lo que en dependencia del valor de GATE0, la salida de la compuerta OR se hace dependiente o independiente del valor que tenga aplicado en su terminal INT0/ el microcontrolador. Si GATE0 está en ´0´ la salida de la compuerta OR es independiente del valor en el terminal INTO/ del microcontrolador, pero si GATE0 es ´1´, el valor de la salida de la compuerta OR depende del valor aplicado en el terminal INT0/ del microcontrolador. Esto queda reflejado en la Tabla siguiente: GATE0

INT0/

Salida compuerta OR

0

No importa el valor que tenga

1

1

0

0

1

1

1

Microcontroladores. El 8051 de la INTEL.

359

Esto por su puesto que lo podemos generalizar para el Temporizador 1 sustituyendo a GATE0 por GATE1 y a INT0/ por INT1/. Retomemos el objetivo fundamental que estamos persiguiendo con esta explicación, que no es otro que analizar las diferentes formas de habilitar el conteo de los contadores de los Temporizadores. Para ello concentrémonos ahora en la salida de la compuerta AND que no es otra que la señal control, que es la que habilita el conteo del contador. Cuando analizamos a la señal TR0 planteamos el caso de que a la salida de la compuerta OR tuviésemos un ´1´ y llegamos a la conclusión de que manipulando a esta señal podíamos habilitar o inhabilitar el conteo y a esto le llamamos Control del Conteo por Software. A la luz de lo estudiado hasta aquí, ¿Cómo podríamos garantizar que la salida de la compuerta OR tenga un ´1´ para poder provocar la habilitación del conteo llevando a ´1´ a TR0? Si ponemos a la señal GATE0 en ´0´, la salida de la compuerta OR estará en ´1´ independientemente del valor aplicado en el terminal INT0/ del microcontrolador, con lo que propiciamos que la habilitación o no del conteo solo dependa del valor que le impongamos por software a la señal TR0. Esta es la condición que faltaba para lograr el Control del Conteo por Software. Por lo que si usted se decide a controlar la habilitación del conteo de los Contadores por software, ponga mediante programa al bit GATE0 o al bit GATE1 para los Temporizadores 0 y 1 respectivamente del Registro TMOD en ´0´ y manipule mediante programa a la señal TR0 o TR1. La pregunta a contestar en este momento sería, ¿Qué sucedería si a la señal GATE0 o GATE 1 se le impone un ´1´? En este caso la salida de la compuerta OR dependerá de la señal aplicada en el terminal INT0/ e INT1/ respectivamente del microcontrolador y por lo tanto el valor que tome la señal control no solo depende del valor que tome TR0 o TR1. Supongamos en este caso que además de imponer por programa un ´1´ en GATE0, imponemos también mediante programa un ´1´ en TR0. ¿Qué sucede en este caso?

Microcontroladores. El 8051 de la INTEL.

360

En este caso el valor que tome la señal control y por lo tanto la habilitación o no del conteo del contador dependerá únicamente del valor que se imponga en el terminal INT0/ del microcontrolador. Si al terminal INT0/ se le aplica un ´0´ la señal control tomará el valor de ´0´ y estará inhabilitado el conteo, pero si se aplica un ´1´ la señal control tomara el valor de ´1´ con lo que queda habilitado el conteo. A este modo de habilitar o inhabilitar el conteo de los contadores de los Temporizadores se le conoce con el nombre de Control del Conteo por Hardware o Disparo por Hardware y constituye otra forma de controlar la operación de los contadores de los Temporizadores. En la Tabla siguiente queda resumido todo los explicado hasta aquí con respecto a la habilitación o no del conteo de los contadores de los temporizadores. TR0 (TR1)

GATE0 (GATE1)

INT0/ (INT1/)

CONTROL

1

0

1

Conteo Habilitado por Hardware

1

1

1

Conteo Habilitado por Software

0

No importa

No importa

Conteo Inhabilitado

A modo de resumen podemos plantear: 1. El Programador tiene la posibilidad de declarar que el inicio del conteo por parte de los contadores sea a través de la activación de una señal externa aplicada en los terminales INT0/ para el Temporizador 0 e INT1/ para el Temporizador 1. Para ello previamente el bit TR0 para el Temporizador 0 y TR1 para el Temporizador 1 del Registro TMOD debieron ser puestos a ´1´ mediante programa y el bit GATE0 para el Temporizador 0 y GATE1 para el Temporizador 1 del mismo registro debieron ser puestos a ´1´ mediante programa también. 2. El Programador tiene la posibilidad de declarar que el inicio del conteo por parte de los contadores sea a través de poner a ´1´ el bit TR0 para el Temporizador 0 y TR1 para el Temporizador 1 del Registro TMOD. Para ello el bit GATE0 para el Temporizador 0 y GATE1 para el Temporizador 1 del mismo registro debieron ser puestos a ´0´ mediante programa también. Analicemos un poco más en detalle, a la luz de dos ejemplos, ambos casos para poder destacar cuando puede ser útil la utilización de uno y cuando puede ser útil la utilización del otro.

Microcontroladores. El 8051 de la INTEL.

361

Ejemplo 9.1.1. Determinar la frecuencia de un tren de pulsos generado por un circuito externo. Si lo que queremos es determinar la frecuencia de un tren de pulsos lo que debemos hacer es contar la cantidad de pulsos de la señal que se desea medir su frecuencia en un intervalo de tiempo dado, para después mediante procedimientos matemáticos obtener la frecuencia. Consideremos que vamos a emplear al Temporizador 0 para realizar esta tarea. Lo primero que debemos hacer es seleccionar cual va a ser la fuente de conteo del contador. Como lo que queremos contar son los pulsos generados por una señal externa es evidente que pondremos al Temporizador a trabajar como Contador, llegándole la señal de conteo por el terminal T0 del microcontrolador. No es necesario, para la tarea que nos hemos impuesto hacer, estar contando todo el tiempo los pulsos de dicha señal, sino solo cuando el programa decida muestrear el valor del mismo. Normalmente, los instrumentos de medición, muestrean la señal a medir cada cierto intervalo de tiempo en dependencia de la velocidad de variación de la señal, es en este momento que se decide tomar el valor de la señal para mostrarla a través de un Display u otro elemento indicador. En nuestro caso lo que queremos es conocer la frecuencia de una determinada señal y esto se efectuará cada determinado intervalo de tiempo, lo que será decidido por el programa, por lo que la señal GATE0 la pondríamos a ´0´ al inicio del programa y no la cambiaríamos en ningún momento del mismo y mediante la manipulación del valor de la señal TR0 decidimos cuando contar y con ello cuando muestrear la señal a medir. Poniendo a TR0 en ´1´ contamos y poniendo a TR0 en ´0´ dejamos de contar. Ejemplo 9.1.2. Determinar de forma automática el tiempo en ´1´ de un pulso generado por un circuito. En este caso es evidente que lo que necesitamos medir es tiempo, por lo que escogeríamos como fuente de conteo para el Temporizador en cuestión a la salida del Pre- Escalador. Ahora bien no nos interesa la medición del tiempo, durante todo el tiempo perdonándonos la redundancia, sino solo cuando una señal externa, la que queremos medir su tiempo de duración, tome el valor de ´1´. Por lo que lo mejor sería poder utilizar esta propia señal como la que habilita el conteo del contador. Para ello pondríamos a TR0, seguimos trabajando con el Temporizador 0, en ´1´, a GATE0 en ´1´ y la señal a medir la introduciríamos por la entrada INT0/ del microcontrolador. Ahora cuando INT0/

Microcontroladores. El 8051 de la INTEL.

362

tome el valor de ´1´ el contador comenzara a contar y cuando caiga a ´0´ detendrá su conteo Lo interesante en este caso podría ser saber, ¿Como el Programa reconoce que la señal a medir pasó de ´1´ a ´0´, y que por lo tanto debe leer el contenido del Contador? El programador tiene la posibilidad de escoger como activación de la fuente de Interrupción externa INT0/ cuando la señal aplicada en ella cae de ´1´ a ´0´. Todo lo que tiene que hacer para ello, según lo hemos estudiado anteriormente, es poner a ´1´ el bit 0 del Registro TCON, para el Temporizador 0 y el bit 2 para el Temporizador 1. Ahora la propia caída de la señal aplicada en INT0/ provoca la inhabilitación del conteo del contador y provoca la solicitud de atención por Interrupción externa INT0/. La Subrutina de atención a esta Interrupción podría leer el contenido del contador del Temporizador 0, cargar un 0 en dicho contador preparándose para el próximo conteo y al mismo tiempo llevar a la señal TR0 a ´0´ para que la habilitación del conteo no sea siempre que la señal externa tome el valor de ´1´ sino cuando el programa lo decida según el tiempo de muestreo que tenga declarado. Analicemos más en detalle los dos Modos básicos de operación de las Temporizadores. 9.2 Los Registros TMOD y TCON. En la explicación del epígrafe anterior hicimos mucha referencia a los Registros TMOD y TCON cuando explicábamos la forma de dar valores de ´0´ o de ´1´ a las señales que permitían escoger la fuente de conteo y el modo de habilitar dicho conteo. Ambos son registros destinados para el trabajo con los Temporizadores, siendo TMOD el registro que permite al programador moldear según sus necesidades a los Temporizadores, mientras que TCON es el registro a través del cual el programador puede controlar el trabajo de los Temporizadores. A ambos registros se tiene acceso mediante instrucciones del Grupo de Transferencia de Datos con la diferencia de que al Registro TCON se puede trabajar también mediante las instrucciones del Grupo de Tratamiento de Bits al ser un registro direccionable bit a bit, mientras que el Registro TMOD hay que tratarlo como un byte no divisible. Analicemos cada uno de estos registros por separado. El Registro TMOD. El Registro TMOD es el registro de modo de los Temporizadores y es uno de los Registros de Funciones Especiales del microcontrolador. Este registro no puede ser direccionado bit a bit y se

Microcontroladores. El 8051 de la INTEL.

363

encuentra dividido, del punto de vista funcional, en dos grupos de 4 bits. Los bits del 0 al 3 están destinados para la programación del Temporizador 0 y los bits del 4 al 7 están destinados para el Temporizador 1, ver Figura 9.2.1.

Figura 9.2.1 Observe que los dos primeros bits de cada nible (4 bits) están destinados para que el programador escoja el Modo de Trabajo que desea seleccionar para cada uno de los Temporizadores en su aplicación. En total son 4 los Modos de Trabajo seleccionables mediante las 4 posibles combinaciones que se pueden hacer con estos dos bits para cada Temporizador. Si usted va a emplear por lo menos uno de los Temporizadores en su aplicación no tiene otra alternativa que escribir sobre este registro para poder moldear el mismo según sus necesidades. Para ello esta en la obligación de utilizar una instrucción del tipo mov, de la cual el operando destino será el Registro TMOD. Por ejemplo, supongamos que en nuestra aplicación necesitamos trabajar con el Temporizador 0, en el Modo 1, como Timer y con control del conteo por software, la instrucción a emplear sería la siguiente: mov

TMOD, #00000001b

Microcontroladores. El 8051 de la INTEL.

364

Con el RESET, el microcontrolador pone todos los bits de este registro en ´0´, por lo que ambos Temporizadores quedan programados de la siguiente manera: 9

Modo de Trabajo 0.

9

Contador de Tiempo, Timer.

9

Habilitado para comenzar el conteo por software.

El Registro TCON. El Registro TCON es el registro de control de los temporizadores y es uno de los Registros de Funciones Especiales del microcontrolador. Este registro puede ser direccionado bit a bit, ver Figura 9.2.2.

Figura 9.2.2 Con el RESET el microcontrolador pone todos los bits de este registro en ´0´ quedando programado de la siguiente forma:

Microcontroladores. El 8051 de la INTEL. 9

Activación de las Interrupciones externas INT0 e INT1 con el nivel de ´0´.

9

No hay Interrupciones externas pendientes de atención.

9

La señal de control de ambos Temporizadores inhabilitada.

9

Ninguna solicitud de interrupción de los Temporizadores pendiente.

365

9.3 Contando tiempo o eventos. Como ya se explico anteriormente, cuando los Temporizadores operan como Timer, su fuente de conteo lo constituye la salida del Pre-Escalador divisor entre 12 de la señal del Oscilador interna por lo que su contador se incrementa en 1 cada 12 periodos de dicha señal, siendo la razón de conteo de 1/12 la frecuencia de la señal de salida del Oscilador. Si a cada ciclo de maquina le corresponden 12 periodos de la señal de salida del Oscilador, resulta evidente que en este caso los Temporizadores se incrementan en 1 con cada ciclo de máquina que ejecuta el microcontrolador. Si necesita aclaración sobre lo planteado en este párrafo remítase al Tema 4, epígrafe 4.3. Cuando opera como Contador, este es incrementado en 1 con cada transición del nivel alto de tensión ´1´ al nivel bajo ´0´, flanco descendente, de la señal externa aplicada al pin T0 para el Temporizador 0 y el pin T1 para el Temporizador 1. En este caso, el microcontrolador necesita de dos ciclos de máquina, 24 periodos de la señal de salida del Oscilador, para reconocer la transición del flanco descendente. ¿A qué se debe esto? Esto es debido a que el microcontrolador muestrea el valor de sus entradas T0 y T1 en la Fase 2 del Estado 5 de cada ciclo de máquina, por lo que, para poder detectar un flanco descendente en la señal aplicada en estas entradas, necesita de un primer ciclo de máquina donde detecta que la señal esta en ´1´ y un segundo para detectar que la señal fue a ´0´, ver Figura 9.3.1

Figura 9.3.1

Microcontroladores. El 8051 de la INTEL.

366

Esta es la causa por lo que la máxima razón de conteo de los temporizadores cuando trabajan como Contador es de 1/24 la frecuencia del Oscilador interno. ¿Qué consecuencia del punto de vista práctico representa esto? Pongamos como ejemplo el caso en que tengamos al 8051 trabajando con un cristal de cuarzo de 12 Mhz. Por su puesto la frecuencia de la señal de salida del oscilador interno se corresponde con esta frecuencia y por lo tanto, para este caso, si el Temporizador esta operando como Timer su contador se incrementará en 1 cada 1 useg. En este caso, el programador debe tomar en cuenta que el tiempo mínimo que podría indicar el Temporizador antes de desbordarse sería de 1 useg y el máximo antes de desbordarse sería de 65 535 useg. Si por el contrario el Temporizador estuviese trabajando como Contador, el diseñador debe tomar en cuenta que la señal a contar no podría tener frecuencia de ocurrencia mayor de 500 Khz. En la explicación anterior se hablo de tiempo que indica el contador antes de desbordarse. La pregunta a contestar en este momento sería, ¿Qué quiere decir que el Contador se desborda?, ¿Qué consecuencias tiene? De esto ya hablamos en párrafos anteriores en el material pero por la importancia que tiene en el entendimiento del funcionamiento de los Temporizadores nos parece que no es tiempo perdido volver a explicar sobre el tema. Se considera que el contador de uno de los Temporizadores se ha desbordado cuando todos sus bits pasan de ´1´ a ´0´, esto es cuando este pasa de su conteo máximo a su conteo mínimo, que no tiene que ser obligatoriamente el 0. Recordemos que los Contadores de los Temporizadores son del tipo ascendentes por lo que se desbordaran cuando lleguen al conteo máximo que impongan la cantidad de bits característicos del Modo de Trabajo en que se encuentre el Contador. Por ejemplo si el Temporizador 0 esta trabajando en un Modo de Trabajo en que el contador tenga 16 bits, este se desbordará con el siguiente pulso después de haber contado 65 535. De hay que si el conteo se inicio con el Contador en 0 y el Temporizador esta trabajando como Timer, con cristal de reloj de 12 Mhz, se desborde al cabo de los 65 536 useg. El desbordamiento del contador provoca que la Bandera de Interrupción, TF, propia del Temporizador tome el valor de ´1´, propiciando un pedido de Interrupción al microcontrolador que será atendido en caso de que se encuentre habilitado.

Microcontroladores. El 8051 de la INTEL.

367

El programador tiene la posibilidad de preguntar por el valor de la Bandera de Interrupción, TF, mediante programa, por lo que los Temporizadores pueden ser atendidos también por Encuesta. Todo lo que tiene que hacer el programa es preguntar cada cierto tiempo por el valor de la Bandera de Interrupción, TF, cuando tome el valor de ´1´ es que el contador se ha desbordado. ¿Cómo preguntar por la Bandera de Interrupción, TF, de los Temporizadores? Como ya vimos en el epígrafe anterior, tanto TF0 como TF1 son bits del Registro TCON, por lo que preguntando por el valor de estos bits mediante una instrucción del tipo jnb o jb conoceremos si el contador del Temporizador 0 se ha desbordado o si el contador del temporizador 1 se ha desbordado. El programador puede variar el número de bits que desea que tenga el contador para una aplicación dada y con ello variar el conteo que provoca su desborde. ¿Cómo escoger el número de bits del contador? Esto esta estrechamente relacionado con el Modo de Trabajo en que se ponga a trabajar a los Temporizadores. 9.4. Los Modos de Trabajo de los Temporizadores. Ambos Temporizadores pueden operar en 4 Modos de Trabajo posibles, conocidos como Modo 0, Modo 1, Modo 2 y Modo 3. Estos Modos de Trabajo se seleccionan mediante la combinación adecuada de ´0´ y ´1´ en los bits 0 y 1 del Registro TMOD para el Temporizador 0 y los bits 4 y 5 del mismo registro para el Temporizador 1, ver Figura 9.2.1. La pregunta a contestar en este momento podría ser, ¿Qué relación existe entre los Modos de Trabajo de los Temporizadores y el número de bits de los Contadores? De analizar los nombres que recibe cada Modo de Trabajo nos daremos cuenta rápidamente de que si existe relación y cual es: 9

Modo 0. Temporizador/Contador de 13 bits.

9

Modo 1. Temporizador/Contador de 16 bits.

9

Modo 2. Temporizador/Contador de 8 bits con Autorrecarga.

Microcontroladores. El 8051 de la INTEL. 9

368

Modo 3. Varios Contadores.

Analicemos a profundidad cada uno de los Modos de Trabajo de los Temporizadores. El Modo 0. Temporizador/Contador de 13 bits. Para la programación del Temporizador en este Modo de Trabajo los bits b0-b1 para el Temporizador 0 y los bits b4-b5 para el Temporizador 1 del Registro TMOD se deben poner ambos a ´0´. Los Contadores de los Temporizadores como ya se ha explicado son de 16 bits, divididos para su trabajo en dos Contadores de 8 bits conectados en cascada. El nombre que reciben estos dos Contadores son: 9

TL, que contiene los 8 bits menos significativos, al que llamaremos a partir de este momento Contador Bajo. Por lo que existirá un TL0 para el Temporizador 0 y un TL1 para el Temporizador 1.

9

TH, que contiene a los 8 bits más significativos, al que llamaremos Contador Alto. Por lo que existirá un TH0 para el temporizador 0 y un TH1 para el Temporizador 1.

Estos Contadores Alto y Bajo de cada Temporizador se agrupan existiendo un par registro entre los Registros de Funciones Especiales del microcontrolador que los representa. El par de registros TH0/TL0 son los que representan al Contador del Temporizador 0 y el par registro TH1/TL1 son los que representan al Contador del Temporizador 1. ¿Qué queremos decir con que representa a los Contadores? Todas las operaciones que desee hacer el programador con los contadores de los Temporizadores lo tiene que hacer sobre estos registros. Por ejemplo si usted quiere conocer el número de conteos efectuado por el Temporizador 1 en un intervalo de tiempo dado, todo lo que tiene que hacer es efectuar la lectura del contenido del par de registros TH1/TL1. En el Repertorio de Instrucciones del microcontrolador no existe ninguna instrucción que permita la lectura de ambos registros en una sola instrucción por lo que la lectura de los mismos la tendrá que efectuar mediante dos instrucciones, leyendo primero a TH1 y después a TL1 o viceversa. Esto es valido para cualquier Modo de Trabajo en que se ponga a trabajar al Temporizador.

Microcontroladores. El 8051 de la INTEL.

369

Los dos contadores no se concatenan de la misma forma para todos los Modos de Trabajo y esto un poco caracteriza a cada uno de ellos, provocando no solo que en cada Modo de Trabajo los Temporizadores operen de distinta forma, sino que también que presenten diferentes conteos para el desbordamiento. El Modo 0 no constituye una excepción de lo explicado, en este Modo de Trabajo se concatenan los 8 bits del Contador Alto, TH, con 5 bits de los bits del Contador Bajo, TL, con lo que se conforma un Contador de 13 bits tal y como se refleja en su nombre. No obstante, para caracterizar a este Modo de Trabajo se dice que el Temporizador cuenta con un Contador de 8 bits con un Pre-Escalador entre 32. La pregunta a responder en este momento sería, ¿Por qué se dice que en este Modo de Trabajo el Contador es de 8 bits con un Pre-escalador entre 32? Observemos la Figura 9.4.1 que nos muestra como queda conformado el Contador de uno cualquiera de los Temporizadores, cuando es seleccionado a trabajar en este Modo de Trabajo.

Figura 9.4.1 Configuración de los Temporizadores en el Modo 0. Observe que del Contador Bajo, TLx, solo están incluidos en la cadena de conteo 5 de sus 8 bits, mientras que del Contador Alto, THx, esta incluido con sus 8 bits. Por otro lado, los 5 bits del Contador Bajo están conectados, en la cadena de conteo, delante de los 8 bits del Contador Alto,

Microcontroladores. El 8051 de la INTEL.

370

es por esto que se dice que en este Modo de Trabajo tenemos un Contador de 8 bits, los que aporta el Contador Alto, con un Pre-escalador entre 32, los que aporta el Contador Bajo. Si tomamos al Contador Alto como el contador en si del Temporizador, la operación que esta efectuando el Contador Bajo es la de dividir entre 32 la frecuencia de la señal a contar la que proviene de una cualquiera de las dos posibles fuentes de conteo ya estudiadas anteriormente. Por ejemplo si el Temporizador 1 se pone a trabajar en este Modo de Trabajo como cont6ador de tiempo, el Contador Alto se estaría incrementando en 1 cada 32 ciclos de máquina, si por otro lado se seleccionara para trabajar como contador de eventos se incrementaría en 1 cada 32 pulsos en el terminal T1 del microcontrolador. Si estamos de acuerdo con explicar este Modo de Trabajo de esta forma, podríamos considerar que el Temporizador se desborda cuando su Contador Alto cuenta 256. Por lo que, si esta trabajando como contador de tiempo se desbordará a los 32 x 256 ciclos de máquina, lo que es igual a 8 192 ciclos de máquina. Si esta trabajando como contador de eventos será a los 32x 256 pulsos en el terminal Tx del microcontrolador correspondiente al Temporizador, lo que es igual a 8 192 pulsos aplicados a dicho terminal. Por lo que si usted quisiera conocer la cantidad de ciclos de máquina que han transcurridos o la cantidad de pulsos aplicados al terminal Tx correspondiente en el caso de que el contador no se haya desbordado, todo lo que usted tiene que hacer es efectuar la lectura del Registro TH correspondiente y este valor multiplicarlo por 32. También el programador podría considerar al Temporizador como un contador de 13 bits, los 8 del Contador Alto más los 5 del Contador Bajo. Ahora el Temporizador se desbordaría a los 8 192 ciclos de maquina o pulsos en la entrada Tx correspondiente al igual que en el caso anterior, tome en cuenta que 213 es igual a 8 192. La pregunta podría ser, ¿Dónde radica entonces la diferencia? Ahora, cuando el programador quiera conocer los ciclos de máquina transcurridos o los pulsos en el terminal Tx correspondiente del microcontrolador antes de que el Temporizador se desborde, todo lo que tendría que efectuar es la lectura del par registro THx/TLx correspondiente, con lo que obtendría este valor directamente, lo que aparentemente resulta más sencillo que en el caso anterior. Pero,

Microcontroladores. El 8051 de la INTEL.

371

¿Cómo conformar el número de 13 bits valido a partir de los 16 bits leídos? Efectivamente, cuando efectuamos la lectura del par registro THx/TLx estamos leyendo 16 bits, cada registro aporta 8, de los que son validos solo 13 ya que el contador es de 13 bits. En este caso sería muy importante que el programador conociera cuales son los bits del Contador Bajo que no se incorporan a la cadena de conteo. De la Figura 9.4.2 podemos observar que son los bits más significativos, b7, b6 y b5, los que no se incorporan a la cadena de conteo por lo que cuando se efectúa la lectura del Registro TLx estos bits deben ser desestimados del valor valido.

Figura 9.4.2 Bits validos de THx y TLx en el Modo 0. De la propia Figura 9.4.2 podemos observar que la cadena de bits obtenidos después de ambas lecturas queda seccionada y no resulta útil directamente, por lo que, si en el caso anterior el valor leído de THx lo teníamos que multiplicar por 32, ahora, los valores leídos de la pareja THx/TLx lo tenemos que conformar para que queden como aparece en la Figura 9.4.3.

Figura 9.4.3 Número conformado correctamente. A continuación se muestra una Subrutina a la que llamaremos CONFORMA, la que podría ser llamada después de la lectura de la pareja de registros THx/TLx de cualquiera de los Temporizadores con el objetivo de obtener bien conformado, en 13 bits, el valor del conteo en este Modo de Trabajo. La Subrutina tiene como entrada en el Registro Acumulador el contenido del registro THx y en el Registro B el contenido de TLx, tal y como se muestra en la Figura 9.42. Como salida da el valor en 13 bits correctamente conformado, en el Registro Acumulador los bits del 0 al 7 y en el Registro B los bits del 8 al 12. ; Subrutina CONFORMA. ; Entrada: Registro Acumulador contenido del Registro TH. ;

Registro B contenido del Registro TL.

Microcontroladores. El 8051 de la INTEL.

372

; Salida: Registro Acumulador los 8 bits menos significativo del conteo. ;

Registro B los 8 bits más significativos del conteo.

conforma:

mov

R5, A

; Salva contenido del Contador Alto

mov

A, B

; Trae contenido del Contador Bajo

; Rota el contenido del Contador Bajo, tres bits a la izquierda. sigue1:

mov

R4, #3

rl

A

djnz

R4, sigue1

anl

A, #11111000b

; Restablece a sus registros originales a los Contadores. mov

B, A

mov

A, R5

; Rotación de THx con TLx a través del bit de Acarreo, tres bits. sigue2:

mov

R4, #3

clr

C

rrc

A

mov

R5, A

mov

A, B

rrc

A

mov

B, A

mov

A, R5

djnz

R4, sigue2

; Preparando rotación del par TLX/THX

; Fin de la rotación.

ret Quizás un aspecto de interés en este momento podría ser darle respuesta a la siguiente pregunta, ¿Será posible, dentro de un mismo Modo de Trabajo, variar el número de conteos con los que el Contador se desborda? El usuario tiene la posibilidad mediante la escritura del par registro THx/TLx declarar un valor de inicio de conteo para el contador diferente de 0 y por ende variar el número de conteos hasta que este se desborde. Por su puesto, solo es posible para un valor inferior que la base de conteo máxima que impone el número de bits del contador en el Modo de Trabajo. Resultaría de interés poder encontrar una ecuación que permita calcular el valor a cargar en el par registro THx/TLx para lograr el desbordamiento del Temporizador para cualquier valor deseado. Esta ecuación debe tomar en cuenta los dos valores que son conocidos de antemano para cualquier aplicación, que son:

Microcontroladores. El 8051 de la INTEL. 9

373

El número de conteos máximo que se puede lograr dado el Modo de Trabajo seleccionado para operar el Temporizador.

9

El número de conteos a los que se desea que el Temporizador se desborde.

Siendo la expresión la que les proponemos a continuación: Valor a cargar = Conteo máximo – Numero de conteos antes de desbordarse Pongamos como ejemplo el caso del Temporizador 0 programado como contador de eventos en el Modo 0, el que deseamos que se desborde cuando le entren 320 pulsos por el terminal T0 del microcontrolador. En este caso el Contador Alto, representado por TH0, se incrementará en 1 cada vez que entren por el terminal T0 del microcontrolador 32 pulsos, por lo que se debe desbordar cuando cuente 10. ¿Cómo lograr que el contador se desborde cuando cuente solo 10 pulsos? En este caso TH0 se debe cargar, antes de comenzar el conteo, con un valor que garantice que cuando cuente 10 pulsos llegue a su conteo máximo, 256, por lo que: Conteo Máximo = 256 Conteos antes de desbordarse = 10 Valor a cargar en TH0 Sustituyendo los datos anteriores en la ecuación propuesta: TH0 = 256 – 10 TH0 = 246 ¿Qué importancia puede traer esto al Programador? En la mayoría de las aplicaciones el interés del programador esta en que el Temporizador le indique cuando a ocurrido una cantidad de veces determinada un evento en especifico. Podría ser cuando ha ejecutado una cantidad de veces determinada un ciclo de máquina el microcontrolador, lo que estaría ligado con un tiempo transcurrido o cuando ha ocurrido una cantidad de veces determinada un evento externo al microcontrolador. La manera que este dispositivo tiene para indicar esto es poniendo a ´1´ su bandera TFx y con ello propiciar un pedido de atención por Interrupción, cosa esta que ocurre cuando su contador se desborde.

Microcontroladores. El 8051 de la INTEL.

374

Ahora bien no siempre la cantidad de eventos que desea el programador que le indique su ocurrencia el Temporizador coincide con la base de conteo del mismo en un Modo de Trabajo dado, es más me atrevería a afirmar que en la mayoría de las ocasiones no coincide, por lo que es de vital importancia para el programador el poder tener la capacidad de alterar esta condición, aspecto este que se lo propicia el poder cargar un valor cualquiera en el par registro THx/TLx. De lo anterior podemos concluir: 9

Cuando el conteo deseado, coincide con el conteo máximo del contador en un Modo de Trabajo dado, el valor a cargar en el par registro THx/TLx es 0 en todos sus bits.

9

Cuando el conteo deseado, no coincide con el conteo máximo del contador en un Modo de Trabajo dado en el par registro THx/TLx no se carga el número de conteos deseado sino que un valor que sumado con este de el número de conteos máximo.

Observemos lo explicado hasta aquí, para el Modo de Trabajo 0, mediante el análisis de los siguientes ejemplos. Ejemplo 9.4.1. Generar un tren de pulsos simétrico a través del terminal P1.0 del microcontrolador. ; Este programa genera un tren de pulsos simétrico a través del pin P1.0 del Puerto 1. ; Para ello se utilizará el Temporizador 0 con las siguientes condiciones de operación ;

Modo 0.

;

Disparo por Software.

;

Base de conteo máximo del contador.

; La frecuencia de la señal generada es de 61 hz. ; De la Subrutina se sale cuando se aprieta una Tecla conectada al terminal P1.1. ; El nombre de la Subrutina será TRENSIME. ; **************************************************************************************************************** ; Programando al Temporizador 0. trensime:

mov

TMOD, # 0

; Modo 0. Disparo por Software.

; Generando el tren de Pulsos a la frecuencia de 61 hz de forma cíclica. lazo1:

setb

P1.0

; genera ciclo en alto del tren de pulsos

acall

tiempo

; demora en ´1´ de la señal generada.

clr

P1.0

; genera ciclo en bajo del tren de pulsos

acall

tiempo

; demora en ´0´ de la señal generada.

jnb

P1.1, salir

sjmp

lazo1

; Se repite el ciclo.

Microcontroladores. El 8051 de la INTEL. salir:

clr

P1.0

375 ; se pone a ´0´ el terminal P1.0

ret : Subrutina que genera el tiempo de demora utilizando al Temporizador 0 ; Frecuencia del Oscilador interno de 12 Mhz, tiempo de demora de 8 miliseg. ; El Temporizador se atiende por Encuesta. tiempo:

mov

TH0, #00000000B

; Se programan los restantes 8 bits

setb

TR0

; Se inicializa el conteo del Temp. 0

jnb

TF0, $

; Se vigila el desbordamiento.

clr

TF0

; Limpia la bandera de desbordamiento del Temporizador

ret

; Regresa al Programa Principal.

En la Subrutina anterior el nivel lógico del terminal P1.0 del Puerto 1, se mantiene en ´1´ durante 8 192 ciclos de máquinas lo que se corresponde con 8 192 microsegundos a 12 Mhz, pasando posteriormente a ´0´ y manteniéndose en este estado durante el mismo tiempo, lo que garantiza la característica de simetría del tren de pulsos generada. Por lo tanto la señal generada se corresponde con un tren de pulsos simétrico con un periodo de 16 384 microsegundos, lo que se corresponde con una frecuencia de aproximadamente 61 Hz. Esta es la frecuencia más baja para un tren de pulsos generado mediante el empleo del Temporizador programado en el Modo 0 con el microprocesador trabajando a 12 Mhz. Una pregunta buena a responder en este momento podría ser, ¿Cuál será la frecuencia máxima que se podrá generar para un tren de pulsos simétrico en este Modo de Trabajo y con el microprocesador trabajando a 12 Mhz? En este caso el valor a cargar en el registro TH0 se corresponde con el mayor posible, o sea, todos los bits en 1 y con ello logramos que con el primer conteo se desborde. El programa quedaría de la siguiente forma, ; Este programa genera un tren de pulsos simétrico a través del terminal P1.0 del Puerto 1. ; Para ello se utilizará el Temporizador 0 con las siguientes condiciones de operación ;

Modo 0.

;

Disparo por Software.

;

Base de conteo máximo del contador.

; La frecuencia de la señal generada es de 15 625 hz. ; De la Subrutina se sale cuando se aprieta una Tecla conectada al terminal P1.1. ; El nombre de la Subrutina será TRENSIME. ; ****************************************************************************************************************

Microcontroladores. El 8051 de la INTEL.

376

; Programando al Temporizador 0. trensime:

mov

TMOD, # 0

; Modo 0. Disparo por Software.

; Generando el tren de Pulsos a la frecuencia de 15 625 hz de forma cíclica. lazo1:

salir:

setb

P1.0

; genera ciclo en alto del tren de pulsos

acall

tiempo

; demora en ´1´ de la señal generada.

clr

P1.0

; genera ciclo en bajo del tren de pulsos

acall

tiempo

; demora en ´0´ de la señal generada.

jnb

P1.1, salir

sjmp

lazo1

; Se repite el ciclo.

clr

P1.0

; se pone a ´0´ el terminal P1.0

ret : Subrutina que genera el tiempo de demora utilizando al Temporizador 0 ; Frecuencia del Oscilador interno de 12 Mhz, tiempo de demora de 32 microsegundos. ; El Temporizador se atiende por Encuesta. tiempo:

mov

TH0, #11111111B

; Se programan los restantes 8 bits

setb

TR0

; Se inicializa el conteo del Temp. 0

jnb

TF0, $

; Se vigila el desbordamiento.

clr

TF0

ret

; Limpia la bandera de desbordamiento del Temporizador ; Regresa al Programa Principal.

Podría resultar interesante poder ver un ejemplo donde nos impongamos una frecuencia a obtener con la señal generada y a partir de este valor determinar el valor a cargar en el registro THx correspondiente, que es la forma en que nos lo vamos a encontrar en la práctica por lo general. Ejemplo 9.4.2. Se desea generar por el terminal P3.0 un tren de pulsos simétrico a la frecuencia de 3.1 Khz. La frecuencia del cristal de cuarzo conectado a los terminales XTAL1 y XTAL2 del 8051 es de 12 Mhz. La señal deseada tiene un periodo de 0,32 milisegundos, o lo que es igual 320 microsegundos, por lo que la misma debe estar en ´1´ durante 160 microsegundos y los restantes 160 microsegundos debe permanecer en ´0´, repitiéndose este proceso de forma cíclica. De lo anterior podemos sacar como conclusión que el Temporizador nos debe indicar con su desbordamiento cada vez que trascurren 160 microsegundos, tiempo este en el que tenemos que hacer cambiar el valor del nivel lógico en el terminal P3.0 para dar la sensación de un tren de pulsos. ¿Cómo lograr lo anterior?

Microcontroladores. El 8051 de la INTEL.

377

Para lograr lo anterior escogeremos al Temporizador 1 el cual lo pondremos a trabajar como contador de tiempo y trabajando en el Modo 0. Considerando que el cristal de cuarzo conectado entre los terminales XTAL1 y XTAL2 del microcontrolador es de 12 Mhz, la ocurrencia de un ciclo de máquina será cada 1 microsegundo y al Contador Alto del Temporizador 1 llegará un pulso cada 32 microsegundos, por lo que debemos programar al registro TH1 de forma tal que se desborde a los 5 pulsos de conteo. Empleando la ecuación obtenida anteriormente: Valor a cargar en TH1 = Conteo Máximo en el Modo 0 – Número de conteos deseados TH1 = 256 - 5 TH1 = 251 O lo que es lo mismo 0FBh en hexadecimal. El fragmento de programa es el que se muestra a continuación al que llamaremos TREN3_1K. ;**************************************************************************************************************** ; Este fragmento de programa genera un tren de pulsos simétrico a la frecuencia de 3.1 Khz. a ; través del terminal 0 del Puerto 3, con la utilización del Temporizador 1, programado en Modo 0, ; controlado por software. ; De la Subrutina se sale cuando se aprieta una Tecla conectada al terminal P1.1. ;**************************************************************************************************************** ; Programando al Temporizador 1. tren3_1k:

mov

TMOD, # 0

; Se programa el Temporizador 1.

; Generando el tren de pulsos por el terminal P3.0 del microcontrolador. lazo1:

salir:

setb

P3.0

; Se genera el ciclo en alto de la señal.

acall

TIEMPO

; Tiempo en alto de la señal

clr

P3.0

; Se genera el ciclo en bajo de la señal.

acall

TIEMPO

; Tiempo en bajo de la señal

jnb

P1.1, salir

sjmp

lazo1

; Se repite el ciclo.

clr

P1.0

; se pone a ´0´ el terminal P1.0

ret ; Subrutina que genera el intervalo de tiempo de los pulsos. tiempo: lazo2:

mov

TH0,# 0FBh

; Se programan los restantes 8 bits

setb

TR1

; Se inicia el conteo del Temporizador 1.

jnb

TF1, $

; Espera por que el Temporizador 1 se desborde

clr

TF1

; Limpia la bandera de desbordamiento.

ret

; Regresa al Programa Principal.

Microcontroladores. El 8051 de la INTEL.

378

Observe de los Programas mostrados en los ejemplos que con solo variar los valores cargados en los registros TH1 se puede variar la frecuencia del tren de pulso generado, manteniendo la señal simétrica. La pregunta a responder en este momento sería, ¿Qué es lo que hace en los programas anteriores que las señales generadas sean simétricas? Esto se logra en los ejemplos anteriores al llamar la misma Subrutina de tiempo tanto para cuando la señal generada esta en ´0´ que cuando la señal generada esta en ´1´. Enfrentemos la solución del problema anterior pero ahora el tren de pulsos a generar no será simétrico. Ejemplo 9.4.3. Generar un tren de pulsos a la frecuencia de 3.1 Khz. con ciclo útil del 40 %, a través del terminal 0 del Puerto 2, con la utilización del Temporizador 0 programado en Modo 0, controlado su disparo por software. Al fragmento de programa lo hemos llamado TRENVARIA. ¿Qué se quiere decir con que el ciclo útil de la señal a generar sea del 40%? El ciclo útil de una señal tren de pulsos se define como la relación existente entre el tiempo en que la señal toma el valor de ´1´ con respecto al periodo total de la señal. Este parámetro se brinda en porciento. Por lo que para nuestro caso dado que el periodo de la señal a generar es de 320 microsegundos y que el ciclo útil de la misma es del 40%, el tiempo en ´1´ de la señal será de 128 microsegundos, mientras que el tiempo en ´0´ será el tiempo restante, 192 microsegundos. ¿Cómo lograr lo anterior? Simplemente haciendo que el programa cuando ponga la salida P2.0 en ´1´ llame a una Subrutina que programe al Temporizador 0 para que avise cuando a transcurrido 128 microsegundos y cuando el programa ponga la salida P2.0 en ´0´ debe llamar a una Subrutina que avise cuando transcurra 192 microsegundos. A continuación mostramos una propuesta de programa para llevar a cabo esta tarea. ; Fragmento de programa TRENVARIA. ; Programando al Temporizador 0. trenvaria:

mov

TMOD, # 0

; Se programa el Temp. 0 en Modo 0.

Microcontroladores. El 8051 de la INTEL.

379

; Generando el ciclo en ´1´ del tren de pulsos. lazo1:

setb

P2.0

; Se pone a ´1´ la señal generada.

; Se espera por el tiempo en ´1´ deseado de la mov

TH0,# 0FCh

acall

tiempo

; Se programan los restantes 8 bits ; Tiempo en ´1´ de la señal.

; Generando el ciclo en ´0´ del tren de pulsos. clr

P2.0

; Se pone a ´0´´ la señal generada.

; Se espera por el tiempo en ´0´.

salir:

mov

TH0,# 0FAh

; Se programan los restantes 8 bits

acall

tiempo

; Tiempo en ´0´ de la señal

jnb

P1.1, salir

sjmp

lazo1

clr

P2.0

; Se repite el ciclo.

ret ; Subrutina TIEMPO, es la que genera los intervalos de tiempo. tiempo:

setb

TR0

; Se inicializa el conteo del Temp. 0

jnb

TF0, $

; Se vigila el desbordamiento.

clr

TF0

ret

; Regresa al Programa Principal.

Observe la programación independiente del Registro TH0 para el ciclo en ´1´ del tren de pulsos y para el ciclo en ´0´ del tren de pulsos. Esto es lo que garantiza, en este caso, que los tiempos de duración de ambos ciclos no sean iguales y con ello que el tren de pulsos generado no sea simétrico. ¿Cómo se garantizo que la frecuencia fuera la misma que la del ejemplo anterior a pesar de variar los tiempos en ´0´ y en ´1´ de la señal generada? Si se mantiene que el número de pulsos a contar totales por parte del Temporizar se mantenga constante, e igual que la empleada en el ejemplo anterior, garantizaremos que la frecuencia de la señal generada sea la misma. El Modo 1. Temporizador/Contador de 16 bits. El único aspecto en el que difiere este Modo de Trabajo del estudiado anteriormente esta en el número de bits del contador y por lo tanto en la base de conteo máxima que se puede lograr. En este Modo de Trabajo el contador se toma completo, 16 bits, por lo que el conteo máximo puede llegar a ser de 65 536, ver Figura 9.4.4.

Microcontroladores. El 8051 de la INTEL.

380

Figura 9.4.4 Estructura de los Temporizadores en el Modo 1 de Trabajo. El Registro TLx, ahora aporta los bits menos significativos (b0 – b7), por lo que el Contador Bajo será de 8 bits, mientras que el Registro THx aporta los bits más significativos (b8 – b15), por lo que el Contador Alto será de 8 bits también, ver Figura 9.4.5.

Figura 9.4.5. Bits que aportan los registros TLx y THx. Para la programación de los Temporizadores en este Modo de Trabajo los bits b0-b1 para el Temporizador 0 y los bits b4-b5 para el Temporizador 1 del Registro TMOD se deben poner a ´1´ y a ´0´ receptivamente. La consecuencia fundamental de contar en este Modo de Trabajo con un número de bits mayor en el contador esta relacionado con el número máximo de conteos que puede dar este antes de desbordarse. Ahora el número máximo de conteo antes de desbordarse que permiten los contadores es de 65 535 y no de 8 192 como en el caso anterior. Esto nos permitiría poder generar intervalos de tiempo más grandes y por su puesto poder contar valores mayores sin la necesidad de tomar en cuenta el desbordamiento del contador. Veamos lo anterior en el siguiente ejemplo. Ejemplo 9.4.4. Generar un tren de pulsos simétrico a la frecuencia de 7.6 hz a través del terminal P1.0 del microcontrolador.

Microcontroladores. El 8051 de la INTEL.

381

Generar un tren de pulsos de 7.6 hz implica generar un tren de pulsos cuyo periodo es de aproximadamente 131 milisegundos o lo que es igual 131 000 microsegundos. Si el microcontrolador esta trabajando con un cristal de 12 Mhz., su ciclo de máquina será de 1 microsegundos, por o que en el Modo de Trabajo 0 el Contador Alto efectuaría un conteo cada 32 y se desbordaría cada 8 192 microsegundos por lo que para indicar que han pasado 131 000 microsegundos se debe desbordar aproximadamente 16 veces. Tarea esta que puede resultar algo incomoda para el programador. ¿Qué sucede si consideramos al contador como la unión del Contador Bajo y el Contador Alto, o sea 16 bits, como ocurre con el Modo de Trabajo 1? En este caso el contador de desbordará a los 65 536 microsegundos (216), por lo que si seguimos el mismo algoritmo de los ejemplos anteriores para generar el tren de pulso tendríamos, terminal en ´1´ durante 65 536 microsegundos y terminal en ´0´ durante 65 536 microsegundos, periodo del tren de pulsos 131 072 microsegundos que es aproximadamente el periodo que queríamos que tuviera el tren de pulsos generado. Esto es lo que mostramos en el fragmento de programa siguiente. ; Este programa genera un tren de pulsos simétrico a través del terminal P1.0 ; Para ello se utilizará el Temporizador 1 trabajando en Modo 1, controlado por ; Software y con el tiempo de conteo máximo. ; La frecuencia de la señal generada es de 7.6 hz. ; La salida de la Subrutina ocurre cuando se aprieta una Tecla conectada al terminal P1.1. ; Subrutina TRENBAJO. ; Programando al Temporizador 1. trenbajo:

mov

TMOD, #01h

; Se programa el Temp. 0 en Modo 1.

; Generando el tren de pulsos. lazo1:

salir:

setb

P1.0

; Se genera el ciclo en alto de la señal.

acall

tiempo

; Tiempo en alto de la señal

clr

P1.0

; Se genera el ciclo en bajo de la señal

acall

tiempo

; Tiempo en bajo de la señal.

jnb

P1.1, salir

sjmp

lazo1

clr

P1.0

; Se repite el ciclo.

ret ; Subrutina que genera los intervalos de tiempo de la señal. tiempo:

mov

TL0, # 0

; Se programa valor de inicio de conteo

Microcontroladores. El 8051 de la INTEL. mov

TH0,# 0

; Se programa valor de inicio del conteo

setb

TR0

; Se inicializa el conteo del Temporizador 0

jnb

TF0, $

; Se pregunta por desbordamiento

ret

382

; Regresa al Programa Principal.

En el fragmento de programa anterior el nivel lógico del terminal P1.0 se mantiene en ´1´ durante 65 536 ciclos de máquinas, que a 12 Mhz representa 65 536 microsegundos, pasando posteriormente a ´0´ manteniéndose en este estado durante el mismo intervalo de tiempo. La señal generada por lo tanto es un tren de pulsos simétrico con un periodo de 131 072 microsegundos, aproximadamente 7.6 Hz. Como se puede observar con un fragmento de programa prácticamente similar hemos sido capaces de generar un tren de pulsos a más baja frecuencia debido fundamentalmente a que contamos ahora con un contador de más bits. ¿Se podrá obtener una señal a una frecuencia más baja a través del terminal P1.0? Aparentemente esto no resulta posible si utilizamos el mismo algoritmo que hemos estado utilizando hasta aquí y empleáramos el mismo Cristal de Cuarzo. Pero podríamos tener dentro de un lazo repetitivo a la Subrutina que garantiza los intervalos de tiempo deseados de la señal para producir la frecuencia requerida, de forma tal que dicha Subrutina se ejecute varias veces estando la señal en ´1´ y varias veces estando la señal en ´0´. Analicemos esto en el siguiente ejemplo. Ejemplo 9.4.5. Generar un tren de pulsos simétrico a la frecuencia de 0.5 hz a través del terminal P1.0 del microcontrolador. En este caso la frecuencia de la señal impone un periodo de la misma de 2 segundos, o sea 2 millones de microsegundos, por lo que la señal debe tener tiempo en ´1´ igual a tiempo en ´0´ e igual a 1 millón de microsegundos. Para poder contar un millón de ciclos de máquina necesitamos un contador de al menos 20 bits, pero en ningún Modo de Trabajo los contadores de los Temporizadores tienen esta cantidad de bits. ¿Cómo lograr entonces estos tiempos de demora con los Temporizadores? Podríamos contar las veces que el Temporizador se desborda de forma tal que lleguemos al tiempo deseado y de la Subrutina no se retorna hasta que se llegue al conteo de desbordamiento

Microcontroladores. El 8051 de la INTEL.

383

máximo. Por ejemplo en el caso que nos ocupa podríamos poner a los Temporizadores para que se desbordara a los 50 000 microsegundos, por lo que el millón de microsegundos deseados pasarían después de que el temporizador se halla desbordado 20 veces. Veamos como proponemos efectuar esta tarea en la Subrutina que se muestra a continuación. ; Este fragmento de programa genera un tren de pulsos simétrico a través del terminal P1.0 con la ; utilización del Temporizador 1 trabajando en el Modo 1, con tiempo de conteo máximo y ; controlado su disparo por software con la ayuda del Registro R2 para alargar los tiempos en ´1´ y ; en ´0´ de la señal generada. ; La frecuencia de la señal generada es de 0.5 hz. ; Subrutina FRECBAJA. ; Programando al Temporizador 1. frecbaja:

mov

TMOD,# 10H

;Programa el Temporizador 1 en Modo 1.

; Generando el tren de pulsos. lazo1:

salir:

setb

P1.0

; Pone la señal a ´1´.

acall

iempo

; Tiempo en ´1´ de la señal generada

clr

P1.0

; Pone la señal a ´0´.

acall

tiempo

;Tiempo en ´0´ de la señal generada.

jnb

P1.1, salir

sjmp

lazo1

clr

P1.0

;Repite el proceso.

ret ; Subrutina que genera los intervalos de tiempo. tiempo:

mov

R2,# 20

; Carga las veces que el contador desbordara.

tiempo1:

mov

TL1, #0B0h

;Inicializa para el conteo a TL1

mov

TH1, #3Ch

;inicializa para el conteo a TH1

setb

TR1

;Inicializa el trabajo del Temporizador 1.

jnb

TF1, $

; Vigila el desbordamiento del Contador.

clr

TF1

djnz

R2,tiempo1

lazo2:

ret

;Fin del ciclo. ;Regresa al programa principal.

En este caso al cargar en el Registro R2 el valor 20 al inicio de la Subrutina tiempo y ser este el contador por software de un lazo dentro del cual se encuentra el conteo del Temporizador, hemos alargado en 20 veces el tiempo en que permanece la señal en ´1´ y en 20 veces el tiempo en que permanece la señal en ´0´, manteniendo la simetría de la señal pero alargando su periodo y con ello disminuyendo su frecuencia de la señal generada.

Microcontroladores. El 8051 de la INTEL.

384

En el caso anterior tanto el tiempo en ´1´ como el tiempo en ´0´ fueron alargados en 1 millón microsegundos, considerando un cristal de cuarzo de 12 Mhz. Esto provoca que el periodo de la señal se alargue hasta los 2 millones de microsegundos deseados para generar la señal de frecuencia de 0.5 hz. Los valores cargados en el par registro TH1/TL1 son los necesarios para que el Temporizador se desborde a los 50 000 microsegundos. Hasta ahora en todos los ejemplos hemos trabajado con los Temporizadores controlando la habilitación de su conteo por software. En el siguiente ejemplo utilizaremos al Temporizador 1 en Modo 1, controlando la habilitación del conteo por hardware con el objetivo de calcular el tiempo de duración de un pulso. Ejemplo 9.4.6. Determinar, con la ayuda del Temporizador 1 el ancho del pulso de la señal externa aplicada al terminal INT1/ del microcontrolador. Lo que se desea es determinar el ancho del pulso de una señal que es generada por algún circuito externo al microcontrolador. Para ello podríamos utilizar uno cualquiera de los Temporizadores operando de la siguiente forma: 1. Mientras la señal externa este en ´0´, no debe contar el Temporizador. 2. Con la subida de ´0´ a ´1´ de la señal externa se debe dar inicio al conteo del contador, que debe contar tiempo ya que lo que necesitamos es, el tiempo en que permanece en ´1´ la señal externa. 3. Con la caída de ´1´ a ´0´ de la señal externa debe dejar de contar el contador y se esta listo para leer directamente del par registro THx/TLx el valor en microsegundos que duro la señal. NOTA: estamos considerando que el ancho de los pulsos externos es menor de 65 535 microsegundos y por ende el contador del Temporizador empleado no se desborda. Para efectuar esta tarea programaremos al Temporizador 1 en el Modo 1, contador de 16 bits, con habilitación de conteo por hardware. ¿Cómo programar al Temporizador 1 para que trabaje en este Modo y por donde entra al Temporizador la señal de hardware que habilita el conteo del Contador?

Microcontroladores. El 8051 de la INTEL.

385

Si observamos la estructura interna de uno cualquiera de los Temporizadores en el Modo de Trabajo 1 y nos detenemos a analizar el circuito que genera la señal control, llegaremos a la conclusión de que si cuando programamos al Temporizador 1 ponemos el bit GATE1 del Registro TMOD en ´1´ y en el bit TR1 del mismo registro en ´1´ también, el valor de la señal control dependerá solo del valor que tenga la señal aplicada al terminal INT1/ del microcontrolador. Si INT1/ esta en ´0´ la señal control tomará el valor de ´0´ y por lo tanto el conteo del contador estará inhibido, si por el contrario el valor de la señal aplicada en INT1/ es ´1´, la señal control tomará el valor ´1´ y por lo tanto el conteo del contador estará habilitado. Esto es lo que deseamos para la solución del ejemplo por lo que es correcto aplicar la señal a contar al terminal INT1/ tal y como se plantea en el enunciado del ejemplo. ¿Cómo el programa detecta que la señal aplicada en INT1/ cambio de ´1´ a ´0´ y por ende finalizó con el conteo? Para dar respuesta a esta pregunta nos tenemos que referir al Registro TCON, ver Figura 9.4.5.

Figura 9.4.5 Bits del Registro TCON. Ya los bits del 4 al 7 de este registro los hemos estudiado, pero vamos a hacer hincapié en estos momentos en los bits b2 y b0. Estos bits están relacionados con la manera en que el microcontrolador reconoce un pedido de Interrupción Externa a través de sus terminales INT0/ e INT1/ respectivamente. Si se carga un ´0´ en cualquiera de estos bits, el microcontrolador reconocerá el pedido de Interrupción en la entrada INT/ correspondiente cuando la señal aplicada en este terminal este en ´0´, mientras que si se carga un ´1´ lo reconocerá con la caída de la señal de ´1´ a ´0´, frente de caída de la señal. Esta última posibilidad es la que se ajusta para poder materializar nuestra aplicación, ya que si se habilita la interrupción externa INT1/, al mismo tiempo que la señal aplicada caiga de ´1´ a ´0´ se detiene el conteo del contador y se solicita Interrupción Externa del tipo 1, lo que podría aprovechar el Programador para efectuar la lectura de los valores almacenados en el par registro TL1/TH1, valor este que se correspondería con el tiempo en ´1´ de la señal aplicada al terminal INT1/ en microsegundos.

Microcontroladores. El 8051 de la INTEL.

386

Veamos un fragmento de programas donde se ejemplifica lo anterior. ; Inicio del programa en la dirección 0. org

0

; Respetando la zona de memoria destinada a la Subrutina de la Interrupción externa INT1/ sjmp

inicio

; Inicio de la subrutina que atiende a INT1/. ; A la salida:

en el registro A el valor en el Contador Alto.

;

en el registro B el valor en el Contador Bajo. org 8 mov

A, TL1

; Lee los 8 bit menos significativo del Contador.

mov

B, A

; Salva en el Registro B el contenido de TL1

mov

A, TH1

; Lee los 8 bits más significativo del Contador

setb

20h.0

; Bandera que indica que hay un dato a mostrar

ret ; Inicio del Programa principal. ; Programando al Temporizador 1 en el Modo 1, con disparo por hardware. inicio:

clr

20h.0

mov

TMOD, #10010000b ; Temporizador 1 en el Modo 1

mov

TH1, #0

mov

TH1, #0

setb

IT1

; Habilita interrupción por frente

jnb

20h.0,$

; Espera por Interrupción.

; Convertir los valores en los registros Acumulador y B a unidades de ingeniería. El llevar el valor anterior a unidades de ingeniería es relativamente sencillo ya que el directamente nos da el valor del tiempo transcurrido desde que la señal de entrada fue de ´0´ a ´1´ hasta que la misma fue de ´1´ a ´0´ en microsegundos, si la frecuencia del cristal de cuarzo con que está trabajando es de 12 Mhz. El Modo 2. Temporizador/Contador de 8 bits con Autorrecarga. Los Modos estudiados anteriormente tienen la característica de necesitar cargar en el par registros TLx/THx el valor donde se desea que el contador comience su conteo cada vez que este se desborda y por lo tanto comienza un nuevo ciclo. Esto por su puesto que resulta molesto para el Programador, el que en muchas aplicaciones desearía que dicho valor se cargara de forma automática. Programar al Temporizador en el Modo 2 de Trabajo permite esta forma de operar.

Microcontroladores. El 8051 de la INTEL.

387

En este modo se configura el Temporizador en cuestión como un contador de 8 bits. Actúa como contador al que hemos dado en llamar Contador Bajo y por ende el conteo se va almacenando en TLx y al igual que en los otros modos la fuente de conteo puede ser interna, salida del divisor entre 12 del oscilador o externa, señal aplicada al terminal T0 o T1 en dependencia del Temporizador al que nos estemos refiriendo. La pregunta a darle respuesta en este momento sería, ¿Qué sucede, en este Modo de Trabajo, con el Contador Alto y con THx? La respuesta a la pregunta anterior queda clara si analizamos que sucede cuando el Contador Bajo se desborda en este Modo de Trabajo. En este caso no solo la bandera de interrupción TFx se activa provocando una solicitud de interrupción, de estar habilitada, sino además el registro TLx se carga con el valor almacenado en el registro THx del propio Temporizador comenzando con un nuevo ciclo de conteo a partir de este valor y no a partir de 0 como ocurre en los otros dos Modos de Trabajo estudiados, por lo que no existe la necesidad de cargar por software al registro TLx con el valor de inicio deseado. A este proceso se le llama Autorrecarga y es el elemento que diferencia este Modo de Trabajo de los anteriores. En la Figura 9.4.6 se muestra como quedan los Temporizadores cuando son programados para operar en este Modo de Trabajo.

Figura 9.4.6 Estructura interna de los Temporizadores en el Modo 2. La pregunta a responder en este momento sería,

Microcontroladores. El 8051 de la INTEL.

388

¿Qué valor es el que se encuentra almacenado en el registro THx cuando se desborda el Contador Bajo? El valor que se encuentra almacenado en el registro THx será el último cargado por el software ante del desbordamiento del Contador Bajo. Este puede ser un valor almacenado al inicio del conteo y que no cambiará más hasta que termine la operación o un valor que puede ser cambiado de forma dinámica por software durante la operación del contador. Observe que ahora el Programador tienen la posibilidad de programar un proceso de forma cíclica sin la necesidad de reprogramar el par registro TLx/THx del Temporizador cada vez que el mismo se desborde, mejorando su exactitud en aplicaciones de tiempo al no depender su operación del software para su reinicio. Veamos lo anterior en el siguiente ejemplo. Ejemplo 9.4.7. Se desea llevar el conteo de la cantidad de cajas llenas de un determinado producto. Cada caja contiene 100 unidades de dicho producto y un circuito externo genera un pulso de duración mayor a 1 milisegundo cada vez que un elemento se introduce en una caja. El número máximo de cajas en un día de trabajo es menor que 256. El resumen del trabajo de un día se muestra a través de 2 Lámparas de 7 Segmentos, mediante la opresión de una Tecla. Para resolver el problema anterior proponemos utilizar al Temporizador 0 programado para trabajar en el Modo 2. Como lo que se desea contar son pulsos generados por un circuito externo, el Temporizador 0 se programará para trabajar como Contador de Eventos y como siempre debe estar habilitado desde que comienzan las operaciones del día, la habilitación del conteo del mismo la haremos por software. La Tecla, la que identificaremos con la letra R, la conectaremos directamente al terminal INT0/ del microcontrolador con el objetivo de atenderla por interrupción. Las dos Lámparas de 7 Segmento se conectarán directamente a los Puertos 0 y 2, ver Figura 9.4.7.

Microcontroladores. El 8051 de la INTEL.

389

Figura 9.4.7 Hardware del sistema. Atendiendo a la tarea que se desea que el equipo haga, el Programa debe detectar cada vez que el contador cuenta 100 elementos. Esto lo podríamos lograr si el contador interrumpiera cada 100 conteos de forma tal que la Subrutina de atención a dicha interrupción pudiera implementar un contador de 8 bits por software de una forma muy sencilla y que al final del día su contenido indicará la cantidad de cajas que se han llenado. Para ello el valor en que debe comenzar el conteo el Contador Bajo del Temporizador 0 será, CONTEO DE INICIO = CONTEO MAXIMO - CONTEO DESBORDAMIENTO CONTEO DE INICIO =

256

CONTEO DE INCIO =

156

-

100

La pregunta a contestar en este momento sería, ¿En que registro cargar este valor si vamos a trabajar en el Modo 2? Este valor lo debemos cargar en ambos registros por separado, TH0 y TL0. Cargándolo en el registro TL0 estamos garantizando que la primera vez el Temporizador se comporte segíun lo

Microcontroladores. El 8051 de la INTEL.

390

deseado para la aplicación y cargándolo en el registro TH0 estamos garantizando lo mismo pero para las demás veces de forma automática. El fragmento de programa sería el siguiente, ;**************************************************************************************************************** ; Este programa determina la cantidad de pulsos que llegan por el terminal T0 del microcontrolador ; dividido entre 100. ; El resultado se muestra en las dos Lámparas de 7 Segmentos después de presionar la Tecla R. ; El desbordamiento del Temporizador 0 se atiende por Encuesta. ;**************************************************************************************************************** ; Dirección de inicio del programa principal. org

0

sjmp

inicio

; Salta las direcciones de la Subrutina.

; Dirección de inicio de la Subrutina de INT0. org

3

; Subrutina de atención a la Interrupción Externa 0. Tecla apretada. mov

A, R3

; Carga en el Registro Acumulador el número de cajas.

; Convierte el número de cajas a BCD Empaquetado. mov

b, #10

div

AB

; En A las decenas y en B las unidades.

acall

muestrad

; Envía a Lámpara las decenas

mov

A, B

acall

muestrau

reti

; Envía a Lámpara las unidades ; retorno de Subrutina de Interrupción.

; Inicializando el valor en las Lámparas de 7 Segmentos. inicio:

mov

A, #0

; Envía 0 a las Lámparas

acall

muestrad

; Envía a la Lámpara de las decenas

mov

A, #0

acall

muestrau

; Envía a la Lámpara de las unidades

; Programando al Controlador de Interrupciones del Microcontrolador. mov

IE,# 81H

;Habilita Interrupción INT0/

setb

IT0

; Interrupción por frente de caída

; Programando al Temporizador 0. mov

TMOD,# 06H

;Modo 2, dispar por software, contador eventos

mov

TL0,# 156

;Programa el contador con el numero inicial

mov

TH0,# 156

;Garantiza la Autorrecarga.

; Se prepara el contador por software de cajas llenas. mov

R3,#0

Microcontroladores. El 8051 de la INTEL.

391

; Se inicia el conteo del Temporizador 0. lazo:

setb

TR0

jnb

TF0, $

clr

TF0

inc

R3

sjmp

lazo

;Se mantiene en un lazo infinito.

; Subrutina que nuestra en el Display las decenas. muestrad:

acall

convierte

mov

P0, A

; Escribe en la Lámpara destinada a las decenas.

ret ; Subrutina que nuestra en el Display las unidades. muestrau:

acall

convierte

mov

P2, A

; Escribe en la Lámpara destinada a las unidades.

ret ; Subrutina que convierte a código de Lámpara de 7 Segmentos. convierte:

mov

dptr, #tabla

movc A, @A+DPTR ret ; Tabla con los códigos de Lámparas de 7 Segmentos. tabla:

db

0c0h, 0f9h, 0a4h, 0b0h, 99h, 92h, 82h, 0f8h, 80h, 90h.

end Observe del Programa anterior la no necesidad de cargar nuevamente en el registro TL0 el valor de 156 cuando este se desborde y se desee comenzar un nuevo conteo, lo que caracteriza al Modo 2 de Trabajo de los Temporizadores. El Modo 3. Varios Contadores. Al programar al Temporizador 0 en este modo de trabajo es como si se le hubiese agregado un contador más al microcontrolador, ya que el Temporizador 0 se desdobla en dos contadores de 8 bits y el tercer contador sería el que aportaría el Temporizador 1. Por su puesto esto provoca limitaciones en algunas de las posibilidades que tienen los contadores en este modo de trabajo si recompara los otros modos de trabajo estudiados, ¿Cuáles son estas limitaciones?

Microcontroladores. El 8051 de la INTEL.

392

El contador que se forma con el Contador Bajo del Temporizador 0 utiliza la lógica de control que fue hasta ahora propia de este Temporizador permitiendo todas las funciones que el Programador podía hacer con el mismo, con la única limitación de que el contador es de 8 bits. Para su carga y lectura utilizar al registro TL0. Por su parte el Contador Alto solo puede ser utilizado como un Contador de Tiempo de 8 bits habilitado por software, apoderándose de las señales TR1 y TF1 que eran propias del Temporizador 1. Para su carga y lectura utilizar al registro TH0. Esto deja muy limitado al Temporizador 1 el que solo queda con la posibilidad de trabajar como Generador de la Frecuencia de Baudios para el Puerto Serie, sin señal de habilitación de conteo y sin poder ser atendido por Interrupción. Para su carga y lectura utilizar el par registro TL1/TH1. En la Figura 9.4.8 se muestra como quedan los diferentes contadores en este Modo de Trabajo.

Figura 9.4.8 Estructura interna de los Temporizadores en el Modo 3. ¿Que aplicación se le podría dar al tercer Contador formado por los restos del Temporizador 1? Existen aplicaciones donde se utiliza como parte del diseño la comunicación serie, implementándola mediante el Puerto Serie propio del microcontrolador. Este Puerto Serie necesita de una señal que sincronice el envió de los bits la que por lo general es entregada por el Temporizador 1, el que en este caso no necesita de señal de habilitación del conteo ni de señal de interrupción para cuando se desborde.

Microcontroladores. El 8051 de la INTEL.

393

Por lo que si en una aplicación dada necesitamos de los dos Temporizadores y además vamos a trabajar con el Puerto Serie del microcontrolador, debemos intentar la solución Programando al Temporizador 0 en el Modo 3 de Trabajo y ver si con los dos Temporizadores obtenidos podemos dar solución al problema planteado. 9.5 Los Temporizadores y la Interrupción. En lo que hemos estudiado hasta aquí en este Tema hemos conocido que el Temporizador se ha desbordado utilizando el método de la Encuesta. Efectivamente en los ejemplos desarrollados hemos utilizado la instrucción, jnb

TFx, $

; x será 0 o 1 en dependencia de que estemos trabajando ; con el temporizador 0 o el 1.

Esto provoca que el Programa caiga en un lazo en el que, la única instrucción que el microcontrolador ejecuta es la propia instrucción, del que no sale hasta que la bandera de desbordamiento TFx del Temporizador tome el valor de ´1´ con lo que indica que el contador de dicho Temporizador se ha desbordado. Como segundo paso debíamos limpiar esta bandera mediante la instrucción, clr

TFx

; x será 0 o 1 en dependencia de que estemos trabajando ; con el temporizador 0 o el 1.

Para dejarlo todo listo para el próximo ciclo de trabajo del Temporizador. Ya conocemos del estudio del Tema 7 que existe otra manera de atender la ocurrencia de determinados eventos que no están sincronizados con el Programa y que su ocurrencia podemos decir que es debido a elementos puramente de hardware. Este otro método es el de la Interrupción. Las preguntas a responder en este momento podrían ser, ¿Están habilitados los Temporizadores con los elementos de hardware que posibiliten la atención de los mismos mediante la Interrupción? En el caso de que la respuesta de la pregunta anterior sea positiva, ¿Cómo esta implementado esto en los Temporizadores?

Microcontroladores. El 8051 de la INTEL.

394

Por suerte la respuesta a la primera de las preguntas es positiva, ya que conocemos del propio Tema 7 el conjunto de ventajas que trae el poder atender un determinado evento por Interrupción y no por Encuesta. Por lo tanto la respuesta a la segunda de las preguntas se hace en estos momentos muy importante para poder continuar con el estudio de los Temporizadores. Ambos Temporizadores constituyen fuentes independientes de pedido de Interrupción para el microcontrolador, fuente estas que requieren ser habilitadas para ser reconocidas y que tienen asociado un vector y una dirección en memoria de programa para almacenar el código de la primera instrucción de la correspondiente Subrutinas que atienden dichos pedidos en una aplicación dada. ¿Dónde habilitar la Interrupción para ambos Temporizadores? Como en el caso de las dos fuentes de Interrupción Externas posibles, INT0/ e INT1/, ya estudiadas, la habilitación del pedido de Interrupción para ambos Temporizadores se efectuará mediante la manipulación de dos bits del Registro IE, el bit 1 para el Temporizador 0 y el bit 3 para el Temporizador 1, ver Figura 9.5.1.

Figura 9.5.1 Los significados de los bits del Registro IE. Por lo tanto si en su aplicación usted necesita atender al Temporizador 0 por Interrupción programe al Controlador de Interrupciones empotrado en el microcontrolador poniendo los bits 7

Microcontroladores. El 8051 de la INTEL.

395

y 1 del Registro IE en ´1´, si lo que usted necesita es atender al Temporizador 1 por Interrupción entonces ponga los bits 7 y 3 del mismo registro en ´1´ y si lo que necesita en su aplicación es atender a ambos Temporizadores por Interrupción ponga los bits 7, 3 y 1 de este registro en ´1´. ¿Cuál es la dirección en Memoria de Programa donde almacenar el código de la primera instrucción de la Subrutina de atención a la Interrupción para cada uno de los Temporizadores? Para el caso del Temporizador 0 esta dirección se corresponde con la 000Bh y para el caso del Temporizador 1 esta dirección se corresponde con la 001Bh. Por lo que en su programa comience a escribir las Subrutinas de atención correspondientes a partir de estas direcciones. Para ello puede utilizar la directiva org. El encabezamiento de un programa que utilice ambas Interrupciones, más las dos externas, podría ser el siguiente, ; Inicio del Programa. org

0

sjmp

inicio ; Preservando la zona de memoria par almacenar las Subrutinas

; Inicio de la Subrutina de atención a la Interrupción Externa 0 org

0003h

sjmp

inte0

; Inicio de la Subrutina de atención a la interrupción para el Temporizador 0. org

000Bh

sjmp

tempo0

; Inicio de la Subrutina de atención a la Interrupción Externa 1 org

0013h

sjmp

inte1

; Inicio de la Subrutina de atención a la interrupción para el Temporizador 1. org

001Bh

sjmp

continua1

En las direcciones simbólicas inte0, tempo0, inte1 y tempo1 se escriben las Subrutinas de atención a la interrupción correspondientes. Me parece que resulta conveniente dar respuesta a la siguiente pregunta antes de resolver algunos ejemplos,

Microcontroladores. El 8051 de la INTEL.

396

¿Cuál es el evento que estamos atendiendo por interrupción en este caso? El evento que estamos atendiendo por interrupción es el desbordamiento de los contadores de los Temporizadores en dependencia del Modo de Trabajo seleccionado para que operen los mismos en una aplicación dada. Por ejemplo si el Temporizador 0 se pone a trabajar en el Modo 2 como contador de tiempo e inicializamos al Registro TL0 con el valor 156, ocurrirá un pedido de interrupción por parte de este Temporizador cada 100 microsegundos, si el cristal de cuarzo conectado al mismo es de 12 Mhz. Enfrentemos la solución del Ejemplo 9.4.7 empleando la Interrupción como método de atención al Temporizador y no la Encuesta como habíamos empleado. Ejemplo 9.4.7. Se desea llevar el conteo de la cantidad de cajas llenas de un determinado producto. Cada caja contiene 100 unidades de dicho producto y un circuito externo genera un pulso de duración mayor a 1 milisegundo cada vez que un elemento se introduce en una caja. El número máximo de cajas en un día de trabajo es menor que 256. El resumen del trabajo de un día se muestra a través de 2 Lámparas de 7 Segmentos, mediante la opresión de una Tecla. En el hardware no existe la necesidad de efectuar ningún cambio por lo que si usted no recuerda el hardware propuesto para la solución de este ejemplo remítase a la Figura 9.4.7. Los cambios significativos ocurren realmente en el programa propuesto para resolver la aplicación. ¿Cuáles serán estos cambios? Ante que todo como al Temporizador 0 lo vamos a atender por Interrupción conjuntamente con la atención de la Tecla, cuando programamos al Controlador de Interrupciones empotrado en el microcontrolador mediante la escritura del Registro IE, no solo habilitamos a la interrupción externa INT0/, sino que también tenemos que habilitar a la interrupción del Temporizador 0. En segundo lugar, conjuntamente con el reservar el espacio de memoria para colocar la Subrutina de atención a la interrupción externa INT0/, debemos reservar el espacio de memoria donde colocar la Subrutina de atención ala interrupción del Temporizador 0. La instrucción que encuestaba constantemente el estado de la bandera de desbordamiento del Temporizador 0, TF0, ahora no tiene que aparecer en el programa.

Microcontroladores. El 8051 de la INTEL.

397

La instrucción que ponía a ´0´ a la bandera de desbordamiento del Temporizador 0 cada vez que este se desbordaba ahora no tiene porque aparecer en el programa ya que esta acción la hace de forma automática el microcontrolador cada vez que atiende el pedido de interrupción de dicho Temporizador. A continuación se muestra la propuesta de programa que brindamos para solucionar el ejemplo planteado empleando la interrupción como manera de atender el desbordamiento del Temporizador 0. ;**************************************************************************************************************** ; Este programa determina la cantidad de pulsos que llegan por el terminal T0 del microcontrolador ; dividido entre 100. ; El resultado se muestra en las dos Lámparas de 7 Segmentos después de presionar la Tecla R. ; El desbordamiento del temporizador 0 se atiende por Interrupción. ;**************************************************************************************************************** ; Dirección de inicio del programa principal. org

0

sjmp

inicio

; Salta las direcciones de la Subrutina.

; Dirección de inicio de la Subrutina de INT0. org

3

sjmp

inte0

; Dirección de inicio de la Subrutina de atención al Temporizador 0. org

000Bh

inc

R3

reti ; Subrutina de atención a la Interrupción Externa 0. Tecla apretada. inte0:

mov

A, R3

; Carga en el Registro Acumulador el número de cajas.

; Convierte el número de cajas a BCD Empaquetado. mov

b, #10

div

AB

; En A las decenas y en B las unidades.

acall

muestrad

; Envía a Lámpara las decenas

mov

A, B

acall

muestrau

reti

; Envía a Lámpara las unidades ; retorno de Subrutina de Interrupción.

; Inicializando el valor en las Lámparas de 7 Segmentos. inicio:

mov

A, #0

; Envía 0 a las Lámparas

acall

muestrad

; Envía a la Lámpara de las decenas

mov

A, #0

Microcontroladores. El 8051 de la INTEL. acall

muestrau

398

; Envía a la Lámpara de las unidades

; Programando al Controlador de Interrupciones del Microcontrolador. mov

IE,# 83H

;Habilita Interrupción INT0/

setb

IT0

; Interrupción por frente de caída

; Programando al Temporizador 0. mov

TMOD,# 06H

;Modo 2, dispar por software, contador eventos

mov

TL0,# 156

;Programa el contador con el numero inicial

mov

TH0,# 156

;Garantiza la Autorrecarga.

; Se prepara el contador por software de cajas llenas. mov

R3,#0

; Se inicia el conteo del Temporizador 0. setb

TR0

; Espera por una cualquiera de las dos posibles Interrupciones. sjmp

$

; Subrutina que nuestra en el Display las decenas. muestrad:

acall

convierte

mov

P0, A

; Escribe en la Lámpara destinada a las decenas.

ret ; Subrutina que nuestra en el Display las unidades. muestrau:

acall

convierte

mov

P2, A

; Escribe en la Lámpara destinada a las unidades.

ret ; Subrutina que convierte a código de Lámpara de 7 Segmentos. convierte:

mov

dptr, #tabla

movc A, @A+DPTR ret ; Tabla con los códigos de Lámparas de 7 Segmentos. tabla:

db

0c0h, 0f9h, 0a4h, 0b0h, 99h, 92h, 82h, 0f8h, 80h, 90h.

end Veamos un nuevo ejemplo en el que utilizaremos también la Interrupción como manera de atender el desbordamiento del contador del Temporizador 1 en este caso. Ejemplo 9.5.1. Hacer sonar una bocina con tres valores de frecuencia diferentes que permita diferenciar los sonidos emitidos por la misma en cada caso. La selección de la frecuencia con la que se desea hacer sonar la bocina se efectúa a través de tres Interruptores del tipo Simple Polo- Simple Tiro.

Microcontroladores. El 8051 de la INTEL.

399

Generar un Tren de Pulsos por uno cualquiera de los terminales de uno de los Puertos del microcontrolador pudiera resultar una tarea a ejecutar en una aplicación dada. Ejemplo de ello podría ser el control de la velocidad de giro de un Motor de Corriente Directa o el control del sonido de una bocina para indicar diferentes tipos de Alarmas. Esta última será la aplicación a resolver escogida para este Ejemplo. Un Tren de Pulsos esta caracterizado por dos parámetros, su frecuencia y su ciclo útil. El primero nos da una idea de la velocidad con que se repite la señal en el tiempo y esta estrechamente ligado con el Periodo de la señal, que no es más que el tiempo que toma la señal en ejecutar un ciclo completo antes de repetirse. Por su parte el ciclo útil no es más que el % del tiempo en que la señal toma el valor de ´1´ lógico con respecto al Periodo de la señal. El variar cualquiera de estos dos parámetros en el Tren de Pulsos generado provocará cambios en el sonido que saldrá de la bocina. El hardware propuesto es el que aparece en la Figura 9.5.2.

Figura 15.2.1. Si el Programa provoca una sucesión de ´1´ y ´0´ en el terminal P2.5 del microcontrolador a una velocidad dada, estarán ocurriendo consecutivos procesos sucesivos de estados de corriente y no

Microcontroladores. El 8051 de la INTEL.

400

corriente por el sounder. Si esto se repite a una frecuencia audible escucharemos el sonido de la bocina. Esta operación es la que debe hacer el Software en esta aplicación. Tres Interruptores, Simple Polo-Simple Tiro, conectados a P0.0, P0.1 y P0.2 a través de sus correspondientes pull-un resistivos permitirán al usuario escoger los tres valores de frecuencia para el Tren de Pulsos generado y con ello poder variar el sonido escuchado en la bocina. La pregunta a responder en este momento sería, ¿Cómo generar de forma precisa el tiempo en ´1´ y el tiempo en ´0´ que a la postre definirán la frecuencia de la señal? Por su puesto que la lógica del Programa será imponer un ´0´ en el terminal P2.5, esperar un tiempo que estará determinado por la frecuencia que queremos generar, una vez pasado el tiempo imponer un ´1´ en dicho terminal y esperar el mismo tiempo antes de imponer nuevamente el ´0´ y con ello comenzar a repetir el ciclo. Hacer transcurrir el tiempo deseado una vez que el terminal se ha puesto a ´0´ o a ´1´ lo podemos hacer en el Programa mediante la ejecución de una demora por software a partir de repetir la ejecución de una determinada instrucción que previamente conocemos su tiempo de ejecución, como lo hemos hecho hasta ahora. No obstante, los Temporizadores nos podrían ayudar en esta tarea sin la necesidad de tener ocupado al microcontrolador solo en esta tarea. De lo estudiado conocemos que una de las posibles maneras en que pueden operar los Temporizadores del 8051 es como Contador de Tiempo. En este modo de operar el contador del Temporizador efectuará un conteo en cada ciclo de máquina que ejecute el microcontrolador hasta desbordarse con lo que, de estar habilitado, solicitaría atención por Interrupción. Si conocemos el tiempo que demora un ciclo de maquina, definido por el Cristal de Cuarzo conectado al Oscilador Interno y si conocemos a cuantos conteos se desborda el contador, conoceremos cada que tiempo solicitara atención por Interrupción este. Esta podría ser nuestra base de tiempo para generar el Tren de Pulsos. Si lo que queremos es variar la frecuencia del Tren de Pulsos generado todo lo que tenemos que hacer es variar el número de conteo con el que el contador del Temporizador se desborda. Esto es lo que hace el fragmento de programa que presentamos a continuación como software para la solución del ejemplo.

Microcontroladores. El 8051 de la INTEL.

401

;**************************************************************************************************************** ; Este fragmento de programa permite generar un Tren de Pulsos a través del terminal P2.5. ; La frecuencia del Tren de Pulsos es seleccionada mediante un conjunto de tres Interruptores ; conectados a los terminales P0.0, P0.1 y P0.2. ; Inicio del Programa. org

0

; Se resguardan las localizaciones de Memoria destinadas para almacenar la Subrutina de atención ; a la Interrupción del Temporizador 0. sjmp

principal

; salto al inicio del programa

; Dirección de inicio de la Subrutina de atención a la interrupción del Temporizador 0. org

000Bh

; Subrutina de atención a la interrupción del Temporizador 0. mov

a, P0

; lee el estado de los Interruptores

anl

a, #00000111b

; limpia la lectura

cjne

a,#7, bocina_on

sjmp

bocina_off

; Este fragmento de programa complementa el valor en el terminal de salida P2.5. ; Programa al Temporizador 0 con el valor que imponen los Interruptores. bocina_on: lazo:

encontre:

mov

R2, #0

mov

R3, #3

rrc

A

jnc

encontre

inc

R2

djnz

R3, lazo

sjmp

bocina_off

mov

A, R2

rl

a

; multiplica por 2 el valor en Interruptores.

mov

dptr, #tabla

; declara puntero a la tabla de frecuencia.

movc a, @a+dptr

;extrae parte alta de valor de la Tabla

mov

TH0,a

;carga parte alta del valor en TH0

inc

a

;apunta al otro byte de valor

movc a, @a+dptr

;extrae parte baja de valor de la tabla

mov

TL0,a

;carga la parte baja de valor en TL0

cpl

P2.5

;complementa el bit de salida

setb

TR0

;habilita al Temporizador 0.

sjmp

salir

;salida

; Fragmento de programa a ejecutar en el caso de la combinación de los Interruptores que ; selecciona bocina no sonando.

Microcontroladores. El 8051 de la INTEL. bocina_off:

mov

TH0, #0FFh

mov

TL0, #0FBh

402

; Salida común de la Subrutina. salir:

reti

; En este fragmento de Programa se programa el Temporizador 0 y se habilitan los servicios de la ; Interrupción. principal:

clr

P2.5

mov

TMOD, #00000001b ; Temporizador 0 en el modo2

mov

TH0, #0FFh

mov

TL0, #0FEh

mov

IE, #10000010b ; habilita la interrupción del Temporizad 0.

setb

TR0

; se inicia el conteo del Temporizador 0.

sjmp

$

; lazo infinito esperando por la Interrupción del

; valor de desbordamiento

; Temporizador 0. ; Tabla con los valores a cargar en el Temporizador 0 para cada una de las posibles frecuencias a ; seleccionar. tabla:

db

0FCh, 17h

; 500 Hz

db

0F8h, 2Fh

; 250 Hz

db

0ECh, 77h

; 100 Hz

end El 8051 cuenta con un Puerto Serie Asincrónico empotrado muy útil para implementar la comunicación entre el sistema diseñado con el microcontrolador y otro cualquiera, como podría ser una Microcomputadora, ubicada a cierta distancia del mismo. Con este Puerto podemos tener en nuestro sistema a Microcontrolador todas las ventajas propias de la transmisión serie, muy utilizada en los últimos tiempos. Al estudio del Puerto Serie del Microcontrolador 8051 esta destinado el próximo Tema de este material.

Microcontroladores. El 8051 de la INTEL.

403

Tema 14. El Puerto Serie Asincrónico empotrado en el Microcontrolador 8051. Poder establecer un canal de comunicación serie asincrónico entre dos dispositivos se convierte en una necesidad en muchas aplicaciones de instrumentación y control automático en la actualidad y constituye la forma más empleada para establecer la comunicación entre los equipos independientes construidos en base a microcontroladores y una microcomputadora ya sea personal o industrial. Esta manera de transmitir los datos serie impone algunas especificidades que de no cumplirse ponen en peligro la comunicación entre ambos dispositivos. Aspectos tales como la frecuencia a que se transmiten los datos, el formato en que se transmiten los datos y los niveles de voltaje a que se transmiten los datos constituyen algunas de estas especificidades. El poder contar, integrado en el microcontrolador, un conjunto de elementos reunidos en un Puerto Serie Asincrónico y Programable, facilitan el trabajo del Programador en el sentido de poder establecer de una manera relativamente sencilla las especificidades definidas anteriormente y constituye un gran apoyo y es un punto más que se anota este dispositivo a la hora de su selección para implementar sistemas dentro del campo de la instrumentación y el control automático. El 8051 cuenta con estos elementos, agrupados en su Puerto Serie Asincrónico Interno de 8 bits y el estudio de este dispositivo será el objetivo fundamental de este Tema. 10.1 El Puerto Serie Asincrónico del 8051. Como ya se planteo el 8051 cuenta con un Puerto Serie Asincrónico el cual puede realizar de forma simultánea las operaciones de recepción y transmisión de un dato serie. Para ello cuenta con dos señales externas, RXD y TXD, a través de las cuales se establece la comunicación con otro dispositivo que utilice la misma forma de recepción y transmisión de los datos. Estas señales comparten el mismo terminal con las señales P3.0 y P3.1 del Puerto 3 respectivamente, ver Figura 10.1.1.

Microcontroladores. El 8051 de la INTEL.

404

Figura 10.1.1 Terminales TxD y RxD del Puerto Serie del 8051. Por el terminal RXD llegan al Puerto Serie del 8051 los datos series transmitidos por otro dispositivo y por el terminal TXD este envía los datos serie hacia otro dispositivo. Esta operación de recibir un dato serie y transmitir un dato serie puede ocurrir de forma simultánea sin acarrear error ni en la recepción ni en la transmisión. A esta capacidad de poder recibir y transmitir simultáneamente se la conoce con el nombre de comunicación full-duplex y es una de las características del Puerto Serie Asincrónico del 8051. El contar con dos terminales independientes para la transmisión y la recepción constituye una condición necesaria para que el Puerto Serie pueda soportar la comunicación full-duplex, pero no suficiente. Se hace necesario también, que internamente el Puerto Serie cuente con dos circuitos almacenadores que se encarguen, uno para el almacenamiento temporal de los datos que llegan hasta que sean leídos por el programa, al que llamaremos Almacenador del Receptor, y el otro para almacenar los datos que el 8051 desea transmitir hasta que el Puerto Serie concluya con su transmisión, al que llamaremos Almacenador del Transmisor, ver Figura 10.1.2.

Microcontroladores. El 8051 de la INTEL.

405

Figura 10.1.2 Almacenador del receptor y del Transmisor del Puerto Serie del 8051. Estos dos almacenadores aunque físicamente independientes, se conocen con el mismo nombre y ocupan la misma dirección dentro de la zona de Registros de Funciones Especiales del microcontrolador. Por lo que a la hora de trabajar con ellos en los programas nos referimos a estos mediante el nombre de SBUF. La Pregunta a contestar en este momento sería, ¿Cómo el 8051 determina si la instrucción a ejecutar se refiere al Almacenador

del

Transmisor o al Almacenador del Receptor? El microcontrolador será capaz de discernir a cual de los dos se esta refiriendo la instrucción en dependencia de que esta sea de lectura o de escritura, o sea, en dependencia de si SBUF es fuente o destino en la instrucción de transferencia. Si la instrucción a ejecutar es de lectura y por lo tanto SBUF es fuente, el microcontrolador determina que se están refiriendo al Almacenador del Receptor y si por el contrario la instrucción a ejecutar es de escritura y por lo tanto SBUF es destino, el microcontrolador determina que se están refiriendo al Almacenador del Transmisor. No basta con enviar el dato a transmitir hacia el Puerto Serie del 8051 para poder establecer una comunicación entre dos dispositivos, aspectos tales como, el formato y la velocidad en que deben ser enviados los datos se convierten en muy importantes y deben ser definidos antes de comenzar una comunicación. El primero esta relacionado con el Modo en que se programa el Puerto Serie para establecer la comunicación y el segundo con la frecuencia de baudios a que se programa dicho puerto para la transmisión/recepción. Por su puesto para que dos dispositivos se puedan

Microcontroladores. El 8051 de la INTEL.

406

comunicar correctamente ambos deben estar programados en el mismo Modo de Trabajo y con la misma Frecuencia de Baudios. 10.2 Los Modos de Operación del Puerto Serie del 8051. El Puerto Serie del 8051 es una Unidad de Transmisión y Recepción Serie Asincrónica y Full Duplex (UART). La comunicación serie asincrónica se ha impuesto de forma significativa en los últimos años como forma de transmitir los datos serie entre un dispositivo autónomo, por lo general diseñado en base a un microcontrolador, y la microcomputadora. En esto quizás influya que las computadoras personales hayan escogido esta forma de transmitir los datos para implementar su canal de comunicación serie así como la sencillez y robustez de esta forma de transmisión. El Puerto Serie puede operar en cuatro Modos diferentes, los que son seleccionados utilizando los bits 6 y 7 del Registro SCON, ver Figura 10.2.1. b7

b6

b5

b4

b3

b2

b1

b0

SM0

SM1

SM2

REN

TB8

RB8

TI

RI

bit

Nombre

Comentario

b0

RI

b1

TI

b2

RB8

b3

TB8

b4

REN

b5

SM2

b6 y b7

SM0-SM1

Bandera de Interrupción de la Recepción. Se activa por hardware al finalizar la recepción del octavo bit en el Modo 0 o hacia la mitad del intervalo de tiempo del bit de stop en los otros modos. Debe ser desactivada por software. Bandera de Interrupción en la Transmisión. Se activa por hardware al final de la transmisión del octavo bit en el Modo 0 o al comienzo del bit de stop en los otros modos. Debe ser desactivada por software. En los Modos 2 y 3 es el noveno bit que se recibe. En el Modo 1, si SM2 = ’0’, es el bit de stop. En el Modo 0 no se utiliza. Se corresponde con el noveno bit a transmitir en los Modos 2 y 3. Es programable por el usuario. Habitualmente es el bit de parada. Si REN = ’1’ esta habilitada la recepción. Si REN = ‘0’ no esta habilitada. En el Modo 2 y 3, si SM2 = ’1’ la Bandera de Interrupción de la recepción no se activará si el noveno bit de datos es igual a ‘’0’. En el Modo 1, si SM2 = ’1’ la Bandera de Interrupción de la recepción no se activará si el bit de stop no se ha recibido. En el Modo 0, SM2 debe estar a ‘0’ Especifican el Modo de Trabajo al que opera el Puerto Serie, respondiendo a la siguiente Tabla SM0 SM1 MODO DESCRIPCION VELOCIDAD 0

0

0

Desplaza 8 bits

Reloj / 12

0

1

1

8 bit UART

Variable

1

0

2

9 bit UART

Reloj / 64 Reloj / 32

1

1

3

9 bit UART

Figura 10.2.1 Registro SCON.

Variable

Microcontroladores. El 8051 de la INTEL.

407

El Registro SCON, Registro de Control del Puerto Serie, es uno de los Registros de Funciones Especiales del Microcontrolador y el mismo puede ser direccionado bit a bit. Expliquemos el significado de los bits de este registro a partir de la explicación detallada de los diferentes Modos de Trabajo del Puerto Serie. El Modo 0. En este Modo de Trabajo los datos en serie que se transmiten / reciben salen / entran por el terminal RXD, mientras que por el terminal TXD sale un tren de pulsos con ciclo útil del 50% el que constituye la señal de reloj que sincroniza la salida / entrada de los bits que constituyen el dato y de hecho define la velocidad de transmisión / recepción del dato serie. El dato a transmitir / recibir es de 8 bits, siendo el primero en salir/ entrar el bit menos significativo y la velocidad de transmisión / recepción expresada en bits/seg., está dada por la relación 1/12 la frecuencia del Oscilador Interno del microcontrolador y por lo tanto esta estrechamente ligada con la frecuencia del Cristal de Cuarzo conectado a este entre los terminales XTAL1 y XTAL2. Una pregunta que puede resultar interesante al lector darle respuesta en este momento sería, ¿En este modo se podrá establecer la comunicación full-duplex? La comunicación full-duplex no puede ser establecida en este Modo de Trabajo, ya que el 8051 emplea una misma línea para transmitir y para recibir los datos, RxD, por lo que el Programador tendrá que decidir de que forma empleará al Puerto Serie, como de de salida para solo trasmitir datos o como de entrada para solo recibir datos. Expliquemos de una forma más detallada el proceso de transmisión / recepción en este Modo de Trabajo. Cuando el Puerto Serie del 8051 está como salida, los datos que fueron enviados al Almacenador del Transmisor del Puerto Serie mediante programa, salen del microcontrolador a través del terminal RXD, mientras que por TXD sale la señal de reloj, un tren de pulsos a la frecuencia de 1/12 la frecuencia del Oscilador Interno. En el caso contrario, como entrada, por el terminal RXD le llegarán al 8051 los datos serie transmitido por un circuito externo, el que sincronizará los bits a enviar mediante la señal de reloj que se transmite el microcontrolador por su terminal TXD. Estos bits son almacenados en el Almacenador de Entrada del 8051. Esto que aparentemente constituye una limitación del Puerto Serie, no resulta así, ya que este modo fue concebido para poder agregar más terminales de entrada o salida a los ya brindados por

Microcontroladores. El 8051 de la INTEL.

408

los Puertos del 8051. En la Figura 10.2.2 se puede ver un ejemplo donde se le agrega un Puerto de Salida de 8 bits al microcontrolador utilizando este Modo de Operación.

Figura 10.2.2 Agregando un Puerto de salida de 8 bits al 8051. La pregunta a contestar en este momento podría ser, ¿Como es inicializada la transmisión de un dato hacia el Puerto de Salida en este Modo de Trabajo? La transmisión de un dato serie comienza con la escritura de dicho dato en el Almacenador del Transmisor mediante una instrucción de escritura del 8051. Una vez concluida la escritura del dato a transmitir en el almacenador, comienza su operación como registro desplazamiento, desplazando el dato, enviando primero al bit menos significativo y terminando la operación con el envío del bit más significativo. La frecuencia a la que ocurre todo este proceso es, como ya se ha explicado, de 1/12 la frecuencia de operación del microcontrolador, la cual gobierna la operación del almacenador interno y al mismo tiempo es enviada al exterior a través del terminal TxD. Una vez que el bit más significativo del dato a transmitir serie es transmitido, se activa la Bandera de Interrupción del transmisor del Puerto Serie TI, bit 1 del Registro SCON, indicándole al microcontrolador que la transmisión ha terminado, que el Almacenador del Transmisor esta vacío y por tanto todo se encuentra listo para la transmisión de un nuevo dato. Veamos un ejemplo donde se muestre en que caso podría ser útil este modo de operación.

Microcontroladores. El 8051 de la INTEL.

409

Ejemplo 10.2.1. En un diseño dado se necesitan emplear las entradas T0 y T1 del microcontrolador como entradas de conteo de los respectivos Temporizadores, así como, agregar Memoria de Datos externa, utilizar las dos entradas de interrupción externas INT0 e INT1 y 16 líneas de salida digital. Comparando las necesidades del circuito a diseñar y los recursos que nos brinda el 8051, llegamos a las siguientes conclusiones: 9

Los Puertos 0 y 2 quedan destinados como buses de datos y direcciones para conectar la Memoria de Datos externa.

9

Del Puerto 3 solo quedan libres dos bits P3.0 y P3.1 ya que el resto son empleados por los Temporizadores, la interrupción y la Memoria de Datos externa.

9

Solo quedan libres para ser utilizados como bits de salida los 8 bits del Puerto 1.

Sin embargo la solución nos impone el disponer de 16 bits para salida digital. La pregunta a responder sería, ¿Como resolver esto? Una solución, que siempre es posible, es agregar externamente un circuito integrado que haga la función de Puerto de Salida, como podría ser uno de los circuitos almacenadores de la serie 74, por ejemplo el 74LS373. No obstante, una solución más económica y fiable podría ser el conectar al Puerto Serie del microcontrolador un registro desplazamiento de 8 bits de la misma compañía, que trabaje como podría ser el 74LS164, ver Figura 10.2.2.

Figura 10.2.2. Agregando 16 líneas de salida digital al 8051.

Microcontroladores. El 8051 de la INTEL.

410

Este Modo de Trabajo no se corresponde con los estándares habituales de la comunicación serie asincrónica, pero puede resultar muy útil en determinadas aplicaciones. Los tres Modos restantes si están acordes con esta forma de comunicación y se corresponden con los estándares de la comunicación asincrónica. Le proponemos que antes de entrar al estudio de los otros Modos de Trabajo, veamos algunos aspectos de interés de la Comunicación Serie Asincrónica. La Comunicación Serie Asincrónica. Un primer aspecto a destacar en la Comunicación Serie Asincrónica, es la no correspondencia entre los bits transmitidos y los bit de información transmitido, en otras palabras no todo lo que se transmite es el dato deseado, sino que dicho dato va acompañado de otros bits que son utilizados para el sincronismo de los dos Puertos que se están comunicando. Un ejemplo típico de lo anterior se ve reflejado en el Figura 10.3.1.

Figura 10.3.1 Formato típico de la transmisión de datos serie. Al dato de 8 bits se le han agregados dos bits, uno al inicio y el otro al final, que no son datos en sí, pero que el Puerto Serie los agrega para que el Receptor detecte cuando comienza a llegarle el dato, BI o bit de inicio, y el otro para que el Receptor detecte cuando se completa la llegada del dato, BS o bit de “stop” o parada. Esto suplanta la necesidad de la llegada al Receptor de una señal de reloj para sincronizar esta operación y de un formato especial de los datos para que se detecte inicio y fin del dato como ocurre en la Comunicación Sincrónica. Por lo que se puede decir que en la transmisión serie asincrónica la señal de sincronización de los datos, papel que hace la señal de reloj en la transmisión serie sincrónica, viene por la misma línea que los datos serie. Esto además trae consigo otro aspecto importante, como todo lo que se transmite no es dato, sería un error cuando se habla de frecuencia de transmisión en bits/segundos igualarla con la cantidad de bits de datos transmitido. Es por esta razón que en la Comunicación Serie Asincrónica se acostumbra a hablar de Frecuencia de Baudios cuando nos referimos a la frecuencia de transmisión, indicando que no todo lo que se transmite es dato. Los valores de Frecuencia de Baudios típicos en la transmisión serie asincrónica en los microcontroladores están en el rango de

Microcontroladores. El 8051 de la INTEL.

411

los 1200 baudios hasta los 18 200 Baudios, los que coinciden con las frecuencias típicas de transmisión del canal serie RS232 de las PC. Otra variable que caracteriza este tipo de transmisión es el Tiempo de Bits, el que no es más que el inverso de la Frecuencia de Baudios. Por lo general durante el Tiempo de Bit la señal transmitida de forma serie no cambia de valor lógico, indicando de esta forma si el bit transmitido es ´0´ o si el bit transmitido es ´1´. Los Bits de Inicio y de Parada no son los únicos bits que se le pueden agregar a la palabra de datos transmitida. En muchas aplicaciones el agregar un noveno bit al dato transmitido permite efectuar correcciones sencillas de errores. Por ejemplo, si este bit que se agrega responde de alguna manera a la paridad de los ´1´ del dato transmitido esto puede ser aprovechado por el Receptor para verificar que en la transmisión no han ocurrido errores simples. Tanto los bits de inicio como de parada, así como los bits de datos y de paridad tienen el mismo tiempo de duración, el Tiempo de Bit, y el mismo formato de transmisión, solo diferenciándose por la posición que ocupan dentro de una trama de datos transmitido. La cantidad de bits destinados para la transmisión del dato, sin contar los Bits de Inicio, Parada o Paridad puede ser variable, permitiendo esto aprovechar de forma más eficiente el tiempo de transmisión en determinadas aplicaciones. Pasemos a estudiar los Modos de Trabajo del Puerto Serie en que se efectúa la transmisión serie de forma asincrónica de los datos. El Modo 1. Para la comunicación en este Modo de Trabajo se utilizan 10 bits que son transmitidos a través de TxD o recibidos a través de RxD, como se muestra en la Figura 10.4.1. Tómese en cuenta que en los Modos que vamos a estudiar a partir de ahora la transmisión es Full-Duplex.

Figura 10.4.1 Paquete de dato a transmitir o recibir en el Modo 1.

Microcontroladores. El 8051 de la INTEL.

412

El primer bit que se transmite es el correspondiente al bit de inicio, BI, seguido de los 8 bits de datos comenzando por el bit menos significativo, bms, y terminando con el Bit Más significativo, BMs, concluyendo la transmisión con el envió del bit de parada, BS. Dar respuesta a dos preguntas en este momento podría resultar de interés, ¿Como el Puerto Serie del 8051 inicia una transmisión? ¿Como el Puerto serie del 8051 detecta la llegada un dato? La transmisión se inicia con cualquier instrucción que utilice SBUF como registro destino. La escritura en SBUF también carga un ‘1’ en la posición del noveno bit del registro desplazamiento del transmisor, el que a la postre será el BS y alerta a la unidad de control del microcontrolador que un dato a transmitir ha llegado. La transmisión comienza realmente en la fase S1P1 del siguiente ciclo de máquina después del desbordamiento del contador del Temporizador 1 dividido por 16, el que será utilizado para brindar la Frecuencia de Baudios a la que se transmitirá el dato. La recepción es iniciada al detectar el Puerto Serie la transición de ´1´ a ´0´, flanco descendente, de la señal aplicada en su terminal de entrada RxD y si el bit 4 del Registro SCON, REN, está a ‘1’ con lo que indica recepción habilitada. Por este motivo este terminal es muestreado a razón de 16 veces la frecuencia del Oscilador Interno, independientemente de la Frecuencia de Baudios a la que se este estableciendo la comunicación. O sea, la entrada RxD está recibiendo un “1”, enviado por el Puerto Serie que transmite, durante todo el tiempo en que no se este transmitiendo datos, a esta información se conoce con el nombre de bit de marca. Esta situación cambia con el envío del BI por parte de transmisor cuando comience la transmisión de un dato con lo que alerta al Receptor del Puerto Serie para que va a recibir un dato. En ambos casos tanto en la transmisión como en la recepción, el Puerto Serie del 8051 indica al microcontrolador cuando la operación ha concluido. En la transmisión, una vez que el Almacenador del Transmisor queda vacío, se activa la bandera de Interrupción TI, indicando que se encuentra listo para recibir un nuevo dato a transmitir. En la recepción, una vez recibido el BS el Puerto Serie activa la bandera de Interrupción RI, indicando que un dato está listo para ser leído. Resumiendo: 9

La transmisión comienza escribiendo el dato a transmitir en SBUF y termina con la activación de la Bandera de Interrupción TI.

Microcontroladores. El 8051 de la INTEL. 9

413

La recepción comienza al detectar un flanco descendente en el terminal RxD siempre y cuando REN se encuentre a ‘1’, terminando con la activación de la Bandera de Interrupción R I.

Una duda que los lectores pueden tener en este momento podría ser, ¿Como seleccionar la velocidad de transmisión y de recepción, o sea la Frecuencia de Baudios, en este Modo? La Frecuencia de Baudios en este Modo de Trabajo es entregada al Puerto Serie por el Temporizador 1 seleccionado para trabajar como Contador de Tiempo en el Modo 2 con Autorrecarga. Como recordaremos del estudio de los Modos de Trabajo de los Temporizadores, cuando operan en este modo, cuenta los ciclos de máquina y en el caso particular del Modo 2 trabaja en el modo de Autorrecarga como Contador de 8 bits cargándose en TH1 el valor en que deseamos que comience el conteo cada vez que se desborde. La pregunta a dar respuesta en este momento sería, ¿Qué valor cargar en TH1 para lograr una Frecuencia de Baudios dada? Cuando se va a establecer una comunicación serie se conoce por parte del programador la velocidad a la cual se desea establecer dicha comunicación. Esta selección dependerá de la aplicación y de las limitaciones que nos imponga el medio físico que soportará dicha comunicación. Por lo tanto partiremos de que en su aplicación ya usted conoce la Frecuencia de Baudios deseada y por lo tanto esto será un dato conocido, la incógnita por lo tanto nos queda en el valor a cargar en TH1. En la ecuación siguiente se relaciona la Frecuencia de Baudios con el valor a cargar en TH1 en este Modo de Trabajo.

2 SMOD FrecuenciaOscilador FrecuenciaBaudios = 32 12(256 − TH 1) La Frecuencia del Oscilador debe estar expresada en Kilohertz, para que en la ecuación anterior la Frecuencia de Baudios se exprese en Kilobaudios. La pregunta en este momento sería, ¿Quien es SMOD?

Microcontroladores. El 8051 de la INTEL.

414

SMOD es el bit 7 del Registro PCON, el cual permite duplicar la Frecuencia de Baudios generada por el Temporizador 1 para un mismo valor almacenado en TH1. El Registro PCON es el Registro de Control del Consumo ya estudiado anteriormente. Por ejemplo si el 8051 está trabajando con un Cristal de Cuarzo de 11 059 Kilohertz y deseamos una Frecuencia de Baudios de 9.6 Kilobaudios, lo lograríamos cargando en SMOD un ‘0’ y en TH1 el valor de FD H. Con estos mismos valores de Frecuencia del Oscilador y de valor en TH1, si el valor cargado en SMOD es ‘1’ la Frecuencia de Baudios sería de 19,2 Kilobaudios. A continuación en la tabla 10.4.1 se recogen los valores a cargar en TH1 para valores significativos de Frecuencia de Baudios, teniendo al microcontrolador trabajando con un Cristal de Cuarzo de 12 Mhz. Frecuencia en Baudios

SMOD

TH1

19 200

0

FEh

1

FDh

0

FDh

1

F9h

0

F9h

1

F3h

0

F3h

1

E6h

0

E6h

1

CCh

9 600 4 800 2 400 1 200

Tabla 10.4.1 Valores a cargar en TH1 para valores de frecuencia en baudios típicas. Veamos un ejemplo donde comunicamos dos 8051 a través de sus respectivos Puertos Serie utilizando el Modo 1 como modo de trabajo de dichos puertos. Ejemplo 10.4.1 Supongamos que en una aplicación dada contamos con un conjunto de 8 Interruptores Simple Polo-Simple Tiro ubicados a cierta distancia, unos 5 metros, de un conjunto de 8 Diodos Emisores de Luz (LEDs) y deseamos que el encendido de los LEDs responda al estado en que se encuentran los Interruptores. De forma tal que si el Interruptor al que llamaremos I0 se encuentra cerrado, el LED que llamaremos L0 se debe encender y en el caso contrario debe permanecer apagado. Esto se debe cumplir de igual forma para el resto de los Interruptores con el resto de sus correspondientes LEDs. Conectar los Interruptores a los terminales de uno de los puertos del microcontrolador y los LEDs a otro tiene el inconveniente de la distancia existente entre uno y otros en esta aplicación. Una

Microcontroladores. El 8051 de la INTEL.

415

solución factible en este caso podría ser tener los Interruptores conectados a los terminales de un puerto de un microcontrolador, al que llamaremos MI y los LEDs conectados a los terminales de un puerto de otro microcontrolador al que llamaremos ML. La pregunta a responder en este momento sería, ¿Cómo efectuar la comunicación entre ambos microcontroladores? Por su puesto que tiene que existir una comunicación entre ambos microcontroladores de forma tal que el microcontrolador ML conozca cuales son los Interruptores, de los conectados al microcontrolador MI, que están cerrados y cuales abiertos para poder tomar la decisión de cuales LEDs enciende y cuales LEDs apaga. Esta comunicación la podríamos establecer a través de los Puertos Series Asincrónicos de ambos microcontroladores. Efectivamente la distancia entre Interruptores y LEDs de 5 metros para la aplicación, nos impondría, si no fuéramos a utilizar la comunicación serie entre ambos microcontroladores, la necesidad de conectar un circuito buffer entre cada una de las líneas del puerto del microcontrolador escogido para conectar los LEDs y sus correspondientes LEDs, de forma tal que la señal digital llegue a estos con sus parámetros de voltaje a pesar de los ruidos eléctricos que se pueden inducir por la distancia. Estamos considerando que los Interruptores están conectados en la misma tarjeta de circuito impreso que el microcontrolador por lo que la distancia entre ellos es muy corta, unos centímetros. Algo parecido sucede si nos decidimos por los dos microcontroladores comunicados a través de su Puerto Serie, con la única diferencia de que la señal digital a proteger en este caso de los ruidos eléctricos seria una sola, la que va del terminal TxD del microcontrolador MI hacia el terminal RxD del microcontrolador ML, lo que indiscutiblemente constituye mejor del punto de vista de la fiabilidad del sistema montado. En la Figura 10.4.2 se muestra el hardware propuesto para la solución de la aplicación.

Microcontroladores. El 8051 de la INTEL.

416

Figura 10.4.2. Propuesta de hardware para la aplicación del ejemplo 10.4. De la figura podemos observar que al terminal TxD del microcontrolador MI se ha conectado un Amplificador Operacional del tipo LM324 trabajando como comparador no inversor siendo su objetivo el de aumentar la diferencia de voltaje entre los niveles de ´0´ y de ´1´ generados por el microcontrolador por dicho terminal. Veamos como logra esto. La alimentación del operacional es de +10 volts y de -10 volts con lo que logramos que los niveles de ‘1’ y de ‘0’ a su salida sean de aproximadamente +10 volts y -10 volts respectivamente. El estado de ‘1’ estará a la salida del operacional cuando el voltaje aplicado en V+ sea mayor que el voltaje aplicado en V-. Por su parte el estado de ‘0’ estará a la salida en el caso contrario. ¿Qué se logra con esto? Con esto se logra que aumente, de forma significativa, la diferencia de voltaje entre ambos niveles lógicos. ¿Qué buscamos con esto?

Microcontroladores. El 8051 de la INTEL.

417

Ahora cuando el microcontrolador MI transmita por su terminal TxD un ‘0’ el voltaje de salida del operacional será de aproximadamente -10 volts, mientras que cuando transmita un ´1´, el voltaje de salida del operacional será de aproximadamente +10 volts, con los que se logra que la diferencia de voltaje entre el ‘0’ transmitido y el ‘1’ transmitido sea de aproximadamente 20 volts. Esto garantiza un aumento en la fiabilidad de la señal transmitida, al soportar la misma mayores niveles de ruido durante su transporte de la fuente al destino, aspecto muy importante en este caso dado que la distancia entre ambos microcontroladores es relativamente larga, 5 metros. ¿Que hacer en el receptor? Por su parte, en el receptor tiene que haber un circuito que haga la operación inversa, o sea, que convierta los niveles de voltaje de +10 volts y -10 volts a los niveles de voltaje típicos de ‘0’ y de ‘1’ de las entradas del 8051 antes de entregárselo a este por su terminal RxD. Para ello hemos utilizado nuevamente un Amplificador Operacional trabajando como comparador, pero ahora su alimentación es de +5 volts y tierra. Un divisor de voltaje colocado a la entrada garantiza que el voltaje de entrada nunca sobrepase los +5 volts, estando entre los voltajes de -5 volts y +5 volts. Ahora cuando al operacional del receptor llegue un voltaje de aproximadamente +5 volts, lo que ocurrirá cuando el nivel de voltaje a la salida del operacional que transmite sea de aproximadamente +10 volts y por ende el microcontrolador esta transmitiendo un ‘1’ por su terminal TxD, entrega a su salida +5 volts, el que se corresponderá con un ‘1’ lógico a la entrada del terminal RxD del microcontrolador del receptor, mientras que cuando le llega un voltaje de aproximadamente -5 volts, el que se corresponde con el caso contrario, entrega

a su salida

aproximadamente 0 volts, el que se corresponderá con un ‘0’ lógico en la entrada RxD del microcontrolador del receptor. ¿Para que esta el circuito 74LS125? El buffer no inversor con posibilidad de ponerse en tercer estado 74LS125 ubicado entre la salida del Amplificador Operacional en el receptor y la entrada RxD en el microcontrolador ML, garantiza que el operacional no sea cargado por la resistencia de pull-up de salida que tienen los terminales del Puerto 3, con lo que se garantizan los niveles de voltaje a la entrada RxD del microcontrolador del receptor.

Microcontroladores. El 8051 de la INTEL.

418

Observe que cuando el microcontrolador MI transmita un ´0´ por su terminal TxD, al terminal RxD del microcontrolador ML llega un ´0´, mientras que cuando transmita un ´1´ llega un ´1´, con lo que garantizamos la integridad de la información transmitida. Este es un circuito que lo podemos utilizar también para efectuar la conexión del Microcontrolador con una Microcomputadora Personal a través de los terminales TxD, RxD y GND de la norma RS232 de la misma, ver Figura 10.4.3.

Figura 10.4.3 Microcontrolador 8051 conectado al Puerto RS232 de una Microcomputadora a través de su Puerto Serie. Retomando la aplicación que nos hemos propuesto resolver, necesitaremos de dos Programas, uno que sea el que dirija la operación del microcontrolador MI y el otro el que dirija la operación del microcontrolador ML. Si ya contamos que el hardware, enfrentemos la tarea de desarrollar estos dos Programas. Comencemos por el Programa que dirigirá las operaciones del microcontrolador MI. Este programa además de garantizar la transmisión serie del dato deseado, le daremos la misión de detectar cuando ha cambiado el estado de al menos uno de los Interruptores, ya que en este momento es que tendrá que efectuar la transmisión, para que los LEDs respondan a este nuevo estado de los Interruptores. Para ello el Programa tendrá que estar muestreando cada cierto tiempo el estado de los Interruptores, compararlo con el último estado para poder decidir si este se mantiene o si existe uno nuevo y por lo tanto se hace necesaria su transmisión.

Microcontroladores. El 8051 de la INTEL.

419

En este Programa utilizaremos al Temporizador 0 para que nos indique cuando hay que efectuar un muestreo del estado de los Interruptores y el Temporizador 1 lo emplearemos para que entregue la Frecuencia de Baudios al transmisor del Puerto Serie. Al Puerto Serie lo pondremos a trabajar en el Modo 1 con frecuencia de transmisión / recepción de 1200 Baudios. ; Este es el programa que debe ejecutar el microcontrolador MI. ; Inicio del Programa. org

0

; Resguardando el espacio en la memoria de Programa destinado para almacenar a las Subrutinas ; de atención a la Interrupción del Temporizador 0 y del Puerto Serie. sjmp

inicio

; Inicio de la Subrutina de atención a la Interrupción del Temporizador 0. org

000Bh

; Subrutina de atención a la Interrupción del Temporizador 0. djnz

R2, salir

djnz

R1, salir1

; El estado de los Interruptores se leen cada 1 segundo. mov

A, P1

cjne

A, 10h, transmite

salir2:

mov

R1, #100

salir1:

mov

R2, #100

salir:

reti

; Fragmento de Programa que transmite un byte por el Puerto Serie. transmite:

mov

10h, A

jb

TI, $

mov

SBUF, A

sjmp

salir2

; Inicio de la Subrutina de atención a la Interrupción del Puerto Serie por fin de transmisión. org

0023h

clr

TI

reti ; Inicio del programa Principal. ; Declarando la condición inicial de todos los LEDs apagados. inicio:

mov

10h, #0FFh

; Programando la Interrupción. ; Habilitar la Interrupción del Temporizador 0 y del Puerto Serie. mov

IE, #10010010b

; Programando al Temporizador 0.

Microcontroladores. El 8051 de la INTEL.

420

; Modo 2. Contador de Tiempo. Habilitar el conteo por Software. Desbordarse a los 100 ; microsegundos. ; Programando al Temporizador 1 para que entregue al Puerto Serie la señal que garantiza una ; frecuencia de baudios de 1200. ; Cristal de Cuarzo del 12 Mhz. mov

TMOD, #00100010b

mov

TL0, #156

mov

TH0, #156

mov

TL1, #0E6h

mov

TH1, #0E6h

mov

PCON, #0

; Programando al Puerto Serie en el Modo 1. mov

SCON, #01000000b

; Habilitando el conteo del Temporizador 0 y del Temporizador 1. setb

TR0

setb

TR1

; Declara los contadores de tiempo empleados por la Subrutina de atención a la Interrupción del ; Temporizador 0 que garantizan el muestreo del estado de los Interruptores cada 1 segundo. mov

R1, #100

mov

R2, #100

; Espera por Interrupción del Temporizador 0 o del Puerto Serie. sjmp

$

; Fin de Compilación del Programa. end Por su parte el Programa que dirigirá las operaciones del microcontrolador ML, tendrá como operación central la de atender la llegada a su Puerto Serie, del dato enviado por el microcontrolador MI. Para ello tendrá que estar operando en el mismo Modo de Trabajo y a la misma Frecuencia de Baudios. Esto debe ser garantizado durante la programación del Puerto Serie. Si observamos la Figura 10.4.2 veremos que los LEDs están conectados al Puerto 1 del microcontrolador ML y se encienden cuando se impone un ´1´ en el terminal donde este conectado, sin embargo, del microcontrolador MI vendrá la orden de encender el LED con un ´0´ y no con un ´1´, por lo que el Programa tendrá que complementar el byte que le llega antes de enviarlo a dicho Puerto. ; Este es el programa a ejecutar el microcontrolador ML. org

0

Microcontroladores. El 8051 de la INTEL. sjmp

inicio

; Inicio de la Subrutina de atención a la Interrupción del Puerto Serie. org

0023h

; Subrutina de atención a la Interrupción del Puerto Serie. ; Deshabilitar la Recepción del Puerto Serie. clr

REN

; Encender los LEDs según el dato enviado. mov

A, SBUF

cpl

A

mov

P1, A

; Limpiar la Bandera de Interrupción del Receptor del Puerto Serie. clr

RI

; Habilitar el Receptor del Puerto Serie. setb

REN

reti ; Inicio del Programa Principal. ; Apagando todos los LEDs. inicio:

mov

P1, #0

; Programando al Puerto Serie. ; Modo 1. Frecuencia de Baudios de 1200. 12 Mhz la Frecuencia del Oscilador. mov

SCON,#01000000b

; Programando al Temporizador 1 para que entregue la señal que garantiza la recepción ; a 1200 baudios. mov

TMOD, #00100000b

mov

TL1, #0E6h

mov

TH1, #0E6h

mov

PCON, #0

setb

TR1

; Habilitar la Interrupción del Puerto Serie. mov

IE, #10010000b

; Habilitar la Recepción del Puerto Serie. setb

REN

; Esperar por la Interrupción. sjmp

$

; Fin de la Compilación del Programa. end

421

Microcontroladores. El 8051 de la INTEL.

422

En la aplicación anterior la comunicación entre los dos microcontroladores ocurre en un solo sentido, del microcontrolador que hemos llamado MI hacia el microcontrolador que hemos llamado ML, pero que cambios habría que hacer tanto del punto de vista del hardware como del software si la comunicación entre ambos microcontroladores fuera en los dos sentidos. Analicemos esto a la luz del siguiente ejemplo. Ejemplo 10.4.2. El problema a resolver es el mismo que el del ejemplo 10.4.1 con la diferencia de que en este caso, el microcontrolador al que están conectados los LEDs es el que solicita cada cierto tiempo, 1 segundo, al microcontrolador al que están conectados los Interruptores que le actualice el estado de los mismos. Antes de enfrentar la solución del problema tratemos de establecer un Diagrama de Flujo de cómo debe funcionar el sistema. 1er Paso. El microcontrolador al que están conectados los LEDs, ML, apaga todos los LEDs y hecha a andar el reloj que le indicara cuando transcurra 1 segundo, esta última operación se va a mantener de forma cíclica garantizándose que ML sea interrumpido cada vez que transcurra este tiempo. Por su parte el microcontrolador al que están conectados los Interruptores, MI, queda a la espera de recibir la orden de enviar por su Puerto Serie el estado de los Interruptores. 2do. Paso. Una vez transcurrido 1 segundo, el microcontrolador ML es interrumpido, indicándole que debe enviar por su Puerto Serie la orden al microcontrolador MI de que le actualice por esta misma vía el estado de los Interruptores. 3er Paso. El microcontrolador MI recibe por su Puerto Serie la orden de actualizar el estado de los Interruptores, los lee y los envía hacia el microcontrolador ML por esta misma vía. 4to Paso. El microcontrolador ML recibe por su Puerto Serie la información actualizada del estado en que se encuentran los Interruptores procediendo a actualizar el estado en que se encuentran los LEDs. 5to Paso. El proceso se repite a partir del 2do Paso. De las tareas definidas a efectuar por ambos microcontroladores en el Diagrama de Flujo que describe la operación del sistema se puede apreciar que ambos microcontroladores efectúan las operaciones de transmisión y recepción de datos a través de su Puerto Serie.

Microcontroladores. El 8051 de la INTEL.

423

Efectivamente en el 2do Paso el microcontrolador transmite un dato por su Puerto Serie, mientras que en el 4to. Paso recibe un dato por este mismo Puerto. Por su parte el microcontrolador MI en el 3er Paso recibe y transmite un dato a través del Puerto Serie. La pregunta a contestar en este momento sería, ¿Qué hay que modificar en el hardware del ejemplo 10.4.1 para que el mismo se ajuste a los requerimientos del ejemplo 10.4.2? Hay que dar la posibilidad de que la información fluya en ambos sentidos, del microcontrolador ML hacia el microcontrolador MI y del microcontrolador MI hacia el microcontrolador ML, por lo que no basta con que se conecte la salida TxD del microcontrolador MI a la entrada RxD del microcontrolador ML, sino que también hay que conectar la salida TxD del microcontrolador ML a la entrada RxD del microcontrolador MI, ver Figura 10.4.4.

Figura 10.4.4. Comunicación full - duplex entre ambos microcontroladores. En la Figura 10.4.4 no hemos conectados los Interruptores al microcontrolador MI ni los LEDs al microcontrolador ML ya que esto no cambie con respecto al esquema de la Figura 10.4.2 que se corresponde con el hardware propuesto para la solución del ejemplo 10.4.1. La pregunta a contestar en este momento sería, ¿Qué hay que modificar en el software del ejemplo 10.4.1 para que el mismo se ajuste a los requerimientos del ejemplo 10.4.2 y al hardware propuesto?

Microcontroladores. El 8051 de la INTEL.

424

Analicemos los programas en cada uno de los microcontroladores por separado. Para el caso del microcontrolador MI del programa sale la necesidad de programar al Temporizador 0 para que interrumpa cada 100 microsegundos ya que esta tarea pasa al microcontrolador ML. Se agrega la necesidad de incluir la recepción por el Puerto Serie. Para el caso del microcontrolador ML al software se debe agregar la programación del Temporizador 0 para que interrumpa cada 100 microsegundos así como la necesidad de transmitir por el Puerto Serie. ; Este es el programa que ejecuta el microcontrolador MI. org

0

sjmp

inicio

; Subrutina de atención a la interrupción del Puerto Serie. org

0023h

clr

RI

; limpia la bandera de interrupción por recepción.

mov

A, SBUF

; la lectura del dato enviado no importa

mov

A, P1

; lee el estado de los Interruptores.

mov

IE, #00010000b ; deshabilita interrupción para enviar dato por Puerto Serie

mov

SBUF, A

; envía el estado de los Interruptores por el Puerto Serie.

jnb

TI,$

; espera por que el dato sea enviado

clr

TI

; limpia la bandera de interrupción por fin d transmisión.

mov

IE, #10010000b ; habilita la interrupción del Puerto Serie

reti ; Inicio del Programa Principal inicio:

mov

IE, #10010000b ; habilita la interrupción del Puerto Serie.

; Programa al Temporizador 1 para que entregue la señal que garantiza la transmisión a ; 1200 Baudios. mov

TMOD, #00100000b

mov

TL1, #0E6h

mov

TH1, #0E6h

mov

PCON, #0

setb

TR1

; Programa al Puerto Serie en el Modo 1 con la recepción habilitada. mov

SCON, #01010000b

; Espera por la llegada de un dato al Puerto Serie. sjmp

$

end ; Este es el programa que se ejecuta en el microcontrolador ML. org

0

sjmp

inicio

Microcontroladores. El 8051 de la INTEL.

425

; Subrutina de atención a la interrupción del Temporizador 0. Se ejecuta cada 100 microsegundos. org

000Bh

; Lazo para garantizar el pedido de actualización cada 1 segundo. djnz

R2, salir

djnz

R1, salir1

; Pide al microcontrolador MI que le actualice el estado de los Interruptores. mov

IE,#00010010b

mov

SBUF, A

jnb

TI, $

clr

TI

mov

IE,#10010010b

; Valores en R1 y R2 que garantizan el pedido de actualización cada 1 segundo. mov

R1, #100

salir1:

mov

R2, #100

salir:

reti

; Subrutina que atiende el pedido de interrupción del Puerto Serie. org

0023h

; Lee el dato enviado por el microcontrolador MI. clr

RI

mov

A, SBUF

cpl

A

mov

P1, A

reti ; Programa de inicio. inicio:

mov

P1, #0

mov

R1, #100

mov

R2, #100

; apaga los LEDs

; Programando al Puerto Serie en el Modo 1 con la recepción habilitada. mov

SCON,#01010000b

; Programando al Temporizador 0 para que interrumpa cada 100 microsegundos. ; Programando al temporizador 1 para que garantice la Frecuencia de Baudios de 1200 Baudios. mov

TMOD, #00100010b

mov

TL0,#156

mov

TH0,#156

mov

TL1, #0E6h

mov

TH1, #0E6h

mov

PCON, #0

setb

TR1

Microcontroladores. El 8051 de la INTEL. setb

426

TR0

; Habilitando la Interrupción del Puerto Serie y del Temporizador 0. mov

IE, #10010010b

; Espera por interrupción de cualquiera de las dos posibles fuentes. sjmp

$

end En el ejemplo anterior el microcontrolador MI al recibir un dato por su Puerto Serie no necesita hacer nada con el mismo ya que esta predeterminada cual es la acción que debe hacer. Pero esto no siempre es así, es más me atrevería a decir que en la mayoría de los casos no es así. Veamos un ejemplo donde esto se pone de manifiesto. Ejemplo 10.4.3. Supongamos que en el ejemplo anterior el microcontrolador ML puede pedirle al microcontrolador MI que le actualice el estado de un Interruptor en particular y no el de todos como había ocurrido hasta ahora. Este interruptor en particular sería el escogido por el usuario mediante tres Interruptores conectados al microcontrolador ML y la orden de actualizar vendría dada por la opresión de una Tecla conectada al mismo microcontrolador. La pregunta a contestar en este momento sería, ¿Qué cambios hay que introducir al hardware en este caso? Como se definió en el enunciado del problema, el usuario cuenta con tres Interruptores conectados al microcontrolador ML para seleccionar cual es el Interruptor, de los conectados al microcontrolador MI, que desea actualizar en un momento dado. La acción es ejecutada cuando la Tecla conectada a este mismo microcontrolador es apretada. A los tres Interruptores conectados al microcontrolador ML los llamaremos S0, S1, y S2 y los conectaremos a los terminales P0.0, P0.1 y P0.2 y a la Tecla la llamaremos A y la conectaremos al terminal P0.3, ver Figura 10.4.5.

Microcontroladores. El 8051 de la INTEL.

427

Figura 10.4.5. Hardware propuesto para la solución del ejemplo 10.4.3. En la Figura 10.4.5 podemos observar la aparición de un nuevo circuito en sustitución de toda la circuitería conformada por los operacionales LM324 utilizadas en el ejemplo anterior. Este nuevo circuito es el MAX232 construido por la MAXIM. La pregunta a contestar en estos momentos sería, ¿Cuáles son las características de este circuito? El MAX232 es un conversor de señales de niveles TTL a niveles RS232. Internamente cuenta con 4 conversores de norma, 2 especializados para la recepción y los otros dos para la transmisión, ver Figura 10.4.6.

Microcontroladores. El 8051 de la INTEL.

428

Figura 10.4.6 Circuito conversor de los niveles de voltaje de TTL a norma RS232. Observe de la Figura 10.4.6 que los 4 circuitos conversores son inversores y que los dos asociados con las señales R1IN, R2IN presentan además la característica de ser Smitch Trigger lo que le permite mejorar la señal que llega desde el microcontrolador que transmite antes de entregársela al microcontrolador que recibe. La pregunta a contestar en este momento sería, ¿Qué es la norma RS232? La norma RS232 es una norma de comunicación estándar definida para la comunicación serie entre microcomputadoras o entre una microcomputadora y un modem o entre una microcomputadora y un equipo ubicado a cierta distancia, la que data de la década de los años 70. Esta norma define las características mecánicas, lógicas y eléctricas que se deben cumplir para poder decir que usted ha implementado un canal RS232. Los Puertos Serie de las Computadoras Personales COM1 y COM2 cumplen con los parámetros establecido por esta norma. De las características mecánicas lo más significativo es el tipo de conector que se debe emplear en el equipo para recibir/transmitir las señales. Este conector, originalmente del tipo DB25, en la actualidad por lo general se emplea del tipo DB9, ver Figura 10.4.7.

Microcontroladores. El 8051 de la INTEL.

429

Figura 10.4.7. Características mecánicas de la norma RS232. En la computadora el conector empleado es del tipo DB9 macho, por lo que el conector en el equipo diseñado por usted con un microcontrolador debe ser del tipo DB9 hembra. Un cable será el encargado de conectar ambos equipos. Este cable para ser considerado RS232 debe tener en un extremo un conector DB9 hembra mientras que en el otro extremo debe ser del tipo DB9 macho, ver Figura 10.4.8.

Figura 10.4.8. Cable RS232. La norma esta compuesta por un conjunto de señales que permiten la comunicación entre los diferentes dispositivos. Algunas de estas señales son de entradas otras de salida, algunas son

Microcontroladores. El 8051 de la INTEL.

430

para la transmisión/recepción de los datos serie y otras para transmitir/recibir las señales de control, ver Figura 10.4.7. De las señales propias de esta norma las más significativas para establecer la comunicación serie entre un microcontrolador y otro o entre un microcontrolador y una Computadora Personal son las señales: 9

TxD

Por este terminal es por donde deben salir los datos serie que transmita el

microcontrolador. 9

RxD

Por este terminal es por donde deben llegar los datos serie que debe recibir el

microcontrolador. 9

GND

Referencia de voltaje. El nivel de voltaje que llegue por este terminal será el

utilizado por el microcontrolador como referencia para comparar con los niveles de voltaje presentes en los otros dos terminales. La pregunta a contestar en este momento sería, ¿Qué ventaje tiene el emplear esta norma? Del análisis de las características eléctricas de la norma podemos obtener los elementos que nos permiten darle respuesta a esta pregunta. Del punto de vista eléctrico las señales que se transiten son referidas a GND y tienen que cumplir con los siguientes niveles de voltaje: •

Para el caso de la transmisión/recepción del ‘0’ los niveles de voltajes deben encontrarse entre +3 volts y +12 volts.



Para el caso de la transmisión/recepción del ‘1’ los niveles de voltajes deben encontrarse entre -3 volts y -12 volts.

Como podemos ver es una norma que transmite en lógica negativa, por lo que a la entrada de ambos equipos, tanto para la transmisión como para la recepción del dato, estos deben ser invertidos. Esta situación también esta presente para las señales de control. La pregunta a contestar en este momento sería, ¿Quién genera los niveles de voltaje propios de la norma para cada uno de los niveles lógicos?

Microcontroladores. El 8051 de la INTEL.

431

De esto se encarga el circuito MAX232. Este circuito tiene la característica de que con una sola fuente de alimentación de +5 volts es capaz de generar estos niveles de voltaje. Su comportamiento sería el siguiente: 9

Los conversores asociados a las señales T1IN y T2IN, a su entrada reciben señales con niveles TTL y ponen en su salida la misma señal invertida pero con niveles propios de la norma RS232.

9

Por su parte los conversores asociados a las señales R1IN y R2IN, a su entrada reciben señales con niveles propios de la norma RS232 y ponen a su salida la misma señal invertida pero con niveles TTL.

Una vez aclarados los aspectos nuevos del punto de vista del hardware concentremos nuestra atención ahora en el software a diseñar para que dirija la operación de ambos microcontroladores. A lo primero que queremos hacer referencia es a los 3 Interruptores conectados al microcontrolador ML a través de los terminales P0.0, P0.1 y P0.2. Mediante su combinación el usuario define cual de los Interruptor de los conectados al microcontrolador MI se debe actualizar su estado. Para ello definimos una relación entre el Interruptor a actualizar su estado y la combinación de los Interruptores conectados al microcontrolador MI, lo que se muestra en la Tabla siguiente. S2

S1

S0

Interruptor

abierto

abierto

abierto

0

abierto

abierto

cerrado

1

abierto

cerrado

abierto

2

abierto

cerrado

cerrado

3

cerrado

abierto

abierto

4

cerrado

abierto

cerrado

5

cerrado

cerrado

abierto

6

cerrado

cerrado

cerrado

7

El software que ejecuta el microcontrolador ML tendrá que leer el Puerto 0 cada vez que la Tecla A sea apretada, decodificar los tres bits menos significativos y enviar la correspondiente orden al microcontrolador MI. Detengámonos un tanto a lo que hemos dado en llamar enviar la orden al microcontrolador MI.

Microcontroladores. El 8051 de la INTEL.

432

Si bien en el ejemplo 10.4.2 la orden de enviar la actualización del estado de los Interruptores del microcontrolador ML al MI consistía solo en enviar una comando por el Puerto Serie independientemente del contenido que tuviera, ahora indiscutiblemente que el contenido de la comando que se envié tiene relevancia. La pregunta a responder en este momento sería, ¿Qué es lo nuevo que hace relevante el contenido de la comando que envié el microcontrolador ML cuando desee actualizar el estado de uno de los Interruptores conectado al microcontrolador MI? En el ejemplo 10.4.2 el microcontrolador MI solo tenia que ejecutar una acción, siempre la misma, cada vez que recibía una comando de actualización del microcontrolador Ml por su Puerto Serie, actualizar el estado de todos los Interruptores conectados a su Puerto 1, pero que ocurre ahora. En el ejemplo que nos ocupa esto ha cambiado ya que el microcontrolador MI puede ejecutar 8 tipos de acciones diferentes cada vez que recibe una comando de actualización del microcontrolador ML por su Puerto Serie. Acción #1.

Actualizar el estado del Interruptor I0.

Acción #2.

Actualizar el estado del Interruptor I1.

Acción #3.

Actualizar el estado del Interruptor I2.

Acción #4.

Actualizar el estado del Interruptor I3.

Acción #5.

Actualizar el estado del Interruptor I4.

Acción #6.

Actualizar el estado del Interruptor I5.

Acción #7.

Actualizar el estado del Interruptor I6.

Acción #8.

Actualizar el estado del Interruptor I7.

Por lo que el contenido de la comando de actualización que le llega al microcontrolador MI por su Puerto Serie debe ser capaz de dejar claro cual es la Acción que este tiene que hacer. Para ello tienen que haber 8 comandos de actualización diferentes, uno para cada tipo Acción a ejecutar por el microcontrolador MI. La pregunta a contestar en este momento sería, ¿Cómo materializar esto?

Microcontroladores. El 8051 de la INTEL.

433

Podríamos tomar la decisión de escoger 8 combinaciones diferentes y aleatorias de ‘0’ y ‘1’ para definir los 8 contenidos diferentes que necesitamos o podríamos establecer alguna regla especifica a la hora de definir el contenido de cada una de las comandos. La primera tiene la ventaja de que escoger los contenidos de las comandos no lleva implícito ningún esfuerzo, es simplemente escoger 8 números binarios de 8 bits diferentes, pero tiene como inconveniente lo difícil de conformar la comando deseada en cada caso en el microcontrolador ML y en decodificarla por parte del microcontrolador MI al no existir una regla que permita establecer alguna regularidad. La segunda tiene la desventaja de necesitar un poco de esfuerzo a la hora de definir los contenidos de las comandos, pero se simplifica grandemente las tareas de ambos microcontroladores a la hora de conformar y decodificar las mismas ya que en el momento en que estamos definiendo la comando estamos pensando en como van a operar sobre ella los programas. Escogeremos la segunda de las variantes y la regla que impondremos será que la posición de un ´1´ dentro de los 8 bits que conforman el comando define cual es el Interruptor que se desea actualizar. Esto queda resumido en la siguiente Tabla. ACCIÓN

COMANDO b7

b6

b5

b4

b3

b2

b1

b0

0

0

0

0

0

0

0

1

Actualizar estado del Interruptor I0.

0

0

0

0

0

0

1

0

Actualizar estado del Interruptor I1.

0

0

0

0

0

1

0

0

Actualizar estado del Interruptor I2.

0

0

0

0

1

0

0

0

Actualizar estado del Interruptor I3.

0

0

0

1

0

0

0

0

Actualizar estado del Interruptor I4.

0

0

1

0

0

0

0

0

Actualizar estado del Interruptor I5.

0

1

0

0

0

0

0

0

Actualizar estado del Interruptor I6.

1

0

0

0

0

0

0

0

Actualizar estado del Interruptor I7.

Ahora todo lo que tiene que hacer el software en el microcontrolador MI cuando reciba una comando es identificar la posición del ‘1’ que viene en la misma y esto le dice cual es el Interruptor del que tenemos que actualizar su estado. Por su parte el microcontrolador ML tendrá que determinar la posición en que debe ubicar el ‘1’ a la hora de conformar la comando. Para ello se basa en la combinación de los Interruptores conectados a él y previamente definida. Hagamos los cambios pertinentes en el software de ambos programas.

Microcontroladores. El 8051 de la INTEL. ; Este es el programa a grabar en el microcontrolador MI. org

0

sjmp

inicio

; Subrutina de atención a la interrupción del Puerto Serie. org

0023h

clr

RI

; limpia la bandera de interrupción por recepción.

mov

A, SBUF

; lectura de la comando

; Identificando el Interruptor a actualizar su estado.

lazo:

encontre:

mov

R2,#0

mov

R3,#8

rrc

A

jc

encontre

inc

R2

djnz

R3,lazo

mov

A, P1

sjmp

trans

mov

A, R2

rl

A

jmp

@A+DPTR

; Ejecutando las comandos. I0:

jb

P1.0, uno

jmp

cero

jb

P1.1, uno

jmp

cero

jb

P1.2, uno

jmp

cero

jb

P1.3, uno

jmp

cero

jb

P1.4, uno

jmp

cero

jb

P1.5, uno

jmp

cero

jb

P1.6, uno

jmp

cero

I7:

jb

P1.7, uno

cero:

mov

A,#1

sjmp

trans

mov

A,#0

I1: I2: I3: I4: I5: I6:

uno:

; lee el estado de los Interruptores.

434

Microcontroladores. El 8051 de la INTEL. trans:

mov

IE,#0

mov

SBUF, A

jnb

TI,$

clr

TI

mov

IE,#10010000b

; envía el estado de los Interruptores por el Puerto Serie.

reti ; Inicio del Programa Principal inicio:

mov

IE, #10010000b ; habilita la interrupción del Puerto Serie.

; Programa al Temporizador 1 para que entregue la señal que garantiza la transmisión a ; 1200 Baudios. mov

TMOD, #00100000b

mov

TL1, #0E6h

mov

TH1, #0E6h

setb

TR1

; Programa al Puerto Serie en el Modo 1 con la recepción habilitada. mov

SCON, #01110000b

; Inicializando la tabla de saltos. mov

DPTR,#0100h

; Espera por la llegada de un dato al Puerto Serie. sjmp

$

; Tabla de saltos. org

0100h

jmp

I0

jmp

I1

jmp

I2

jmp

I3

jmp

I4

jmp

I5

jmp

I6

jmp

I7

; Fin de compilación. end ; Este es el programa a grabar en el microcontrolador ML. org

0

sjmp

inicio

; Subrutina que atiende el pedido de interrupción del Puerto Serie. org

0023h

435

Microcontroladores. El 8051 de la INTEL.

436

; Lee el dato enviado por el microcontrolador MI. clr

RI

mov

A, SBUF

; Conforma el dato a escribir en el Puerto 1. rrc

A

mov

A, P1

rlc

A

djnz

R5,lazo1

mov

P1, A

sjmp

salir

trans1:

clr

TI

salir:

reti

lazo1:

; Programa de inicio. inicio:

mov

P1, #0

; apaga los LEDs

; Declarando la demora. mov

R1, #100

mov

R2, #100

; Programando al Puerto Serie en el Modo 1 con la recepción habilitada. mov

SCON, #01110000b

; Programando al Temporizador 1 para que garantice la Frecuencia de Baudios de 1200 Baudios. mov

TMOD, #00100000b

mov

TL1, #0E6h

mov

TH1, #0E6h

setb

TR1

; Habilitando la Interrupción del Puerto Serie. . mov

IE, #10010000b

; Declarando puntero a tabla mov

DPTR,#0090h

; Espera por Tecla apretada. repite:

jb

P0.3,$

jnb

P0.3,$

mov

A,P0

cpl

A

anl

A,#00000111b

mov

R5,A

rl

A

jmp

@A+DPTR

; Conformando la comando

Microcontroladores. El 8051 de la INTEL. C0:

mov

A, #00000001b

sjmp

trans

mov

A, #00000010b

sjmp

trans

mov

A, #00000100b

sjmp

trans

mov

A, #00001000b

sjmp

trans

mov

A, #00010000b

sjmp

trans

mov

A, #00100000b

sjmp

trans

mov

A, #01000000b

sjmp

trans

C7:

mov

A, #10000000b

trans:

mov

SBUF,A

jnb

TI,$

clr

TI

mov

IE, #10010000b

sjmp

repite

C1: C2: C3: C4: C5: C6:

437

; Tabla de saltos. org

0090h

sjmp

C0

sjmp

C1

sjmp

C2

sjmp

C3

sjmp

C4

sjmp

C5

sjmp

C6

sjmp

C7

; Fin de compilación. end El Modo 2. Este Modo de Trabajo es muy parecido al anterior, la diferencia fundamental estriba en la inclusión de un bit de datos programable en la cadena de bits que se envía en la transmisión. El formato ahora es el siguiente, ver Figura 10.5.1.

Microcontroladores. El 8051 de la INTEL.

438

Figura 10.5.1 Formato de transmisión de los datos en el Modo 2. Las preguntas a responder en estos momentos serían, ¿Quien es este noveno bit de datos?, ¿De donde sale?, ¿Como lo podemos programar? ¿Que función realiza? Observemos el bit 3 del Registro SCON, ver Figura 10.5.2. Este bit recibe el nombre de TB8 y es el que constituye el noveno bit que se agrega a la cadena de bits en la transmisión de un dato.

Figura 10.5.2 El bit TB8 en el Registro SCON. La pregunta a contestar en este momento sería, ¿Cómo ocurre este proceso? En el proceso de transmisión de un dato al final de la cadena de bits se incorpora el valor que tenga almacenado en ese momento el bit TB8, el cual fue cargado previamente, por el Programador, a ‘0’ o a ‘1’ mediante una instrucción que utilice como destino el bit 3 de este Registro. Este bit, podría ser utilizado como un bit para la detección de errores en la comunicación entre dos dispositivos. Si cargáramos en este, el valor del Bit de Bandera de Paridad correspondiente al dato transmitido, el Receptor podría verificar si el dato que le llego tiene la misma paridad de unos con que se transmitió y con ello detectar cualquier error de cambio de valor que pueda haber ocurrido durante la comunicación. La pregunta a responder en este momento sería,

Microcontroladores. El 8051 de la INTEL.

439

¿Como el receptor puede determinar el valor de este bit y con ello verificar la paridad de unos del dato recibido? En el Receptor este noveno bit de datos es almacenado en el bit RB8 del Registro SCON, ver Figura 10.5.3, de forma tal que mediante una instrucción de lectura que utilice como fuente al bit 2 de este registro después de una recepción permitiría al Programador conocer el valor de este noveno bit.

Figura 10.5.3 El bit RB( en el Registro SCON. ¿Como seleccionar la Frecuencia de Baudios en este Modo de Trabajo? Solo son posibles dos Frecuencias de Baudios para la transmisión/recepción en este Modo de Trabajo las cuales son escogidas en dependencia del valor con que haya sido programado el ya conocido bit SMOD del registro TCON, según como se muestra en la Tabla 10.5.1. SMOD

Frecuencia en Baudios

0

1 / 64 la Frecuencia del Oscilador

1

1 / 32 la Frecuencia del Oscilador Tabla 10.5.1.

El Modo 3. Este Modo de Trabajo lo podemos ver como la unión de los Modos 1 y 2, ya que en lo referente al formato del dato transmitido es similar al Modo 2 y con respecto a la selección de la Frecuencia de Baudios es similar al Modo 1. Por lo tanto en este Modo de Trabajo podemos agregar un bit de datos programable al dato transmitido y podríamos seleccionar la Frecuencia de Baudios a partir del Temporizador 1, adaptándose más a los estándares en las comunicaciones series. La pregunta a contestar en este momento seria, ¿Qué es lo nuevo en este Modo de Trabajo?

Microcontroladores. El 8051 de la INTEL.

440

Los Sistemas de Control Distribuidos con Supervisión Centralizada vienen jugando un papel cada día más significativo en la automatización industrial. Poder tener la inteligencia distribuida por diferentes puntos del sistema a controlar, le brinda flexibilidad, rapidez y fiabilidad a los Sistemas de Control. En la introducción creciente en la industria de este modo de organizar y distribuir los elementos del Sistema de Control han tenido gran influencia el desarrollo y los relativos bajos costos de los microprocesadores y los microcontroladores. Estos han permitido la construcción de sistemas remotos de control, sensores e instrumentos inteligentes de bajo costo, los que unidos al desarrollo que ha tenido en los últimos años las comunicaciones digitales han permitido esta nueva forma de concebir los sistemas de control. Todo esto nos permite crear una red de instrumentos y equipos inteligentes que distribuida por toda la Planta permiten, al mismo tiempo, el trabajo independiente y el trabajo cooperado de los elementos que conforman el Sistema de Control en la obtención de un objetivo común, el funcionamiento eficiente de la misma. Una pregunta interesante a responder en este momento sería, ¿Como el Microcontrolador 8051 se incorpora a este concepto? El 8051 contiene todos los elementos del hardware para implementar de una forma sencilla un Canal de Comunicación Serie, premisa inviolable para entrar en el juego, como ya se estudio anteriormente. Pero con esto solo no basta. Analicemos el sistema distribuido presentado en la Figura 10.6.1.

Figura 10.6.1 Sistema de Control Distribuido con Supervisión Central mediante Microcomputadora.

Microcontroladores. El 8051 de la INTEL.

441

En la Figura 10.6.1 se muestra una red tipo bus la cual tiene en el nivel jerárquico superior una Microcomputadora y en el nivel jerárquico inferior un conjunto de elementos que pueden ser controladores, sensores inteligentes, instrumentos, actuadotes inteligentes, etc. Todos estos elementos, a los que hemos llamado equipos inteligentes, tendrán en común, en nuestro ejemplo, que están construidos con el microcontrolador 8051 y se encuentran interconectados entre sí y a su vez con la Microcomputadora a través de su canal de comunicación serie, utilizando como norma de comunicación la RS-485. La pregunta a contestar en este momento podría ser, ¿Cuál es la norma RS-485? La norma de comunicación serie RS-485, es una norma no referida a tierra como ocurre con la RS232, de gran uso en las redes para el control industrial, dada su alta inmunidad al ruido y su relativo largo alcance sin la necesidad de elementos amplificadores intermedios. Esta norma es especialmente desarrollada para sistemas industriales multipunto que esta habilitada para transmitir y recibir datos a frecuencias altas y largas distancias. Algunas de sus especificaciones son las siguientes: •

Alcance máximo de la transmisión sin la necesidad de elementos amplificadores intermedios de 1200 metros. Esto constituye un segmento.



Velocidades de transmisión por encima de 10 Megabaudios.



Voltaje de transmisión diferencial a través de lineas balanceadas lo que le brinda una gran inmunidad al ruido.



Número máximo de equipos conectados en un segmento de 32.



Permite la comunicación bidireccional con protocolo Amo – Esclavo a rav’es de dos hilos.



Los equipos en un segmento son conectados de forma paralela.

La pregunta a contestar en este momento ser’ia, ¿Cómo implementar en mi sistema a microcontroladores la norma RS-232? En la actualidad se construyen por parte de los principales fabricantes de circuitos integrados un circuito que permite efectuar la conversión en cuanto a voltaje y corriente de la señal entregada por el microcontrolador a través de sus terminales TxD y RxD del Puerto Serie y los requeridos por la norma. Un ejemplo de este circuito es el fabricado por la MAXIM, El MAX485 el que mostramos en la Figura 10.6.2.

Microcontroladores. El 8051 de la INTEL.

442

Figura 10.6.2 Circuito Integrado MX485 fabricado por la MAXIM. La pregunta a contestar en este momento sería, ¿Cómo conectar el MAX485 al Puerto Serie del 8051 para materializar la norma RS485? Observe de la estructura interna del circuito mostrada en la Figura 10.6.2 que internamente el mismo cuenta con dos buffer no inversor con posibilidad de poner su salida en tercer estado, identificados como D y R. Para ello cuentan, además de la entrada y la salida del correspondiente buffer no inversor, con una entrada de habilitación las que es activas en ´1´ para el buffer D y activa en ´0´ para el buffer R. El buffer D es el utilizado para conectar al transmisor del Puerto Serie del microcontrolador, TxD, mientras que el buffer R es el utilizado para conectar al receptor del Puerto Serie o sea a RxD. Los terminales del MAX485 a conectar a TxD y RxD son el DI y el R0 respectivamente. ¿Qué función realizan entonces los terminales de habilitación DE y RE/? La norma RS485 es una norma de comunicación half-duplex por lo que el microcontrolador o esta transmitiendo o esta recibiendo y es una norma concebida para que el protocolo de comunicación entre los diferentes dispositivos que conforman la red se establezca según la comunicación del tipo Amo-Esclavo. De forma tal que, los dispositivos conectados a la red como esclavos están constantemente a la escucha y por lo tanto tienen habilitados el buffer R conectado al receptor, mientras que el buffer D conectado al transmisor se encuentra en tercer estado. Cuando a dicho microcontrolador le corresponda transmitir habilita al buffer D y deshabilita al buffer R. Para esto es que se utilizan las entradas de habilitación DE y RE/ las que deben ser conectadas a dos bit cualquiera de uno de los Puertos del 8051 para ser controlado su valor mediante programa. En la Figura 10.6.3 se muestra una posible implementación de la norma RS485 empleando el circuito integrado MAX485.

Microcontroladores. El 8051 de la INTEL.

443

Figura 10.6.3. Canal serie con Norma RS485. La pregunta a contestar en este momento sería, ¿Qué papel juega la resistencia Rt en el circuito de la Figura 10.6.3? Cada discontinuidad en el par de hilos conductores de la norma se traduce en una señal reflejada con su correspondiente distorsión sobre la señal que se esta transmitiendo. Este efecto es especialmente perjudicial en los terminales de la linea que si no estan correctamente ‘macheados’ causas serios errores en los datos transmitidos. Para eliminar este fenómeno es que se conecta la resistencia Rt. El valor de la resistencia Rt debe ser lo m’as cercano posible al valor de la impedancia de la linea. Aunque el equipo receptor adiciona alguna resistencia a la resistencia de la linea de transmisión, normalmente es suficiente con que el valor de Rt sea el propio de la impedancia de la línea. Regresando al sistema presentado, los equipos inteligentes harán el papel de “esclavos” en la red, mientras que el “amo” lo hará la Microcomputadora conectada en el sistema. De lo definido hasta aquí la comunicación entre la Microcomputadora y los demás elementos de la red se hace según

Microcontroladores. El 8051 de la INTEL.

444

un funcionamiento “amo-esclavo”, donde todas las transferencias de información son iniciadas por esta. Una pregunta interesante a responder en este momento sería, ¿Como será en este caso el funcionamiento de la red? 1er. Paso. La Microcomputadora coloca en el bus de campo la dirección del elemento en la red con quien se quiere comunicar. 2do. Paso. La Microcomputadora recibe la confirmación del reconocimiento por parte del equipo inteligente seleccionado. 3er. Paso. La Microcomputadora envía una palabra de comando donde define el tipo de operación a realizar con el elemento seleccionado. 4to. Paso. La Microcomputadora recibe información del equipo inteligente seleccionado de la recepción de la comando. 5to. Paso. Se efectúa la transferencia de datos entre la Microcomputadora y el equipo inteligente seleccionado. 6to. Paso. Regresar a las condiciones iniciales al sistema. De los seis pasos que hemos definido en nuestro supuesto Protocolo de Comunicación, mientras que en el primero, la dirección del equipo inteligente con quien desea comunicarse la Microcomputadora debe llegar a todos los equipos inteligentes conectados en la red por igual, la información que se mueve en los restantes pasos, que constituyen datos y confirmaciones de buena operación, solo son de interés para el equipo inteligente que haya sido seleccionado. La pregunta a contestar en este momento sería, ¿Como lograr que una información que se mueve por el bus común a todos los equipos inteligentes, en algunos casos llegue a todos y en otros solo a uno de ellos, al seleccionado? ¿Como diferenciar la información que se mueve por el bus de la red en datos y dirección? Para dar respuesta a las dos preguntas anteriores estudiemos con más profundidad los Modos 2 y 3 del Puerto Serie, fundamentalmente en lo relacionado con la interrupción en la recepción. Como se explico anteriormente en los Modos 2 y 3 una vez que al Puerto Serie llega el noveno bit de datos, la Bandera de Interrupción de la Recepción, RI, se activa, solicitándose atención por

Microcontroladores. El 8051 de la INTEL.

445

interrupción, indicándole al microcontrolador que un dato se encuentra almacenado en el Almacenador del Receptor listo para ser leído. Aunque lo anterior es cierto, no siempre sucede así. El Programador tiene la posibilidad de enmascarar la llegada de un dato al Puerto Serie y por tanto que no se solicite interrupción, con lo que el 8051 en cuestión no se da por enterado de la llegada del mismo, obviándolo. Para ello está el bit 5 del Registro SCON, ver Figura 10.6.4.

Figura 10.6.4 El bit SM2 en el registro SCON. Mediante la programación de este bit se puede condicionar la recepción o no de un dato por el Puerto Serie en estos dos Modos de Trabajo. Si SM2 es programado en ‘0’, cada vez que se complete la llegada de un dato al Puerto Serie, este solicitará interrupción, pero si SM2 es programado en ‘1’, el Puerto Serie solicitará interrupción solo si el noveno bit del dato recibido es ‘1’. Con esto le damos respuesta a las dos preguntas anteriores: 1. Para la primera pregunta, mediante el envió de la información en algunos casos con el noveno bit en ‘1’ y programando de forma adecuada el bit SM2 de los elementos de la red, algunos en ‘0’ y otros en ‘1’. 2. Para darle respuesta a la pregunta dos podríamos definir por ejemplo que la Microcomputadora cada vez que envía una dirección dicha información llevará el noveno bit en ‘1’ y cuando se transmitan datos este bit estará en ‘’0’. Aplicando lo anterior al ejemplo definido al inicio: 1er Paso La Microcomputadora enviará la dirección del elemento de la red con que se quiere comunicar, para ello la dirección va en 8 bits y el noveno bit en ‘1’. En este momento todos los elementos de la red tendrán programados el bit SM2 de sus Registros SCON en ‘1’ y por ende

Microcontroladores. El 8051 de la INTEL.

446

todos recibirán la información y podrán comparar la dirección enviada con su dirección para detectar si es el seleccionado. 2do. Paso. El elemento seleccionado podría enviar la dirección de la Microcomputadora con el noveno bit en ‘1’ como un reconocimiento de que todo está bien e inmediatamente lleva su bit SM2 a ‘0’, el único de todos los elementos de la red que lo hace. 3ro, 4to. y 5to. Pasos. La información que se mueve por el bus de la red tiene el noveno bit en ‘0’ por lo que solo será recibida por el equipo seleccionado, que a su vez es el único que tiene su bit SM2 en ´0´, quedando enmascarada para el resto de los equipos conectados a la red. 6to. Paso. El equipo seleccionado lleva nuevamente su bit SM2 a ‘1’, quedando todo listo para un nuevo enlace de la Microcomputadora con otro de los equipos conectados a la red o con el mismo nuevamente. Una pregunta que resulta interesante darle respuesta en este momento sería, ¿Cuantos elementos podrían estar conectados a la red? Como se ha explicado la dirección se envía en 8 bits con el noveno bit en ‘1’ por lo que se pueden generar 256 direcciones diferentes, por lo que del punto de vista teórico, debido a esta causa, al bus podrían estar conectados 255 elementos. ¿Por qué planteamos que debido a esta causa? Otro elemento a tomar en consideración en cuanto a la cantidad de equipos que se pueden conectar al bus es la carga que estos representan. Cada equipo que conectamos a la red representa para esta una carga que se refleja en la corriente que toma independientemente que este habilitado el buffer o no. Por ejemplo en el caso del MAX485 la corriente que toma del bus común cuando el buffer esta deshabilitado es de 300 microamperes, por lo tanto, al menos esta corriente el circuito la esta tomando de este bus ya que la corriente que toma cuando esta habilitado es mayor . Esto limita por este aspecto a que en el bus solo se puedan conectar 32 equipos, considerando que cada uno implementa la norma RS485 con este mismo circuito. Si bien los problemas resueltos resultan sencillos y por su puesto que no utilizaríamos dos microcontroladores para resolver los mismos en un caso práctico, el objetivo que perseguimos fue el de que ustedes prestaran toda su atención a la operación de la Interrupción, de los Temporizadores y del Puerto Serie y no en la aplicación resuelta en si. En el próximo Tema enfrentaremos la solución de problemas más cercanos a los que nos podemos proponer con el empleo de este microcontrolador.

Microcontroladores. El 8051 de la INTEL.

447

Tema 11. Aplicaciones de mediana complejidad con el Microcontrolador 8051. Con lo estudiado hasta este momento, prácticamente lo conocemos todo sobre el microcontrolador 8051 y estamos en condiciones de resolver tareas un tanto más complejas que las resueltas en los Temas anteriores. El objetivo de este Tema es el de poder utilizar por primera vez en el libro toda la potencialidad del microcontrolador 8051 para resolver una aplicación dada. 11.1 Frecuencimetro Digital. El poder contar con un equipo que nos permita medir la frecuencia de una señal periodica puede resultar muy util en las labores de puesta a punto de un sistema basado en microcontroladores. Efectivamente, en muchas aplicaciones el microcontrolador es el responsable de generar una señal periodica de la cual una de sus caracteristicas fundamentales puede resultar ser su frecuencia. Por ejemplo si deseamos hacer sonar una bocina para indicar alarma por cualquier motivo, a esta bocina le debemos alicar una señal periodica con una determinada frecuencia para que la misma suene y pueda ser escuchada por alguna persona, que es el objetivo fundamental de una alarma sonora. En este caso el poder concocer el valor de la frecuencia de la señal periodica que genera el microcontrolador resulta de vital importancia para la puesta a punto del circuito. En este epígrafe enfrentaremos la tarea de diseñar un equipo basado en el microcontrolador 8051 cuya función es la de poder efectuar la medición de la frecuencia de señales periodicas en el tiempo. Ejemplo 11.1 Diseñar un Frecuencimetro Digital basado en el microcontrolador 8051. Las características de la señal a medir son: •

La señal puede ser bipolar (voltaje negativo y positivo).



La señal puede ser del tipo tren de pulsos o sinusoidal.



Voltaje máximo = 5 volts.



Voltaje mínimo = -5 volts.



Frecuencia máxima de la señal = 400 Khz



Frecuencia mínima de la señal = 1 Hz

La Frecuencia de la señal se deb mostrar en un Display a Cristal Líquido (LCD) cada vez que una Tecla, a la que llamaremos Medir, sea apretada. Un Interruptor, al que llamaremos Rango, le permite indicar al usuario en cual de los dos posibles rangos de frecuencia para el equipo se encuentra la señal a medir.

Microcontroladores. El 8051 de la INTEL.

448

Para comenzar podría resultar interesante darle respuesta a la siguiente pregunta, ¿Cuál de los circuitos empotrados en el 8051 me podría ser útil para resolver esta aplicación? La frecuencia de una señal no es más que la cantidad de veces que se repite en 1 segundo. Para el caso de los dos tipos de señales a medir que admite el equipo a diseñar, tren de pulsos o señal sinosoidal, esto lo podríamos traducir en la cantidad de veces que la señal va de su valor máximo de voltaje a su valos mínimo de voltaje o viceversa en 1 segundo, o lo que es lo mismo la cantidad de pulsos en 1 segundos, para la primera señal y para el caso de la sinosoide seria la cantidad de veces que ocurre el semiciclo positivo de la señal o el semiciclo negativo. Observe que en cualquiera de los casos la palabra clave es la cantidad, por lo que al problema que nos estamos enfrentando no es otro que el de contar la cantidad de veces que ocurre un determinado evento y para ello los Temporizadores podrián resultar de gran utilidad. La soluición que estamos proponiendo para medir la frecuencia de la señal es la de utilizar al Temporizador 0 programado para que trabaje como contador de eventos. La señal a contar será aplicada por lo tanto al terminal T0 del microcontrolador y la habilitación del conteo proponemos que se haga por software, una vez detectada que la Tecla Medir es apretada. La pregunta a contestar en este momento podría ser, ¿Cuáles son las condiciones que imponen los Temporizadores del 8051 a la señal que se aplica a sus terminales de entrada de conteo, T0 para el caso del Temporizador 0, para garantizar que su conteo sea correcto? Por su puesto que la respuesta a esta pregunta es muy importante ya que de estas condiciones depende si se puede cumplir con los requerimientos impuestos al equipo. Los Temporizadores del 8051 imponen, para que su conteo sea correcto, que la frecuencia de la señal aplicada a su entrada externa de conteo no puede ser mayor que,

Frecuencia. max . =

Fcristal 24

Microcontroladores. El 8051 de la INTEL.

449

Por lo que si consideramos que la Frecuencia del Cristal de Cuarzo ( Fcristal ) que vamos a conectar al oscilador interno del microcontrolador es de 12 Mhz, la frecuencia máxima ( Frecuencia max ) que puede tener la señal a la que vamos a medir su frecuencia será,

Frecuencia max =

12 Mhz = 500 Khz 24

Valor este superior a los 400 Khz que impone como frecuencia máxima de la señal a medir por el equipo. Otra de las condiciones que imponen los Temporizadores del 8051 es el tiempo mínimo en ‘0’ o en ‘1’ admisible a la señal. Efectivamente la señal puede ser simétrica y por lo tanto su tiempo en ‘0’ y su tiempo en ‘1’ serán iguales, por lo que con cumplir con los requerimientos de frecuencia es suficiente para que el Temporizador cuente correctamente, pero no todas las señales que se vayan a medir tienen que ser simétricas. La pregunta a contestar en este momento sería, ¿Cuál es el valor del tiempo mínimo que puede tomar la señal en cualquiera de sus dos estados? Este tiempo mínimo viene dado por la expresión,

12 Fcristal

t min imo =

Por lo que para un cristal de cuarzo de 12 Mhz el tiempo mínimo de la señal en cualquiera de sus dos estados será,

t min imo =

12 = 1μseg 12 Mhz

Hablamos de tiempo mínimo de cualquiera de sus dos estados porque la señal a medir puede ser que tenga ciclo útil mayor del 50% (tiempo en ‘1’ > tiempo en ‘0’ ) y por lo tanto aquí hay que garantizar que el tiempo en ‘0’ sea mayor que el tiempo mínimo, pero si la señal a medir tiene ciclo útil menor del 50% (tiempo en ‘1’ < tiempo en ‘0’ ) entonces lo que tenemos que garantizar es que el tiempo en ‘1’ sea mayor que el tiempo mínimo.

Microcontroladores. El 8051 de la INTEL.

450

Una vez aclarados estos aspectos relacionados con las condiciones que debe cumplir la señal que estamos midiendo dediquemos un tiempo al resto de los elementos que conforman al Frecuencimetro. La primera pregunta a contestar en este sentido podría ser, ¿Cómo detectar que la Tecla Medir fue apretada? Para ello proponemos conectar dicha tecla al terminal INT0/ del microcontrolador y atenderla mediante el mecanismo de interrupción empotrado en el mismo, de forma tal que, cuando se apriete la Tecla se interrumpa la operación del microcontrolador y se pase a ejecutar el conjunto de instrucciones que permite efectuar la medición y posterior visualización de la frecuencia de la señal. No obstante, antes de que la señal este lista para ser tratada por el Temporizador tiene que sufrir algunas transformaciones que permita el buen funcionamiento de este elemento del microcontrolador. Efectivamente la señal de entrada puede tomar una gama variable y relativamente grande de valores de voltajes en el intervalo de + 5 volts hasta – 5 volts, valores de voltaje que pueden ser positivos y negativos. Por ejemlo una señal puede tener todos sus valores positivos, o sea, entre 0 volts y +5 volts, o todos sus voltajes negativos, o sea, entre 0 volts y – 5 volts o valores positivos y negativos, mientras que la entrada T0 del microcontrolador reconoce los niveles de voltajes que define la familia de circuitos integrados CMOS para el nivel lógico de ‘0’ y de ‘1’, o sea, valores de voltaje positivos y en un determinado intervalo de valores. ¿Como lograr la compatibilidad en cuanto a voltaje entre la señal a medir y la entrada T0? Para ello proponemos colocar entre la entrada destinada en el equipo para aplicar la señal a medir y la entrada T0 del microcontrolador el circuito que se muestra en la Figura 11.1..

Microcontroladores. El 8051 de la INTEL.

451

Figura 11.1 Circuito para el tratamiento de la señal a medir. Para su explicación el circuito lo hemos dividido en tres subcircuitos a los que le hemos dado los nombres, de izquierda a derecha, de: •

Filtro.



Conformador de onda.



Conformador de señal.

El Filtro es el primer circuito que se encuentra la señal a medir una vez que entre al equipo. Este esta conformado básicamente por el circuito operacional LM082 en una configuración que permite eliminar la componente de directa de la señal a medir, con lo que garantizamos que la señal quede simetrica con respecto a la referencia de tierra del circuito. Los valores de resistencia fueron calculados tomando en cuenta de que el Filtro iba a ser en un solo paso. Claro que solo con esto no es suficiente ya que la señal puede tener una diferencia entre su voltaje máximo y mínimo tan pequeño que no garantice que se mueva en el intervalo de voltaje propios de los niveles lógicos de la familia de circuitos integrados CMOS, requeridos para que el Temporizador reconozca al ‘0’ y al ‘1’ y con ello poder contar adecuadamente. De esta tarea se encarga el segundo circuito en la cadena, al que hemos llamado Conformador de Onda. Este circuito esta basado también en un circuito operacional LM082 conectado como comparador con fuente de alimentación de +5 volts y -5 volts. El voltaje de entrada es comparado con el valor de referencia de voltaje de 0 volts del circuito con lo que garantizamos que a su salida la forma de onda de la señal sea un tren de pulsos entre los valores de voltaje de +5 volts y – 5 volts, independiente de si la señal de entrada es una sinusoide o un tren de pulsos.

Microcontroladores. El 8051 de la INTEL.

452

No obstante, la señal obtenida tiene valores de voltaje negativos lo que constituye un problema para el buen funcionamiento del Temporizador. ¿Qué debemos hacer con la señal para poder aplicarla a la enrada T0 del Temporizador 0 y asi poder pasar a la medición de su frecuencia? Para llegar a la respuesta de la pregunta anterior primero analisemos que señal es la que tenemos a la salida del segundo subcircuito. En este punto tenemos una señal muy bien definida en cuanto a su frecuencia y con niveles de voltaje cercanos a los requeridos por la entrada T0. ¿Por qué decimos que la señal tiene niveles de voltaje cercanos a los requeridos por T0? Porque la señal ya toma valores en todo la gama de voltajes que pueden tomar las señales definidas por la familia de circuito integrados CMOS, de 0 volts a +5 volts, lo unico que nos falta es eliminar el semiciclo de la señal que toma valores de voltaje negativos, de 0 volts a -5 volts, recortando a 0 volts el semiciclo de la se;al que toma valores de voltaje negativos y dejando pasar integramente el semiciclo en que la seña toma valores de voltaje positivos. Para esto contamos con el tercer subcircuito en la cadena al que hemos llamado el Conformador de Señal. Este circuito esta integrado por un diodo que funciona como un rectificador de media onda, eliminando los valores negativos de la señal y un buffer inversor tercer estado de la familia de circuitos integrados HCT que se encarga de darle las características de voltaje y corriente que demanda la entrada T0 del Temporizador. Una vez que la señal a medir haya pasado por este circuito contamos con una señal del tipo tren de pulsos, enmarcada en el intervalo de voltaje entre 0 volts a +5 volts, independientemente del tipo de señal y de sus caracteristicas de voltaje, pero, conservando su valor de frecuencia original que es la caracteristica de la señal que debe permanecer inalterable para el buen funcionamiento del equipo. Otros elementso acompañan a este circuito en el equipo, estos son: •

La Tecla Medir de la que ya hemos hablado.



Un Interruptor al que hemos llamado Rango, destinado para escoger en cual de los dos posibles rangos de frecuencia se puede encontrar la señal a medir.



Un Display a Cristal Líquido (LCD) para interactuar con el usuario y mostrar el valor de frecuencia de la señal.

Microcontroladores. El 8051 de la INTEL.

453

La Tecla Medir, como ya explicamos, proponemos atenderla por Interrupción y por ende la conectaremos al terminal INT0/ del microcontrolador. La Subrutina que atiende la ocurrencia del evento de apretar dicha Tecla, por lo tanto, se debe ubicar a partir de la localización de la Memoria de Programa cuya dirección se corresponde con la 0003h. Por su parte, el Interruptor Rango esta en el circuito con el objetivo de que el usuario escoja uno de dos posibles rangos de frecuencia en los que se puede encontrar la señal a medir, por lo que su caracteristica fundamental es la de poder tener dos estados muy bien definidos, uno para cada rango posible a escoger. Estos dos posibles estados podrían ser cerrado o abierto, por lo que con un Interruptor Simple Polo – Simple Tiro podría resultar la solución. Este proponemos conectarlo al terminal P3.0 del microcontrolador. Para interactuar con el Display a Cristal Líquido (LCD) utilizaremos un bus de 8 bits el que conformaremos con el Puerto 1 del microcontrolador, mientras que las señales de control proponemos generarlas a través de los terminales P3.6 y P3.7 del microcontrolador. Dado que al LCD solo lo escribiremos su señal R/W la conectaremos directamente a la referencia de tierra del circuito. En la Figura 11.2 se muestra el circuito que proponemos para materializar al

Frecuencimtro

Difgital.

Figura 11.2 Hardware propuesto para el Frecuencimetro Digital basado en el microcontrolador 8051.

Microcontroladores. El 8051 de la INTEL.

454

Ya tenemos una propuesta de hardware para materializar el circuito, pero, aun nos falta el software que ejecutado por el microcontrolador permita que el hardware diseñado cumpla con la traea que deseamos. Este software debe reflejar, fundamentalmente, el algoritmo que escojamos para medir la frecuencia de la señal. ¿Cuál es el algoritmo que emplearemos para determinar la frecuencia de la señal? Como ya exlicamos anteriormente, la frecuencia de una señal no es más que la cantidad de veces que se repite en un segundo, en otras palabras, para el caso de un tren de pulsos no es más que la cantidad de pulsos en 1 segundo, por lo que si al Temporizador 0 lo ponemos a contar durante un segundo los pulsos que le llegan por su terminal T0, estando en un principio en 0, el valor almacenado en TH0/TL0 al final del conteo se corresponde con la frecuencia en herz de la señal. Por su puesto que este algoritmo limitaría la frecuencia de la señal a medir a 65 536 herz, ya que después de esta cantidad de pulsos contados por el Temporizador este se desborda, considerando que esta trabajando en el Modo 1, perdiendo la cuenta que llevaba. Este valor de frecuencia máxima no satisface el rango de frecuencia a medir que hemos impuesto al Frecuencimetro ¿Cómo solucionar este problema? Una solución podría ser el de disminuir el tiempo de conteo y el valor medido afectarlo por una constante. Por ejemplo si el tiempo de conteo se disminuye a 1 milisegundos, el valor que tenga TH0/TL0 al final del tiempo de conteo lo debemos multiplicar por 1000 para conocer la frecuencia en Hz. No obstante, la lectura directa de TH0/TL0 en este caso me daria la frecuencia de la señal en Khz. Por lo que el el tiempo de conteo del Temporizador podrían ser dos: •

1 segundo para señales que se encuentren en el intervalo de frecuencia de los herz (1 Hz a 999 Hz)



1 milisegundo para señales que se encuentren en el intervalo de frecuencia de los Kiloherz (1 KHz a 400 KHz)

¿Cómo conocer si la señal esta en el intervalo de los Hz o de los KHz? Aquí entra a jugar la posibilidad que se le dio al equipo de que el usuario definiera mediante el Interruptor Rango el posible intervalo de recuencia en que se debe encontrar la señal a medir. Para

Microcontroladores. El 8051 de la INTEL.

455

esto hemos dividido la señal a medir en dos intervalos o rangos de medición, a los que hemos llamado Rango Hz y Rango KHz. Dentro del Rango HZ hemos puesto a todas las señales cuya frecuencia esta entre 1 Hz y 999 Hz, mientras que en el Rango KHz las señales que estan entre 1Khz y 400 Khz. Esto lo asociaremos con el estado en que se encuentre el Interruptor Rango el que debe ser impuesto por el usuario antes de dar la orden de medir al Frecuencimetro. Interruptor Rango abierto implica que la frecuencia de la señal a medir se encuentra dentro del Rango Hz, mientras que, Interruptor Rango cerrado implica que la frecuencia de la señal a medir se encuentra dentro del Rango KHz. La pregunta a contestar en este momento sería, ¿Quién impone el tiempo de medición del Temporizador? Para ello hemos destinado al Temporizador 1, trabajando como Contador de Tiempo y habilitando su conteo por software. Efectivamente una vez que se conozca en cual Rango de Medición se encuentra la señal que deseamos medir, en los registro TH1/TL1 del Temporizador 1 se carga la constante de tiempo que provoca la interrupción del microcontrolador en 1 segundo o en 1 milisegundo en dependencia de dicho rango. Esta interrupción

provocará la detención del conteo del Temporizador 0 y

desencadenará todas las instrucciones que permiten determinar el valor de la frecuencia de la señal a medir y su posterior visualización a través del LCD. El software desarrollado para esta aplicación es el que se muestra a continuación. ; ************************************************************************************************************ ; Inicio del Programa del Frecuencimitreo Digital basado en el 8051. org

0

sjmp

inicio

; La Tecla es atendida por Interrupción, específicamente INT0/. ; Provoca que por el LCD se muestre el cartel2, ‘por favor espere’. ; Se inicializa el registro R2 el que es utilizado si el tiempo de conteo escogido es de 1 segundo. ; Se inicializa la Bandera Fuera de Rango, 25h.0. ; Se da inicio al proceso de medición el que termina con la visualización. org

0003h

mov

R2, #0

sjmp

salto

; El tiempo de conteo escogido no es el adecuado dada la frecuencia de la señal a medir.

Microcontroladores. El 8051 de la INTEL.

456

; Si se desborda el Temporizador 0 se procede a sacar el cartel de ‘fuera de rango’ ; Se setea la bandera de Fuera de Rango indicando que esta condición a ocurrido. ; Le da valor al registro R2 en dependencia del estado del Interruptor Rango, con lo que se escoge ; valores diferentes para el tiempo de medición. org

000bh

setb

25h.0

mov

DPTR, #tcartel3

lcall

cartel

sjmp

salto3

; Si se desborda el Temporizador 1 incrementar R2 para detectar el fin del tiempo de conteo ; Reinicia el conteo del Temporizador 1 programando los valores en TH1/TL1 en correspondencia ; con el tiempo de conteo escogido. org

001bh

clr

TR1

inc

R2

mov

TL1, 21h

mov

TH1, 22h

setb

TR1

reti ; Continuación de la Subrutina que atiende la INT0/ salto:

fin:

mov

DPTR, #tcartel2

lcall

cartel

; saca cartel de esperar por medición.

sjmp

ciclo

; escoge el tiempo de conteo para el Temporizador.

clr

25h.0

reti ; Continuación de la Subrutina de INT0/ salto3:

jnb

P3.0, pon1

mov

R2, #20

sjmp

salir

pon1:

mov

R2, #1

salir:

reti

; Inicio del Programa Principal. inicio:

clr

P3.7

; deshabilita el LCD.

clr

25h.0

; bandera de fuera de rango

clr

25h.5

; bandera de medicion erronea

lcall

proglamp

; establece la comunicacion con el diplay

mov

DPTR, #tcartel1

lcall

cartel

; muestra cartel de presentación.

Microcontroladores. El 8051 de la INTEL. ; Programacion de las interupciones externas y de los Temporizadopres. ; INT0/ por caida. Tecla Medir. ; Temporizador 0 contador de eventos de 16 bits Cuenta los pulsos de la señala medir. ; Temporizador 1 contador de tiempo de 16 bits. Establece el tiempo de conteol. mov

IE, #10001011b

mov

IP, #00001010b ; máxima prioridad a los Temporizadores.

mov

TCON, #00000001b

mov

TMOD, #00010101b

; Espera por la orden de Medir mediante el apretado de la Tecla del mimso nombre. sjmp

$

; en espera de que aprieten la Tecla Medir.

; Determinando el tiempo de conteo a habilitar para la medición en curso. ; Para ello lee el estado del Interruptor RANGO. ; RANGO cerrado la señal a medir esta en el Rango de 1 KHz a 400 KHz. ; RANGO abierto la señal a medir esta en el Rango de 1HZ a 999 HZ. ciclo:

jnb

P3.0, base2

; La seleccionada es el tiempo de conteol 1 para señales entre 1Hz a 999Hz mov

TL1, #0AFh

mov

21h, #0AFh

mov

TH1, #3Ch

mov

22h, #3Ch

mov

TL0, #18h

mov

TH0, #0FCh

; escogiendo tiempo de conteo en 1 segundo.

;cuenta pulsos hasta 999Hz antes de desbordarse.

; Inicio de la medición de la frecuencia de la señal.. setb

TR1

setb

TR0

; Espera que pase el tiempo de medición. cjne

R2, #20, $

; en espera del tiempo deseado

; Va a mostrar el valor de la medición. ; Detiene el conteo de ambos Temporizadores. clr

TR0

clr

TR1

; Fuera de Rango. jb

25h.0,salto1

; Prepara el dato de la medición para ser mostrado en el LCD. lcall

resta1

jb

25h.5,salto1

lcall

separa

lcall

muestra

457

Microcontroladores. El 8051 de la INTEL.

salto1:

lcall

unidad1

clr

25h.5

lcall

dem1seg

mov

DPTR, #tcartel1

lcall

cartel

sjmp

fin

458

; El tiempo de conteo es el 2 para señales entre 1KHz y 400KHz base2:

mov

TL1, #17h

mov

21h, #17h

mov

TH1, #0FCh

mov

22h, #0FCh

mov

TL0, #70h

mov

TH0, #0FEh

;cuenta pulsos hasta 400KHz antes de desbordarce.

; Inicializa el conteo de ambos Temporizadores. setb

TR1

setb

TR0

; Espera que pase el tiempo de medición. cjne

R2, #1, $

; Detiene el conteo de los Temporizadores. clr

TR0

clr

TR1

; Fuera de rango jb

25h.0, salto2

; Prepara el dato producto de la medición para ser mostrado por el LCD.

salto2:

lcall

resta2

jb

25h.5,salto2

lcall

separa

lcall

muestra

lcall

unidad2

clr

25h.5

lcall

dem1seg

mov

DPTR, #tcartel1

lcall

cartel

sjmp

fin

; Determina la cantidad de pulsos contados por el Temporizador 0 para rango de conteo entre 1 HZ ; y 999 HZ. ; Para ello resta al conteo final de dicho Temporizador el número en el cual empezó a contar. resta1:

mov

40h, #18h

Microcontroladores. El 8051 de la INTEL. mov

41h,#0FCh

lcall

convierte

459

ret ; Subrutina que obtiene la cantidad de pulsos contados por el Temporizador 0. convierte:

salcon:

mov

A, TL0

subb

A, 40h

; numero por el que empezo a contar el Temporizador 0

mov

30h, A

; valor real de la frecuencia (bms)

mov

A, TH0

subb

A,41h

; numero por el que empezo a contar el Temporizador.

mov

31h, A

; valor real de la frecuencia (BMs)

mov

A,30h

subb

A,#0

jnz

salcon

subb

A,31h

jnz

salcon

setb

25h.5

mov

DPTR,#tcartel5

lcall

cartel

ret

; Determina la cantidad de pulsos contados por el Temporizador 0 para rango de conteo entre ; 1KHz y 400 KHz. ; Para ello resta al conteo final de dicho Temporizador el número en el cual empezó a contar. resta2:

mov

40h,#70h

mov

41h,#0FEh

lcall

convierte

ret ; Esta subrutina divide el número en unidades, decenas y centenas para que pueda ser mostrado ; en el Display LCD. separa:

mov

A, 30h

mov

B, #10

div

AB

mov

30h,A

mov

DPTR, #tabla ;tabla de combinaciones

mov

A,31h

anl

A,#00000011b ;solo llegan a ocupar los 2 bits menos significativos

rl

a

jmp

@A+DPTR

; Tabla de saltos

Microcontroladores. El 8051 de la INTEL. tabla:

comb0:

sjmp

comb0

; cuando en 31h hay 00

sjmp

comb1

; cuando en 31h hay 01

sjmp

comb2

; cuando en 31h hay 10

sjmp

comb3

; cuando en 31h hay 11

mov

40h, B

; digito menos significativo: unidades

mov

A,30h

mov

B,#10

div

AB

mov

41h,B

;decenas

mov

42h,A

; digito mas significativo: centenas

mov

A, #6

;primer digito

add

A,B

lcall

compara

mov

40h,B

;unidad

mov

A,30h

;segundo digito

mov

B,#10

div

AB

mov

30h,A

mov

A,#5

lcall

sumconC

addc

A,B

lcall

compara

mov

41h,B

mov

A,30h

mov

B,#2

lcall

sumconC

addc

A,B

mov

42h,A

ret comb1:

;tercer digito

ret comb2:

mov

A,#2

add

A,B

lcall

compara

mov

40h,B

mov

A,30h

mov

B,#10

div

AB

mov

30h,A

;primer digito

;segundo digito

460

Microcontroladores. El 8051 de la INTEL. mov

A,#1

lcall

sumconC

addc

A,B

lcall

compara

mov

41h,B

mov

A,30h

mov

B,#5

lcall

sumconC

addc

A,B

mov

42h,A

;tercer digito

ret comb3:

mov

A, #8

add

A,B

lcall

compara

mov

40h,B

mov

A,30h

mov

B,#10

div

AB

mov

30h,A

mov

A,#6

lcall

sumconC

addc

A,B

lcall

compara

mov

41h,B

mov

A,30h

mov

B,#7

lcall

sumconC

addc

A,B

mov

42h,A

;primer digito

;segundo digito

;tercer digito

ret compara:

cjne

A,#10,dif

mayual:

mov

B,#10

div

AB

setb

23h.1

ret dif:

jnc

mayual

mov

B,A

clr

23h.1

;si cy=0 A>10 y se pasa a mayor igual

461

Microcontroladores. El 8051 de la INTEL.

462

ret sumconC:

jb

23h.1, conC

; si la bandera esta en 1 es necesario sumar con el carry

clr

C

;si la bandera esta limpia no es necesario adicionar el carry

ret conC:

setb

C

ret ; Programando el LCD. proglamp:

mov

P1, #38h

lcall

esccom

lcall

dem40

mov

P1, #06h

lcall

esccom

lcall

dem40

mov

P1, #0Eh

lcall

esccom

lcall

dem40

; define el bus de datos

;define el corrimiento del cursor

;enciende el display

ret ; Subrutina que saca por el LCD un cartel previamente almacenadoi en ASCII en una Tabla en la ; memoria de programa. ; La dirección de inicio de la Tabla debe estar almacenada en el registro DPTR antes de llamar a la ; Subrutina. cartel:

lazo:

mov

P1, #01h

lcall

esccom

lcall

dem164

mov

R5, #16

mov

R6, #0

mov

A, R6

; limpia el display

movc A, @A+DPTR mov

P1, A

lcall

esccar

lcall

dem40

inc

R6

djnz

R5, lazo

ret ; Esta Subrutina muestra el resultado en el LCD. muestra:

mov

DPTR, #tcartel4

lcall

cartel

; Cambia de renglón.

Microcontroladores. El 8051 de la INTEL. mov

P1, #0C4h

lcall

esccom

lcall

dem40

463

; Muestra en el LCD el valor de la medición. mov

A, 42h

lcall

muestraLCD

mov

A, 41h

lcall

muestraLCD

mov

A, 40h

lcall

muestraLCD

; tomando las centenas ; tomando las decenas ; tomando las unidades

ret ; Subrutina que muestra en el dispay un carácter ASCII previamente carghado en el Acumulador muestraLCD:

add

A, #48

mov

P1, A

lcall

esccar

lcall

dem40

ret ; Escribiendo las unidades de la frecuencia en Hz. unidad1:

mov

P1, #0C8h

lcall

esccom

lcall

dem40

mov

P1, #72

lcall

esccar

lcall

dem40

mov

P1, #122

lcall

esccar

lcall

dem40

; posicionando las unidades en el LCD

; el ASCII de la letra H.

; el ASCII de la letra z.

ret ; Escribiendo las unidades de la frecuencia en Khz. unidad2:

mov

P1, #0C8h

lcall

esccom

lcall

dem40

mov

P1, #75

lcall

esccar

lcall

dem40

mov

P1, #72

lcall

esccar

lcall

dem40

; posicionando las unidades en el LCD.

; el ASCII de la letra K.

; el ASCII de la letra H

Microcontroladores. El 8051 de la INTEL. mov

P1, #122

lcall

esccar

lcall

dem40

; el ASCII de la letra z.

ret ; Subrutina que escribe un comando en el LCD. esccom:

clr

P3.6

setb

P3.7

nop clr

P3.7

ret ; Subrutina que escribe un carácter ASCII en al LCD. esccar:

setb

P3.6

setb

P3.7

nop clr

P3.7

ret ; Subrutina que provoca na demora de 1.64 milisegundos. dem164:

mov

R7, #4

lazo164:

mov

R6, #205

djnz

R6,$

djnz

R7, lazo164

ret ; Subrutina que provoca una demora de 40 microsegundos. dem40:

mov

R7, #20

djnz

R7, $

ret ; Subrutina que provoca una demora de 1 segundo. ; permite mantener el valor de la frecuencia medida durante 1 segundo en el LCD para que sea ; medida antes de quedar listo el equipo para una nueva medición. dem1seg:

mov

r5, #8

lazo21:

mov

r4, #250

lazo11:

mov

r3, #250

djnz

r3,$

djnz

r4,lazo11

djnz

r5, lazo21

ret ; Tablas almacenadas en memoria de programas. tcartel1:

db

‘Apriete la Tecla ”

464

Microcontroladores. El 8051 de la INTEL. tcartel2:

db

‘Por Favor espere’

tcartel3:

db

‘Fuera de rango ’

tcartel4:

db

‘La Frecuencia es’

tcartel5:

db

‘Medicion erronea’

465

; Fin de compilación. end ; *************************************************************************************************************** 11.2 Controlador de Semáforo. . Un semáforo es un ejemplo de un dispositivo que funciona de forma secuencial y ciclica. Este consta de un conjunto de luces, por lo general 3, que se encienden y se apagan siguiendo un programa preestablecido y que no cambia en cuanto a su secuencia de operación, las que se repiten durante todo el tiempo de trabajo del mismo. Este programa preestablecido es el que le da las caracteristica de semáforo a este equipo, por eso le llamaremos Programa Semáforo. Otro aspecto importante esta relacionado con el tiempo en que permanece encendida una luz determinada dentro de la secuencia, el que es variable entre diferenetes semáforos, dependiendido de las caracteristicas de la via que este controlando. Por lo general estos dispositivos ejecutan dos programas durante su operación en el dia, considerando como 1 día las 24 horas. Uno, el Programna Semáforo del cual ya habiamos hablado anteriormente y el otro encendiendo y apagando de forma intermitente solo una de las luces, la roja o la amarilla en dependencia de las caracteristicas de la via que este controlando. A este programa lo llamaremos Programa Intermitente.. El paso de un programa a otro se realiza de forma automática según la hora del día. Durante el día y las primeras horas de noche en que el tráfico es alto se activa el Programa Semaforo. En el final de la noche, por lo general las 23:00 horas, y en la madrugada, por lo general hasta las 5:00 horas, en que el trafico disminuye mucho, el semáforo ejecuta el programa intermitente. Tomando en consideración todos estos aspectos propongamonos diseñar un Controlador para Semáforos con el empleo de un microcontrolador 8051, según el enunciado del ejemplo 11.2. Ejemplo 11.2. Diseñar un Controlador para Semáforos basado en el microcontrolador 8051. Las caracteristicas del controlador a diseñar son las siguientes: •

Los semáforos a controlar son de 3 luces, roja, verde y amarilla.

Microcontroladores. El 8051 de la INTEL. •

466

Los semáforos a controlar contarán con una señal sonora que indicara a los peatones cuando pueden cruzar la calle.



Debe permitir seleccionar 5 tipos de Programas Semáforos diferentes, tiempo de encendido y apagado de las luces y secuencia.



Debe controlar de forma automática el paso del Programa Semáforo al Programa Intermitente y vicecersa.



Debe permitir el trabajo con luces y dispositivos sonoros de diferentes caracteristicas electricas.



Debe indicar la hora en curso y permitir actualizar la hora en cualquier momento.

Para comenzar podría resultar interesante darle respuesta a la siguiente pregunta, ¿Cuáles de los recursos del 8051 son los necesarios para dar solución al problema que nos han propuesto? Una de las condiciones impuestas al controlador es la de permitir que el semáforo trabaje con 5 Programas de encendido y pagado de las luces diferentes, Programas Semaforo. Esto permite que el Controlador pueda ser adaptado a las caraterísticas de operación requeridas por el Semáforo al que va a controlar e impuestas por las caracteristicas de la via donde el mismo vaya a ser instalado. ¿Cómo el operador seleccionará el Programa Semáforo a ejecutará por el controlador? Para ello contará con un conmutador de 5 posiciones, una posición por cada posible Programa a seleccionar, de forta tal que todo lo que tiene que hacer el operador es colocar este conmutador en la posición que selecciona el Programa deseado atendiendo a las caracteristicas de la via donde vaya a ser instalado el Semáforo.. Para la atención de este conmutador dedicaremos los 5 bits menos significativos del Puerto 3, del P3.0 al P3.4, conectandolo según se muestra en la Figura 11.2.1.

Microcontroladores. El 8051 de la INTEL.

467

Figura 11.2.1. De la forma en que hemos conectado el conmutador el operador lo que hace es imponer un ‘0’ en una de las entradas del Puerto 3 en dependencia de la posición en que ponga el conmutador. De forma tal que si el operador quiere escoger el Programa 1, pondra el conmutador en la posición 1 imponiendo un ‘0’ en el terminal P3.4 de dicho Puerto, por lo que todo lo que tendrá que hacer nuestro programa es encuestar el estado en que se encuentran los bits de P3.0 a P3.4 para conocer cual de los posibles Programas es el seleccionado. Para poder ejecutar el Programa seleccionado el controlador debe llevar un conteo del tiempo, ya que un Programa no es más que dividir la operación del semáforo en estados que estan caracterizado por la condición en que se encuentran las luces y el tiempo en que debe permanecer en este estado. Los Programas los dividiremos en 5 estados: •

Estado 1.

Luz Roja encendida. Luz Verde apagada. Luz Amarilla apagada. Bocina sonando.



Estado 2.

Luz Roja encendida. Luz Verde apagada. Luz Amarilla apagada. Bocina no sonando.

Microcontroladores. El 8051 de la INTEL. •

Estado 3.

468

Luz Roja apagada. Luz Verde encendida. Luz Amarilla apagada. Bocina no sonando.



Estado 4.

Luz Roja apagada. Luz Verde encendida. Luz Amarilla encendida. Bocina no sonando.



Estado 5.

Luz Roja apagada. Lus Verde apagada. Luz Amarilla encendida. Bocina no sonando.

El tiempo de duración de cada uno de los estdos depende del Programa seleccionado. Por ejemplo para el Programa 1, en nuestro ejemplo, los tiempos de duración de cada estado son los siguientes: •

Estado 1

5 segundos.



Estado 2

15 segundos.



Estado 3

20 segundos.



Estado 4.

15 segundos



Estado 5

5 segundos.

Observe que la suma de los tiempos de duración de cada uno de los estados en este Programa es de 1 minuto, lo que va a ser así para todos los Programas por igual. En la Tabla siguiente mostramos de forma resumida los tiempos de diuración de cada uno de los Estados para cada uno de los Programas. Programa 1

2

3

4

5

Estado 1

5 seg.

5 seg.

5 seg.

5 seg.

5 seg.

Estado 2

15 seg.

10 seg.

15 seg.

5 seg.

20 seg.

Estado 3

20 seg.

20 seg.

15 seg.

30 seg.

20 seg.

Estado 4

15 seg.

20 seg.

20 seg.

15 seg.

10 seg.

Estado 5

5 seg.

5 seg.

5 seg.

5 seg.

5 seg.

Microcontroladores. El 8051 de la INTEL.

469

Si a esto le sumamos la condición impuesta al controlador de que debe indicar la hora, queda evidente la necesidad de implementar un reloj en el controlador. Para ello destinaremos al Temporizador 0 del 8051 el que interrumpira cada 50 000 microsegundos de forma tal que 20 interrupciones de dicho Tempoprizador indicaran que ha transcurrido 1 segundo. Para indicar la hora utilizaremos un Display formado por 6 Lamparas de 7 Segmentos de Änodo Común la que conectaremos los segmentos al Puerto 2 y con los bits de P1.0 a P1.5 activaremos la Lámpara en cada momento, ver Figura 11.2.2.

Figura 11.2.2. Es una caracteristica del trabajo con este tipo de visualizador, cuando son conectados como aparece en la Figura 11.2.2, la necesidad de escribir cada cierto tiempo la información en el mismo si se quiere mantener la misma de forma estable y entendible por el usuario, a este proceso se le llama Refrescamiento. Esto es debido a que todas las Lámparas estan conectadas a un bus común, en este caso el creado con los terminales del Puerto 2, no contando con un almacenador propio.

Microcontroladores. El 8051 de la INTEL.

470

Un criterio muy empleado es el de refrescar la información en las Lámparas cada 30 milisegundos o lo que es lo mismo 30 veces en un segundo, con lo que se garantiza estabilidad en la información que se muestra en el visualizador y nitides de la misma. Si disminuimos esta frecuencia de refrescamiento la información en el visualizador comienza a ser intermitente, efecto este indeseable para el usuario. Por otro lado si la aumentamos la información se verá con más nitides pero estariamos ocupando en un porciento innecsesario el tiempo del microcontrolador. Proponemos para nuestra aplicación utilizar el criterio de refrescar 30 veces en 1 segundo. ¿Cuál de los recursos con os que cuenta el microcontrolador nos puede ayudar en esta tarea? Por su puesto que la respuesta a la pregunta anterior es los Temporizadores. Ya el Temporizador 0 lo tenemos empleado para indicar la base de tiempo del reloj interno por lo que proponemos utilizar al Temporizador 1 para llevar a cabo esta tarea, el que programaremos para que interrumpa cada 30 000 microsegundos. Para poner en hora el reloj se han destinado dos Teclas identificadas con los nombres HORAS y MINUTOS las que proponemos conectar a los terminales P3.6 y P3.5 respectivamente. Estas Teclas funcionaran de la siguiente forma. Una vez que el Controlador sea llevado al modo de trabajo Poner en Hora, cada vez que la Tecla HORA sea apretada se incrementará en 1 el número que aparece en el campo HORA en el visualizador y con ello el registro destinado por el programa para llevar el conteo de las Horas del reloj. Una acción similar provocará el apretara la Tecla MINUTOS pero con el campo MINUTOS en el visualizador y con el registro destinado a llevar el conteo de los minutos del reloj. Hablamos en el parrafo anterior del Modo Poner en Hora, ¿Tendra otro Modo de Trabajo el Controlador? Definiremos dos como los posibles Modos de Trabajo en que puede estar operando el Controlador: 1. Modo de Trabajo Poner en Hora. 2. Modo de Trabajo Trabajo como Semáforo. El Modo Poner en Hora es al que debemos llevar el Controlador cada vez que querramos actualizar la Hora del reloj interno del mismo. Una vez activado este Modo de Trabajo, ocurren las siguientes acciones:

Microcontroladores. El 8051 de la INTEL. •

471

La luz roja del Semáforo se enciende permaneciendo en este estado durante todo el tiempo en que el controlador se mantenga en este modo de trabajo.



El reloj interno se detiene quedando fija en el visualizador la hora, los minutos y los segundos al que fue activado este modo de trabajo.



Las Teclas HORA y MINUTOS se activan con el objetivo de que el operador pueda actualizar el reloj interno.

Por su parte en el Modo Trabajo Semáforo ocurren las siguientes acciones: •

Se activa el reloj interno.



El visualizador se actualiza con la hora en curso a medida que va transcurriendo el tiempo.



Se activa el Conmutador de Programas.



Se pasa a ejecutar el Programa seleccionado por el operador.

¿Como escoger estos Modos de Trabajo? Para ello proponemos colocar en el circuito un Interruptor Simple Polo Simple Tiro conectado al terminal P3.7 del 8051, de forma tal que: •

Interruptor abierto Modo de Trabajo Poner en Hora.



Interruptor cerrado Modo de Trabajo Trabajo Semáforo.

En la Figura 11.2.3 se muestra como quedan conectados estos dispositivos al microcontrolador.

Figura 11.2.3.

Microcontroladores. El 8051 de la INTEL.

472

El objetivo del Controlador es el de encender y apagar un conjunto de luces según un programa preestablecido, con la condición impuesta de permitir que las caracteristicas eléctricas de las luces sea variable de un Semáforo a otro. ¿Cómo lograr lo anterior? La acción de apagar o encender una cualquiera de las luces del Semáforo le llevaremos a cabo mediante la puesta a ‘0’ o a ‘1’

de un terminal determinado de uno de los Puertos del

microcontrolador. Por ejemplo podriamos destinar a los terminales P0.0, P0.1 y P0.2 del Puerto 0 para las luces rojas, amarilla y verde respectivamente. Pero las caracteristicas electricas de estos terminales del Puerto 0 no permiten que se le conecten directamente cualquier tipo de luces, es más nos atreveríamos a decir, que es bastante reducido los tipos de luces que se le pueden conectar directamente. Por ejemplo si las luces del Semáforo necesitan de 24 volts con 500 miliamperes para encender ya estas no podrian ser conectadas directamente a estos terminales. Para lograr esta necesaria compatibilidad entre las salidas de los Puertos utilizados para controlar el encendido y apagado de las luvces del Semáforo y las caracteristicas eléctricas de las diferentes luces que pueden estar presente en los mismos emplearemos relay. ¿Qué es un relay? Un relay es un dispositivo electromagnetico conformado por un enrollado y un interruptor, ver Figura 11.2.4.

Figura 11.2.4. Entre sus caracteristicas se encuentran: •

Voltaje en el enrollado.



Resistencia en el enrollado.



Corriente máxima en el Interruptor.



Voltaje máxima en el Interruptor.

Microcontroladores. El 8051 de la INTEL.

473

¿Cómo funciona este dispositivo? Analicemos el funcionamiento de los relay utiilizanco como ejemplo al mosrado en la Figura 11.2.4. El relay presentado en la figura tiene dos contactos o dos interruptores con un punto común (c). Uno de los contactos se encuentra entre los terminales a y c del relay y se dice que es un contacto normalmente abierto, mientras que el otro se encuentra entre los terminales b y c del relay y constituye un contacto normalmente cerrado. La palabra normalmente indica el estado en que se encuentra el interruptor cuando a su enrollado no se le esta aplicando voltaje. ¿Qué sucede cuando al enrollado se le aplica el voltaje en el enrollado que aparece como dato del relay? Los contactos pasan al estado contrario al que se encontraban cuando a su enrollado no se le aplicaba este voltaje. Para el ejemplo que estamos analizando los contactos a y c se cerrarian y los contactos b y c se abririan. ¿Cómo conectariamos los relay en nuestro Controlador? Con los terminales del Puerto controlamos que se le aplique el voltaje requerido a los enrollados de los relay para que estos se activen. De esta manera manejamos el estado en que se encuentran los interruptores, cerrados o abiertos. A los interruptores del relay conectamos las luces del Semáforo de froma tal que las caracxteristicas electricas de los contactos serán los que impongan los tipos de luces, en cuanto a voltaje y corriente, que pueden ser manejadas por el controlador, ver Figura 11.2.5.

Microcontroladores. El 8051 de la INTEL.

474

Figura 11.2.5. En el circuito mostrado en la figura aparece otro dispositivo entre los terminales del Puerto 0 del microcontrolador y los relay los que aparecen con el nombre de Optoacoplador. ¿Qué es un Optoacoplador? ¿Para que conectarlos entre los terminales del Puerto y los relay? Un Optoacoplador es un dispositivo electrónico que esta integrado por dos elementos: •

Un diodo emisor de luz, al que llamaremos Emisor.



Un transistor bipolar con su base sensible a la luz, al que llamaremos Detector.

El objetivo fundamental de estos dispositivos es el de aislar eléctricamente al circuito conectado al Emisor del circuito conectado al Detector. Efectivamente entre el Emisor y el Detector del Optoacoplador no existe conexión eléctrica ninguna por lo que el circuito conectado al Detector no influye del punto de vista eléctrico prácticamente en lo absoluto al circuito conectado al Emisor. Esto es muy conveniente cuando se trabaja con circuitos que puedan introducir fuertes ruidos eléctricos al microcontrolador en su operación, como

Microcontroladores. El 8051 de la INTEL.

475

pueden ser las bobinas o enrollados como es el caso de los relay. Esta es la razón por la que aparece conectada en nuestra propuesta de circuito, para aislar eléctricamente la operación d elos relay que soportan las luces del Semáforo de los terminales del Puerto 0 que controlan su operación. ¿Cómo funcionan estos circuitos? Si por el Emisor circula la corriente requerida este emitira una luz que incidirá directamente en la base del Detector, el que se podría llegar a saturar si las resistencias en los circuitos se calcularon buscando este objetivo. Si por el contrario por el Emisor no circula corriente este no emitirá luz y por ende el Detector se encontrara cortado. En nuestro ejemplo nosotros lo que haremos es controlar el paso o no de corriente por el Emisor de los Optoacopladores y con ello manejaremos los contactos de los relay, con lo que gobernamos el encendido o apagado de las luces del Semáforo. Por ejemplo si decidimos que la luz roja se encenderá cuando los contactos a y c del relay conectado al terminal P0.0 se cierran todo lo que tenemos que hacer por programa es que cuando querramos encender la luz roja pongamos en ‘0’ al terminal P0.0 del Puerto 0 del microcontrolador. Esto provocará que por el Emisor del Optoacoplador correspondiente circule corriente, con lo que saturamos al Detector del este Optoacoplador. Esto provoca que por el enrollado del relay circule la corriente necesaria para que los contactos a y c se cierren y con ello la luz roja se cierra. Cuando querramos apagar dicha luz todo lo que tendremos que hacer es poner en ‘1’ al mismo terminal, con lo que no circula corriente por el Emisor del Optoacoplador, cortandose el Detector, no circulando corriente por el enrollado del relay, abriendose los contactos a y c. En la Figura 11.2.6 se muestra el hardware completo que proponemos para la solución del ejemplo planteado.

Microcontroladores. El 8051 de la INTEL.

476

Figura 11.2.6. El software que proponemos para controlar la operación del hardware mostrado es el que muestra a continuación. ;**************************************************************************************************************** ; Inicio del Programa Semáforo. org

0

ljmp

inicio

; El Temporizador 0 marca la base de tiempo del reloj. org

000bh

ljmp

actualiza

; El Temporizador 1 marca el tiempo de refrescamiento del Visualizador. org

001bh

ljmp

visuali

; Inicio del Programa Principal. ; Inicializa los Registros que van a ser utilizados por el programa. inicio:

mov

R0,#0

; para contar un segundo

mov

R1,#0

; para llevar el conteo de los segundos

Microcontroladores. El 8051 de la INTEL. mov

R2,#0

; para llevar el conteo de los minutos

mov

R3,#0

; para llevar el conteo de las horas

clr

21h.0

; bandera de modo especial de trabajo.

; Programando a los circuitos empotrados en el microcontrolador que van a ser utilizados. ; Controlador de Interrupciones. ;

INT0/ para la Tecla HORAS

;

INT1/ para la Tecla MINUTOS.

;

TEMP0 marca la base de tiempo del reloj

;

TEMP1 marca el tiempo de refrescamiento del Visualizador. mov

IE,#10001010b

; Programando a los Temporizadores. ; Temporizador 0. Modo 1, contador de tiempo, disparo por software. ; Temporizador 1. Modo 2, contador de tiempo, disparo por software. mov

TMOD,#00100001b

; Temporizador 0 se desborda cada 50 000 microsegundos mov

TL0, #0b0h

mov

TH0, #3ch

; Temporizador 1 se desborda cada 200 microsegundos. mov

TL1, #37h

mov

TH1, #37h

; Habilita al Temporizador 1. Refrescamiento del display. setb

TR1

; Inicializa al registro DPTR con el puntero a la tabla de conversion de binario a ; codigo de Lampara de 7 Segmentos. mov

DPTR,#tabla

; Encuesta el modo de trabajo. encuesta:

jb

P3.7,teclado

; esta en el Modo Poner en Hora

; Esta en el Modo Semaforo. sigue:

jb

21h.0,$

jnb

P3.4,prog1

; es el Programa 1.

jnb

P3.3,prog2

; es el Programa 2.

jnb

P3.2,prog3

; es el Programa 3.

jnb

P3.1,prog41

; es el Programa 4.

jb

P3.0,encuesta

ljmp

prog5

; Salto a programa 4. prog41:

ljmp

prog4

; Poniendo en hora al reloj.

; es el Programa 5.

477

Microcontroladores. El 8051 de la INTEL. teclado:

mov

P0,#11111110b; enciende la luz roja

clr

TR0

; detiene el reloj

lcall

minutos

; apretaron la Tecla MINUTOS.

lcall

horas

; apretaron la Tecla HORAS

sjmp

encuesta

; ninguna Tecla apretada.

; Hecha a andar el Programa 1. prog1:

setb

TR0

; hecha a andar el reloj.

mov

P0,#11110110b; enciende la luz roja y hace sonar la bocina.

; Espera por 5 segundos. est11:

mov

A,R1

cjne

A,#5,est11

; Apagar la bocina. est21:

mov

P0,#11111110b

mov

A,R1

cjne

A,#20,est21

; Apagar la luz roja. ; Encender luz verde. est31:

mov

P0,#11111011b

mov

A,R1

cjne

A,#40,est31

; Apagar la luz verde. ; Encender la luz verde - amarilla. est41:

mov

P0,#11111001b

mov

A,R1

cjne

A,#55,est41

; Encender la luz amarilla. est51:

mov

P0,#11111101b

mov

A,R1

cjne

A,#0,est51

; Repetir el proceso. sjmp

encuesta

; Hecha a andar el Programa 2. prog2:

setb

TR0

mov

P0,#11110110b; enciende la luz roja y hace sonar la bocina.

; Espera por 5 segundos. est12:

mov

A,R1

cjne

A,#5,est12

; Apagar la bocina.

478

Microcontroladores. El 8051 de la INTEL.

est22:

mov

P0,#11111110b

mov

A,R1

cjne

A,#15,est22

; Apagar la luz roja. ; Encender luz verde. est32:

mov

P0,#11111011b

mov

A,R1

cjne

A,#35,est32

; Apagar la luz verde. ; Encender la luz verde - amarilla. est42:

mov

P0,#11111001b

mov

A,R1

cjne

A,#55,est42

; Encender la luz amarilla. est52:

mov

P0,#11111101b

mov

A,R1

cjne

A,#0,est52

; Repetir el proceso. sjmp

encuesta

; Hechar a andar el Programa 3. prog3:

setb

TR0

mov

P0,#11110110b; enciende la luz roja y hace sonar la bocina.

; Espera por 5 segundos. est13:

mov

A,R1

cjne

A,#5,est13

; Apagar la bocina. est23:

mov

P0,#11111110b

mov

A,R1

cjne

A,#20,est23

; Apagar la luz roja. ; Encender luz verde. est33:

mov

P0,#11111011b

mov

A,R1

cjne

A,#35,est33

; Apagar la luz verde. ; Encender la luz verde - amarilla. est43:

mov

P0,#11111001b

mov

A,R1

479

Microcontroladores. El 8051 de la INTEL. cjne

A,#55,est43

; Encender la luz amarilla. est53:

mov

P0,#11111101b

mov

A,R1

cjne

A,#0,est53

; Repetir el proceso. ljmp

encuesta

; Hechar a andar el Programa 4. prog4:

setb

TR0

mov

P0,#11110110b; enciende la luz roja y hace sonar la bocina.

; Espera por 5 segundos. est14:

mov

A,R1

cjne

A,#5,est14

; Apagar la bocina. est24:

mov

P0,#11111110b

mov

A,R1

cjne

A,#10,est24

; Apagar la luz roja. ; Encender luz verde. est34:

mov

P0,#11111011b

mov

A,R1

cjne

A,#40,est34

; Apagar la luz verde. ; Encender la luz verde - amarilla. est44:

mov

P0,#11111001b

mov

A,R1

cjne

A,#55,est44

; Encender la luz amarilla. est54:

mov

P0,#11111101b

mov

A,R1

cjne

A,#0,est54

; Repetir el proceso. ljmp

encuesta

; Hecha a andar el programa 5. prog5:

setb

TR0

mov

P0,#11110110b; enciende la luz roja y hace sonar la bocina.

; Espera por 5 segundos. est15:

mov

A,R1

; hecha a andar el reloj.

480

Microcontroladores. El 8051 de la INTEL. cjne

A,#5,est15

; Apagar la bocina. est25:

mov

P0,#11111110b

mov

A,R1

cjne

A,#25,est25

; Apagar la luz roja. ; Encender luz verde. est35:

mov

P0,#11111011b

mov

A,R1

cjne

A,#45,est35

; Apagar la luz verde. ; Encender la luz verde - amarilla. est45:

mov

P0,#11111001b

mov

A,R1

cjne

A,#55,est45

; Encender la luz amarilla. est55:

mov

P0,#11111101b

mov

A,R1

cjne

A,#0,est55

; Repetir el proceso. ljmp

encuesta

; Actualiza la hora. Es la Subrutina correspondiente a la interrupcion del Temporizador 0 ; cada 50 000 microsegundos. actualiza:

mov

20h,A

; resguarda el contenido del registro A

; Averigua si ha pasado 1 segundo por lo que se hace necesario actualizar la hora. ; Para ello utiliza el registro R2 el que debe llegar al cnteo de 20. inc

R0

cjne

R0,#20,fin1

; Actualizar los segundos.

sigue3:

mov

R0,#0

inc

R1

jnb

21h.0,sigue3

mov

A,22h

xrl

A,#11111111b

orl

A,#11111110b

mov

22h,A

mov

P0,A

cjne

R1,#60,fin1

; en R1 los segundos.

; se actualizan los minutos.

481

Microcontroladores. El 8051 de la INTEL. ; Actuaizo los minutos. mov

R1,#0

inc

R2

; en R2 los minutos

cjne

R2,#60,fin1

; se actualizan las horas.

; Actualizo las horas.

sigue1: sigue2:

mov

R2,#0

inc

R3

cjne

R3,#23,sigue1

setb

21h.0

cjne

R3,#5,sigue2

clr

21h.0

cjne

R3,#24,fin1

mov

R3,#0

; en R3 las horas. ; inicio del modo especial ; fin del modo especial

; Reprogramo el temporizador 0 para que interrumpa nuevamente a los 50 000 microsegundos. fin1:

mov

Tl0, #0b0h

mov

Th0, #3ch

mov

a,20h

; restablezco el contenido del registro A.

reti ; Subrutina que refresca el Visualizador. ; Es la Subrutina corespondiente a la interrupcion del Temporizador 1. ; Se jecuta cada 200 microsegundos. visuali:

mov

20h,A

; resguarda el valor en el registro A.

mov

A,R3

; en el registro R3 estan las horas en binario.

lcall

bcd

; convierte las horas a BCD desempaquetado.

; Muestra las horas.

movc A,@a+DPTR

; convierte a codigo de Lampara de 7 Segmentos

; Escribe en la Lampara 1 del Visualizador. mov

P2,A

setb

P1.0

setb

P2.7

lcall

demora

clr

P1.0

; Hace el mismo tratamiento con el segundo carater BCD de las horas. mov

A,B

movc A,@A+DPTR

; en el registro B el segundo caracter BCD ; convierte a codigo de Lampara de 7 Segmentos

; Escribe en la Lampara 2 del Visualizador. mov

P2,A

setb

P1.1

482

Microcontroladores. El 8051 de la INTEL. lcall

demora

clr

P1.1

; Muestra los minutos. mov

A,R2

; en el registro R2 los minutos en binario.

lcall

bcd

; convierte los minutos a BCD desempaquetado

movc A,@A+DPTR

; convierte a codigo de Lampara de 7 Segmentos

; Escribe en la Lampara 3 del Visuañlizador mov

P2,A

setb

P1.2

setb

P2.7

lcall

demora

clr

P1.2

; Hace el mismo tratamiento con el segundo carater BCD de las minutos. mov

A,B

movc A,@A+DPTR

; en el registro B el segundo caracter BCD ; convierte a codigo de Lampara de 7 Segmentos

; Escribe en la Lampara 4 del Visualizador. mov

P2,A

setb

P1.3

lcall

demora

clr

P1.3

; Muestra los segundos. mov

A,R1

; en el registro R1 los segundos en binario.

lcall

bcd

; convierte los segundos a BCD desempaquetado

movc A,@A+DPTR

; convierte a codigo de Lampara de 7 Segmentos

; Escribe en la Lampara 5 del Visualizador. mov

P2,A

setb

P1.4

setb

P2.7

lcall

demora

clr

P1.4

; Hace el mismo tratamiento con el segundo carater BCD de los segundos. mov

A,B

movc A,@A+DPTR

; en el registro B el segundo caracter BCD ; convierte a codigo de Lampara de 7 Segmentos

; Escribe en la Lampara 6 del Visualizador. mov

P2,A

setb

P1.5

setb

P2.7

lcall

demora

483

Microcontroladores. El 8051 de la INTEL. clr

484

P1.5

; Restablece el contenido del registro A. mov

A,20h

reti ; Actualiza de forma manual los minutos. minutos:

salmin:

jb

P3.5,salmin

jnb

P3.5,$

inc

R2

cjne

R2,#60,salmin

mov

R2,#0

; espera porque liberen la Tecla.

ret

; Actualiza de forma manual las horas. horas:

salhor:

jb

P3.6,salhor

jnb

P3.6,$

inc

R3

cjne

R3,#24,salhor

mov

R3,#0

; espera porque liberen la Tecla.

ret

; Subrutina que provoca una demora de 8 000 microsegundos. demora:

mov

R5,#100

lazodem:

mov

R4,#40

djnz

R4, $

djnz

R5,lazodem

ret ; Subrutina que convierte en número en binario en 8 bits almacenado en el registro A ; a BCD desempaquetado. ; El BCD correspondiente a los 4 bits menos significativos salen en el registro B. ; El BCD correspondiente a los 4 bits mas significativos salen en el registro A. bcd:

mov

B,#10

div

AB

ret ; Tablas con los codigos a Lampara de 7 Segmentos de los digitos decimales. tabla:

db

40h,79h,24h,30h,19h,12h,02h,78h,00h,18h

end ; ***************************************************************************************************************

Microcontroladores. El 8051 de la INTEL.

485

Tema 12. El Microcontrolador 8051 trabaja como Microprocesador. Podemos encontrarnos con aplicaciones en que alguno de los recursos que brinda el microcontrolador empotrados en el no sea suficiente para la solución de las mismas. Por ejemplo, al Programa desarrollado no le es suficiente con los 4k localizaciones de Memoria de Programa interna destinados para su almacenamiento, o no nos es suficiente con los 128 byte de Memoria de Datos interna para almacenar los datos que impone la aplicación, o necesitamos de más terminales que los que nos brindan los Puertos de Entada/Salida para conectar diferentes dispositivos al microcontrolador, o no nos es suficiente con los dos Temporizadores, etc. ¿Que hacer en estos casos? El microcontrolador 8051 tiene un Modo Especial de trabajo en el que se comporta como un microprocesador, generando externamente su propio Bus de Direcciones, Bus de Datos y Señales de Control de manera tal que se le puede agregar tanto Memoria de Programa como Memoria de Datos, así como otros dispositivos de forma externa. Al estudio de este Modo Especial de Trabajo esta dedicado este Tema. 12.1 Los Buses Externos del Microcontrolador 8051. Las primeras preguntas que nos hacemos una vez que conocemos que existe este Modo Especial de Trabajo por lo general son las siguientes, ¿Hasta que cantidad de Memoria de Programa se le puede agregar externamente al microcontrolador? ¿Hasta que cantidad de Memoria de Datos se le puede agregar externamente al microcontrolador? ¿Hasta que cantidad de Puertos de Entrada/Salida se le puede agregar externamente al Microcontrolador? La respuesta a estas preguntas esta estrechamente relacionado con la cantidad de bits que compongan el Bus de Direcciones Externo que entregue el 8051. El Bus de Direcciones Externo del 8051 es una extensión de su Bus de Direcciones Interno y por lo tanto es de 16 bits. Esto hace que el microcontrolador pueda generar como máximo 64 K direcciones diferentes.

216 = 65536 = 64 K

Microcontroladores. El 8051 de la INTEL.

486

Por lo que si estamos agregando externamente es Memoria de Programa la capacidad máxima podría llegar a ser de 64 Kilobyte, mientras que si lo que estamos agregando es Memoria de Datos la capacidad máxima sería de la misma magnitud. Concentrémonos inicialmente en la Memoria de Programa. La mayoría de las versiones del microcontrolador 8051 traen empotrados en el circuito integrado una capacidad dada de Memoria de Programa la que varía de una versión a otra. La pregunta a responder en este momento sería, ¿No entran en contradicción la Memoria de Programa Interna que viene empotrada en el microcontrolador con los 64 Kilobyte posible a conectar externamente al mismo? Existen tres terminales del microcontrolador 8051 de los cuales no hemos hablado hasta el momento en el presente libro y que estan estrechamente relacionados con el agregar circuitos, ya sean Memoria de Programa o Memoria de Datos o Puertos de Entrada/Salida, de forma externa al microcontrolador 8051. Estos terminales son, ver Figura 12.1:



EA/. External Addres. Terminal de entrada.



PSEN/. Program Enable. Terminal de salida.



ALE. Addres Match Enable. Terminal de salida.

Mediante la manipulación del terminal EA/, el diseñador puede definir diferentes combinaciones para la Memoria de Programa: •

EA/ en ´0´. Toda la Memoria de Programa es externa, desestimando el microcontrolador su Memoria de Programa interna. En este caso la Memoria de Programa Externa agregada al microcontrolador puede llegar a ser como máximo de 64 Kilobyte.

Microcontroladores. El 8051 de la INTEL. •

487

EA/ en ´1´. La Memoria de Programa del microcontrolador es una combinación de la Interna con la agregada externamente. En este caso el microcontrolador si estima en su trabajo su Memoria de Programa Interna, permitiendo al diseñador aumentar esta capacidad agregando Memoria de Programa de forma externa, hasta un máximo de 64 Kilobyte entre la suma de las capacidades de ambas. Por ejemplo si el microcontrolador con que estamos trabajando cuenta con na capacidad de Memoria de Programa Interna de 4 Kilobyte, el diseñador puede agregar externamente como máximo 60 Kilobyte, ver Figura 12.2.

Figura 12.2. En el caso de la Memoria de Datos, la capacidad máxima de Memoria de Datos Externa posible a agregar al microcontrolador es de 64 Kilobytes independientemente de la capacidad de Memoria de Datos Interna del microcontrolador. Esto es independiente al valor impuesto al terminal EA/, ver Figura 12.3.

Microcontroladores. El 8051 de la INTEL.

488

Figura 12.3. La pregunta a contestar en este momento sería, Si existe la posibilidad, en un diseño dado, que localizacines de la Memoria de Datos Interna tengan las mismas direcciones que localizaciones de la Memoria de Datos Externa, ¿Cómo el microcontrolador puede diferenciar a cual se esta refiriendo el Programa en una instrucción dada? Para ello, en el Repertorio de Instrucciones del microcontrolador, existe una instrucción específica para trabajar con la Memoria de Datos Externa distinta de la empleada para trabajar con la Memoria de Datos Interna. Esta instrucción es MOVX, por lo que el microcontrolador cuando se encuentra en el Programa con esta instrucción reconoce que la intensión del programador es la de trabajar con Memoria de Datos agregada externamente y no con la Memoria de Datos Interna empotrada en el microcontrolador, ver Figura 12.4.

Microcontroladores. El 8051 de la INTEL.

489

Figura 12.4. Una limitante lo constituye que si usted tiene la necesidad de agregar otros circuitos como Puertos de Entrada/Salida al microcontrolador, estos los tiene que ubicar dentro del espacio de memoria destinado para la Memoria de Datos Externa y por lo tanto le robaran capacidades a esta última. Por lo que el microcontrolador al trabajar con Puertos de Entrada/Salida Externos los trata como Memoria de Datos y teniendo que emplear el programador la instrucción MOVX para efectuar una operación sobre los mismos. El Bus de Datos Externo también constituye una extensión del Bus de Datos Interno por lo tanto es de 8 bits. El 8051 conserva para sus conexiones externas la Arquitectura de Von Neuman interna tratando a la Memoria de Datos como segregada. Estos dos elementos imponen que el tamaño en bits de cada localización de Memoria tanto de Programas como de Datos sea de 8 bits, agrupándose los bits en las localizaciones de memoria en byte. Hasta aquí hemos hablado de Bus de Direcciones Externo y de Bus de Datos Externo, pero cuando estudiamos los terminales del microcontrolador 8051, no existía ninguno destinado a estas operaciones. Las preguntas a responder en este momento podrían ser, ¿Por que terminales del 8051 salen las líneas del Bus de Direcciones Externo? ¿Por que terminales del 8051 salen las líneas del Bus de Datos Externo?

Microcontroladores. El 8051 de la INTEL.

490

Para darle respuestas a estas interrogantes estudiemos el comportamiento del microcontrolador 8051 cuando trabaja en su Modo Especial de Trabajo. 12.2 Modo Especial de Trabajo del Microcontrolador 8051. Analicemos los terminales el Puerto 0 y del Puerto 2 del microcontrolador 8051, ver Figura 12.5.

Figura 12.5. Las funciones alternativas de estos terminales constituyen las líneas de los Buses de Direcciones y de Datos. A través de los terminales del Puerto 2 se envían los bits de la parte alta del Bus de Direcciones, desde A8 hasta A15, mientras que el Puerto 0 constituye un bus multiplexado de Direcciones y de Datos, de forma tal que a través del mismo salen los bits de la parte baja del Bus de Direcciones desde A0 hasta A7 y los bits del Bus de Datos desde D0 hasta D7. De ahí que el nombre que reciban las funciones alternativas de este puerto sean AD0 hasta AD7, A de address y D de data. ¿Cómo funcionan estos Buses? Durante cada operación de búsqueda del código de la instrucción a ejecutar en Memoria de Programa Externa o en cada operación de lectura en Memoria de Programa Externa o en cada operación de lectura o escritura en Memoria de Dato Externa a través de los terminales del Puerto

Microcontroladores. El 8051 de la INTEL.

491

2, el microcontrolador envia los 8 bits más significativos correspondientes a la dirección de la localización de Memoria Externa involucrada en la operación, mientras que a través de los terminales del Puerto 0 se envían, los 8 bits menos significativos correspondientes a la dirección de la localización de Memoria Externa involucrada en la operación primero y un instante de tiempo después, esta dirección desaparece de dichos terminales enviándose o recibiendose en dependencia del tipo de opareción que este ejecutando el microcontrolador el dato involucrado en dicha operación, ver Figura 12.6.

Figura 12.6. Es responsabilidad del diseñador almacenar externamente la parte baja del Bus de Direcciones, A7-A0, antes de que desaparezca de los terminales del Puerto 0 de forma tal que la misma se mantenga estable durante todo el tiempo que dura el ciclo de máquina externo garantizando de esta forma la ejecuci’on corecta de la operaci’on del microcontrolador. Para ello tiene que demultiplexar los terminales del Puerto 0. ¿Como hacer esto? Para poder hacer la demultiplexación se hace necesario que el microcontrolador indique externamente cuando es el momento preciso para almacenar la información presente en los terminales del Puerto 0, información esta que resultará a la postre la parte baja de la dirección. Para ello viene en ayuda del diseñador la señal ALE, terminal 30 del ciruito integrado, que genera el microcontrolador, ver Figura 12.7.

Microcontroladores. El 8051 de la INTEL.

492

Figura 12.7. Hasta ahora no habíamos hablado sobre esta señal porque cuando el 8051 trabaja como microcontrolador la misma no resulta importante tenerla en cuenta, no obstante, cuando este trabaja en su modo especial, como en este caso, si resulta imprescindible hablar de ella. ALE es una señal activa en ´1´ y que el microcontrolador activa para indicar que esta efectuando una operación en memoria externa. Durante el tiempo en que ALE se encuentre en ´1´, los terminales del Puerto 0 están haciendo la función de Bus de Direcciones y por ende en ellos se encuentra la parte baja de la dirección de memoria externa con la que desea trabajar el microcontrolador, ya sea de programa o de datos, ver Figura 12.8.

Figura 12.8.

Microcontroladores. El 8051 de la INTEL.

493

Observe que la parte baja de la dirección se mantiene en las líneas del Puerto 0 mientras la señal ALE se encuentra en ´1´, desapareciendo un instante después de que caiga esta señal a ´0´. No obstante, la parte baja de la dirección desaparece del Puerto 0 antes de que responda el dispositivo externo que ha sido direccionada. Esto por su puesto que provocaría un error en la operación del sistema si esta dirección no es preservada hasta que el dispositivo externo direccionado concluya con su operación. Esto hace que sea imprescindible para el diseñador capturar y almacenar el valor en los terminales del Puerto 0 con el frente de caida de la señal ALE y con ello conformar la parte baja del Bus de Direcciones del sistema. Para ello se puede emplear un Circuito Almacenador de 8 bits de la Familia 74 de la Texas Instruments, como es el 74LS373, ver Figura 12.9.

Figura 12.9. Los bits de la parte alta del Bus de Direcciones que salen por los terminales del Puerto 2 no son necesarios almacenar ya que se mantiene durante todo el tiempo que dure la operación con el dispositivo externo.

Microcontroladores. El 8051 de la INTEL.

494

La operación externa que esta haciendo el microcontrolador puede ser sobre una localización ubicada en la Memoria de Programa Externa o sobre una localización ubicada en la Memoria de Datos Externa. La pregunta a contestar en este momento sería, ¿Como el microcontrolador indica que la dirección que esta generando se corresponde con una localización de Memoria de Programa o con una localización de Memoria de Datos? Son tres las señales empleadas por el microcontrolador ara indicar sobre que tipo de memoria externa esta efectuan la operación y que tipo d eoperación es la que esta efectuando. Estas señales son, PSEN/, WR/ y RD/, ver Figura 12.10.

Figura 12.10. La primera se activa cuando el microcontrolador esta efectuando una operación de búsqueda de un código almacenado en la Memoria de Programa Externa o leyendo el contenido de una localización ubicada en dicha memoria. De las otras dos no habiamos hablado aún las mismas comparten los terminales con los bits 6 y 7 del Puerto 3, ver Figura 12.10, constituyendo funciones alternativas de las mismas. WR/ se activa cuando el microcontrolador esta efectuando una operación de escritura en Memoria de Datos Externa y RD/ cuando el microcontrolador esta efectuando una operación de lectura en Memoria

Microcontroladores. El 8051 de la INTEL.

495

de Datos Externa. Las tres señales son activas en ´0´ y son excluyentes. En la Tabla que se muestra a continuación se resume lo expresado anteriormente sobre estas tres señales. PSEN/

RD/

WR/

OPERACIÓN

0

1

1

1

0

1

1

1

0

Búsqueda del código de la próxima instrucción a eejcutar en Memoria de programa Externa. Lectura de un dato almacenado en una localización de memoria de Datos Externa. Escritura de un dato en una localización de memoria ubicada en Memoria de Dato Externa.

En la Figura 12.11 se muestra como el Microcontrolador genera en el tiempo las señales anteriores en los ciclos de acceso a memoria externa.

Operaciones de Búsqueda y Lectura en Memoria de Programa Externa.

Microcontroladores. El 8051 de la INTEL.

496

Escritura en Memoria de Datos Externa.

Lectura en Memoria de Datos Externa. Figura 12.11. La generación de las señales PSEN/, RD/ y WR/ pueden ser aprovechadas para pasar a través de ´buffers´ las líneas del Bus de Datos y con ello darle la misma capacidad de carga a todas las

Microcontroladores. El 8051 de la INTEL.

497

líneas de los buses. En la Figura 12.12 se muestra como quedaría el circuito utilizando el Buffer Bidireccional de 8 bits de la Familia 74 de la Texas Instruments, 74LS245.

Figura 12.12. ¿Como el microcontrolador determina que el acceso que tiene que hacer a memoria se corresponde con memoria externa y no con su memoria interna? Comencemos con los accesos a la Memoria de Programa. Siempre que el microcontrolador vaya a efectuar una operación de lectura en la Memoria de Programa ya sea en una Búsqueda del Código de la próxima instrucción a ejecutar o en una Lectura propiamente dicho y se esta refiriendo a una localización de memoria cuya dirección no se corresponde con una localización de Memoria de Programa Interna, el microcontrolador efectúa un acceso a Memoria de Programa Externa generando la señal PSEN/ y enviando por los Puertos 0 y 2 la dirección correspondiente, recibiendo el código o el dato leido a través de los terminales del Puerto 0.

Microcontroladores. El 8051 de la INTEL.

498

Por ejemplo, para versiones del 8051 con capacidad de Memoria de Programa Interna de 4 Kilobyte o lo que es lo mismo, direcciones enmarcadas entre la 0000h a la 0FFFh, si la dirección de la localización de Memoria de Programa a la que esta accesando el microcontrolador está por encima de este rango de direcciones, el microcontrolador efectuará una operación sobre la Memoria de Programa Externa activando la señal PSEN/. Esto ocurre así independientemente del nivel lógico impuesto en el terminal EA/ del microcontrolador. ¿Que sucede si la localización con la que se esta trabajando tiene una dirección correspondiente al rango de direcciones de la Memoria de Programa Interna del microcontrolador? La operación que haga el microcontrolador dependerá en este caso del valor lógico impuesto en el terminal EA/ del mismo. Si el nivel lógico impuesto en EA/ tiene el valor de ´1´ el microcontrolador decidirá que la operación se corresponde con la Memoria de Programa Interna y por ende no activará la señal PSEN/ manteniendolá a ´1´ y no sacará la dirección correspondiente a la localización involucrada en la operación por los Puertos 0 y 2. Si el nivel lógico impuesto en EA/ es ´0´, el microcontrolador considerara que no tendrá Memoria de Programa Interna y por ende todas las referencias que haga a localizaciones de Memoria de Programa serán a memoria ubicada externamente. En este caso tomará la decisión de activar PSEN/ cuando corresponda y sacará la dirección de la localización involucrada en la operación a través de los terminales de los Puertos 0 y 2. En la Figura 12.13 se muestra un ejemplo donde todo el espacio posible a ocupar por la Memoria de Programa, 64 Kilobyte, se le conectan externamente al 8051. Observe que EA/ esta fija a ´0´ por lo que el 8051 desestima toda su Memoria de Programa Interna.

Microcontroladores. El 8051 de la INTEL.

499

Figura 12.13. En el caso particular de la Memoria de Datos Externa el microcontrolador determina que se esta trabajando con ella a partir del tipo de instrucción que se este ejecutando. Existe un tipo de instrucción dentro del Repertorio de Instrucciones del microcontrolador que es la que tiene que utilizar el Programador si en su sistema existe Memoria de Datos Externa para referirse a ella, que es la instrucción MOVX. 12.3 Instrucciones para el trabajo con Memoria de Datos Externa. Como toda instrucción del tipo del tipo MOV, cuenta con dos operandos, uno que hace la función de fuente del dato a mover y el otro como destino a donde almacenar el dato movido. MOVX

< destino >, < fuente >

La única diferencia con las anteriores es que uno de los dos operandos, o el destino o la fuente se tiene que corresponder con una localización ubicada en la Memoria de Datos Externa. Si se corresponde con una instrucción de lectura, la localización fuente es la que se encuentra ubicada en la Memoria de Datos Externa y si se corresponde con una instrucción de escritura, la localización destino es la que se encontrará ubicada en la Memoria de Datos Externa. La primera de ellas provocara la activación de la señal de RD/, mientras que la segunda la de WR/.

Microcontroladores. El 8051 de la INTEL.

500

En dependencia, del Modo de Direccionado empleado para direccionar la localización de la Memoria de Datos Externa involucrdada en la instrucción, encontramos diferentes tipos de instrucciones MOVX. Modo de Direccionado Indirecto. MOVX

A, @Ri

Ri se corresponde con uno de los Registros R0 o R1 del Banco de Registro activo. Al ejecutar esta instrucción, el contenido de Ri se toma como una dirección de 8 bits, la que apuntará a la localización de Memoria de Datos Externa involucrada en la misma. A

(Ri)

Esta instrucción provoca la activación de la señal RD/ del microcontrolador, el contenido del Registro Ri sale por el Puerto 0 como la parte baja de la dirección y por el Puerto 2 sale el contenido del Registro Almacenador del Puerto 2. Esta instrucción destruye lo que este almacenado en el Registro Almacenador del Puerto 0, pero no así el del Puerto 2. Este tipo de instrucción permite dar un tratamiento a la Memoria de Datos Externa como si estuviera conformada por un conjunto de 256 páginas de 256 byte cada una. La página con que se este trabajando la indica la información en los erminales de Puerto 2 y la ubicación dentro de la página la indica la información en los terminales del Puerto 0. MOVX

A, @DPTR

DPTR es un registro de16 bits que pertenece al SFR. Al ejecutarse esta instrucción el contenido del Registro DPTR es tomado como una dirección de 16 bits que apunta a la localización de Memoria de Datos Externa con que se desea trabajar. En este caso toda la Memoria de Datos Externa se ve como un gran bloque de 64 Kilobyte. A

(DPTR)

Esta instrucción provoca la activación de la señal RD/ del microcontrolador, ademas de que la parte alta del Registro DPTR sale por los terminales del Puerto 2 y la parte baja por los terminales del Puerto 0. Esta instrucción destruye lo que este almacenado en el Registro Almacenador del Puerto 0, pero no así el del Puerto 2.

Microcontroladores. El 8051 de la INTEL. MOVX

501

@Ri, A

Provoca lo contrario de la primera instrucción. (Ri)

A

En este caso se activa la señal WR/ del microcontrolador. MOVX

@DPTR, A

Provoca lo contrario de la segunda instrucción. (DPTR)

A

En este caso se activa la señal WR/ del microcontrolador. Estas instrucciones no las estudiamos en el epígrafe “Las Instrucciones para trabajar con la Memoria Interna” ya que no deben ser utilizadas en los Programas cuando el 8051 no tenga Memoria de Datos conectadas externamente.. 12.4 Ejemplo de sistema expandido. Veamos un ejemplo que nos permita reunir todos los aspectos vistos en este Tema. En la Figura 12.14 se muestra al 8051 con 2 Kilobyte de Memoria de Datos conectadas externamente mediante el empleo de una memoria RAM Estática del tipo 2016.

Microcontroladores. El 8051 de la INTEL.

502

Figura 12.14 A las localizaciones de esta Memoria de Datos Externa se le han destinado las direcciones desde la 0000h hasta la 07FFh. La afirmación anterior sin dejar de ser cierta, no es completamente cierta, ¿Por qué decimos esto? Si observamos la lógica de selección empleada para seleccionar la Memoria 2016 nos percataremos de que basta con que el microcontrolador active las señales RD/ o WR/, para que la señal CS/ de dicha memoria vaya a ´0´ y con ello ocurra su activación. Esto es debido a que para generar la señal CS/ de la 2016 se ha empleado una de las compuertas AND que vienen integradas en el circuito 74LS09 a la que le hemos puesto como entradas las señales WR/ y RD/. Lo anterior provoca que, independientemente de la dirección sobre la que el microcontrolador este efectuando su operación de lectura o escritura en Memoria de Datos Externa, la memoria 2016 en nuestro circuito será seleccionada. En este caso a una misma localización de la Memoria de Datos Externa se le han destinado varias direcciones y por ende para referirse a ellas en el Programa puede ser utilizada cualquiera de ellas. Por ejemplo a la localización destinada para la dirección 0000h también nos podemos referir mediante las direcciones 0800h, 1000h, 1800h, 2000h, 2008h y así sucesivamente hasta la F000h y la F800h. Observe que es como si se hubiera dividido todo el espacio destinado a la Memoria de

Microcontroladores. El 8051 de la INTEL.

503

Datos Externa en 32 Bloques de 2 Kilo localizaciones y en cada uno de ellos existe una imagen de los datos de la Memoria de Datos real. Este modo de direccionar aunque presenta este inconveniente, tiene la ventaje de ser muy sencillo del punto de vista del hardware y por lo tanto recomendado cuando nos sobra espacio en la zona destinada a las localizaciones de la Memoria de Datos Externa que tiene el microcontrolador. Supongamos que la tarea que queremos que haga el Programa es la de mover una Tabla de Datos de 100 byte almacenada en las localizaciones de la Memoria de Datos Interna del microcontrolador a partir de la dirección 00h hacia las localizaciones de la Memoria de Datos Externa conectadas al microcontrolador a partir de la dirección 0100h. El programa sería el siguiente: ; Subrutina MUEVE. ; Preparar condiciones iniciales para el movimiento de los 100 datos. mueve:

mov

R3, #100

; declaro numero de datos en la Tabla.

mov

R0, #0

; declaro dirección de inicio de la Tabla Fuente

mov

DPTR, #100h

; declaro dirección de inicio de la Tabla Destino

; Lazo que mueve los 100 datos de una zona de memoria a la otra. lazo1:

mov

A, @R0

movx @DPTR, A

; traigo dato de la Tabla Fuente. ; envió dato a la Tabla Destino.

; Preparo prximo movimiento. inc

R0

inc

DPTR

; Pregunto si se termino de mover todos los datos de una Tabla a otra. djnz

R3, lazo1

ret

; fin de la Subrutina.

12.5 Diseño de un ´´Data Logger´´. Quizás lo primero que debemos hacer antes de enfrentar la solución del problema planteado es darle respuesta a la pregunta siguiente, ¿Qué es un ´´Data Logger´´? Un ´´Data Logger´´ es esencialmente un circuito de Adquisición de Datos que por lo general se encuentra alejado del Sistema Supervisorio Central, por lo general una Microcomputadora. En algunos casos, existe comunicación en línea entre la Microcomputadora y el ´´Data Logger´´, pero en otros casos dado lo remoto en que se encuentra ubicado el mismo, esta comunicación no

Microcontroladores. El 8051 de la INTEL.

504

existe, surgiendo la necesidad de que una persona cada cierto tiempo extraiga la información almacenada y la transporte mediante algún elemento de almacenamiento masivo

hasta la

Microcomputadora. En ambos casos se hace necesario que el ´´Data Logger´´ cuente con suficiente capacidad de almacenamiento como para almacenar la información necesaria, mientras espera por que sea tomada por la Microcomputadora Central. Esta capacidad de almacenamiento por lo general es mayor que la que brindan la mayoría de los microcontroladores en su área de Memoria de Datos Interna. Recordemos que en el caso del 8051 esta capacidad de almacenamiento es de solo 128 byte. ¿Cuál es la solución a dar en este caso? La solución es conectar de forma externa al microcontrolador la capacidad de Memoria de Datos que demande la aplicación, para lo que tenemos que recurrir a trabajar al mismo en su Modo Especial de Trabajo. Esta solución tambien podría ser dada mediante el empleo de un microprocesador como elemento central del circuito a diseñar, por lo que la pregunta a responder podría ser, ¿Diseño mi sistema basado en un microprocesador o en un microcontrolador? Por desgracia para los diseñadores no existe una receta que pueda seguirse paso por paso que le permita, al final de la aplicación de la misma, encontrar la respuesta correcta a la pregunta anterior. Respuesta que en la mayoría de los casos resulta compleja, máximo si tenemos en cuenta que, toda aplicación que usted sea capaz de resolver empleando un microcontrolador, usted lo puede resolver también mediante un sistema basado en un microprocesador. Lo inverso no se cumple siempre. Es por esto que la respuesta a esta pregunta depende en gran medida de la experiencia del diseñador y de las condiciones concretas del punto de vista material con que se cuente. Téngase presente que una buena selección no depende solo de si el microprocesador escogido o si el microcontrolador escogido es el idóneo, sino que además, el contar con las herramientas adecuadas para el desarrollo y puesta a punto del sistema es un aspecto prácticamente definitorio. No obstante, algunas consideraciones que pueden resultar de utilidad a los diseñadores nuevos, conformadas por el autor de este material a partir de su experiencia práctica se las brindamos a continuación.

Microcontroladores. El 8051 de la INTEL.

505

1. Si la aplicación a resolver es lo suficientemente pequeña que permite ser resuelta solo con los recursos internos del microcontrolador, no vacile y resuelva la aplicación con un sistema basado en el microcontrolador en cuestión. Esta primera conclusión resulta evidente y estos no son los casos más difíciles a la hora de tomar una decisión, siendo lo que hemos venido haciendo hasta ahora en los diferentes ejemplos resueltos que hemos enfrentado. 2. Si la aplicación a resolver no es lo suficientemente pequeña como para ser resuelta solo con los recursos internos del microcontrolador y por lo tanto necesita de circuitos que lo apoyen y que deben ser conectados externamente, tome papel y lápiz y saque cuenta de que le resulta más económico. Por lo que a la hora de enfrentar la solución de una aplicación cualquiera el primer paso a dar por el diseñador esta relacionado con la determinación de los recursos tanto de hardware como de software que se espera necesitar para la solución de la misma. Consideremos que hemos llegado a la conclusión de que emplearemos al microcontrlador 8051 para dar solución al problema que nos hemos planteado. Observe que en este caso existe la necesidad de expandir las potencialidades del microcontrolador mediante la conexión externa de Memoria de Datos. La pregunta a responder en este momento sería, ¿De cuanto es esa capacidad de Memoria de Datos a conectar de forma externa al Microcontrolador? Para poder determinar esta capacidad se hace necesario darle respuesta a las siguientes preguntas, ¿Cada que tiempo serán tomados por la Microcomputadora Central los datos almacenados en el ´´Data Logger´´? ¿Cuantas son las variables físicas que están siendo tomados sus valores por parte del ´´Data Logger´´? ¿Cuantos son los bits necesarios para almacenar en la Memoria de Datos el valor de las variables físicas tomado en cada muestreo? Las respuestas a las tres preguntas anteriores se encuentran resumidas en el enuciado siguiente donde se define las caracteristicas del Data Logger que queremos diseñar.

Microcontroladores. El 8051 de la INTEL.

506

Diseñar un ´´Data Logger´´ el que almacena los valores de 8 variables físicas con una precisión de 8 bits cada 15 segundos. La información almacenada será descargada por la Computadora Central 1 vez al día. Lo primero que debemos determinar es la capacidad total de la Memoria de Datos a conectar externamente al microcontrolador. Consideraremos que todos los datos obtenidos de la conversión de la variable física a digital serán almacenados en dicha Memoria de Datos Externa. Dada que la precisión de la conversión es de 8 bits, para almacenar el valor binario de una variable física cualquiera cada vez que es muestreada se necesita de una localización de memoria. Como son 8 las variables físicas muestreadas se necesitaran 8 localizaciones para almacenar los valores binarios obtenidos en cada muestreo. Estamos considerando que todas las variables físicas que se toman tendran el mismo tiempo de muestreo. ¿Cuántas localizaciones serán necesarias para almacenar los valores binarios de las 8 variables físicas? Un día de trabajo consta de 24 horas, que llevados a minutos serían 1440 minutos, que llevados a segundos serian 86400 segundos. Este es el intervalo de tiempo en que la información será descargada a la Microcomputadora y por lo tanto los datos tomados pueden ser borrados para tomar datos nuevos que pueden ocupar las mismas localizaciones de memoria que las anteriores. Este parámetro resulta imprescindibles para poder determinar la capacidad de almacenamiento mínima necesaria.. En este intervalo de tiempo se pueden realizar un total de 5760 muestreos, si en cada muestreo el numero de variables físicas que se muestrean es de 8, serán necsarias 8 localizaciones en cada muestreo. Mediante una simple operación de multiplicación podemos determionar que en 5760 muestreos serán neceraias 46080 localizaciones. Del analisi anterior podemos concluir que, al microcontrolador le será necesario conectar externamemnte al menos 46080 localizaciones de 8 bits de Memoria de Datos. En la Figura 12.15 se muestra la propuesta de hardware que hacemos para el ´´Data Logger´´ que nos hemos propuesto diseñar.

Microcontroladores. El 8051 de la INTEL.

507

Figura 12.15 Dada que la capacidad de Memoria de Datos a conectar externamente al microcontrolador debe ser como mínimo de 46080 localizaciones hemos tenido que utilizar 3 circuitos del tipo 27513, que no son más que Memorias del tipo RAM Estática (RAMS) cuya capacidad por circuito es de 16 Kilobyte con lo que tenemos en el circuito 48 Kilobyte o lo que es lo mismo 49512 localizaciones lo que resulta suficiente para la aplicación que nos estamos proponiendo. Esta Memoria RAMS consta de 14 bits en su Bus de Direcciones los que han sido conectados en todos los casos a los bits de A0 a A13 del Bus de Direcciones Externo del microcontrolador. Su Bus de Datos es de 8 bits los que han sido conectados al Bus de Datos Externo del microcontrolador. A través de tres señales se controla la operación que la Memoria RAMS debe ejecutar, estos tres señales son, CE/, OE/ y WE/. Todas activas en ´0´ y la función que realizan son las siguientes: 9

CE/

Habilitación de la Memoria. Operación de Lectura o de Escritura.

9

OE/

Habilita el Buffer de Salida de la Memoria. Operación de Lectura.

9

WE/

Habilita el Buffer de Entrada de la Memoria. Operación de Escritura.

Estas señales serán generadas por:

Microcontroladores. El 8051 de la INTEL.

508

9

CE/

Salida correspondiente del Decodificar de Direcciones del Circuito..

9

OE/

La señal RD/ del microcontrolador.

9

WE/

La señal WR/ del microcontrolador.

La pregunta a responder en este caso sería, ¿Quién es el Decodificador de Direcciones y que función realiza? En nuestro circuito este papel lo desempeña el Circuito Decodificador de 2 a 4, 74139. Este circuito a partir del valor en los bits A14 y A15 del Bus de Direcciones Externo del microcontrolador determina y selecciona el dispositivo externo con que quiere trabajar este. En nuestro caso: A15

A14

Dispositivo seleccionado.

0

0

Memoria de Datos RAMS # 1.

0

1

Memoria de Datos RAMS # 2.

1

0

Memoria de Datos RAMS # 3.

1

1

Conversor Análogo-Digital

Esto provoca que las direcciones de las localizaciones destinadas para cada una de las Memorias y el Conversor sean las siguientes: Dispositivo

Desde

Hasta

Memoria de Datos RAMS # 1

0000 h

3FFF h

Memoria de Datos RAMS # 2.

4000 h

7FFF h

Memoria de Datos RAMS # 3

8000 h

BFFF h

Conversor Análogo-Digital

C000 h

FFFF h

Para la habilitación del Decodificador de Direcciones se utiliza el AND lógico de las señales WR/ y RD/ del microcontrolador. Cualquiera de las dos en ´0´, indica que el microcontrolador esta efectuando una operación de lectura o escritura en Memoria de Datos Externa y por lo tanto la dirección presente en el Bus de Direcciones Externo del microcontrolador se esta refiriendo a alguno de los dispositivos conectados externamente. El Conversor Análogo-Digital es tratado del punto de vista del software como si fuera Memoria de Datos Externa y por lo tanto cualquier instrucción que utilice como operando una de las direcciones comprendidas entre la C000h y la FFFFh se estará refiriendo a dicho circuito.

Microcontroladores. El 8051 de la INTEL.

509

Continuando con el Conversor Análogo-Digital ADC0808, este consta de 8 entradas analógicas o entradas de conversión a las que se deben conectar las salidas de los sensores utilizados por el ´´Data Logger´´. Internamente el ADC0808 consta de un Conversor Análogo-Digital de 8 bits el que es capaz de convertir una señal analógica aplicada en su entrada entre los valores de 0 y 5 Volts a un número binario de 8 bits. La pregunta a dar respuesta en este momento sería, Si el conversor interno solo tiene una entrada analógica, ¿Como es posible conectar 8 señales analógicas al mismo? Para ello el ADC0808 consta internamente con un multiplexor analógico de 8 entradas el que es controlado su operación a través de los terminales del circuito ADDA, ADDB y ADDC. En dependencia de la combinación de ´0´ y ´1´ impuesta en estos terminales será la entrada analógica conectada a la entrada del conversor interno, cumpliendo con la siguiente Tabla. ADDC

ADDB

ADDA

Entrada analógica conectada

0

0

0

IN0

0

0

1

IN1

0

1

0

IN2

0

1

1

IN3

1

0

0

IN4

1

0

1

IN5

1

1

0

IN6

1

1

1

IN7

Para imponer la combinación deseada en estos tres terminales del Conversor hemos utilizado los terminales 0, 1 y 2 del Puerto 1. Una señal de ALE del Conversor tiene que ser habilitada para que este reconozca la combinación a la entrada de los terminales anteriores. Esta señal será generada por el programa a través del terminal 3 del Puerto 1. Otras tres señales son de vital importancia en el funcionamiento del Conversor, OE/, START/ y EOC. La función de estas señales son las siguientes: OE/ (entrada). Su puesta a ´0´ saca de tercer estado a los bits del Bus de Datos del Conversor, imponiendo en estos el valor en binario correspondiente a la conversión de la señal analógica seleccionada a través de los terminales ADDA, ADDB y ADDC.

Microcontroladores. El 8051 de la INTEL.

510

START/ (entrada). Su puesta a ´0´ inicia un ciclo de conversión en el Conversor interno. EOC (salida). Su puesta a ´1´ por el Conversor indica que un ciclo de conversión ha terminado y que por lo tanto el valor binario resultante se encuentra listo para ser leído. La señal START/ será generada siempre que el microcontrolador ejecute cualquier instrucción de transferencia que utilice como operando destino, una de las direcciones cualquiera de las destinadas al Conversor. mov

C000h, A

; inicio de conversión.

Por su parte la señal OE/ será generada siempre que el microcontrolador ejecute una instrucción de transferencia que utilice como operando fuente, una de las direcciones cualquiera de las destinadas al Conversor. mov

A, C000h

; lectura del Conversor.

Para que el microcontrolador detecte que el Conversor ha concluido con la conversión ordenada se ha conectado la salida EOC del Conversor al terminal P1.4 del microcontrolador. Esto provoca que el programa tendrá que encuestar el valor impuesto en este terminal por el Conversor una vez que de Inicio de Conversión. Mientras tenga impuesto un valor de ´0´ el Conversor esta en el proceso de conversión y el microcontrolador tendrá que seguir esperando. Cuando se imponga un valor de ´1´ quiere decir que el Conversor ha concluido con su operación de conversión encontrándose el mismo listo para ser leído. Resumiendo lo explicado hasta aquí con respecto al modo de operación del Conversor en el circuito: 1. Escoger, a través de los terminales P1.0, P1.1, P1.2 y P1.3 del microcontrolador, la señal analógica de las 8 posibles a ser convertida por el Conversor. 2. Dar Inicio de Conversión mediante la ejecución de una instrucción de escritura en el Conversor, mov

C000h, A.

3. Esperar por el Fin de la Conversión encuestando el terminal P1.4.

Microcontroladores. El 8051 de la INTEL.

511

4. Leer el numero binario obtenido por el Conversor producto de la conversión mediante la ejecución de una instrucción de lectura en el Conversor, mov

A, C000h.

La Interfaz RS-232 la hemos materializado mediante el circuito MAX232, un circuito transceptor que es capaz de convertir las señales TTL/CMOS a su entrada a señales que cumplen con los parámetros eléctricos de la norma RS232 y viceversa. Con estas premisas enfrentemos la tarea del desarrollo del software para esta aplicación. Primero definamos como es que va a trabajar el ´´Data Logger´´. La tarea principal del ´´Data Logger´´ es la de recopilar los valores de las 8 señales analógicas cada 15 segundos y almacenarlas en la Memoria RAMS en espera de que se le de la comando, a través de su Puerto Serie, de que vacié la Memoria de Datos. La pregunta a responder en este momento sería, ¿Quién indica que han transcurrido los 15 segundos de la última toma de valores y que por lo tanto una nueva toma de valores debe ejecutarse? Para ello emplearemos el Temporizador 0, al que lo pondremos a trabajar en el Modo 1 como Timer, con la Interrupción habilitada. No obstante con esto no basta ya que este Temporizador trabajando en el Modo 1 como pretendemos, su desbordamiento máximo ocurriría cada 65536 microsegundos dado el Cristal de Cuarzo empleado en el circuito, lo que no es suficiente. Para resolver esta situación la Subrutina de Atención a la Interrupción del Temporizador 0 inicialmente implementará un Contador Decreciente con un valor de inicio de 228, el que comenzará una secuencia de toma de valores del Conversor una vez que llegue al valor de 0. 65536 microsegundos x 228 = 14 942208 microsegundos ≈ 15 segundos La otra Interrupción habilitada es la del Puerto Serie por donde llegará el comando de vaciar los datos almacenados. Este proceso de vaciado de la Memoria de Datos Externa no es rígido en el tiempo por lo que puede ocurrir en cualquier momento dentro de las 24 horas máximas de almacenamiento del ´´Data Logger´´ sino se quiere correr el riesgo de perder datos almacenados por sobreescritura. La pregunta a responder en este momento sería,

Microcontroladores. El 8051 de la INTEL.

512

¿Cómo el ´´Data Logger´´ reconoce que ya envió todos los datos almacenados validos para un proceso de vaciado dado? Para ello en las dos primeras localizaciones de Memoria de Datos se implementara un Contador Ascendente el que llevara el conteo de los datos almacenados en dicha memoria los que se corresponden con la cantidad de valores de las variables físicas tomadas. Se utilizan dos localizaciones para almacenar el Contador ya que el número de datos almacenados puede sobrepasar el número de 256 entre un vaciado de la memoria y otro. ; Inicio del Programa. org

0

; Resguarda la zona de memoria destinada para las Subrutinas de Atención a ; la Interrupción. sjmp

inicio

; Inicio de la Subrutina de Atención al Temporizador 0. org

000Bh

sjmp

convierte

; Inicio de la Subrutina de Atención al Puerto Serie. org

0023h

sjmp

vacia

; Inicio del Programa Principal. ; Limpia la memoria RAMS. inicio:

acall

limpia

; Habilita la Interrupción de las fuentes que serán utilizadas. mov

IE, #10010010b

; Declarando el Contador Ascendente que acompaña al Temporizador 0. mov

R3, #228

; Programando al Puerto Serie. mov

SCON, #01010000b

; Programa los Temporizadores. ; Temporizador 0 se desborda cada 65536 microsegundos. ; Temporizador 1 genera el ´´Baud Rate´´ del Puerto Serie a 1200 baudios. mov

TMOD, #00100001b

mov

TH0, #FFh

mov

TL0, #FFh

mov

TH1, #E5h

mov

TL1, #E5h

mov

PCON, #0

Microcontroladores. El 8051 de la INTEL. ; Habilita el conteo de ambos Temporizadores. setb

TCON.4

setb

TCON.6

; Poner al Microcontrolador en el Modo de Idle. espera:

setb

PCON.0

sjmp

espera

; Subrutina de Atención a la Interrupción del Temporizador 0. convierte:

djnz

R3, salir

; Inhabilita la Interrupción. mov

IE, #00010010b

; Inhabilita el conteo del Temporizador 0. clr

TCON.4

; Declarando el selector de la entrada analógica. mov

R4, #0

; Declara el Contador de Numero de Conversiones. mov

R5, #8

; Selecciona la entrada analógica a convertir. lazo1:

mov

P1, R4

inc

R4

; Genera el pulso de ALE. setb

P1.3

acall

demora

clr

P1.3

; Dar Inicio de Conversión. mov

C000h, A

; Esperar por fin de Conversión. jnb

P1.4, $

; Lee el Conversor. mov

A, C000h

; Almacena el dato en la Memoria de Datos. movx @DPTR, A inc

DPTR

djnz

R5, lazo1

acall

contador

; Habilita la Interrupción. mov

IE, #10010010b

; Habilita el conteo del Temporizador 0. setb

TCON.4

513

Microcontroladores. El 8051 de la INTEL. salir:

reti

, Subrutina que actualiza el numero de datos almacenados en la Memoria de ; Datos. contador:

mov

A, 0000h

add

A, #8

mov

0000h, A

mov

A, 0001h

addc

A, #0

mov

0001h, A

ret ; Subrutina que genera una demora de 512 microsegundos. demora:

mov

R6, #FFh

djnz

R6, $

ret ; Subrutina de atención a la Interrupción del Puerto Serie. vacia:

clr

SCON.0

; Inhabilitar la atención de la interrupción. mov

IE, #00010010b

; Transmitiendo el Bloque de Datos almacenados en memoria de Programa. lazo2:

mov

DPTR, #0002h

movx A, @DPTR mov

SBUF, A

jnb

SCON.1,$

inc

DPTR

mov

A, 0000h

djnz

A, lazo2

mov

A, 0001h

djnz

A, lazo2

acall

limpia

; Habilita la interrupción. mov

IE, #10010010b

reti ; Subrutina que carga en 0 todas las localizaciones de la Memoria de Datos. limpia: mov

DPTR, #0

lazo3:

mov

A, #0

movx @DPTR, A inc

DPTR

mov

A, DPTH

514

Microcontroladores. El 8051 de la INTEL. cjne

A, #C0h, lazo3

mov

DPTR, #0002h

515

ret El programa esta hecho de forma tal que cuando el microcontrolador este efectuando la toma de los valores de las 8 entradas analógicas, la atención a la interrupción se inhabilita de forma tal que si llega en ese momento una interrupción del Puerto Serie esta se desatiende. En el caso contrario cuando se esta transmitiendo por el Puerto Serie los datos almacenados en la memoria de Datos, la atención a la Interrupción nuevamente se inhabilita no efectuándose toma de nuevos valores de las entradas analógicas mientras dure este proceso. Veamos a continuación un ejemplo donde se emplea el microcontrolador 8031 para resolver la aplicación propuesta. En este caso el programa a ejecutar por el microcontrolador se encuentra almacenado en una Memoria del tipo PROM externa. 12.6 Diseñando con el Microcontrolador 8031. En la mayoría de los sistemas a desarrollar, resulta indispensable el uso de un exhibidor o display que nos muestre mediante mensajes escritos, las demandas del equipo, los requerimientos, los mandatos externos, las señalizaciones, las alarmas, etc. El uso de un exhibidor alfanumérico nos proporciona la solución a esta necesidad, facilitando el manejo y aprendizaje del dispositivo que ha sido implementado. En este Epígrafe se propone utilizar un Display a Cristal Líquido (LCD) de 2 líneas por 16 caracteres por línea, el cual es fabricado por diversas compañías. Este exhibidor puede interconectarse

directamente,

con

el

bus

de

datos

de

cualquier

microprocesador

o

microcontrolador, gracias a que tiene un bus de datos con tres estados. Además contiene una Memoria RAMS interna que le permite almacenar hasta 128 caracteres y una Memoria ROM con 160 caracteres matriciales de 5x7 puntos, y 30 caracteres de 5x10 puntos. La ventana del exhibidor permite ver 32 caracteres a la vez, en 2 líneas de 16 caracteres cada una. Un esquema del mismo se muestra en la Figura 12.16.

Microcontroladores. El 8051 de la INTEL.

516

Figura 12.16 La función que realizan los terminales son los que se muestran en la siguiente Tabla. Terminal

Señal

Función.

1

GND

Referencia de Tierra, 0 Volts.

2

Vdd

Alimentación Positiva, +5 Volts.

3

Vo

Voltaje de Contraste. En el intervalo de 0 V a +5 V.

4

RS

Selección de Caracter o Comandos

5

R/W

Selección de Escritura o Lectura

6

E

7

DB0

8

DB1

9

DB2

10

DB3

11

DB4

12

DB5

13

DB6

14

DB7

Habilitación Bit Menos Significativo del Bus de Datos

Bus de datos

Bit Más significativo del Bus de Datos.

La utilización de un Teclado para seleccionar una acción de control o para introducir las variables solicitadas por el sistema, es otro de los circuitos que resulta indispensable en muchas aplicaciones. Existen dos tipos de teclado los denominados matriciales y los que tienen un punto en común con todas las Teclas. Los Teclados Matriciales aunque más complejos de trabajar del punto de vista del software permiten atender Teclados con un número mayor de Teclas que los otros, empleando los mismos recursos del microcontrolador. En este ejemplo se trabajará con uno del tipo matricial de 3 columnas por 4 renglones, en total 12 Teclas.

Microcontroladores. El 8051 de la INTEL.

517

Cada vez que se oprime una Tecla existen los denominados rebotes, los cuales son indeseables, debido a que se genera varias veces la demanda de la Tecla oprimida, lo que ocasiona que el mismo valor de la Tecla sea leído varias veces. En algunos sistemas este inconveniente es anulado mediante programa que verifica los valores, eliminando los efectos indeseables del rebote. En otros sistemas se elimina mediante hardware. Existe un circuito de la familia de circuitos integrado TTL que resulta ideal para esta función, el 74279, el que contiene dos biestables del tipo RS. En este ejemplo proponemos eliminar los efectos indeseables del rebote por hardware, pero no lo haremos mediante el uso del circuito ijntegrado 74279 sino que emplearemos el circuito integrado 74C922, de la Familia misma familia de circuitos integrados. Este circuito integrado fue desarrollado específicamente para la atención de Teclados Matriciales por lo que contiene los elementos que permiten mediante hardware eliminar los efectos indeseables del rebote. Para ello solo pide que se le conecten dos capacitores que se externamente a dos de sus terminales. La pregunta a hacerse en este momento podría ser, ¿Por qué utilizar este circuito integrado y no el 74279 al que hicimos referencias anteriormente? La causa esta en otra de las funciones que soporta este circuito, que no tiene el 74279. Este circuito tiene la ventaje de efectuar por hardware la búsqueda de la Tecla apretada y de informarnos mediante una de sus salidas cuando esto ha ocurrido, almacenando en un registro interno, el que puede ser leido a traves de sus terminales de datos, el codigo de posición de la Tecla apretada. Esto libera al software de un gran número de tareas que debe efectuar cuando atiende un Teclado Matricial puramente por software. Otras característica de este circuito integrado son las de poder manejar hasta un Teclado Matricial de 16 Teclas y de poder conectarse directamente al Bus de Datos de un microcontrolador ó microprocesador. El presente Epígrafe tiene por nombre “Diseñando con el microcontrolador 8031” y la pregunta ha hacernos en este caso podría ser, ¿Qué de particular tiene que el diseño sea con el microcontrolador 8031 como elemento basico?

Microcontroladores. El 8051 de la INTEL.

518

El 8031 es una de las versiones del 8051, el que forma parte de la misma familia de microcontroladores de este último. Como miembro de la familia consta de un conjunto de caracteristicas identicas a las del 8051, pero al mismo tiempo cuenta con un conjunto de caracteristicas que lo diferencian, de estas la que más nos nteresa del punto de vista del diseño es que el 8031 es un microcontrolador que no tiene empotrada Memoria de Programa. Esta condición impone la necesidad de que toda la Memoria de Programa le tiene que ser conectada externamente. Para materializar la Memoria de Programa en nuestra aplicación utilizaremos el circuito integrado 27512, Memoria PROM de 64 kilobyte con lo que ocupamos todo el posible espacio de direcciones para Memoria de Programa de este microcontrolador. Para materializar la zona de alamcenamiento de datos externa emplearemos el circuito integrado 61128, Memoria RAMS de 32 kilobyte de capacidad. La pregunta que ustedes se podrían hacer en este caso podría ser, ¿Por qué empleamos una un circuito integrado de 32 kilobyte para materializar la Memoria de Datos externa del microcontrolador y no una de 64 kilobyte que permitiria aprovechar todo el posible espacio de direcciones que tiene este microcontrolador para este tipo de memoria? Por su puesto que esta decisión parte de un analisis donde se determina la capacidad de memoria necesaria para almacenar datos que demanda la aplicación. En nuestro caso se decidio que con 32 kilobyte era suficiente. Esto permite que el LCD y el Teclado Matricial lo podamos conectar al bus del microcontrlador compartiendo el espacio de direcciones con los 32 kilobyte de Memoria RAMS. El diagrama que muestra el diseño propuesto del sistema se muestra en la Figura 12.17.

Microcontroladores. El 8051 de la INTEL.

519

Figura 12.17 El decodificador de 2 a 4 de la familia 74 de la Texas Instruments, 74LS139 hace el papel de decodificador de Direcciones para la selección de cada uno de los circuitos del sistema. El procedimiento para inicializar el exhibidor es el siguiente: 9

Primeramente se establece el tipo de interfase a la cual el exhibidor se va a conectar, en nuestro caso, se trata de un microcontrolador con un Bus de Datos de 8 bits, al cual se va a conectar directamente. La palabra de control que se envía al exhibidor para definir lo anterior es el número 38H. El hardware del sistema debe garantizar que cuando se envié esta comando al exhibidor la señal RS debe estar en ´0´, la señal R/W debe estar en ´0´ y la señal E debe estar en ´1´. Es muy importante esperar por un lapso de tiempo de 40 microsegundos antes de enviar la siguiente comando al exhibidor.

NOTA: Cada instrucción, toma un cierto tiempo de ejecución que va de 40 microsegundos hasta 1.64 milisegundos, en dependencia de la operación que la misma efectué sobre el exhibidor.

Microcontroladores. El 8051 de la INTEL. 9

520

Limpiar todas las localizaciones de la memoria del exhibidor y regresar la misma a su posición inicial. Para ello el comando a enviar se corresponde con el código 01h. Esta instrucción toma un tiempo de 1.64 milisegundos.

9

Establecer el movimiento del cursor hacia la derecha, la pantalla del exhibidor permanece fija con la entrada de los caracteres. Para ello se debe enviar el comando cuyo código es 06h. Esta instrucción toma un tiempo de 40 microsegundos.

9

Prender la pantalla del exhibidor, se activa el cursor señalando la posición del próximo carácter de entrada y se desactiva el parpadeo. Para ello el código de la comando a enviar se corresponde con el 0Eh. Esta instrucción toma un tiempo de 40 microsegundos.

9

Posicionar el cursor en el primer carácter y la primera línea, enviando el comando cuyo código es 80 h. Esta instrucción toma un tiempo de 40 microsegundos.

A partir de aquí se puede comenzar a enviar los caracteres que se desean exhibir dejando un tiempo entre cada uno de ellos de 40 microsegundos como mínimo. Cada vez que se envié un carácter al exhibidor se debe garantizar que el terminal RS se encuentre en ´1´. Por ejemplo para enviar los caracteres correspondientes a las letras A y B al exhibidor, se debe enviar el código ASCII correspondiente a estos caracteres y esperar 40 microsegundos entre caracteres. A continuación se muestran los programas correspondientes para la atención del exhibidor y del Teclado Matricial. ; ***********************************************LCD*********************************************************** ; Programa para el manejo del Exhibidor Alfanumérico. ; Las direcciones del Exhibidor son: ;

Control

8000h

;

Carácter

8001h

; Inicio del Programa. exhibe:

mov

DPTR, #8000h

mov

R0, #0

mov

P2, #80h

lcall

xcbdor

; Envía los caracteres de Control al Exhibidor. inc

DPTR

lcall

xcbdor

; Se envía el código 01h de Control, limpia pantalla, el que requiere de

Microcontroladores. El 8051 de la INTEL. ; 1.64 milisegundos para su ejecución. lcall

limpia

; Carga el apuntador con el primer mensaje. bien:

mov

DPTR, #bienv

; Se envía a la Subrutina que exhibe en dos líneas de una vez. lcall

doblex

lcall

time

; Se envía el código 01h de Control. mov

R0, #0

lcall

limpia

; Se envía un solo mensaje a la primera línea a partir de la columna 5.

terexh:

mov

DPTR, #medio

mov

A, #85h

lcall

coexh

lcall

time

lcall

limpia

sjmp

bien

; Subrutina de Control y Presentación del Exhibidor. doblex:

mov

A, #80h

acall

coexh

inc

DPTR

mov

A, #C0h

acall

coexh

fexh:

ret

coexh:

mov

R0, #0

mov

P2, #80h

movx @R0, A acall

qarnta

inc

R0

acall

xcbdor

ret xcbdor:

clr

A

movc A, @A+DPTR jz

termin

movx @R0, A acall

qarnta

inc

DPTR

521

Microcontroladores. El 8051 de la INTEL. sjmp termin:

522

xcbdor

ret

; Subrutina de tiempo de 40 microsegundos. qarnta:

mov

R7, #20

tiempo:

djnz

R7, tiempo

ret ; Subrutina que envía el código 01h de Control y además consume los ; 1.64 milisegundos de su ejecución. limpia:

ti1600:

mov

DPTR, #clear

lcall

xcbdor

mov

R6, #40

lcall

qarnta

djnz

R6, ti1600

ret ; Subrutina de tiempo de 2 segundos. time:

mov

R1, #02

e2:

mov

R0, #90

e3:

mov

R6, #99

e4:

mov

R7, #50

wait:

djnz

R7, wait

djnz

R6, e4

djnz

R0, e3

djnz

R1, e2

ret ; Tabla de mensajes del Exhibidor. contex:

db

38h, 00h, 06h, 0Eh

iniexh:

db

80h, 00h,

clear:

db

01h, 00h

bienv:

db

´BIENVENIDOS AL´

db

00h

db

´SISTEMA´

db

00h

db

´EN MEDIO´

db

00h

medio:

end ; ****************************************************************************************************************

Microcontroladores. El 8051 de la INTEL.

523

; ****************************************TECLADO MATRICIAL****************************************** ; Programa para el manejo del Teclado. ; Este Fragmento de Programa toma datos del Teclados y los envía al ; Exhibidor ; Dirección del Teclado 9000h. ; Inicio del Programa. org

0

; Resguardar la zona de Memoria de Programa destinadas para almacenar la ; Subrutina de Atención a la Interrupción Externa 0. ljmp

teclad

; Dirección de Inicio de la Subrutina de Atención a la Interrupción Externa 0. org

0003h

; Subrutina de Atención a la Interrupción Externa 0. setb

20h.0

mov

DPTR, #9000h

movx A, @DPTR anl

A, #0Fh

add

A, #30h

; convirtiendo a ASCII

reti ; Programa Principal. teclad:

esptec:

mov

TCON, #01h

mov

DPTR, #8000h

mov

R0, #0

acall

subes

mov

DPTR, #texto

acall

subex1

mov

A, #C0h

acall

poscur

mov

DPTR, #text1

acall

subex1

jnb

20h.0, esptec

clr

20h.0

mov

DPTR, #8001h

movx @DPTR, A tex:

mov

R7, #20h

djnz

R7, tex

; Mueve el cursor del Exhibidor hacia la izquierda mov

A, #01h

Microcontroladores. El 8051 de la INTEL. acall

524

poscur

; Se repite el dato continuamente. sjmp

esptec

; Subrutina que exhibe el carácter en el Exhibidor. subex1:

mov

R0, #01h

subexh:

mov

P2, #80h

subex:

clr

A

movc A, @A+DPTR jz

finexh

mov

@R0, A

mov

R2, #10h

lazex2:

mov

R1, #FFh

lazexh:

djnz

R1, lazexh

djnz

R2, lazex2

inc

DPTR

sjmp

subexh

finexh:

ret

poscur:

mov

DPTR, #exhi

movx @DPTR, A lazpos:

mov

R1, #FFh

djnz

R1, lazpos

ret ; Tablas con los Textos. contrl: texto: text1:

db

38h, 01h, 02h, 06h, 0Fh, 80h, 00h

db

00h

db

´OPRIMA UNA TECLA´

db

00h

db

´TECLA´

db

00h

end ; ***************************************************************************************************************