Está en la página 1de 70

Ingeniera en Informtica Eliezer Ramrez Cabrera Rodrigo Heredero Robayna

1 Introduccin .................................................................................................................. 3 2 Objetivos de la prctica ................................................................................... 4 3 Hardware............................................................................................................................. 5 3.1 Sensor Infrarrojos TFMS 5360 ............................................................... 5 3.1.1 Conexionado y acondicionamiento del sensor al microcontrolador. .................................................................................................. 9 3.2 Conexionado y acondicionamiento del diodo emisor. ...... 10 4 Desarrollo de la prctica. ............................................................................ 11 4.1 Ejemplo de implementacin de programa de prueba para el diodo emisor de infrarrojos. ............................................................... 13 5 Protocolo de comunicacin .............................................................................. 16 5.1 Nivel Bajo ............................................................................................................ 18 5.2 Nivel Medio ......................................................................................................... 29 5.3 Nivel Alto ............................................................................................................ 31 6 Implementacin ........................................................................................................... 32 6.1 Creacin de Libreras............................................................................. 33 6.2.1 Emisor_Nivel_Bajo.asm...................................................................... 34 6.2.2 Receptor_Nivel_Bajo.asm ................................................................ 39 6.3 nivel_paquetes.lib ....................................................................................... 45 6.3.1 Emisor_Paquete.asm ........................................................................... 46 6.3.2 Receptor_Paquete.asm ........................................................................ 49 6.4 nivel_paquetes_variables.lib ............................................................. 51 6.5 Divide_Paquetes_Emisor.asm .................................................................. 51 6.6 Divide_Paquetes_Receptor.asm ............................................................. 54 6.7 Divide_Paquetes_Emisor (2).asm ........................................................ 56 6.8 Implementacin del nivel bajo en modo rpido.................. 59 6.9 Implementacin del nivel bajo con paridad. ........................ 61 6.9.1 Emisor ............................................................................................................. 62 6.9.2 Receptor: ..................................................................................................... 65 7 Manual de instrucciones ................................................................................... 65 7.1 implementacin fsica:............................................................................. 65 7.2 implementacin software: ..................................................................... 65 8 Restricciones del sistema de comunicacin por infrarrojos. ..................................................................................................................... 68 9 Ejercicios Propuestos ......................................................................................... 69 10 Referencias bibliogrficas ......................................................................... 70

1 Introduccin
En la presente prctica vamos a hacer uso del microcontrolador PIC16f84 para el control de un sistema de comunicacin basada en Infrarrojos. El microcontrolador se hace idneo para este tipo de comunicaciones, ya que: Como en todo sistema de comunicacin, se dan un emisor del mensaje y un receptor del mismo. Es un caso bsico de comunicacin, donde el mensaje a transmitir entre un dispositivo y otro es necesario encapsularlo en un protocolo, o lo que es lo mismo codificarlo. El PiC, como microcontrolador, posee capacidad de procesamiento de datos, lo que permite codificar y decodificar un mensaje. En un sistema de comunicacin es fundamental la flexibilidad, que nos permita explotar los recursos al mximo y estudiar distintas estrategias de comunicacin. El PIC nos permite esa ductilidad, ya que nos permite configurar cualquier sistema de comunicacin sin hacer modificaciones en el Hardware, simplemente cambiando el programa del microcontrolador. A parte, estamos ante un caso tpico de instrumentacin basada en sensores y actuadores de infrarrojos. Debido a la naturaleza del infrarrojo, estos dispositivos trabajan en un rango de frecuencias bastante altos ( por ejemplo, como se ver, el sensor de infrarrojos trabaja a 36khz). Esto requiere el uso de seales ( tanto en el emisor como en el receptor) acondicionadas con una frecuencia elevada, que permita el muestreo correcto de la seal sin prdida de informacin. .El ciclo de instruccin del PIC consta de 4 ciclos del reloj principal, y por tanto el tiempo de ciclo de instruccin es 1 s (ya que la frecuencia del reloj es de 4Mhz ). Esto lo hace lo suficientemente rpido para poder hacer el muestreo de la seal en el receptor o la emisin de la seal en el correspondiente emisor. Por estas razones, por ejemplo, un mdulo de adquisicin como LabJack con muy baja frecuencia de muestreo y actuacin no sera suficiente para este sistema. Finalmente, la lgica discreta con la que trabaja el microcontrolador permite el manejo de seales de una manera ms robusta y ajena de fallos, rasgo fundamental en un sistema de comunicacin donde un solo bit pude modificar completamente el mensaje que se quiso enviar originalmente.

Para el diseo y estudio de este sistemas, vamos a pasar por distintas etapas, que consistirn en: Estudio de los componentes bsicos a utilizar, principalmente el Sensor de Infrarrojo TFMS5360 y el emisor de Infrarrojo LED. Estudio del Acondicionamiento necesario para acoplamiento de los dispositivos Hardware a la placa en la que se encuentra el PIC16f84. Estudio del Protocolo de comunicacin para envo de mensajes entre emisor y receptor. Aplicacin a programas del sistema de comunicacin implementado.

2 Objetivos de la prctica
En esta segunda prctica de Diseo de sistemas basados en microprocesadores hemos decidido realizar una prctica basada en la comunicacin por infrarrojos. La idea de hacer una prctica de este tipo no fue repentina. Antes de realizar esta prctica barajemos otras posibles prcticas de libre eleccin para esta asignatura. Algunos ejemplos de prcticas candidatas fueron: control de un lector de cdigos de barras, traduccin de cdigo Morse a palabras en lenguaje natural y viceversa o las mismas prcticas propuestas por el profesor. La primera opcin, la de un control de un lector de cdigo de barras, fue descartada porque a simple vista pareca bastante complicada. Empecemos a pensar en cmo realizarla y comencemos a atormentarnos antes de tiempo, aunque quizs sin razn. Pensando en la manera de realizarla nos dimos cuenta de que quizs tendramos que implementar una librera de operaciones matemticas tales como la divisin o la multiplicacin, ya que la idea para identificar cada una de las barras del cdigo de barras, suponiendo que no siempre el sensor de luz se va a mover a la misma velocidad ya que estara manejada por una mano humana pero suponiendo tambin que cuando empieza a leer el cdigo de barras lo leer todo a la misma velocidad, era tener una primera barra de referencia a partir de la cual midiramos el ancho de cada una de las barras segn el tiempo que estuviera sobre ellas el sensor de luz. Esta forma de medir el ancho de las barras conllevara tener que realizar alguna operacin matemtica debido a las reglas de tres que tendramos que haber usado para identificar el ancho de las barras usando como medida el tiempo. Es por ello por lo que era probable que tuviramos que realizar la librera matemtica. La verdad es que esta idea nos daba un poco de respeto, ya que tendramos que realizar una librera matemtica, comprobar que funcionara y tendramos que suponer que la velocidad con la que se recorre el cdigo de barras es constante (algo poco probable si es una mano humana la que maneja el sensor de luz). En principio tenamos intencin de realizar esta prctica, hasta que ser nos ocurri que una prctica interesante tambin de realizar sera la segunda opcin comentada, la del cdigo Morse. Esta prctica, aunque interesante, sera tambin bastante sencilla. Si utilizramos el teclado para introducir las seales necesarias al PIC, solo tendramos que comprobar el tiempo que permanece pulsada una tecla del teclado y compararlo con una tabla de rangos de tiempos (tendran que ser rangos de tiempos debido a que quien lo manejara sera una persona, con lo que no podra medir con una precisin de microsegundos el tiempo que tiene que mantener pulsada la tecla) para determinar el smbolo al que representa el cdigo Morse identificado. Aunque esta prctica pareca sencilla, se podra complicar si pensramos en realizar el proceso contrario, es decir, traducir una ristra de letras a una salida en cdigo Morse. Adems se podra aadir que esa salida en cdigo Morse se pudiera transmitir a otro PIC que leyera el cdigo Morse, lo tradujera, y mostrara en la LCD los smbolos correspondientes a la transmisin en Morse traducidos.

En principio, esta transmisin se realizara por contacto fsico, es decir, mediante un cable conectando los dos PIC. Fue entonces, pensando en la manera de realizar esta prctica, cuando se nos ocurri que la transmisin podramos realizarla sin necesidad de un contacto fsico debido a que podramos utilizar medios de transmisin como el de un diodo emisor de infrarrojos, como el mando de la televisin, ya que ste acepta un rango bastante amplio en la direccin del emisor y es fcil de conseguir tanto el emisor como el receptor de infrarrojos. Finalmente, de aqu surgi la idea de realizar un PIC emisor de seales en infrarrojo y un PIC receptor de seales infrarrojo. Pero lo que decidimos finalmente no fue enviar cdigo Morse, puesto que si ya tenamos los instrumentos necesarios para realizar la comunicacin mediante infrarrojos, podramos enviar bytes en lugar de cdigo Morse, y hacer que dos PICs se comunicaran mediante este mtodo. Esta prctica es interesante de realizar y se le puede aadir la complejidad que se desee. Adems, como ya hemos dicho antes, los instrumentos necesarios para realizar esta prctica eran fciles de conseguir, ya que todos los televisores tienen un receptor de infrarrojos y un mando con un diodo emisor. En el caso de que no pudiramos conseguir estos dispositivos (el diodo emisor y el receptor de infrarrojos), podramos comprarlo en una tienda especializada en electrnica, ya que estos dispositivos se pueden conseguir a bajo precio. Es por esto por lo que definitivamente decidimos hacer esta prctica. En principio haramos que dos microcontroladores PICs se comunicaran entre ellos y despus le iramos aadiendo robustez y especificidad a esta emisin-recepcin, ampliando la prctica mientras tuviramos tiempo.

3 Hardware
3.1 Sensor Infrarrojos TFMS 5360
Este sensor de infrarrojos es un sensor que se suele utilizar en los televisores y en vdeos para recibir las seales que tenan los mandos a distancia a stos. Son bastante comunes y fciles de conseguir. Adems en Internet se pueden conseguir hojas de caractersticas de este tipo de sensor. Este sensor tiene tres patillas, una para el voltaje que se le suministre desde fuera, otra para la tierra y la tercera para la salida de datos. Estas tres patillas estn conformadas como se muestran en la siguiente figura:

Las patilla GND es la patilla que deber de estar conectada a tierra. La patilla Vs ser la patilla que deber estar conectada a la fuente (que deber de ser de 5 voltios). La patilla OUT es la que nos proporcionar la salida del sensor, segn la informacin que consiga captar de las ondas de luz infrarroja que reciba. Este sensor es de la familia de los sensores TFMS 5..0. Las caractersticas a destacar de esta familia de sensores son: Poseen un detector de luz y un preamplificador en un solo encapsulado. Una salida activa a nivel bajo. Esto quiere decir que la salida del sensor estar proporcionando 5 voltios mientras el sensor no reciba nada. Cuando reciba un tren de pulsos a una velocidad adecuada, el sensor de infrarrojos tendr en su salida de datos 0 voltios. Este tipo de lgica nos permite conocer cuando se ha estropeado el sensor, ya que, mientras no reciba el tren de pulsos necesario, deber contener 5 voltios en su lnea de salida. Si hubiera un cero podramos deducir que no est funcionando correctamente. Filtro interno para frecuencias PCM. Alta inmunidad contra ambientes luminosos. Consumo de 5 voltios, baja consumo de potencia Compatibilidad con TTL y CMOS Transmisin continua es posible. Ms adelante se comentar esta caracterstica ms detenidamente. Todos los sensores de infrarrojos de la familia TFMS 5..0 tendrn la misma forma de la figura y la caracterstica ms relevante que los diferenciarn ser la frecuencia en la que trabajarn estos. En las caractersticas de estos sensores se ha hablado de alta inmunidad contra ambientes luminosos. La alta inmunidad es conseguida debido a que para que el sensor de una respuesta a una onda de luz infrarroja deba recibir esa onda con unas caractersticas determinadas. Esto es as porque si diera una salida a bajo nivel para cualquier onda de luz infrarroja, se producira una lectura incontrolada del sensor, estara constantemente leyendo siempre y cuando hubiera una fuente de luz que pudiera proporcionar ondas de luz infrarroja al sensor, como puede ser la luz solar. El sensor debe poder distinguir entre cuando recibe la luz infrarroja de forma controlada y cuando recibe ruido. Es por ello por lo que para que el sensor d una respuesta acertada tengamos que enviar un tren de pulsos bien definidos de ondas infrarrojas. Este tren de pulsos tiene que tener una determinada frecuencia asociada que coincida con la frecuencia reconocida por el sensor. Ms adelante se explicar como ha de enviarse un tren de pulsos y con qu retardos para poder recibir con el sensor de infrarrojos una respuesta continua.

En concreto el sensor de infrarrojos utilizado por nosotros es el TFMS 5380. Este sensor trabaja a una frecuencia de 38 KHz. Eso significa que el perodo de cada pulso de un tren de 1 pulsos de infrarrojos deber durar = 0, 00002631 segundos, es decir, 26,31 38000 microsegundos. Otro punto de las caractersticas de las que se ha hablado es el de la transmisin continua porque debido a las especificaciones del sensor, ste debe recibir un tren de pulsos, como se acaba de comentar, para que responda a unas ondas de luz infrarroja. Este tren de pulsos deber mantenerse activo durante un tiempo menor o igual al 40 % del tiempo total que dura el pulso que se obtendr del sensor, es decir, que el perodo en el que est recibiendo el sensor el tren de pulsos tiene que ser igual a 0,4 veces el tiempo que tarda el sensor en recibir el tren de pulsos mas estar un perodo inactivo antes de recibir el siguiente tren de pulsos. Evidentemente, para lograr obtener estas caractersticas tiene que haber dentro del encapsulado mucho ms que un diodo receptor de luz infrarroja. En la siguiente figura se puede ver como est estructurado el sensor de infrarrojos interiormente:

Se puede observar que hay un circuito de control, un demodulador, un transistor para la salida,.... El circuito de control probablemente sea el que controla que los tiempos de envo de las ondas de infrarrojos (trenes de pulsos, silencios, ...) sean los correctos, mientras que el circuito modulador sea el que permite que la salida del sensor sea una salida continua en respuesta al tren de pulsos de entrada. En cambio, el circuito del transistor lo que permite es mantener una salida a 5 voltios mientras el transistor, algo que ocurrir cuando reciba una seal correcta el sensor de infrarrojos. Esto es as puesto que el transistor acta como una especie de conmutador, que cerrar el circuito cuando reciba una seal correcta y lo abrir mientras esto no ocurra, manteniendo la salida a 5 voltios mientras est abierto y a 0 voltios (puesto que est a tierra) cuanto el transistor acte cerrando el circuito. En la siguiente figura se muestra como debe de ser una transmisin para que el sensor la detecte adecuadamente:

En la figura las dos barras pequeas sobre el eje x indican una especie de abreviatura. Por ejemplo, las dos barras pequeas sobre el eje x que se encuentran en el periodo inactivo de la seal indican que la seal permanecer inactiva durante un tiempo mayor al que se ha podido representar en el grfico. Lo mismo ocurre con las dos barras en el eje x durante el tren de pulsos. Indicarn que el tren de pulsos se mantendr durante un tiempo que era tedioso de representar. En esta figura se puede ver que se ha llamado tpi al tiempo que permanece activo el tren de pulsos y T al tiempo que transcurre desde que se activa el tren de pulsos de la primera seal hasta que se recibe el siguiente tren de pulsos. Ahora, una vez puesto nombres a los tiempos, podemos repetir la caracterstica que expresbamos antes de una forma menos tediosa de entender. Para que el sensor de infrarrojos reciba de una forma correcta los datos, el tiempo T debera estar compuesto por un 40% (como mximo) de su periodo de un tren de pulsos y un 60% (como mnimo) de una seal inactiva. Adems, en la hoja de caractersticas se especifica que para un funcionamiento ptimo del sensor, el tpi debera de durar como mnimo 400 s. Esto implica que para que funcionara de forma ptima el sensor TFMD 5380 debera recibir como mnimo 400/26 pulsos (un pulso dura 26 s aproximadamente a 38 kHz de frecuencia) que son unos 15 pulsos. En la hoja de caractersticas viene especificada la respuesta que dara el sensor a una seal recibida como la de la anterior figura. Segn la hoja de caractersticas la seal que proporcionara el sensor a una entrada como esa es parecida a la siguiente:

Segn esta figura que nos proporciona la hoja de caractersticas, el tiempo en le que el sensor estar dando una seal a nivel bajo es igual al tpi, aunque con un error de 160 microsegundos. En verdad, aunque la hoja de caractersticas de este sensor insiste en que debe de haber un 60% de tiempo inactivo y un 40% de tiempo a tren de pulsos para un correcto funcionamiento hemos comprobado empricamente que en realidad con que el periodo inactivo y el periodo a tren de pulsos sea un 50% del periodo total basta para que el funcionamiento sea correcto.

Es por ello que el tiempo que hemos utilizado en nuestra prctica para el tren de pulsos es la mitad del tiempo total, ya que es ms fcil de manejar dividiendo por dos y multiplicando por dos los periodos, que en adelante trataremos como marcos de bits para la transmisin. Debido a estas caractersticas para la transmisin, si quisiramos enviar la informacin como bits, en donde un nivel bajo en la salida del sensor indicara la recepcin de un 1 y un nivel alto la inexistencia de la recepcin o la recepcin de un cero, para enviar un byte de informacin la forma de enviar los datos por parte del emisor sera la siguiente: Enviando el byte 10101010

Marco de bit

Tren de pulsos a 38 KHz

A una transmisin como esta el sensor de infrarrojos respondera as:

Marco de bit Es decir, que en el control del receptor tendramos que definir un marco de bit de duracin suficiente para que le de tiempo a leer al sensor el tren de pulsos y el periodo inactivo. Adems, tendramos que definir un programa controlador que trabajara con lgica inversa. La salida del sensor es continua, como se ha dicho antes. Esto facilita las cosas de cara a implementar un programa para el controlador del sensor (en este caso un PIC), ya que solo habr que comprobar el nivel en el que est la seal, y no si se produce un tren de salida del sensor.

3.1.1 Conexionado y acondicionamiento del sensor al microcontrolador.


En el siguiente circuito se puede ver un esquema general de conexionado de un sensor infrarrojos de la familia TFMS 5..0 con un microcontrolador.

En la figura se puede ver el diodo emisor (el diodo situado a la izquierda) y el receptor (el situado a la derecha). El diodo receptor est dentro del encapsulado del sensor de infrarrojos. En nuestro caso el diodo emisor tiene que estar apuntando directamente al sensor de infrarrojos, ya que debido a la baja intensidad que proporciona el PIC al diodo emisor, ste no puede emitir la luz infrarroja en un amplio rango de actuacin. An as, el diodo emisor puede estar situado a unos metros del sensor, aunque siempre apuntando al sensor. La salida del sensor ir directamente conectada al microcontrolador. En el circuito implementado por nosotros ira directamente al bit 4 del puerto A. Se puede ver en la figura anterior como se pueden aadir una resistencia de 330 en el cable de alimentacin del sensor y un condensador de 4.7 F conectando la entrada de suministro de voltaje del sensor a la salida a tierra del mismo. Esto nos servira si quisiramos o necesitramos evitar perturbaciones en el suministro de energa. Otro aspecto importante para el acondicionamiento del sensor es el aadido opcional de una resistencia entre la entrada de suministro de energa del sensor y la salida de datos. sta resistencia deber de tener un valor resistivo de ms de 10 k para su correcto funcionamiento. ste ltimo aspecto fue determinante en nuestra prctica, ya que uno de los problemas que nos surgi fue el que no conseguamos que funcionara correctamente la conexin del PIC con el sensor. La razn era que la intensidad, sin esta resistencia aadida, circulaba hacia la tierra y no llegaba hasta el sensor de infrarrojos. Una vez colocada esta resistencia logremos que el sensor funcionara correctamente. Ahora habamos conseguido que la intensidad no fuera toda a tierra y que el sensor pudiera devolver intensidad al PIC en su respuesta.

3.2 Conexionado y acondicionamiento del diodo emisor.


El emisor es un simple diodo emisor de infrarrojos conectado a un microcontrolador que le proporcionar voltaje o no segn este microcontrolador quiera enviar o no ondas de luz infrarrojas. El circuito implementado es como el que sigue:

5V

C
GROUND

< 250

Para que el diodo emisor funcione con la intensidad que proporciona el microcontrolador debe de tener menos de 250 de resistencia. En nuestro caso hemos implementado algunos aadidos adicionales a la prctica. Es por esto por lo que necesitamos el puerto B del microcontrolador PIC tanto para el teclado como para establecer una comunicacin con el diodo emisor. Esto trae ciertos problemas consigo, como podra ser que no llegan los datos necesarios a travs del puerto B y desde el teclado hasta el microcontrolador. Es por ello por lo que, como acondicionamiento, hemos aadido un potencimetro entre la salida del puerto B y la entrada al diodo emisor para poder controlar la intensidad que llega al diodo. En nuestro caso, cuando queramos manejar el teclado, tendremos que ampliar el valor de la resistencia del diodo. En cambio, si queremos manejar el diodo emisor tendremos que disminuir bastante el valor la resistencia para que llegue hasta el emisor la intensidad adecuada para que pueda emitir infrarrojos. La intensidad que proporciona el PIC es de aproximadamente unos 0.65 Miliamperios. Esto puede ser un problema. En el caso del diodo emisor, esta intensidad es suficiente como para que emita los infrarrojos, aunque lo hace en un rango muy restringido. Habr que situar el diodo emisor en la direccin que apunta al sensor de infrarrojos para que ste pueda recibir la luz infrarroja que ste emite. Creemos que este rango de emisin tan restringido es debido a la baja intensidad proporcionada por el microcontrolador PIC, ya que este emisor lo hemos obtenido de un mando de una televisin. En el mando de la televisin este emisor lograba alcanzar un rango de emisin bastante amplio. Es por ello por lo que creemos que si logrramos amplificar la intensidad (mediante un transistor) que le llega al diodo conseguiramos un mayor rango de actuacin del emisor.

4 Desarrollo de la prctica.
Antes de empezar con esta prctica haba que conseguir el sensor de infrarrojos que queramos utilizar. La forma de conseguirlo podra ser obtenindolo de un vdeo o televisor casero, tanto el emisor como el receptor, o comprndolo en un tienda de electrnica. Inicialmente logremos conseguir tanto un sensor como un emisor de un televisor y un vdeo. Al principio de esta prctica utilizbamos un sensor TFMS 5360 a 38 khz. posteriormente, cuando ya tenamos bastante inicializada la prctica, este sensor pas misteriosamente a mejor vida y nos vimos obligados a comprar uno similar.

El sensor que logremos comprar en una tienda de electrnica fue un sensor TFMS 5360, que va a 36 kHz, por lo que no nos hizo falta modificar demasiado el programa para que este sensor aceptase el tren de pulso que era enviado por el emisor, ya que como se puede ver en la siguiente frmula, tenemos que el nmero de instrucciones que tenemos que ejecutar para conseguir el tren de pulso a 38 kHz son dos menos que para conseguir que el tren de pulsos vaya a 36 kHz, por lo que solo habrn de aadirse dos instrucciones nops, una en cada semiperiodo de un pulso del tren de pulsos.

N deinstrucciones =

1 MHz 1000000 = = 26,3157 38 KHz 38000 1 MHz 1000000 N de instrucciones = = = 27,7778 36 KHz 36000

Antes de comenzar a realizar el programa de control del emisor queramos comprobar que el sensor que tenamos funcionaba, y como funcionaba. Esto lo hicimos con la ayuda de un osciloscopio y con una fuente de corriente alterna, aunque con la fuente alterna no conseguimos una seal por parte del sensor con el suficiente sentido como para poder sacar conclusiones. El sensor lo conectemos a una fuente de corriente continua que nos proporcionaba 5 voltios. El osciloscopio lo conectemos a la patilla de salida del sensor, situada a la derecha de ste desde un punto de vista frontal, para poder conocer la respuesta del sensor a los diferentes trenes de pulsos.

5 Voltios Osciloscopio

El osciloscopio tena que estar configurado para que pudiera mostrar una salida de 5 voltios. De la forma en la que nosotros lo tenamos configurado era para que mostrara una escala de cinco voltios por cuadrado de la pantalla del osciloscopio. Con esto sabamos cuando estaba a 5 voltios la salida del sensor de una forma muy simple, ya que cada cuadro equivala a 5 voltios. Para configurar el tiempo en el osciloscopio se puede ir modificando la escala de los cuadros para ver cual es la escala preferida, segn la frecuencia a la que est recibiendo el sensor. Lo que interesa es poder ver el ancho del pulso para conocer el tamao del marco de bit que nos est proporcionando el sensor de infrarrojos.

Con la ayuda del osciloscopio vimos que la fuente de corriente alterna no consegua hacer funcionar al sensor de una forma controlada. Esto se puede explicar debido a las caractersticas del sensor. El sensor, para funcionar correctamente, necesita periodos de inactividad tan amplios o ms amplios an que el periodo de tiempo en el que est recibiendo el tren de pulsos. Las otras alternativas al generador de corriente alterna eran implementar un programa de prueba para probar el sensor o utilizar un mando a distancia para intentar ver lo que recibe el sensor cuando se le apunta con la mano y se intenta establecer una comunicacin con el sensor. La primera alternativa era la ms sencilla de realizar, ya que tenamos el mando y habamos conectado el sensor al osciloscopio, por lo que solo tenamos que apuntar y apretar un botn. Con el mando de la televisin vimos que el sensor funcionaba puesto que daba una respuesta que pareca bastante ms controlada y regular que la respuesta que nos proporcionaba el generador de corriente alterna. Una vez probado que el sensor de infrarrojos funcionaba, tenamos que ver como funcionaba el emisor de infrarrojos. Esto era un poco ms complicado, ya que para ello haba que conseguir que el diodo emitiera una serie de pulsos que fueran acordes con las caractersticas del sensor. Con el fin de emitir el tren de pulsos implementemos un programa sencillo en ensamblador. Conectemos el diodo emisor al PIC y comencemos la transmisin. Estuvimos probando y no obtenamos en el sensor de infrarrojos lo que queramos, hasta que nos dimos cuenta que era por el tiempo de inactividad que haba que dejar despus de cada tren de pulsos en el emisor. Estuvimos probando entonces con variaciones en le tiempo del tren de pulsos, ponindolo en el 60% del periodo total, el 40%, .... Hasta que finalmente dimos con que a pesar de que la hoja de caractersticas del sensor nos deca que tena que ser el 40% del periodo o menos, utilizando el 50% tambin obtenamos unos resultados aceptables. Con trenes de pulsos de mayor duracin con respecto al perodo inactivo la respuesta no estaba controlada. No obtenamos una respuesta regular, (al igual que lo que obtenamos con el generador de corriente alterna), mientras que con trenes de pulsos con una menor duracin con respecto al perodo inactivo obtenamos una respuesta mucho ms regular, y que concordaba con lo que queramos transmitir. A continuacin veremos un programa ejemplo que se puede utilizar para obtener una respuesta conocida del sensor de infrarrojos.

4.1 Ejemplo de implementacin de programa de prueba para el diodo emisor de infrarrojos.


Como ya se ha dicho, el sensor de infrarrojos TFMS 5360 no recibe cualquier tipo de seal basada en infrarrojos, debido a que si fuera de esta forma, estara constantemente recibiendo seales debido a la luz solar.

Debido a esto, y para probar el sensor infrarrojos, debemos implementar un programa para el PIC 16F84 en el que reproduzca un tren de pulsos para el emisor de infrarrojos con el fin de poder analizar la respuesta del sensor de infrarrojos ante una seal de estas caractersticas. El PIC 16F84 va a una frecuencia de 1 MHz. Necesitamos una frecuencia para el tren de pulsos de 36 KHz, por lo tanto, con el microcontrolador PIC 16f84 tendremos una velocidad suficiente para poder reproducir el tren de pulsos necesario. Lo nico que se habr de tener en cuenta para poder implementar un programa que defina un tren de pulsos adecuado al sensor de infrarrojos TFMS 5360 es el tiempo que tardan las instrucciones en ejecutarse, ya que no todas las instrucciones se ejecutarn en el mismo perodo de tiempo, para que el sensor de infrarrojos logre distinguir el tren de pulsos de seales ruidosas externas. Es por ello que antes de empezar tendremos que hacer una valoracin del nmero de instrucciones que debemos introducir entre el inicio y el fin de cada semiperodo del tren de pulsos para poder definir ste con una precisin aceptable para el sensor. Una instruccin en el PIC 16F84 se ejecutar en 1 microsegundo, mientras que una instruccin de salto, o una instruccin condicional en la que se produzca el salto debido al valor de la condicin, tardar en ejecutarse 2 microsegundos, es decir, dos ciclos de reloj del microcontrolador. Si tenemos en cuenta estos tiempos de ejecucin para las instrucciones, podra implementar una macro fcilmente que realizara un semiperodo para un tren de pulsos. Para crear esta macro debemos tener en cuenta la siguiente frmula en la que determinamos el nmero de instrucciones que necesitamos para simular el tren de pulsos:

N de instrucciones =

1 MHz 1000000 = = 27,7778 36 KHz 38000

Esta frmula se puede determinar mediante una simple regla de tres, diciendo algo parecido a que si el nmero de instrucciones que se deberan ejecutar si el microcontrolador fuera de 36 KHz es de una instruccin para completar un perodo, Cuntas necesitaramos si tuviramos un microcontrolador a una frecuencia de 1000 KHz?. Con lo que el nmero de instrucciones que necesitaramos se calculara con la siguiente regla de tres: 36 KHz 1000 KHz 1 instruccin

x instrucciones El resultado de esta frmula ha dado un nmero decimal de instrucciones, pero no afectar demasiado a la forma en la que lee el sensor la seal si redondeamos hacia abajo. Es decir, que para realizar un perodo completo necesitaremos las instrucciones necesarias para completar los 27 microsegundos. Para implementar los trenes de pulsos podramos utilizar macros, o llamadas a funciones que realicen el semiperodo positivo y el semiperodo negativo. En este caso utilizaremos macros, ya que si utilizramos funciones tendramos que descontar las instrucciones de salto que se producen tanto en la llamada como en el retorno de la funcin. De todas formas, habr que descontar las instrucciones que se produzcan para realizar los saltos el bucle, en el que implementaremos el nmero de pulsos que queremos que contenga el tren de pulsos.

El procedimiento podra ser de la siguiente forma: La macro semiperiodo estara diseada como sigue:
MACRO semiperiodo fill (nop),12 ENDM

Como se puede ver, tenemos solo 12 instrucciones, en lugar de 13, esto es debido a que adems del semiperodo, necesitamos ejecutar las instrucciones bsf y bcf que activan o desactivan el bit cero del puerto B. ; 1 Ponemos el puerto B como salida, vamos a enviar la seal al diodo emisor desde el bit cero del puerto B.
bsf movlw movwf bcf STATUS,RP0 00h TRISA STATUS,RP0

; 2 Creamos el bucle llamando a la macro que realiza el retardo correspondiente a un semiperodo, para ello cargamos el nmero de veces que queremos que se ejecute el bucle.
movlw mowf Bucle bsf semiperiodo bcf semiperiodo decfsz goto end Npulsos Contador PORTB,0 PORTB,0 Contador,1 Bucle

El tren de pulsos que conseguiramos por la salida del bit cero del puerto B con este programa sera parecido al siguiente:

Cada vez que se ejecute el bucle se ejecutar un periodo del tren de pulsos. Se puede ver como entre pulso y pulso adems se ejecutan tres instrucciones. Esto se podra arreglas utilizando el retardo del semiperiodo a cero, pero no es necesario, ya que la velocidad a la que

se ejecutan las instrucciones nos permiten cierto error. Adems veremos que el sensor de infrarrojos nos permite cierto error tambin. No es demasiado rgido con lo que nos especifica la hoja de caractersticas. Con este programa ya tendramos implementado un tren de pulsos. Ahora solo queda implementar el perodo de tiempo que necesitamos que se encuentre inactivo el diodo emisor para que hay una respuesta controlada por parte del sensor de infrarrojos. Para implementar este periodo de inactividad simplemente habr que hacer el mismo bucle anterior pero las dos instrucciones que activan y desactivan el puerto, ahora tienen que ser las dos de desactivado del puerto, es decir, bcf, o tambin ponerlo a cero una vez y realizar el bucle anterior sin activar ni desactivar el puerto de salida B, puesto que ya estara desactivado. Podra ser algo como sigue:
movlw mowf Bucle1 bcf semiperiodo bcf semiperiodo decfsz goto end Npulsos Contador PORTB,0 PORTB,0 Contador,1 Bucle1

Se han puesto las dos instrucciones bcf puesto que aunque no son necesarias, si queremos contabilizar al 50% exacto del periodo total sin mucho error deberamos poner el mismo nmero de instrucciones. Con este programa ya tendramos implementado un programa de prueba para el sensor de infrarrojos.

5 Protocolo de comunicacin
Primeramente, decir que la unidad bsica de transmisin es el Byte. Por tanto, una de nuestras tareas de sntesis del mensaje ser precisamente descomponerlo hasta llegar a la unidad bsica transmisible en este sistema de comunicacin. Este tamao es suficiente para lo que es el propsito de esta prctica, que no es ms que el de la transmisin de mensajes en forma de Caracteres ASCII. Llegados a esta unidad bsica de transmisin, dadas las restricciones Hardware que presenta el proyecto ( tenemos un nico emisor de infrarrojo y un nico receptor de infrarrojo), vamos a desarrollar una comunicacin unidireccional (1 pic controlar al emisor y el otro al receptor). Por este, el sistema de control de errores se ver afectado por esta unidireccionalidad, y, como veremos ms adelante, ser imposible que el receptor pueda comunicar al emisor que

debe de mandar de nuevo el ltimo envo ya que lleg con error, por tanto, nuestro sistema de control de errores se basar en la redundancia ( ya que no puede el receptor avisar al emisor que le lleg mal el envo, que el emisor mande varias veces cada envo por si hiciera falta repetir el mensaje). Por otra parte, la transmisin va a ser de tipo serie, ya que es imposible formar varios canales de comunicacin simultneos con un nico emisor y receptor. Por ello, vamos a usar una solucin al problema de la transmisin de datos basada en el protocolo de comunicacin estndar del RS-232, y trabajaremos sobre este protocolo de comunicacin base para desarrollar un propio protocolo que ser descrito a continuacin. Finalmente, para fijar todos los objetivos a conseguir con la implementacin posterior, tenemos que decir que no va a ser objetivo la rapidez de transmisin, aunque una vez conseguidos los objetivos bsicos intentaremos hacer una breve introduccin a este tpico. En cambio, si primar como objetivo la robustez del protocolo de comunicacin, y capacidad de detectar errores y, en consecuencia, hacer uso de la redundancia que veremos que poseen los mensajes para poder enmendar estos errores que pudieran producirse. La filosofa bsica a la hora de la implementacin ser la modulacin: dividir el protocolo en diversas capas independientes de manera que las capas superiores usen las funciones que les proporcionan las inferiores, sin necesidad del conocimiento interno de las capas inferiores, simplemente usando una interfaz que el proporciona esa capa inferior. Es decir, las capas superiores usan las llamadas a funciones inferiores, pero no pueden ver internamente como estn implementadas, por lo que no pueden acceder a cualquier parte del cdigo de la capa inferior, solo a las que eta capa inferior exporta como externa y proporciona como servicios. La modulacin nos aporta facilidades a la hora de la sntesis del Sistema, por tanto solo son beneficios para el diseador del sistema de comunicacin, no para el usuario. Si el sistema de comunicacin funciona, le es lo mismo al usuario que haya sido creado modularmente o no. Esta ventajas que proporciona al diseador del sistema de comunicacin son: Fcil Depuracin y localizacin de errores: las capas son independientes, por lo que se pueden analizar cada una individualmente. Fcil solucin de Errores, sin necesidad de modificar todo el sistema de comunicacin, solo modificando aquellos mdulos defectuosos. Fcil escalabilidad: si se desea modificar la filosofa de alguno de los niveles se puede hacer sencillamente manteniendo las interfaces ( para que los niveles superiores puedan seguir funcionando), e igualmente se pueden aadir capas de abstraccin a partir de las bsicas que vamos a desarrollar.

Emisor
0

Receptor

Emisin: Serie Unidireccional

10010110

De hecho, para el estudio de este protocolo de comunicacin tambin va a ser ms sencillo el explicarlo capa a capa de forma inductiva: partiendo de la base vamos abstrayendo niveles superiores del protocolo, hasta llegar el nivel ms alto.

Las capas que en la presente prctica se han desarrollado para sintetizar el protocolo han sido: Nivel Bajo: es el nivel ms bsico, en el que, a partir de los 8 bits del byte (unidad bsica en este nivel) a mandar, se confeccionar la codificacin de estos bits (startbit, stopbit, etc) para ser mandados y se enviarn en modo serie. Por parte del receptor, a partir de bits individiales se recogern y decodificarn para obtener el mensaje de 8 bits originales. Tambin en este nivel se desarrollan funciones con el fin de sincronizar los envos, bien sea a nivel de bytes, o a nivel de paquetes. Nivel Medio: en este nivel se usan las funciones de envo y recepcin de bytes, envo y recepcin de sincronismos para los bytes y los paquetes, para sintetizar paquetes (unidad bsica en este nivel) como una reunin de conjuntos de bytes. Por tanto los bytes se organizarn en paquetes o grupos.

Nivel Alto: es el mximo nivel de abstraccin, se usan las funciones de envo y recepcin de paquetes del nivel anterior (adems de los de sincronizacin de paquetes del nivel ms bajo). Estos paquetes se envan redundantemente ( varias veces cada paquete, no cada byte, sino cada grupo de paquetes), y se desarrollar una lgica para, en funcin de los errores que se produzcan, volver a tomar el mismo paquete o esperar al siguiente diferente. La unidad bsica son los conjuntos redundantes, y en ltima instancia es el programa de usuario que usa las herramientas para un fin determinado. Ntese que, a la hora de abstraer en estos niveles, no se trata de que un elemento de un nivel superior pueda usar solo funciones de su capa inmediatamente inferior. Puede usar funciones de cualquier nivel inferior a l, sea o no inmediata. Lo que no podr nunca es usar funciones de un nivel superior a la capa en la que se encuentra este elemento. Un posible diagrama que exprese lo aqu explicado sera:

Nivel Alto(programa de protocolo)

Nivel Medio(paquetes)
Nivel Bajo (bytes)

5.1 Nivel Bajo


Comencemos a explicar este protocolo de comunicacin desde el sustrato ms bsico y elemental, que servir como base sobre la que se edificar todo el sistema de comunicacin.

En este nivel, la unidad bsica es el Byte, de manera que los algoritmos desarrollados irn destinados al envo de un byte. Ms adelante veremos como conformar un mensaje mediante Bytes. Un Byte se conforma de 8 bits, de manera que para ser enviados necesitarn de una fase previa de codificacin en el emisor, y de decodificacin en el receptor. Este Byte Codificado necesita ser mandado en serie (bit a bit) a travs del Led de infrarrojos, y recibido por el receptor de infrarrojos, por tanto definamos previamente qu es un bit para este protocolo de comunicacin.

Marco de Bit
El marco de bit, que es el periodo que dura la transmisin de un bit, va a influir notablemente en la velocidad de la transmisin ( a menor marco de bit menor es el tiempo que tarda la transmisin) y en la robustez del mismo (es ms fcil que se produzcan errores de sincronismo entre el emisor y el receptor cuanto menor sea el Marco de Bit) El hardware del que disponemos nos dar la gua definitiva sobre que marco de Bit usar. Como hemos visto, el sensor de infrarrojos TFMS 5360 trabaja a una frecuencia de 36kHz, que supone un periodo de 27.78 s. Como sabemos, este sistema de infrarrojos trabaja por rfagas: en funcin de la relacin entre el tiempo en que se emite un pulso peridico a una determinada frecuencia, y el tiempo en el que no se emite ningn pulso, se genera una determinada seal de salida en el sensor TFMS 5360. La combinacin de un pulso y un silencio o ausencia de pulso conformarn 1 marco de bit. Por ello, a la hora de elegir el pulso peridico que forme parte de la zona de la rfaga en la que se emite un pulso, parece razonable tomar una pulso con un periodo de seal similar a la que el sensor de infrarrojos puede tomar, esto es, unos 27.78 s.. Cuando pasemos a programar una simulacin de este pulso en el Pic ( en el emisor) veremos que no vamos a tomar exactamente este valor, sino que tomaremos unos 26 s. Esto se explica debido a que en el Pic no existe ninguna instruccin que tenga una duracin de menos de 1 s, lo cual implica que no podemos tomar un semipulso de 27.78/2 = 13.89 s. En este caso vamos a tomar una redondeo inferior, tomando un semipulso de 13 s, por tanto un periodo del pulso de la rfaga de 26 s. En cuanto a la duracin del marco de bit, nuevamente recurrimos a las especificaciones del sensor de infrarrojos TFMS 5360, analizando que: El tiempo de duracin de la parte de rfaga con pulso activo (con emisin de pulso peridico) debe ser superior o igual a 400 s para obtener una transmisin ptima (Pgina 4 del fichero de especificaciones tfms.pdf). Esto supone un nmero de pulsos superior a 400/ 26 15 pulsos completos. Nos conviene que el sensor sea capaz de mantener una seal de salida continua, esto significa, que la seal de entrada en modo de rfagas (periodo con pulso activo y periodo con pulso inactivo) sea copiada por el sensor de infrarrojos a una salida con un periodo activo igual al periodo del pulso inactivo de la rfaga de entrada, y un periodo inactivo igual al periodo del pulso peridico de la rfaga de entrada.

Rfaga de entrada

Marco de Bit

Marco de Bit

Seal de Salida del Sensor continua.

Periodo Pulso Peridico o activo

Periodo Silencio o inactivo.

Periodo Nivel Bajo Salida

Periodo Nivel Alto Salida

Lo Expresado en el diagrama es lo deseado: poder controlar desde el emisor cual va a ser los periodos activos o inactivos del marco de bit del receptor, ya que ste ltimo no sea ms que una traduccin de la rfaga de entrada en una Salida digital ( y por tanto, que el marco de bit tenga la misma duracin en ambos dispositivos, emisor y receptor). Para ello, la seal devuelta por el sensor debe ser continua. Para que sea continua, es fundamental que se cumpla la interrelacin [1] PeriodoActivoRafagaEntrada / MarcoDeBit 0.4 (Pgina 1 del fichero de especificaciones tfms.pfd), por lo que el periodo de pulso peridico de la rfaga de entrada debe suponer menos de un 40% del Marco de Bit total. En la experiencia [2], nos damos cuenta de que esta cifra no es ms que orientativa, ya que con que no suponga ms de un 50% aproximado del marco de bit es suficiente para que pueda mantener en sensor una salida continua. Barajando estas dos restricciones que nos impone el sensor TFMS5360, vemos que el marco de bit terico debe de ser con un periodo activo de la rfaga de entrada de 400 s, y, suponiendo que esto supone un 40% del marco de bit total, el marco de bit total sera de 1000 s. Ms an, el nmero de pulsos del periodo activo de la rfaga de entrada seran 400/26 15 pulsos, y , puesto que en 1000 s hay cabida para 1000/26 38 pulsos, 28 periodos de pulsos como periodo inactivo de la rfaga de entrada. En la realidad, esto es arriesgar demasiado, y , puesto que tenemos como objetivo una seal lo ms robusta posible, a menor marco de bit nos obligara a tener medidas con mucha ms precisin todas las instrucciones que formen parte de las funciones del Pic para emitir y recibir bytes, para evitar la desincronizacin entre emisor y receptor. Esto dificulta notablemente la tarea de programacin del microcontrolador. Un marco de bit ms amplio nos da mucha ms flexibilidad y holgura sin que se desincronicen ambos dispositivos. En vistas de lo dicho, y de lo aclarado en el punto [2] , vamos a tomar nuestro primer consenso, y configurar nuestro marco de bit de la siguiente manera:

El periodo con el que se transmite el pulso del periodo activo de la rfaga de entrada es de 26 s. El Marco de Bit, tanto en la seal del Emisor como en la del Receptor, ser de 200 pulsos, esto es 200 * 26 = 5200 s. Es un marco de bit lo suficientemente holgado para permitirnos una programacin ms sencilla. Ntese que, debido a la restriccin [1] no es posible que el periodo activo de la rfaga ocupe todo el marco de bit, pues la seal de salida no se mantendra continua. Por ello, transitivamente, es imposible que podamos obtener una salida completamente a nivel bajo durante todo el marco de bit, ya que las salidas a cero tienen el mismo periodo que el periodo activo de la rfaga. Sin embargo, si podemos poseer un periodo inactivo de la rfaga de entrada que ocupe todo el marco de bit, y por tanto, si puedo obtener una salida del sensor que sea todo el marco de bit a nivel alto. Esto hace que Emitir un 1 el emisor no sea tan sencillo como mandar durante todo el marco de bit el pulso, ya que la salida no se mantendra, pero si que se puede emitir un cero como todo el marco de bit sin pulso, ya que el receptor si generara una salida con todo el marco de bit a nivel alto (si mantendra la seal continua). Por tanto, en vez de enviar Bits como presencia de pulso en todo el marco de bit, o ausencia el cero en su defecto, vamos a tomar este convenio: Si queremos mandar un cero ( seal a nivel bajo), mandamos todo el marco de bit sin pulso, por lo que la salida del sensor ser continua a nivel alto:
Marco de Bit Marco de Bit

....0..
Emisor Receptor

Si, por el contrario, queremos enviar un uno ( seal a nivel alto) mandaremos un escaln, con el primer semiperiodo activo (mandar pulso con periodo 26 s) y el segundo inactivo ( sin pulso). El marco de bit se divide por tanto en un 50% activo (100 pulsos) y 50% inactivo ( suficiente para mantener una seal de salida continua segn lo explicado en [2]). De esta manera, el envo de un bit 1 se traduce en:
Marco de Bit Marco de Bit

....1.. Vase que en el receptor, el escaln tiene el primer semiperiodo a nivel bajo y el segundo a nivel alto. Esto indicar que lo que se est emitiendo es un 1.
Emisor Receptor

Ejemplo de bit a 1 Enviado por el Emisor, con todos los parmetros sealados:

Marco de bit
13s 13s

26

Periodo Activo

Periodo InActivo

(equivalente a 100 pulsos. Periodo=100*26=2 600s)

Codificacin / Decodificacin del Byte a transmitir


En primer lugar, vamos a situarnos desde el punto de vista del emisor, el cual, para poder mandar el Byte necesitar codificarlo antes convenientemente. [3] Hay que tener en cuenta que a partir de ahora, cada vez que hagamos referencia al envo de un bit a 1 ser, en ltima instancia, segn el formato que explicamos anteriormente ( una rfaga con un semiperiodo con pulso periodico activo y con un semiperiodo en silencio), de igual manera que un bit a 0 ser segn el formato explicado (periodo en silencio o inactivo de la rfaga ocupa todo el marco de bit). Esta codificacin va ser muy similar a la que se haca en el protocolo de comunicacin RS-232. Por lo que dispondremos de: Un StartBit Inicial: el Start Bit es un bit 1 emitido por el emisor (tal como vimos, se efectuar una rfaga con semiperiodo con pulso activo y semiperiodo sin pulso). Indica al receptor que el emisor tiene intencin de emitir un byte, por lo que permite al receptor preparase para poder capturar ese byte. Previo al StartBit la seal tenia que haber estado a nivel bajo. Envo en serie de los bits: En un determinado registro de declaje tendremos los 8 bits correspondientes al Byte que se quiere enviar. Pues bien, en esta fase el emisor debe de ir desplazando este registro, y capturando el carry o bit que, por el overflow, abandona cada vez al registro, para enviarlo en serie por el canal de comunicacin ( 1 marco de bit para cada bit, en total 8 marcos de bits son consumidos en esta tarea). Por tanto, el mtodo de emisin ser comenzar a enviar el Byte por su bit ms significativo (MSB, ya que el registro de declaje se desplaza hacia la izquierda registro hacia la izquierda), uno a uno, desplazando en el registro de declaje y enviando por el canal el bit overfloweado, hasta llegar al bit menos significativo (LSB) Control de Errores se puede situar tras el envo del Byte algn marco de bit referente a control de errores como la Paridad. Pero en principio, en el desarrollo de esta prctica vamos a intentar tratar y detectar errores de otra manera distinta a la Paridad como veremos ms adelante, por lo que, en el programa bsico de este dispositivo de comunicacin de datos no vamos a aadir este bit en la codificacin. StopBit: en principio, tiene como funcionalidad dar tiempo al receptor para que pueda re sincronizarse con el emisor (por si ste desea enviar ms

bytes) tras el tratamiento de la informacin recibida y tambin le vamos a dar un papel fundamental en la deteccin de fallos en el mensaje recibido a causa de desincronizarse. A travs del Stobit vamos a montar un sistema de deteccin de desincronizaciones, para que el receptor pueda actuar en consecuencia y re sincronizarse con el emisor previo a cualquier otro envo de datos. Ya tenemos los elementos bsicos para codificar el byte a transmitir. Antes de ver como organizar estos elementos en un mensaje concreto, vamos a ver que significado tendrn estos elementos bsicos en el receptor:

El StartBit inicial: previo a este, el receptor se encontrar rastreando la seal del sensor, que deber estar a nivel alto mientras no se reciba nada (si no hay rafaga de entrada, el sensor mantiene una salida constante a nivel alto) hasta que el sensor devuelva una seal a nivel bajo, que ser el StartBit, lo que significar que el siguiente envo ser ya el bit ms significativo del dato a enviar. El receptor preparar un registro acumulador, en el que ir guardando todos los bits que le lleguen. Acumulacin de Bits: los siguiente 8 envos de bits se correponden con el de la informacin a transmitir, por lo tanto se irn traduciendo a bits ( si es un escaln la salida del sensor es un bit a 1, y si est totalmente a nivel alto es un bit a cero) y acumulando en un registro de desplazamiento (desplazando hacia la izquierda el mismo e introduciendo por la parte menos significativa del registro, ya que el primero es el bit ms significativo). Control de Errores: En caso de que se enve una paridad ( que en el caso base que vamos a estudiar no se va a dar), la acumulacind e bits tambin incluira un conteo de paridad, para finalmente comparar con este ltimo bit de paridad enviado y detectar si hay errores o no. En caso de Errores, simplemente se guardar en un registro para que los niveles superiores puedan darse cuenta de que hubo un error. StopBit: primeramente, el receptor deber garantizar que se enva un determinado nmero de Stopbits, y en caso de que ese nmero no se cumpla, significar que hay un fallo de sincronizacin entre emisor y receptor, y por tanto se indicar en un registro que podr ser observado en niveles superiores de abstraccin. Solo cuando se garantiza un nmero mnimo de StopBits se procede con la resincronizacin, en la que el receptor volver a preparar todos los registros y se pondr a la escucha de nuevo por si el emisor le enva otro dato seguidamente. A grandes rasgos, este es el protocolo a seguir. Ms adelante ser analizado con ms detalle y diagramas de flujo pertinentes, cuando ya estemos a la altura de la Implementacin. Pongamos por ejemplo que se desea enviar el Byte = 10011000. La codificacin del mismo en el Emisor sera la siguiente ( sin considerar el bit de paridad, ya que no es el caso base que vamos a tratar):

[Emisor] Codificacin Lgica (unidad bsica es el bit)


1 (msb) 0 0 1 1 0 0
0 (LSB)

Start Bit

StopBit

Vase que todava no hemos definido que tipo de StopBit vamos a usar, de manera que, hasta que lo decidamos, lo mantendremos como indeterminado. Vase que adems, sea como sea el Stop bit, tiene que terminar en una etapa de silencio previo a cualquier transmisin posterior.

[Emisor] Codificacin Fsica (Unidad bsica es la rfaga) En este nivel vamos a traducir los bits a rfagas, tal y como especificamos en el apartado de la definicin del marco de bit, y en el punto [3], que ser la seal que realmente reciba el receptor.
1 (msb) 0 0 1 1 0 0
0 (LSB)

Start Bit

StopBit

Nuevamente no conocemos el StopBit, pero s sabemos que tiene que acabar en alguna rfaga con semiperiodo inactivo o en silencio que ocupe todo el marco de bit.

[Receptor] Decodificacin Fsica El sensor receptor recibe la rfaga de entrada, en funcin de ella, produce salidas continuas (pues para eso se hizo el anlisis pertinente en la seccin del Marco de Bit), bien un escaln, o bien una seal a nivel alto. As, la seal devuelta por el sensor de infrarrojos ante la rfaga anterior sera:

Vemos, no solo la seal devuelta por el sensor de infrarrojos, sino adems, el muestreo que va a hacer el Pic receptor, para poder tomar la informacin necesaria del mensaje. Cada flecha es una muestra. As, comienza con una alta frecuencia de muestreo, mientras la lnea est a nivel alto, pues querr decir que el emisor no desea enviar nada. En el momento que detecte que la lnea est a nivel bajo, significa que el emisor ha mandado un StartBit, por lo que va a comenzar una emisin. Ahora, el Pic tiene que calcular el

tiempo que debe de esperar hasta volver a tomar una muestra. Como vemos, debido a que la seal o es un escaln o un nivel alto, siempre el segundo semiperiodo del marco de bit est a nivel alto. No es ms que redundancia que no nos aporta ninguna informacin. Solo el primer semiperiodo del marco de bit nos proporciona informacin util. Por ello, el tiempo que deber esperar hasta volver a tomar una muestra deber de ser El tiempo del marco de bit ( situarse al comienzo del siguiente marco) ms la mitad del primer semiperiodo del segundo marco de bit ( unos 100/2= 50 pulsos, el tiempo de 50 pulsos de 26 s). El situarnos a la mitad del primer semiperiodo nos permite mayor holgura y flexibilidad, de manera que robustece un poco ms el sistema y no permite que el emisor y receptor se desincronicen fcilmente). A partir de aqu, el periodo de muestreo ser el mismo que la duracin de 1 marco de bit, para situarse siempre a la mitad del primer semiperiodo. Vase que en el periodo de StopBit no se pone a la escucha directamente, sino que un cierto nmero de marcos de bits va a seguir muestreando para comprobar que el StopBit se cumple completamente, y as detectar si hay error de sincronizacin o no. Siempre terminar ponindose a la escucha para el siguiente envo. [Receptor] Decodificacin Lgica Simplemente ser detectar cual es el StartBit, y a partir de el, tomar las siguientes 8 muestras, tomando su complemento a 2 (si esta nivel alto es un cero y si esta a nivel bajo es un 1) y almacenndolas en un registro de desplazamiento, que terminar conteniendo los 8 bits enviados.

El StopBit
La tarea de elegir un StopBit no es una tarea trivial. Tenemos que elegir un StopBit que permita resincronizarse al receptor (el emisor tiene que dar tiempo suficiente al receptor para poder ponerse a la escucha y atenderle) y adems detectar si el dato recibido por el receptor es vlido o fruto de una desincronizacin ( detectar desincronizaciones). El StopBit a utilizar ser: Un primer marco de Bit a 1 en el emisor. Los once marcos de bits siguientes a 0 en el emisor. Por su parte, el receptor deber de comprobar que recibe primero n escaln, y por lo menos 9 marcos de bits siguientes deben de ser a nivel alto. A partir de ese momento, puede ya ponerse a la escucha, pues el emisor y el receptor siguen sincronizados, y el byte que se acaba de recibir por tanto es vlido. El motivo de elegir este StopBits se puede ver con varios ejemplos de sincronizacin y deteccin de los mismos: CASO A) Imaginemos que deseamos mandar el byte 10011001. Imaginemos que el receptor detecta el start bit, el bit ms significativo, el siguiente, y antes de terminar, por ejemplo, cuando se recibi el bit representado en magenta, imaginemos que alguien se mete en medio de la va de comunicacin durante un largo tiempo, de manera que es como si el emisor siguiera enviando todo ceros. El receptor por tanto, interpretara que el byte enviado fue

10011000, que evidentemente es errneo. Si el StopBit fuera simplemente mantener la lnea a nivel alto durante un nmero de marcos de bits ( como si el emisor no mandara ms que ceros) sera imposible detectar que ese dato recibido es fruto de un fallo de sincronizacin. Pues bien, que el primer stopbit sea un 1 ( escaln en el receptor) solventa este problema. Al comprobar el receptor que todos los StopBits son correctos, detectar que , como el primero no es un 1 ( pues al meterse alguien en medio, es como si el emisor no mandara nada, o sea, el sensor devuelve la lnea a nivel alto) hay un fallo de sincronizacin, y por tanto desechar este byte como vlido y har uso de alguno de los sistemas de correccin de errores que describiremos ms tarde. CASO B) Supongamos que se esta enviando un Byte, y , por una desincronizacin, no lo tomas desde el comienzo sino desde la mitad. Por ejemplo:

Start Bit

Primer Stop Bit a 1

Resto StopBits a cero

Imaginemos que, por error de desfase, el receptor toma como StartBit el primer bit del Stop bit a 1 ( en un caso extremo). Si el nmero de StopBits a nivel bajo es pequeo, puede pasar que, cuando el receptor vaya a comprobar el primer StopBit esta a nivel bajo coincida con el Start bit o un bit posterior a este a nivel alto, y por tanto, no pueda detectar jams que el StartBit tomado no era el verdadero. Por ejemplo si el nmero de StopBits a cero despus del primero a 1 son 8 (nmero de bits que forman el mensaje que se desea transmitir) pasara esto:

Stopbits

Start Bit Falso!! En realidad primer bit a 1 del conjunto de StopBits.

Primer StopBit falso!! En realidad StartBit del primer Envio.

Por tanto, si el siguiente envo coincide que son todo ceros, al receptor los comprueba como si fueran los 8 StopBits a nivel bajo que hemos puesto, y es incapaz de ver que en realidad se est desfasando, y que no tom el StartBit correcto. La solucin para esto es tomar un nmero de StopBits a nivel bajo superior al nmero de bits que se transmiten (8bits, 1 byte). Es por ello, que hemos usado 11 StopBits a cero tras el primero como un bit a 1 ( las referencias a bit 1 y bit cero hacen referencia al emisor).

En cambio, el receptor solo tiene que comprobar que hay 9 StopBits correspondientes a un cero emitido ( 9 sigue siendo mayor que 8 bits), tras lo cual se pone a la escucha. Vase que el emisor manda 11 y el receptor solo comprueba 9. Por tanto, tiene 2 StopBits para resincronizarse con el emisor.

Protocolos de sincronizacin
Ya tenemos conceptos suficientes para poder enviar y recibir bytes, la unidad bsica en el nivel bajo que estamos describiendo. Veremos ms adelante diversos protocolos para el manejo de estos Bytes codificados. En estos protocolos de niveles superiores hacen falta herramientas de sincronizacin: son en realidad separadores que permiten distinguir o separar dos entes de la misma naturaleza ( como Bytes codificados de la manera en la que los hemos codificado). Evidentemente, estas herramientas deben de ser diferentes que los entes que se pretenden separar. Como veremos, estos entes que queremos separar entre s no van a ser ms que bytes codificados de la manera que se ha explicado. Por ello, la manera de codificar estas herramientas de sincronizacin entre entes debe ser diferente que la de codificar bytes, pues si no fuese as sera imposible distinguir al separador ( si el separador es lo mismo que se pretende separar, no sirve como separador). Debido a lo explicado, aunque estas herramientas de sincronizacin se van a usar en niveles superiores, conviene implementarlas en el Nivel Bajo, ya que, si no fuese as: O se utiliza para crear estas herramientas elementos del nivel bajo. Pero en este caso, las herramientras del nivel bajo no es mas que emisin de bytes, luego el separador es lo mismo que lo que se pretende separar. No nos sirve. O implementarlas en niveles superiores, pero como el nivel bajo solo exportara herramientas para transmitir bytes, no podran usar ninguno de los recursos usados en el nivel bajo, y tendran que hacer la implementacin completa, incluyendo el sistema de rfagas en el emisor y el de muestreo en el receptor. Esto evidentemente es desperdicio de cdigo. Por estas razones, es en el nivel bajo donde vamos a encasillar estas herramientas de sincronizacin, para aprovechar los recursos de este nivel en la codificacin. Principalmente vamos a necesitar dos herramientas de sincronizacin, cuya utilidad ser explicada ms adelante. Aqu solo vamos a ver como se implementan y por tanto como lograr que el separador sea distinto de lo separado. Es usado en el nivel medio, para la formacin de paquetes. As, bsicamente separa paquetes entre s. 1 paquete se forma por tanto de bytes codificados y de 1 sincronismo que lo encabeza. Evidentemente, la codificacin de este sincronismo debe de ser diferente a la codificacin del Byte, pues si no podra servir para separar grupos de bytes ( paquetes) entre s. Para ello, simplemente se codificar como un StartBit Inicial, 9 bits de datos a 1 desde el punto de vista del emisor (esta es la diferencia que los distinguir de los bytes) y 1 primer StopBit como bit a 1 seguido de 11 StopBits como bits a cero. El que tenga 1 bit ms de datos, hace que se pueda distinguir perfectamente de los Bytes, de manera que si en el lugar que hace falta 1 Sincronismo el receptor se encuentra con 1 byte, le va a faltar un bit a 1 antes de los Stopbits ( se detectar el fallo de sincronizacin), e igualmente, si cuando toca un Byte se recibe un sincronismo, tambin se detectar (sobrar un bit a 1, por tanto, en la revisin de StopBits a cero, la presencia de un 1 har que se detecte el error.

Sincronismo

Ntese que, a pesar del aumento de bits de datos, el nmero de StopBits a cero sigue siendo superior ( 11 ) por tanto sigue sirviendo para detectar errores de desfases entre Emisor y Receptor.

En el nivel ms alto, har falta distinguir entre conjuntos de paquetes. Como un paquete se forma de bytes y 1 Sincronismo, la herramienta para separar conjuntos de paquetes debe de ser diferente a la codificacin del Byte y del Sincronismo. Simtricamente a la solucin anterior, solucionaremos la codificacin de la Trama aadiendo un bit de datos, y por tanto codificando 1 StartBit, 10 bits de datos a 1 ( bits a uno desde el emisor), 1 primer Stopbit con valor de bit a 1, y 11 Stopbits a bit a cero. Vase que el nmero de Stopbits a cero sigue siendo superior que al nmero de bits de datos, por lo que siguen pudindose detectar desfases entre emisor y receptor. -------------------------------------------------------------------------------------------------------------------------------Una importante anotacin hay que hacer respecto al Sincronismo y la Trama: a diferencia de la decodificacin en el receptor, si se detecta algn fallo en la emisin, no se refleja ese fallo en un registro que pueda verse desde niveles superiores. Dado que se trata de herramientas de sincronizacin, si se detecta algn fallo en la decodificacin del Sincronismo y la Trama simplemente se vuelve a la espera del StartBit, y solo se continua y se sale de este bucle cuando emisor y receptor estn sincronizados, es decir, se detecte un Sincronismo o una Trama ( segn el caso) de forma completa y sin errores. Con esto se asegura que cada cierto tiempo (el que tarda el receptor en pedir en el protocolo un Sincronismo o Trama) se resincronicen emisor y receptor. Codificacin de un Byte (10011000) [Emisor] * En la recepcin, la nica diferencia entre Sincronizacin y Trama, y la codificacin de los Bytes, consiste en que, mientras que en los Bytes , los datos se almacenan en un registro de declaje, en la Sincronizacin y Trama se comprueba que cada bit de dato es un bit 1 enviado por el emisor, sin necesidad de almacenarlo.

Trama

StartBit

8 Bits Datos

StopBit a 1

11 StopBits a cero

Codificacin de un Sincronismo [Emisor]

StartBit

9 Bits Datos (Bits a 1)

StopBit a 1

11 StopBits a cero

Codificacin de una Trama [Emisor]

StartBit

9 Bits Datos (Bits a 1)

StopBit a 1

11 StopBits a cero

5.2 Nivel Medio


Este nivel har uso de las herramientas de protocolo desarrolladas en el Nivel Bajo para el envo y recepcin de Bytes, se extraer un nuevo nivel de abstraccin como unidad bsica: El Paquete. Un paquete consistir en un grupo de bytes codificados con informacin. De esta manera, en el envo de un paquete, cmo diferenciar un paquete de otro, si todo lo que se envan son Bytes codificados? Hace falta de un Ente diferente a la codificacin de los Bytes, que sirva como marcador o separador entre paquetes distintos ( grupos de Bytes distintos). Esta herramienta ser el Sincronismo ( ya implementado y descrito en el Nivel Bajo). Para encabezar un paquete usaremos un Sincronismo que bsicamente separar la codificacin del ltimo byte del paquete anterior de la codificacin del primer Byte del paquete actual que queremos enviar. El receptor, al leer un Sincronismo, detectar la intencin del emisor de mandar un paquete y preparar todos sus registros para tal causa. En definitiva, tras descomponer un mensaje en bytes, agrupamos los bytes en grupos o paquetes, que no son ms que slices del mensaje original. Mensaje l a

hola_mundo
m
Nivel Bajo

m
Nivel Medio

Sincronismo

Byte Codificado

Byte Codificado. 8 Bits a cero

Paquete

Este Sincronismo carece de cualquier informacin sobre el paquete, solo sirve como separador e indicador de comienzo de nuevo paquete. La funcin que desempeaba el StartBit en la codificacin a nivel bajo de un Byte, es la misma que la que desempea Sincronismo en este nivel de paquetes. El nmero de bytes que forma cada paquete vamos a ver en la implementacin que puede ser prefijada por el programador del sistema, o se puede elegir por el usuario. Lo que si que no puede pasar es que un mismo mensaje se divida en paquetes de tamao variable: cada mensaje se organiza en paquetes de envo del mismo tamao entre s. El tamao de cada paquete va a influir principalmente en el tiempo de envo del mensaje: si el paquete tiene por ejemplo 1 nico Byte, y el mensaje tiene 10 Bytes, entonces se envan 10 Bytes y 10 Sincronismos !. Si, por el contrario tomamos un paquete de mayor tamao, por ejemplo 5, entonces se haran 2 envos de 5 bytes cada uno ( con 1 Sincronismo cada uno). Es decir 10 Bytes, y solo 2 Sincronismos !. Nos hemos ahorrado el tiempo que tardan en emitirse 8 Sincronismos. Pero esta solucin se contrapone al principio de hacer el mensaje ms turgente: hemos dicho que si se produce un error en el envo de Bytes ( si se da en sincronismo simplemente

hasta que no se sincronice no avanza el receptor) ste se muestra en un registro que puede ser ledo desde niveles superiores. Cuanto menos bytes tenga el paquete hay menos posibilidades de error, y ms posibilidades de detectar donde se produjo el fallo y corregirlo ( por redundancia como veremos). Cuanto ms bytes tenga un paquete es ms propenso a error, y ms propenso a que despus de toda la redundancia con la que enviemos los paquetes ( en el nivel Alto) siga existiendo error. Por tanto, hay que llegar a una solucin de compromiso. En el caso ms bsico hemos considerado un paquete de 3 bytes, pero no va a ser el nico caso que implementemos. Otro requisito bsico es que el receptor tiene que conocer de antemano el tamao del paquete, ya que en caso contrario, Cundo llama a la funcin de recibir Sincronismo? Si no espera un sincronismo , cuando el emisor le mande un sincronismo no va a poder tomarlo, y lo considerar como un error en la emisin, por lo que volver a sincronizarse el receptor (pero una vez que ya pas el sincronismo) y para ello perder ya algn byte (justo el que segua al sincronismo). Esto provocara por ejemplo que el sistema de comunicacin siempre perdiera el primer Byte que se emite. Finalmente, si se observa el diagrama atentamente, se observar que se puede dar el caso de que no hayan suficientes Bytes para formar un ltimo paquete completo. Qu hacer en tal caso? Adems, el receptor no sabe de antemano el tamao del mensaje. Cmo se entera de que el mensaje ha terminado?. Es importante saber que no deseamos un receptor con espera activa, es decir, que se est infinitamente comprobando si le llega algn otro mensaje. Vamos a disear un receptor capaz de detectar el final de un mensaje, y en tal caso, poder pasar el sistema a un modo de bajo consumo (SLEEP del microcontrolador PIC16f84). Por todo esto, vamos a imponer una restriccin a este protocolo: al final del mensaje guardado en memoria debe de almacenarse 1 byte a cero completo, como si tambin se quisiera transmitir. Lo que har el emisor ser leer de memoria y organizar los bytes codificados en paquetes, hasta que llegue a codificar un Byte que sea 0h. En este caso, si el paquete del que forma parte este Byte a 0h no esta completo, completar con ceros. Lo que har el receptor ser ir recibiendo paquetes, hasta que en un paquete se de un 0h (al menos uno). En este caso no esperar por la recepcin de ms paquetes y dormirse el receptor tras tratar el ltimo paquete. Por tanto, es fundamental que, en el mensaje que queramos transmitir, no hayan bytes totalmente a 0h, pues todo byte que venga despus no ser tratado por el receptor y en ese punto se cortar el mensaje de cara al receptor aunque el emisor siga mandando datos. Por tanto, el diagrama antes hecho, no esta completo, y debera de ser:
Nivel Bajo Un cero al final del mensaje en memoria como si fuera parte del mensaje

--

m
Nivel Medio

Rellenar con ceros

5.3 Nivel Alto


En este nivel, el protocolo se basar en usar los paquetes del Nivel Medio para implementar el mtodo de transmisin final. As, vamos a organizar los paquetes en conjuntos Redundantes: cada paquete se va a enviar un determinado nmero de veces, que debe de ser prefijado y el mismo para receptor y emisor. Cada conjunto redundante no es ms que el mismo paquete repetido varias veces. Esto va a conformar el sistema de correccin de errores ( el de deteccin ya lo hemos visto, que son los StopBits), de manera que si el receptor, al recibir un paquete, detecta que en alguno ( 1 cualquiera) de sus Bytes hubo algn error de sincronizacin (leyendo el registro en el que se guardaba si haba habido un error o no, visible desde el nivel ms alto), deshecha lo obtenido, y se pone a la escucha del siguiente envo, que ser el mismo paquete ( otra oportunidad). El nmero de oportunidades es el nmero de veces que se enva un paquete. Si , por el contrario, se recibe un paquete perfectamente, ya no har falta volver a recibirlo, por lo que el receptor ya podr ponerse a la escucha de otro paquete diferente. El problema reside en Cmo detectar si el paquete siguiente es diferente o es el mismo de antes?. Los Sincronismos no poseen informacin acerca de ello, por tanto no puede saberse. La nica manera es la utilizacin las Tramas ( implementadas en el nivel bajo) para separar conjuntos de paquetes . Si se encabeza cada conjunto redundante con una Trama, se puede distinguir cuando se est enviando el mismo paquete o es otro diferente. As, si el receptor recibe bien el paquete, se pone a la escucha no del siguiente paquete, sino de la siguiente Trama ( o sea del siguiente conjunto redundante o paquete diferente).
hol a m a m

hol

hol

a m

und

und

und

o**

o**

o** Trama

El nmero de Tramas es el mismo que el nmero de paquetes distintos a emitir. Nuevamente, la Trama carece de cualquier informacin til para el sistema de comunicacin, por tanto, cuanto menos sean, ms rpido ser el sistema ( menos redundante). Por ello conviene tener el menor nmero posible de Paquetes, y por ello, ante un mismo mensaje, que el tamao del paquete sea grande para que se divida menos el mensaje. Sin embargo, con paquetes demasiado grandes se corre el riesgo de mayor nmero de errores. Al tener ms bits, ms posibilidades de errores, y esto hace que quizs el nmero de oportunidades ( o redundancia) que brinda el sistema no sea suficiente para completar un envo de un paquete limpio y carente de errores. Como nuestro principal objetivo es la robustez, llegaremos a una solucin de compromiso pero tendiendo a paquetes no muy grandes para que sean ms robustos. La eleccin del nmero de veces que se enva un paquete ( la redundancia) implica que, si se elige un nmero bajo, las oportunidades de corregir un error sern menores por lo que ser menos robusto, sin embargo ser mas rpido. En cambio, si se selecciona un algo nmero de veces que se enva un paquete, el sistema ser ms robusto, pero ms lento. El consenso al que vamos a llegar es que la redundancia o el nmero de veces que se repite el envo de un paquete sea 3 veces. Por tanto, cada Conjunto Redundante posee 3 veces el mismo paquete, tal como muestra la figura que representa la emisin del emisor.

6 Implementacin
En este apartado vamos a proceder con la programacin de los PICs implicados (1 PIC que controle al emisor y otro al receptor) en el sistema de comunicacin, para que se respeten todas las premisas descritas en el apartado de protocolo. Primeramente, y para organizar esta tarea de implementacin del control del emisor de infrarrojos y el receptor, o la parte Software, vamos a adoptar una filosofa de trabajo. Ya que el protocolo ha sido descrito de un modo modular, parece evidente que la implementacin de ambos sistemas de control ( para emisor y receptor) vaya a ser modular, a travs de Libreras. Es decir, vamos a dividir el sistema de control de cada parte de la comunicacin en 3 niveles, que se correspondern con los 3 niveles de protocolo ya descritos. El nivel ms inferior ser una librera que exportar funciones relativas a la emisin y recepcin de datos, tramas y sincronismos. Existir otra librera que represente al nivel medio, y que, usando la librera bsica antes descrita, se encargue de organizar la informacin en paquetes. Finalmente, habr un programa principal que, usando ambas libreras, organice la informacin en Conjuntos redundantes, y en el receptor, lleven a cabo la deteccin y correccin de errores ( por redundancia), adems de mostrar los datos al usuario para que pueda observar la bondad de los resultados obtenidos. Este programa principal representa al protocolo de nivel ms alto. ste ltimo nivel no se ha implementado como una librera ( aunque tambin se pudiera) ya que, en tal caso, lo nico que tendra que hacer el programa principal sera tratamiento de ristras: llamar a una funcin de esta supuesta librera, y previamente, el emisor tendra que cargar o tomar la frase para cargarla en memoria y pasrsela a esta librera de nivel Alto, y el receptor tratar la ristra que el mismo almacena en memoria durante la emisin. Hemos preferido interpretar este nivel Alto directamente como el programa principal, e incluir en este el tratamiento de la ristra que conforma el mensaje. Por tanto, este programa tiene tres estratos: los dos ms bajos en forma de libreras y el ms alto en forma de programa principal. Adems, vase que cada estrato esta bifurcado en dos partes simtricas entre s: el control del led emisor y el del sensor de infrarrojos receptor ante lo mandado por el led emisor. Por tanto, a la hora de explicar la implementacin hecha, seguiremos una induccin, comenzando por el nivel ms bajo, y siempre interrelacionando en cada mdulo las acciones del emisor frente a las que desempea el receptor para recibir el mensaje. Librera nivel_bajo.lib Emisor Receptor

Librera nivel_paquetes.lib Emisor Receptor

Main

Emisor (Ristra + NivelAlto)

Main

Receptor (Ristra + NivelAlto)

6.1 Creacin de Libreras


Antes de comenzar a describir la implementacin, hay que hacer hincapi en la tcnica usada para implementar las libreras. Podramos tomar un nico fichero ASM que tuviera todas las funciones suministradas al emisor y las suministradas al receptor. As, al compilar crearamos un nico fichero de tipo objeto, y una librera basada en ese fichero de tipo Objeto. Sin embargo, esta implementacin tan trivial de las libreras tiene un problema bsico: si el emisor hace un acceso de alguna de las funciones de la librera, se carga en memoria, no solo las funciones pertinentes a la emisin, si no tambin las referentes a la recepcin. Por ejemplo, se podra estar reservando espacio en la memoria de datos para registros que en realidad nunca se van a usar por que solo son usados por el receptor. Esto nos sugiere otro modo de implementar cada librera: las funciones de emisor y receptor separadas en dos ficheros ASM separados, de manera, que al compilarlos cada uno individualmente, se cree un fichero objeto para cara uno, y con dos ficheros objeto, crear la librera. La diferencia ahora es que, cuando el emisor acceda a alguna funcin propia suya, acceder solo a un fichero objeto dentro de la librera, por lo que no se cargar en memoria todos los registros y funciones del otro objeto. Se que, con una misma librera, mantengamos independientes las funciones y registros del emisor y receptor. En el diseo de los programas se ha tenido en cuenta que el emisor no haga referencia a ninguna de las funciones o registros exportados por el receptor, y viceversa en el caso del receptor.

6.2

nivel_bajo.lib

En esta librera se van a implementar, tanto para el emisor, como para el receptor, herramientas para codificar y decodificar bytes, tramas y sincronismos. Esta librera poseer dos objetos provenientes de dos ficheros *.asm diferentes: Emisor_nivel_bajo.asm: posee todas las funciones de nivel bajo necesarias controlar la emisin del Led de infrarrojos, y en ltima instancia, estas funciones sern las que tengan un contacto directo con el control de este actuador led a travs de los pines del puerto B del PIC. Bsicamente va a exportar 3 funciones: EnviarByte: codifica el byte a transmitir, y lo traduce de un lenguaje lgico (bits) a un lenguaje fsico( traduccin en rfagas). Esta traduccin a lenguaje fsico ser la que se usar como salida y actuar directamente sobre el Led. EnviarSincronismo: codifica el sincronismo descrito en el protocolo, lo traduce a lenguaje fsico (rfagas) y lo transmite al Led. Emitir_Trama: idnticamente, codifica la trama, la traduce a rfagas y la transmite al Led. Receptor_nivel_bajo.asm: en este fichero se encuentran todas las funciones referentes al control y muestreo del sensor de infrarrojos, funciones que tiene por tanto un contacto no transitivo y directo con la salida del sensor a travs del puerto A del PIC. Bsicamente exportar 3 funciones y un registro:

RecibirByte: Se encarga de recibir el byte codificado, decodificarlo y guardarlo en un registro de declaje. Si se produce algn error, lo indicar en el registro Fallo. RecibirSincronismo: Se encarga de comprobar que la seal de sincronismo llega correcta. Mientras no llegue completa y sin errores el receptor no saldr de esta funcin. Recibir_Trama: idnticamente, no deja avanzar al receptor hasta que se reciba la trama de forma completa y sin errores. Fallo: es un registro que exporta, y donde se refleja si ha habido algn error en el ltimo byte recibido o no. Sirve para que niveles superiores, en funcin de este registro, acepten el byte recibido o lo rechacen.

Pasemos pues a una descripcin exhaustiva de cada funcin exportada en cada submdulo de la librera.

6.2.1 Emisor_Nivel_Bajo.asm
En primer lugar, vamos a ver una serie de funciones internas ( no exportadas y por tanto no visibles exteriormente) destinadas a la traduccin de los bits en nivel lgico a rfagas. Estas funciones son Pulso1 ( para traducir un bit a 1 a rfagas, segn protocolo visto) y Pulso0. Se dan dos registros claves en ambas funciones: CONTAct: guarda el nmero de pulsos activos ( pulsos peridicos) que debe de tener el marco de bit correspondiente a la rfaga a enviar. De acuerdo con esto, si se desea mandar un cero, no se debe mandar ningn pulso ( registro a cero), y si se desea mandar un uno, entonces hay que mandar 50% pulso activo y 50% silencio en la rfaga del marco de bit. Por tanto cargaremos un 100 ( en decimal) en el registro para que justo la mitad del marco de bit (duracin equivalente a 200 pulsos activos) sea de rfaga activa. CONTInact: similar al anterior, guarda el nmero de pulsos equivalentes al tiempo dentro del marco de bit que debe estar en silencio o no mandar anda el emisor. (sabiendo que cada pulso son 26s) . Si se desea mandar un cero, todo el marco de bit debe de estar en silencio el emisor ( por tanto se inicializa el registro a 200, que son pulsos totales que pueden haber en un marco de bit), y si se desea enviar un 1, cargaremos un 100 correspondiente al 50% del marco de bit, para formar un 50% de pulso peridico y 50% de silencio dentro del marco de bit. Una vez que cada funcin inicializa ambos registros convenientemente segn lo explicado, invocan a una funcin que traduce el contenido de ambos registros a pulsos emitidos a travs del bit 0 del puerto B hacia el emisor. Esta es la funcin Pulso. La funcin Pulso se desdobla en dos partes o secciones:

Per_a_tren: emite tantos pulsos peridicos de periodo 26 s como indica el registro CONTAct. Por tanto, si la rfaga a emitir posee un tren de pulsos peridico ( o periodo activo) ste se emitir antes que el inactivo, debido a la ordenacin secuencial de la funcin Pulso. Para crear ese pulso, pone el bit 0 del puerto B a 1 y llama a la funcin NOPS, que lo nico que hace es un retardo de 13 s en total, contando el nmero de nops y ciclos de instrucciones de call y return. Acto seguido, pone el bit 0 del puerto B a 0 y llama de nuevo a la funcin NOPS, que vuelve a hacer un retardo de 13 s. En definitiva, se desarrolla un pulso de 26 s, con mitad a nivel alto y mitad a nivel bajo. Pues bien, esta operacin se repite tantas veces como indica el registro antes mencionado. Per_inact: similar al anterior, ahora hace la traduccin del registro CONTInact, con la salvedad de que no genera un pulso, sino que solo genera el espaciamiento temporal equivalente a tal pulso. Se consigue poniendo el bit 0 del puerto B a cero y llamar a NOPS dos veces, con lo que se completa el retardo de 26 s en simple silencio ( ya que las dos veces el bit 0 del puerto B se mantiene a cero). Per_a_tren
x CONTAct veces. bcf CALL BCF CALL PORTB,0 NOPS PORTB,0 NOPS x CONTIact veces.

Per_a_tren
bsf CALL BCF CALL PORTB,0 NOPS PORTB,0 NOPS

Ntese que, en el caso de que el Pulso1 ea invocado, como interesa hacer un semiperiodo con tren de pulsos y otro sin tren de pulsos, se llama a la funcin Pulso tal cual, que har secuencialmente el tren de pulsos y despus el silencio. Sin embargo, en el caso de Pulso0, no interesa comenzar por Pulso, ya que pasara primero por Per_a_tren, que sirve para enviar tren de pulsos que en realidad no necesita. Por tanto, emplea un atajo, y en vez de llamar a Pulso, llama a Per_Inac directamente, como si fuera otra funcin, que solo se centrar en un marco de bit completo de silencio y por tanto sin emisin de ningn tren de pulsos. Pulso Pulso1
Tanto Tren de Pulsos como Silencio Directamente Silencio

Per_a_tren Per_inact

Pulso0

Por tanto, las funciones internas Pulso1 y Pulso0 permiten que, en las funciones exportadas, se pueda trabajar a nivel lgico ( con bits a 1 y a cero, tal como se definieron en los protocolos) y con simplemente llamar a estas dos funciones descritas, se traducen automticamente a lenguaje fsico o de rfagas.

>>EnviarByte Esta funcin se encarga de enviar un Byte, que deberemos de pasarle en el acumulador w del PIC. Para enviarlo, lo codifica en funcin del protocolo a nivel bajo descrito. Ya que es un protocolo de emisin serie de datos, esta funcin presenta un aspecto secuencial. Adems trabaja a nivel lgico ( enviando bits a 1 o a cero), de manera que al invocar a Pulso1 o Pulso0 segn el caso se hace la conversin automtica de estos bits a 1 o cero a rfagas o seales que controlan al Led emisor de infrarrojos. Para describir la implementacin, haremos una traza por sus distintos hitos de ejecucin: 1) Etapa de configuracin: guarda el dato a enviar en el registro Dato, configura el bit 0 del puerto B como salida, ), pues ser la lnea a travs de la cual mandar la seal al led infrarrojo, (vase que al invocar a Mod_TrisB, usa la constante SAL que sirve para configurar el bit 0 del puerto B como salida. Esta constante est definida en el fichero de Constantes.inc, y finalmente desactiva el Pull Up. Esto es necesario, por que, como veremos en niveles superiores, se usan las libreras del teclado y del LCD, que activan el Pull Up y no lo desactivan. Al activarse el Pull Up del puerto B puede afectar a la correcta transmisin de la seal desde el Pic hasta el led infrarrojo. 2) StartBit: enva el Startbit ( un bit a 1, invocando a Pulso1 para traducir el bit a rfagas), almacena en INC el nmero de bits de datos que se van a enviar, que sern siempre 8 ( en caso de ser 9 o 10 como en Sincronismo o Trama, ya veremos que solucin se adopta para enviar el bit de ms). 3) LeerByte: Se trata de un bucle, de manera que en cada iteracin (en total 8 iteraciones, 1 por cada bit de datos, ya que el bucle se basa en el decremento de INC) desplaza el registro que contiene el dato (Dato) a la izquierda, de manera que el acarreo ( que ser el bit ms significativo) nos indica, si es un 1 que se debe mandar un Pulso1 pues ese bit ms significativo era un 1, o Pulso0 en caso contrario. Vase que el resultado del desplazamiento se guarda en el propio registro Dato. Por tanto en la siguiente iteracin, el bit ms significativo ser el que antes era anterior al ms significativo. Con esto se consigue, tras 8 iteraciones, leer los 8 bits y traducirlos a rfagas con Pulso1 y Pulso0. 4) Ampliacin de Datos: esta seccin no tiene etiquete en s, pero se sita justo a la salida del mismo bucle, y, en funcin del registro Banderilla, permite ampliar el nmero de bits de datos a 9 o 10. El modo de funcionamiento es el siguietne: BTFSc call btfsc call Banderilla,0 Pulso1 Banderilla,1 Pulso1

Si se invoca a EnviarByte, Banderilla se encuentra a cero en su bit menos significativo (LSB) y el contiguo a el, por tanto no se emite ningn Pulso1 de ms. Esto quiere decir que el nmero de bits de datos no se ampla, y se queda en 8. Si se invoca a EnviarSincronismo, se llama transitivamente a EnviarByte pero con el LSB de Banderilla a 1, por lo que emitir el primer Pulso1, no emitiendo el segundo (ya que solo el bit menos significativo se encuentra a 1, no el siguiente menos significativo, segn la lgica implementada). Esto quiere decir que se ha ampliado el nmero de bits de Datos a 9. La razn de enviar un 1 y no un 0, es que, como vimos en el protocolo de nivel bajo, el Sincronismo consisten en 9 bytes de Datos, todos siento bits a 1. Se supone que los 8 primero ya se han enviado (y estaban a 1, se conseguir como veremos ms adelante), y ahora simplemente enva el noveno. Si se invoca a EnviarTrama, de idntica manera , se llama transitivamente a EnviarByte pero con Banderilla con sus dos bits menos significativos a 1, por tanto, emitir los dos Pulso1s segn la lgica implementada (al testear que el bit menos significativo esta a 1, emite un Pulso1, y al testear que el siguiente bit menos significativo tambin esta a 1, emite otro Pulso1). El nmero de bits de datos sern entonces 10: 8 primeros en LeeByte, y los dos ltimos en esta lgica. Vase que la Trama necesita 10 bits de datos todos a 1, por esto es por lo que se aaden dos Pulso1 a los 8 bits ya empleados, y no Pulso0. Esta estructura optimiza el cdigo, ya que tanto para enviar un byte, como una trama y un sincronismo se emplea exactamente el mismo cdigo, pero con el registro Banderilla con valor diferente para aadir o decrementar el nmero de bits de datos.

5) StopBit: simplemente se lanza el Stopbit ya descrito en el protocolo: un primer bit a 1 ( llamada a Pulso1) y, tras ello, se incrementa el registro INC a 11, para entrar en el bucle Etiqueta, que se encargar de enviar Pulso0 tantas veces como decrementos de INC hasta llegar a cero (es decir, 11 bits a 0).

Podra hacerse ya un breve resumen de la utilidad de los registro declarados en este nivel bajo: Registro Descripcin CONTAct Indica el nmero de pulsos que deben de generarse en el Marco de bit a convertir a rfaga. CONTInac Indica el nmero de pulsos que es equivalente al tiempo que tiene que permanecer el emisor recibiendo una seal a nivel bajo del puerto B del PIC. INC Su valor indica el nmero de iteraciones totales de los distintos bucles usados en la funcin EnviaByte. Dato Almacena el Dato a enviar. De su declaje irn extrayndose los bits a enviar por el puerto serie. Banderilla Si esta a cero, el nmero de bits de datos a enviar es 8 (envo de un Byte), si es 1, el nmero de bits de datos es 9 (envo de Sincronismo) y si es 3, el nmero de bits de datos es 10 (envo de Trama).

>>EnviarSincronismo Pone a 1 el valor menos significativo de Banderilla, carga en w el valor ffh, y llama a EnviarByte. Con esto consigue enviar un Sincronismo, con 9 bits de datos a 1 ( 8 de los 8 bits a 1 del registro w, ms el que se aadir por el valor del bit menos significativo de Banderilla). Esta manera de implementarlo disminuye el nmero de lneas de cdigo considerablemente. Es importante hacer notar que, tras el envo del sincronismo, se devuelve Banderilla a su estado original, antes de modificar el bit menos significativo a 1. Esto permite que si, por ejemplo, tras un sincronismo se llame a un EnviarByte, la Banderilla no contine a 1, y por tanto no se vuelva a mandar un bit de datos de ms. >>EnviarTrama Similar al anterior, pero en este caso, no solo se inicializa w a ffh y se inicializa el bit menos significativo de Banderilla a 1, sino que tambin se inicializa el bit contiguo al menos significativo a 1 tambin, por lo que no solo se enviarn los 8 bits a 1 correspondientes a w, sino tambin 1 pulsos a 1 adicionales, siendo en total 10 pulsos a 1, como se describi en el protocolo. De la misma manera, tras el envo, se deja lso dos bits de Banderilla a cero, para evitar que al enviar un Byte contiguo al envo de una Trama se le asignen 10 bits de datos debido al valor de Banderilla. Los siguientes diagramas de flujo se corresponden con el algoritmo visto:
* WDato * Configuracin de bit0 del PuertoB como Salida (Mod_TrisB SAL) * Desactivacin del Pull Up StartBit: Pulso1 8 INC

No

<<Dato

INC = 0 ? Si
Banderilla(LSB) = 1?

Si Pulso1

No Pulso0

Si Pulso1

No

INC 1 INC

Banderilla(LSB+1) = 1?

Pulso1

No Si

StopBit * Pulso1 * 11 INC

INC = 0 ? Si LEYENDA: RETURN

No

Pulso0

INC-1 INC

Bucle Recorrido secuencial. << Desplazamiento a la Izquierda = comparacin de igualdad. asignacin. Reg(LSB) bit menos significativo Reg(LSB+1) bit contiguo al LSB.

6.2.2 Receptor_Nivel_Bajo.asm
En este fichero, que contiene las funciones que se complementan con las ya explicadas (de cara a la recepcin de las mismas) posee una funcin interna no visible desde el exterior, que sirve para el muestreo. Como se explic en el protocolo, el muestreo no es continuo: una vez que recibe el primer StartBit, deja de muestrear continuamente, para muestrear: Justo tras el StartBit, deja de muestrear el tiempo suficiente para saltarse el marco de bit correspondiente al StartBit (como al detectar el Startbit se le detecta casi desde su comienzo, este salto es de un marco de bit completo, o sea, el tiempo equivalente a 200 pulsos) y situarse a la mitad del primer semiperiodo del siguiente, ya que es el primer semiperiodo el nico que le permite distinguir entre si lo que se manda es un cero o un 1 (la mitad de un semiperiodo es el tiempo equivalente a 50 pulsos). Por tanto, tras recibir el primer StartBit, el Pic debe de esperar el tiempo equivalente a 250 pulsos para volver a hacer la siguiente muestra. A partir de aqu, para muestrear justo en la mitad del siguiente semiperiodo, debe esperar para muestrear un tiempo equivalente a 200 pulsos ( 1 marco de bit completo). 1 vez acabado el StopBit, debe volver a muestrear sin tiempo de espera, continuamente.
250 pulsos 200 pulsos 200 pulsos 200 pulsos 200 pulsos ................

Muestreo Continuo

Pues bien, esa funcin interna a la que hacamos referencia era ESPERA, que se encarga de, dado un nmero de pulsos en el registro NPulsos, detener al receptor durante un tiempo equivalente al nmero de pulsos que posee el registro NPulsos. La manera de calcular el tiempo que equivale a ese nmero de pulsos es analizar el algoritmo que genera pulsos en el Emisor.

Emisor
Per_a_tren bsf CALL BCF CALL PORTB,0 [*] NOPS PORTB,0 [*] NOPS ESPERA

Receptor
CALL CALL Nop Nop DECFSZ NPulsos GOTO ESPERA return NOPS NOPS

DECFSZ CONTAct,1 GOTO Per_a_tren return

En primer lugar, observamos que del emisor solo hemos tomado Per_a_tren. En realidad tanto Per_a_tren como Per_inac son similares y secuenciales, por tanto podemos coger para el anlisis solo 1 de los dos ( a lo sumo, sern mitad y mitad del marco de bit, si suponemos que NPulsos es 100, y CONTAct esta a 100 tambin, ambos deberan de tardar el mismo tiempo en ejecutarse. La funcin NOPS es la misma en los dos, por tanto dura lo mismo. Sin embargo, si contamos el tiempo que tarda 1 y otro, vemos que, en el caso del Emisor se dan siempre dos instrucciones ms que en el Receptor, debido a la puesta del puerto B a 1 o 0 marcados en [*] . Este error de dos ciclos, se multiplica por el nmero de bucles, que es 100. Por tanto, se dara un desfase de 200 s, entre el emisor y el receptor. Por este motivo hay que aadir dos NOP en cada iteracin de ESPERA, para evitar este desfase entre el emisor y el receptor, que se ira retrasndo cada vez ms hasta salirse del marco de bit y desincronizarse con respecto al Emisor. De hecho, en la prctica no nos dimos de aadir estos dos NOPS, y comprobamos empricamente que se desfasaban ambos dispositivos. El Emisor y Receptor. Ahora s, la funcin ESPERA nos permitir retrasar el muestreo el tiempo equivalente del nmero de pulsos que est almacenado en NPulsos. A continuacin vamos a analizar las funciones que exporta este fichero.

>>RecibirByte Se encarga de muestrear el sensor de infrarrojos, y analizar la informacin que este le devuelve, para decodificar todo byte enviado ( de forma codificada) por el emisor) y guardar este dato en el registro acumulador del PIC, el registro w. Por tanto, al recibir un Byte, y decodificarlo, el byte sin codificar lo guarda en el registro w. Vase que al ser un registro de propsito especfico del microcontrolador, no hace falta declararlo como externo o global para que pueda ser visto desde niveles superiores su valor.

La implementacin puede explicarse describiendo secuencialmente (al ser una recepcin de tipo secuencial de la informacin) cada hito que presenta el algoritmo, tal y como se hizo en EnviarByte, de la manera: 1) Configuracin: en esta fase se invoca a Mod_TrisA ENT, para configurar el bit 4 del puerto A como entrada que es a travs de la cual el PIC recibir la seal del circuido del sensor de infrarrojos. Tambin se desactiva el Pull UP, ya que en niveles superiores puede ser activado, sobre todo al invocar a la librera del teclado y la LCD. El que est activado podra afectar la entrada a travs del bit 4 del puerto A. 2) HearFast: es el modo de muestreo rpido. En este caso se encuentra constantemente testeando la salida del sensor, hasta que est a nivel bajo (sea un cero lo que devuelve en el bit 4 del puerto A). En tal caso se ha recibido un StartBit, es decir, el emisor tiene intenciones de enviar un bit. Sale de este bucle de muestreo rpido y va a StartBit, donde invocar a ESPERA para situarsea la mitad del primer semiperiodo del marco de bit siguiente. Vase, que se carga en NPulsos el valor SalgoMayor, que si analizamos en el fichero cabecera Constantes.inc, veremos que es un valor de 250 pulsos, tal como antes indicamos. 3) Bits: Ya situados en la mitad del primer semiperiodo del siguiente marco de bit, se inicializa el registro INC a 8 ( pues 8 sern los bits que se enven por parte del emisor), y borra el registro de Declaje, que ser usado para ir guardando y desplaznado los bits que se van recibiendo. De esta manera, comienza un bucle (LeeBit), donde se lee la seal que hay en la lnea, y si es un cero el bit 4 del puerto A es que se ha enviado un 1 en el emisor, por lo que se acarrea un 1 en el Registro Declaje y se desplaza a la izquierda), en cambio si es un 1 el bit 4 del puerto A es que se ha enviado un 0 el emisor, por lo que se acarrea un 0 en Declaje. Tras esto, se llama a ESPERA con un nmero de pulsos igual a SaltoNormal ( que se correspondern con 200 pulsos para situarse en la mitad del primer semiperiodo del siguiente marco de bit). Con esto, queda listo para muestrear el siguiente bit. Este proceso se repetir 8 veces en funcin de INC. 4) Stopbittb: una vez ya completados los 8 bits, se comprueba que se recibe el Stopbit completo y sin errores. Primeramente se comprueba que el primer StopBit es un 1 lgico enviado por el emisor ( en el receptor, que el bit 4 del puerto A est a nivel bajo, es decir a cero). Si as es, se hace un retardo de SaltoNormal pulsos para situarse en la mitad del primer semiperiodo del siguiente marco de bit ( para leer el siguiente). Pero si no es as, significa que hay un error de desincronizacin de errores. Al detectarse el error, se va a CONTROL_ERROR, que simplemente pone el primer bit (menos significativo) del registro Fallo a 1, y va a GuardarMostrar. Que guarda el contenido de Declaje en w ( el dato recibido lo guarda en W, que ser rechazado en niveles superiores debido a que hay un fallo) y retornar. A partir de este punto, se inicializa INC a valor 9, y comienza un bucle, donde se comprueba si el bit 4 del puerto A esta a 1

(emisor ha mandado un cero). Si es as, espera los 200 microsegundos , decrementa INC y vuelve a buclear. Si todos los marcos de bit, los 9, son bit ceros mandados por el emisor ( es decir, siempre que se muestrea cada 200 microsegundos la lnea del bit 4 del puesto A esta a 1) terminar en GuardarfMostrar (lo que significar que el byte recibido es bueno) para guardar ese byte recibido en W y poder devolverlo al proceso que invoc esta funcin y retornar. Pero si en alguna de las comprobaciones el bit 4 el puerto A esta a cero ( el emisor envi un 1) hay uin fallo de sincronizacin, por lo que se va a CONTROL_ERROR tal como antes. Es importante ver que, en caso de Error, simplemente se avisa en el registro Fallo, en su bit menos significativo. Como este registro es global, va a poder ser revisado por un nivel superior y comprobar, antes de tratar el Byte devuelto en w, si es correcto o no. El siguiente diagrama de flujo explica este algoritmo:
* Configuracin de bit4 del PuertoA como Entrada (Mod_TrisA ENT) * Desactivacin del Pull Up

StartBit

No ? No
<< Declaje

PortA (4) = 0

Si Si
1Declaje (0) PortA (4) =0?

No

INC 1 INC
INC = 0

ESPERA(200)

Si StopBits
PORTA (4) = 0

No

CONTROL ERRORES 1 Fallo (0 )

GuardarMostrar DeclajeW RETURN

Si
ESPERA(200) 9 INC

No No ?

Si

INC 1 INC ESPERA(200)

INC = 0

PORTA (4) = 1

Si

>> RecibirSincronismo Si bien, podramos haber optado, como en el emisor, por usar el mismo cdigo, no lo hemos hecho, ya que, ahora el objetivo no es almacenar en un registro un dato, sino ms bien comprobar que el dato que se manda son bits a 1 enviados por el emisor. Ya que son dos filosofas completamente diferentes hemos optado por no emborronar el cdigo original del RecibirByte con subterfugios para amalgamarlo con el RecibirSincronismo, sino considerarlos dos cdigos deparados. An as, ambos cdigos se parecen mucho, por lo que no vamos a volver a explicarlo. Solo vamos a explicar los puntos en los que difiere el RecibirSincronismo con respecto al algoritmo del RecibirByte. Ahora el registro Declaje no tiene sentido usarlo como declaje propiamente dicho, pues no necesitamos almacenar los bits que llegan, solo comprobarlos. Por tanto lo vamos a usar tal y como usbamos Banderilla en el Emisor, de manera que si el registro Declaje tiene el bit menos significativo a 0, significa que nos encontramos ante un Sincronismo y por tanto el nmero de bits de datos tras el StartBit que se espera recibir son 9. Si por el contrario, este bit menos significativo de Declaje est a 1, significa que un EnviarTrama fue el que invoc al EnviarSincronismo, por lo tanto, no se esperan recibir 9 bits a 1 (desde el emisor) de datos como en el caso anterior, sino 10 bits. Decidido ya si se esperan 9 bis a 1 desde el emisor (LSB de Declaje a 0) o 10 ( lo contrario), se entra en un bucle donde, a diferencia del EnviarByte, no se guardan, solo se comprueban que son bits a 1 desde el emisor (bit 4 de PORTA a cero en receptor). Si as es, se hace un ESPERA y se vuelve a comprobar el siguiente. Si no se cumple hay un Error. Pasado esto se comprueban los StopBits. Pero tanto en la comprobacin de los StopBits como en la de que los bis de datos, todos se correspondan con bits a 1 emitidos por el emisor, si hay algn error no se indica en ningn registro, sino que se vuelve a la etiqueta HearFast2, es decir, el receptor se vuelve a poner a la escucha. De esta manera, hasta que no se sincronice ( respecto a Sincronizacin o trama) con el emisor de forma completa, no saldr de esta funcin el receptor.

>> RecibirTrama Similar al EmitirTrama, carga en el bit menos significativo del registro Declaje un 1 para indicar que se espera una trama, y acto seguido invoca a RecibirSincronismo. Cuando se vuelva desde la funcin RecibirSincronismo querr decir que emisor y receptor estarn sincronizados. Se pone el registro de Declaje de nuevo su bit menos significativo a cero, para evitar problemas en llamadas futuras a funciones que usen el Declaje. A continuacin se muestra un diagrama de flujo correspondiente al RecibirSincronismo:

* Configuracin de bit4 del PuertoA como Entrada (Mod_TrisA ENT) * Desactivacin del Pull Up

StartBit

No ?

No

PortA (4) = 0

Si
PortA (4) =0?

ESPERA(250)

Si INC 1 INC ESPERA(200)

Declaje (0) = 0

Si
9INC

No
10INC

INC = 0

No

Si StopBits No
PORTA (4) = 0

RETURN

Si
ESPERA(200) 9 INC

No No ?

Si

INC 1 INC ESPERA(200)

INC = 0

PORTA (4) = 1

Si

Finalmente, vamos a hacer una descripcin de los registro usados y su funcionalidad en el receptor a nivel bajo: Registro Fallo Descripcin Registro global, que ( en este nivel) si posee el bit menos significativo indica que en la ltima recepcin hubo un error de sincronizacin, y si esta a cero que fue una recepcin sin incidentes. El bit contiguo al menos significativo ser usado en niveles superiores para detectar si el byte recibido fue un 00h ( si esta activado) o no, por tanto, si se ha llegado al fin del mensaje o no. Indica el nmero de pulsos, cuyo tiempo equivalente ( aproximadamente ) es Npulsos * 26s, que ser el tiempo que la funcin ESPERA permanecer inactiva haciendo tiempo hasta que llegue el momento del siguiente muestreo. Es una espera activa. Su valor indica el nmero de iteraciones totales de los distintos bucles usados en la funcin RecibirByte y RecibirSincronismo En RecibirByte almacena los bits recibidos por el sensor de infrarrojos y traducidos a nivel lgico. Su contenido final es el dato enviado por el emisor, pero decodificado. En RecibirSincronismo, simplemente indica con su bit menos significativo si se tien que recibir un Sincronismo ( bit a 0) o una Trama (bit a 1).

NPulsos

INC Declaje

6.3 nivel_paquetes.lib
En esta librera se dan todas las funciones propias del Nivel Medio descrito en la seccin de protocolo, para el envo y recepcin de Paquetes. El rasgo fundamental que lo diferenciar del resto de libreras de paquetes desarrolladas, es que el tamao de los paquetes es fijo, y viene definido por NBytes_Paquete, que se encuentra en el fichero cabecera Constantes.inc. En principio su valor es 3, por tanto, con esta librera vamos a establecer un protocolo de paquetes donde el tamao de los mismos sea de 3 bytes. Nuevamente, nos encontramos con que esta librera de forma de los objetos compilados y construidos de dos objetos provinientes de dos ficheros *.asm diferentes: uno para el Emisor y otro para el Receptor: Emisor_Paquete.asm: Posee funciones para ensamblar los paquetes a partir de las funciones de nivel bajo de emisin ya descritas, de manera que permite que los niveles superiores puedan usar como unidad bsica de divisin del mensaje el paquete ( codificar el mensaje a travs de paquetes). Las funciones y registros que exporta son: Emitir_Paquete: Dado un puntero a una posicin de memoria donde se encuentra el mensaje, toma los 3 bytes que existan en memoria a partir de esa posicin y los enva anteponindole un envo de sincronizacin, por tanto, esta funcin toma 3 bytes y hace y enva con ellos un paquete.

Retarda_Paqjuete: simple funcin que simplemente hace un bucle para provocar una espera activa en el programa que lo invoca. Servir para espaciar la emisin de los paquetes en el nivel Alto que usa como unidad de transmisin el paquete y as evitar desfases con el receptor. FalloE: Registro que se exporta para indicar al programa que invoco un EmitePaquete si el paquete que se envi era el ltimo del mensaje ( pues contiene un cero) o no.

Receptor_Paquete.asm: Contiene todas aquellas funciones referentes a la recepcin de paquetes, de manera que organiza las seales que le llegan del sensor en Paquetes, reconstruyendo pues los paquetes que le son enviados. Por tanto, dota al nivel alto de una herramienta para recibir unidades bsicas no tan diminutas como Bytes, sino unidades bsicas mayores ( ms informacin). Este fichero exporta: RecibirPaquete: permite a los niveles que la invocan esperar no bytes sino conjuntos de bytes, ya que construye paquetes a travs de funciones y unidades bsicas proporcionadas en el nivel bajo. As, los bytes que le llegan los almacena en la posicin de memoria a la que seala el registro FSR. Por tanto, el que invoca esta funcin debe de pasar en FSR la direccin de memoria donde se desea que se almacenen los 3 bytes a recibir.

6.3.1 Emisor_Paquete.asm
En s, este fichero no posee ms que las funciones que exporta: >> retarda_paquete Al hacer un recuento de las instrucciones que se dan ya en el programa principal de nivel alto, y compararlas con las del receptor a nivel alto, encontramos un cierto desfase, ya que el receptor posea ms instrucciones que el emisor entre el envo de cada paquete, por tanto cada vez se iba retrasando ms y ms hasta que terminaba por desincronizarse. Pero el problema del conteo de instrucciones no es fcil cuando nos encontramos en un nivel alto, ya que hay muchas funciones que forman parte de otras libreras. Por ello, ante la imposibilidad de realizar una cuenta totalmente exacta, si optamos por una solucin lgica: retardar en el emisor el envo de cada paquete o conjunto de paquetes. As, siempre que el emisor tarde ms que el receptor, no habr problemas ( el emisor esperar). El problema sera justamente lo contrario, que el emisor fuese ms rpido que el receptor. Pues bien para producir un retardo entre el envo de cada paquete o cada conjunto de paquetes, hemos desarrollado esta funcin que le es proporcionada por la librera de nivel_paquete.lib al programa de nivel alto que use la emisin de paquetes. Consiste, simplemente, en un bucle de 75 iteraciones (mediante el registro DATOAUX). Si queremos contar exactamente el retardo que produce sera: 2 ciclos de inicializaciones + 74*3 + 4 = 228 ciclos de instruccin = 228s

>> Emitir_Paquete Previo a llamar a esta funcin, el programa invocador tiene que poner en el registro FSR un puntero a la direccin de memoria en la que se encuentra el primer Byte a enviar. As, esta funcin enviar un paquete que contenga al byte que indica el FSR y los 2 siguientes Bytes. Para explicar la implementacin, vamos a hacer una descripcin secuencial de los pasos que sigue esta funcin para formar y enviar un paquete de 3 bytes: Inicializacines: en primera instancia se borra el registro FalloE para que no haya ninguna interferencia entre el resultado de un envo anterior y el de este envo. Igualmente, se carga en el registro INCRE el nmero de bytes que formar el paquete, representado por NBytes_Paquete definido en el fichero de Constantes.inc en principio con valor 3 (las explicaciones irn referida a 3, pero saber que en realidad cambiando NBytes_Paquete se puede cambiar el nmero de bytes de paquete ). Comienzo del paquete: para encabezar el paquete se enva un Sincronismo con EnviarSincronismo, herramienta ya descrita en el nivel bajo. Con esto indicar al receptor que va a comenzar a enviarse un paquete. LoopEP: en este bucle se va a proceder con leer el Byte apuntado por el FSR (que se encuentra en INDF)y ver si es un cero: Si no es un cero: se carga ese byte en W y se invoca a EnviarByte para que lo mande. Incrementa el FSR o puntero a memoria, para que en el prximo bucle se enve el byte contiguo a ste en memoria, y se decrementa INCRE. Por tanto, en ltima instancia se repetir este bucle y se mandarn 3 bytes, que son los 3 contiguos en memoria a partir de la posicin indicada por FSR. Si es un cero: si es un cero, se enva igualmente, pero abandona el bucle y va a la etiqueta ExitEP, que bsicamente sigue con el decremento de INCRE pero enviando solo ceros. Es decir, a partir del momento que se manda 1 cero, el resto del paquete se rellena con ceros. Tambin se pone el bit 1 del registro FalloE a 1, indicando a niveles superiores ( ya que el registro es global) que este paquete es el ltimo ( ya que segn el protocolo, uno o ms ceros indican el final del mensaje en un paquete).

Ntese que el puntero a memoria se quedar, como mximo, sealando al siguiente Byte que no ha sido enviado (la posicin inicial + 3). Incluso al enviar ceros se avanza el puntero FSR aunque los ceros no se estn leyendo de memoria. Esto es para que el efecto de EmitirPaquete siempre sea el mismo ( dejar FSR 3 posiciones ms avanzadas de la original que se pas al programa). Hace ms sencillo el control en niveles superiores, ya que siempre deja el registro FSR 3 posiciones ms adelantado (en general NBytes_Paquete posiciones ms adelantado). Para acceder al contenido de la memoria apuntada por FSR usamos el registro INDF, que posee el valor del byte almacenado en la posicin a la que apunta actualmente FSR.

* 0FalloE * Nbytes_PaqueteINCRE

EnviarSincronismo

No
INDF = 0

? Si 1 FalloE(1)
INCRE = 0

No

Si

RETURN

INDF w
EnviarByte

FSR+1FSR INCRE-1INCRE

Si

No

FalloE (1) = 1

FSR+1FSR INCRE-1INCRE

INCRE = 0

No 0W
EnviarByte

La descripcin de los registros usados sera: Registro Descripcin INCRE Solo sirve para contar el nmero de veces que se tiene que repetir el bucle de EmitirPaquete, que coincide con el nmero de Bytes que debe tener el paquete. DATOAUX Solo sirve para contar el nmero de bucles de la funcin retarda_paquete. FalloE Registro que seala, si tiene el bit 1 a 1 que en el ltimo paquete hay un cero, por tanto es el ltimo paquete a enviar del mensaje. Es global y puede ser usado por niveles superiores para controlar cuando se acaba el mensaje y por ello el envo. FSR & INDF FSR seala a la posicin de memoria donde se encuentra el siguiente byte del mensaje a enviar. INDF contiene en todo momento el contenido de la memoria apuntada por FSR.

6.3.2 Receptor_Paquete.asm
Este fichero no posee ms que una sola funcin, que es la que exporta: >>Recibir_Paquete En este caso, el registro FSR debe de contener la posicin de memoria a parir de la cual se irn almacenando los bytes que se vayan recibiendo ( hasta un mximo de Nbytes_Paquete, que es la misma constante definida en el fichero Constantes.inc, en principio con valor 3 ( el receptor ir almacenando 3 bytes en posiciones contiguas de memoria a partir de la posicin original a la que apunta FSR). Su implementacin contiene los siguientes hitos: 1) Inicializaciones: primeramente, se borra el registro Fallo, para que el resultado de envos anteriores no puedan ser confundidos con el del envo de este paquete. Obsrvese lo siguiente: El registro de Falloen principio, indica en su bit menos significativo con 1 si ha habido un fallo al transmitir un byte. No convendra mejor borrar Fallo cada vez que se recibe un byte, para que se sepa en qu byte hubo un error? En tal caso, el borrado del Fallo lo hubisemos hecho en el comienzo de la funcin de nivel bajo RecibePaquete. La respuesta es la siguiente: a nosotros no nos interesa en que byte se produjo el error, solo si el paquete tubo un error, por que el sistema de correccin de errores ( la redundancia) no distingue en que byte se produjo el fallo. Como dijimos en el protocolo, solo nos interesa conocer si hubo fallo en alguno de los bytes o no del paquete, para desechar todo el paquete y tomar el siguiente envo de los paquetes redundantes ( a nivel alto). Es por ello que el registro Fallo solo se borra en este nivel de paquetes. Si al hacer llamadas al RecibirByte alguna de las 3 llamadas ( 3 bytes por paquete) o ms de una o otras poseen error, con que solo 1 tenga error, ya el registro de Fallo tendr el bit menos significativo a 1 ( gracias a que no se borr en el nivel bajo). Si hubisemos borrado cada vez que se recibe un Byte, posiblemente en el primero se produjo error, pero en el segundo no, as como cada Byte borra el registro Fallo, solo se sabra si hubo un fallo en el ltimo byte recibido, no en los otros 2. El borrar Fallo en el nivel de paquetes nos permite solventar este problema. Por otra parte, se inicializa CUENTA con el nmero de bytes por paquete Nbytes_Paquetes, pues ser el contador que cuente cuantos Bytes van recibidos para saber cuando acaba el paquete. 2) Sincronismo: siempre que se desee recibir un paquete, previo a esto, el receptor tiene que estar sincronizado con el emisor. Por ello todo paquete tiene que venir encabezado por un Sincronismo. RecibirSincronismo nos permite que el receptor no se ponga a recibir el paquete hasta que no reciba el sincronismo que le indique que va a comenzar un paquete. 3) LooR: una vez sincronizados el emisor y receptor se procede con un bucle, en el cual se recibe un byte con RecibirByte se guarda en INDF (por tanto se est guardando en la posicin de memoria a la que apunta el registro FSR) se avanza la posicin de memoria incrementando FSR para

que el siguiente byte recibido se guarde contiguamente, se decrementa CUENTA y vuelta a empezar al bucle para recibir otro Byte 4) Comprobacin final: para terminar devuelve FSR sealando al ultimo Byte que se introdujo en memoria (si en nivel alto se quiere leer el primer Byte que se meti en memoria, basta con restarle a la posicin que seale FSR Nbytes_Paquete). Por ltimo se comprueba que si ese ltimo byte recibido al que seala FSR despus de decrementarlo es un cero. Si es un cero entonces es que era el ltimo paquete, luego ser guarda en el registro Fallo, en el bit 1 un 1 si este era el ltimo paquete ( por que contiene al menos 1 cero final). Con eso se avisa a los niveles superiores que este es el ltimo paquete a tratar.
* 0Fallo * Nbytes_PaqueteCUENTA

RecibirSincronismo RecibirByte

Si
FSR-1FSR

WINF

FSR+1FSR

INDF = 0

? Si

CUENTA-1CUENTA

No

CUENTA = 0

No

1 Fallo(1) RETURN

La descripcin de los registros usados sera: Registro Descripcin CUENTA Solo sirve para contar el nmero de veces que se tiene que repetir el bucle de RecibirPaquete, que coincide con el nmero de Bytes que debe tener el paquete. DATOAUX Solo sirve para contar el nmero de bucles de la funcin retarda_paquete. Fallo Registro que seala, si tiene el bit 1 a 1 que en el ltimo paquete hay un cero, por tanto es el ltimo paquete a recibir del mensaje. Es global y puede ser usado por niveles superiores para controlar cuando se acaba el mensaje y por ello la escucha. FSR & INDF INDF contiene en todo momento el contenido de la memoria apuntada por FSR. Al modificar el contenido de INDFse modifica el de la posicin de memoria de que seala FSR.

6.4 nivel_paquetes_variables.lib
Este es otro caso de librera de nivel medio, que es exactamente igual a la anterior, pero con una sutil diferencia de funcionalidad: en vez de estar predefinido del nmero de bytes que posee el paquete con Nbytes_Paquete en el fichero Constantes.inc, vamos a hacer que el programa de usuario pueda elegir el tamao del paquete de forma dinmica. + Para ello, en el caso del Emisor_Paquete.asm, el cambio a hacer es la introduccin de un registro global, NBPackE, de manera que el programa de nivel alto que invoque a Emitir_Paquete, deber previamente no solo dar la pocin de memoria donde comienzan los Bytes a Enviar, sino tambin indicar en el registro NBPackE el tamao del paquete ( un nmero). As, si en el momento de invocar a Emitir_Paquete se encuentra un 4 en NBPackE, el paquete que se enve ser de 4 bytes, etc. A nivel de cdigo, la nica diferencia es que en vez de cargar en INCRE el valor de Nbytes_Paquete, carga el contenido de NBPackE en ese instante. En el caso del Receptor_Paquete.asm el cambio ser la introduccin de un registro global NBPackR, de forma que al invocar el Receptor de nivel alto a la funcin Recibir_Paquete, deber de indicar en NBPackR el nmero de Bytes que conforma el paquete. Uno de los problemas ser ves de que manera puede el Receptor cul es el nmero de Bytes que el usuario introdujo en el Emisor. Lo veremos en el nivel alto. Por tanto, a nivel de implementacin, la nica modificacin ser que, al cargar en CUENTA el valor de Nbytes_Paquete, en vez de ello, cargar el valor del registro NBPackR.

6.5 Divide_Paquetes_Emisor.asm
Este es el primer programa de nivel alto que vamos a ver. Su funcin ser sencillamente dividir un mensaje en paquetes y enviarlos en conjuntos redundantes. El nmero de veces que se repite cada paquete ( por tanto nmero de paquetes iguales en un conjunto redundante) viene definido por la constante REDUNDANCIA definida en el fichero Constantes.inc. Este nmero va a ser predefinido antes de compilacin y por defecto tenemos que la redundancia sea de 3. Igualmente, decir que este programa esta preparado para una librera de nivel_paquetes.lib tal que el nmero de Bytes por Paquetes venga definido por la constante Nbytes_Paquete, tal y como se describi la primera librara de Nivel_paquetes.lib. Hay que tener cuidado con no usar la librera Nivel_paquetes_variables.lib con este programa de usuario, pues no esta preparado para ello. Ms tarde veremos un programa que si est preparado para trabajar con una librera de paquetes variables. Antes de ver el programa principal considerar que se da una tabla que contiene ordenados de mayor ndice a menor ndice todas las letras que conforman el mensaje. Se pueden acceder a estos Bytes invocando a la funcin Ristra ( previamente poniendo en w la posicin en la que est la letra a extraer de la tabla). Ahora, podemos proceder con explicar el algoritmo:

1) Cargar el Mensaje en Memoria: en todas las libreras hechas se nos exigen punteros a memoria de Datos en donde se encuentra el mensaje ( a travs de FSR). Sin embargo, ahora mismo tenemos la frase en memoria de instrucciones (preferimos hacerlo as para que fuera ms fcil de modifica el mensaje. Si hubisemos introducido el mensaje directamente en memoria de datos hubiese sido ms complicado cambiar el mensaje). Por tanto vamos a pasar por el bucle Bucle, donde un contador CONT inicializado a cero ir sacando Bytes de la Tabla y introducindolos en memoria de datos correspondiente con la etiqueta Mensaje. El registro FSR estar inicializado inicialmente a Mensaje, y los bytes que saquemos de la tabla los iremos introduciendo en la memoria de datos a travs de INDF. Tras cada byte incrementaremos tanto el contador CONT y tambin FSR. As hasta que completemos todas las letras que hay en el la tabla. Vase que el nmero de bytes de la tabla debe de coincidir con el valor de MaxNBytes_Mensaje en el fichero Constantes.inc, que tambin coincide con el tamao del espacio reservado en memoria de datos para Mensaje. Ms tarde analizaremos que limitaciones tiene ese espacio. Tras ello se inicializa el FSR al comienzo del Mensaje ( primera posicin de Mensaje). 2) EPPro: aqu se va a trazar primeramente el comienzo del conjunto redundante. Para ello, inicializa CONT con el valor de REDUNDANCIA o nmero de veces que se tiene que mandar cada paquete, se emite la primera trama para identificar al conjunto redundante, mediante EmitirTrama, y se borra el registro de FalloE para evitar que el resultado de otros envos afecte a este. A partir de este momento en el que se inicializ el conjunto redundante, comienza un bucle en el que se va a repetir tantas veces como indica REDUNDANCIA el siguiente proceso: se llama a EmitirPaquete, de manera que al FSR que seala a la primera posicin se le modificar y terminar en una posicin FSR + Nbytes_Paquete, segn las especificaciones de EmitePaquete que ya analizamos. Por ello, para repetir el mismo paquete, basta con restarle Nbytes_Paquete al FSR devuelto por EmitePaquete, y volver a buclear. Antes de ello, invocamos a retarda_paquete para poder dar tiempo al receptor a tratar la informacin. Una vez que ya se ha repetido esto el nmero de veces indicado por REDUNDANCIA, se le suma al FSR ( recin restado Nbytes_Paquete) el mismo Nbytes_Paquete con el fin de dejarlo apuntando al primer byte que formar parte del siguiente paquete, y se vuelve a EPPro, a no ser que en el registro FalloE se encuentre un 1 en el bit 1, en cuyo caso este conjunto redundante recin enviado era el ltimo y ya puede terminar la emisin.

Registros: La descripcin de los registros usados sera: Registro Descripcin CONT Sirve en cada conjunto redundante para controlar el nmero de iteraciones del bucle ( en total este nmero es igual a REDUNDANCIA). MENSAJE Zona de memoria destinada a guardar el mensaje a enviar. Su tamao es MaxNBytes_Mensaje Cargar Ristra en Memoria Mensaje FSR
REDUNDANCIA CONT

EmitorTrama

0FalloE

EmitirPaquete

FSR Nbytes_Paquete FSR

FSR+Nbytes_Paquete FSR

Retarda_Paquete

CONT-1 CONT No Si

CONT = 0 ?

Si
FalloE (1) = 0 ?

No END.

6.6 Divide_Paquetes_Receptor.asm
Simtrico al anterior, se va a encargar de tomar paquetes de tamao fijo (Nbytes_Paquete), de manera que si no se produce ningn fallo, los imprime en la LCD y espera a la siguiente Trama ( es decir el siguiente conjunto redundante, ignora las respeticiones del mismo paquete). Sin embargo, en caso de fallo tiene en total tantas oportunidades como el nmero que indica REDUNDANCIA en el fichero CONSTANTES.inc, ( comn con el emisor). Por tanto, ignorar el paquete recin recibido y se pondr a la escucha del siguiente. Si finalmente pierde todas las oportunidades, no imprime nada en la LCD, y se pone a la escucha del siguiente conjunto redundante. Ha perdido un paquete definitivamente, pero por lo menos no pierde todos los del mensaje. Una descripcin detallada sera la siguiente: 1) Inicializaciones: nada ms comenzar el programa se configura e inicializa la LCD. 2) Bucle de recepcin de paquetes: Primeramente se comienza en Recibe a recibir el conjunto redundante recibiendo una Trama con RecibeTrama, y se carga en AUXILIAR el nmero REDUNDANCIA, que van a ser el nmero de oportunidades de capturar el paquete, o lo que es lo mismo, el nmero de veces que se enva el mismo paquete en el conjunto redundante. A partir de aqu, se inicia un bucle interno para tratar todo el conjunto redundante. En este bucle interno comienza en Reb_Paq_again. Se inicializa FSR a recent_Paquete que va a ser la zona de memoria donde se van a almacenar los Bytes recibidos que contiene el paquete. Vase que en la declaracin de recent_paquete, el tamao del mismo coincide con el nmero de bytes del paquete Nbytes_Paquete. Se invoca a RecibirPaquete para guardarlo en la memoria, y se revisa el registro Fallo por si se produjo algn error. Si se produjo algn error, se decrementa AUXILIAR y vuelve a Reb_Paq_again. Si sigue dando errores y Auxiliar llega a cero se han agotado las oportunidades, por lo que se acepta que el paquete esta perdido, y se vuelve a Recibe para aunque sea tomar el siguiente conjunto redundante. Pero en el caso de que no se de Fallo, se va a la etiqueta Seguir, donde se inicializa a FSR para que apunte a los Bytes que se acaban de grabar en memoria (en recent_paquete, ya que este fue el puntero que se le pas a FSR antes de RecibirPaquete). Acto seguido se van uno a uno escribiendo en la LCD siempre y cuando no sean estos bytes igual a cero. Desde que uno sea cero, se va a la etiqueta final LOOPINACTIVER, donde, antes de dormirse, se escribe un signo = en la LCD, para luego pasar a modo de bajo consumo el microcontrolador, pues ya termin la emisin.

Registros: La descripcin de los registros usados sera: Registro Descripcin AUXILIAR Sirve simplemente para indicar nmero de bucles mximos a hacer, tanto a la hora de dar oportunidades en funcin de Redundancia, como a la hora de contar el nmero de bytes que hay que escribir en la LCD. recent_paquete Zona de memoria destinada a guardar el mensaje recibido. Como el nmero de Bytes por paquete es fijo (Nbytes_Paquete), y solo hace falta guardar los bytes de un paquete en memoria, pues a medida que se van tomando nuevos paquetes se pueden ir volcando los antiguos en la LCD, dejando la memoria libre, solo necesita como espacio Nbytes_Paquete.

Configurar LCD
Inicializar LCD
RecibirTrama
REDUNCANCIAAuxiliar

Si

No

AUXILIAR = 0 ?

Recent_paquete FSR

Auxiliar 1 Auxiliar

RecibirPaquete

Fallo (0) = 0 ?

No

Si
Recent_paquete FSR Nbytes_PaqueteAUXILIAR

INDF W

LCD_DATO

= W END.

Si
INDF = 0 ?

No
LCD DATO FSR +1 FSR

Auxiliar 1 Auxiliar

Si

AUXILIAR = 0 ?

No

Vase que en el manejo de la LCD, cada vez que se carga un dato en la pantalla, hay que borrar el bit 2 del puerto A, para evitar que se desconfigure al usar el puerto A para recibir Datos tambin

6.7 Divide_Paquetes_Emisor (2).asm


En este caso, vamos a acometer el diseo de un programa emisor que haga uso de la librera de nivel medio nivel_paquetes_variables.lib, que recordamos presenta la posibilidad de elegir desde el nivel superior cul es el nmero de Bytes del Paquete. El programa de nivel alto deber comunicrselo inicializando el registro global que proporciona el nivel de paquetes NBPackE. Una vez inicializado, cada vez que se emita un paquete se har con ese nmero de Bytes especificado. A continuacin vamos a citar solo las modificaciones respecto al programa Emisor principal ya descrito que hemos tenido que hacer para que pudiera funcionar con esta nueva librera: 1) Inicializar pantalla: antes que nada imprime por la pantalla de la LCD la frase que se da en la tabla RistraPantalla, accediendo secuencialmente a cada posicin de la tabla. Este mensaje pide al usuario teclear el nmero de Bytes que se desea que tenga el paquete. 2) Cargar mensaje en memoria de datos: al igual que en emisor antes descrito, se carga el mensaje que se presenta en memoria de cdigo ( en una tabla) a la memoria de datos ( Mensaje). 3) Tec: aqu comienza un bucle, que hace uso de las libreras del teclado para poder leer del mismo . As, va a estar continuamente bucleando hasta que en el teclado se escriba algo (registro Tecla sea distinto de 80h). Una vez que lee algo , comprueba que est entre 1 y MaxNBytes_Paquete-1, constante que se encuentra en constantes.incy que debido a que vale 5, permite paquetes de hasta 4 bytes. ( de 1 a 4 bytes). Si la tecla pulsada no esta entre estas, vuelve a Tec. Sino continua, lo guarda en POS y lo escribe por pantalla. Recuerde que para que el pic pueda leer del teclado es fundamental que el potenciometro del circuito este a algo de resistencia, distinta de cero. Si no va a lograr leer el programa desde el Teclado. 4) Configurar los puestos: el puerto A, como entrada ( para el punto 5). 5) Comienzo manual de transmisin: entra en un bucle en Bucle_em, de manera que hasta que el usuario no ponga el puerto A, el interruptor ms a la derecha a cero, no se va a comenzar con el envi. Recuerde que antes de activar este interruptor, el potencimetro deber de volver a su posicin inicial, es decir a resistencia 0, para que la intensidad de salida del PIC no se desve al teclado. 6) Envo de nmero de paquetes: uno de los problemas que citamos antes era el de cmo se poda enterar el Receptor del nmero de Bytes que tendra cada paquete, para inicializar su registro NBPackR. Pues bien, antes

de comenzar la emisin, el emisor le enva un conjunto redundante, con un paquete de tamao 1 solo byte, donde lo que se transmite es el contenido de POS , es decir, el nmero de Bytes del paquete. Tras enviar esto tantas veces como indica REDUNDANCIA, inicializa NBPackE con el valor de Pos, eso es, el nmero de bytes de paquete. 7) Final: a partir de ahora se har el envo normal, idntico que en el primer Emisor que vimos, pero usando el contenido de NBPackE en vez de Nbytes_paquete. Este diagrama ayudar a comprenderlo.
Escribir en LCD N_Paquetes?

Cargar mensaje en Ristra en Mensaje(memoria de datos)

Leer de Teclado en Tecla Si


Tecla = 80h ?

No Llamar a CodsTecla Obtener en POS el nmero pulsado


0 < Pos < MaxNBytes_Paquete-1 ?

No

Si Configuirar Puerto A como entrada

No

PORTA = 0 ?

Si 1 NBPackE Emitir POS tantas veces como REDUNDANTE, en un conjunto redundante. POS NBPackE Emitir resto de mensaje en conjuntos redundantes de NBPackE bytes cada paquete (como en el caso base explicado)

6.8 Divide_Paquetes_Receptor (2).asm


Similar al anterior, ahora el nmero de paquetes es variable, ( ya que usa la librera de paquetes variables como nivel de paquetes), por lo que en el protocolo, antes de comenzar la transmisin el Emisor deber de comunicarle cual es el nmero de Bytes que tiene cada paquete ( para ponerse de acuerdo ambos). Una vez esto, simplemente tiene que desarrollarse igual que antes, pero usando la librera de paquetes variables. Las modificaciones bsicas al programa original son: 1) Nada ms comenzar el programa, se inicializa NBPackR a 1, pues el primer conjunto redundante, que nos indica el nmero de bytes por paquete que se van a transmitir, son paquetes con 1 solo byte indicando ese nmero. 2) En la recepcin de dicho conjunto redundante incial (encabezado pro un RecibirTrama), se dan tantas oportunidades como indique REDUNDANCIA. Desde que una recepcin del de RecibirTrama sea vlida, ya se puede avanzar en el programa. Esta recepcin vlida se habr guardado en NBPackR, por lo que, a partir de ahora, el algoritmo del Receptor es similar al de antes, solo que en vez de usar Nbytes_paquete, usa el contenido de NBPackR. 3) Pero, si en la recepcin del primer conjunto redundante que posee la informacin sobre el nmero de bytes de paquete, se agotan todas las oportunidades de redundancia y en todas da fallo, el programa termina automticamente ( no puede trabajar el receptor si no sabe el nmero de bytes que va a tener cada paquete).

Un diagrama explicativo sera:

RecibirTrama

REDUNDANCIAAUXILIAR 1NBPackR Aux2FSR

No
Auxiliar = 0 ?

RecibirPaquete

S
Fallo (1) = 1 ?

Si

AUXILIAR-1AUXILIAR

No
Recibir el resto de conjuntos redundantes, tal como en el algoritmo anterior

Escribir en LCD un = END

NOTA: en esta seccin solo se estn comentando el funcionamiento y estrategias de implementacin usadas. Para ver ms detalladamente los requisitos de cada funcin y sus efectos en los registro del microcontrolador, leer las explicaciones que se hayan en los mismo fichero *.asm en lo que fueron desarrollados.

6.8 Implementacin del nivel bajo en modo rpido.


En las siguientes lneas se explicar como se realiz la implementacin del emisor y del receptor de forma que la transmisin sea ms rpida de lo que lo es con los ficheros de nivel bajo iniciales. Las implementaciones del nivel bajo inicialmente tenan un marco de bit de un tamao de 200 pulsos (100 pulsos para el perodo activo y 100 para el inactivo para obtener la interpretacin de un bit a 1, y 200 pulsos inactivos para obtener la interpretacin de un bit a cero). La idea de agilizar la transmisin surgi porque con los protocolos de transmisin actuales el envo es muy lento debido a la redundancia y al envo de bytes especiales que se utilizan para sincronizar al receptor con el emisor. La transmisin de 9 letras se volva muy lenta, ya que llegaba a durar dos o tres segundos. Pero es verdad que con un marco de bit de 200 pulsos no estbamos llevando al lmite la capacidad del sensor, ni mucho menos. Inicialmente decidimos utilizar estos 200 pulsos para tener mucha ms holgura (y por lo tanto mucho ms robustez, ya que habramos de tener muchas instrucciones de mas o de menos en el receptor para perder la sincronizacin) de cara a que no tenamos muy bien medido el tiempo que tardaba el emisor en enviar un byte y prepararse para enviar el siguiente con respecto al tiempo que tarda el receptor en obtener el bit y almacenarlo. Por ejemplo, si el emisor emite un bit en el tiempo 0, y prolonga la emisin de este bit hasta los 200 pulsos (que seran 200 pulsos por 26 microsegundos que tarda cada pulso), tendramos que al emitir el prximo bit el emisor se retrasar unas 5 instrucciones (por ejemplo) para cargar el bit que tiene que enviar y enviarlo, mientras que el receptor se va a retrasar unas 3 instrucciones (por ejemplo) porque solo tiene que guardar el bit recibido y ponerse nuevamente a la escucha. Para ponerse a la escucha el receptor esperar 200 pulsos para leer el prximo bit. Tenemos que en enviar un bit el emisor tarda los 200 pulsos ms las 5 instrucciones mientras que el receptor tarda las 200 instrucciones ms loas 3 instrucciones para almacenar el bit. En principio el receptor realizara 2 instrucciones de menos que el emisor (que seran unos 2 microsegundos frente a los 5200 microsegundos que tarda cada transmisin de un bit), lo que no tendra importancia de cara la sincronizacin, ya que tenemos bastante holgura (si nos situamos a mitad del bit para leerlo tendramos una holgura de 2600 instrucciones que podra durar el receptor ms o menos que el emisor, lo que nos permitira recibir 1300 bits sin que se desincronizase el receptor). Con estos 200 pulsos tendramos una holgura exagerada, ya que solo queremos emitir 8 bits seguidos ms el Start bit y los Stop Bits. Es por ello por lo que finalmente decidimos disminuir el marco de bit de forma considerable. Ahora el marco de bit sera de 50 pulsos (la cuarta parte del pulso que tenamos antes), aunque podramos disminuir el marco de bit hasta

los 30 pulsos, ya que el lmite para el sensor est en los 15 pulsos para el tren de pulsos, que sera la mitad del marco de bit. Pero no lo hicimos tan a la ligera. Aunque an con este marco de bit tenamos una holgura bastante considerable para equivocarnos en un nmero considerable de instrucciones del emisor frente al receptor, decidimos medir las instrucciones del receptor y del emisor para que no hubiera desfases de uno frente a otro en la transmisin. Si nos faltaban instrucciones en alguno de los dos, en el emisor o en el receptor, le aadamos instrucciones nops. A continuacin se dan las medidas que se han hecho de los dos procedimientos para equilibrar la transmisin. Las cuentas se han hecho de forma que estn ordenadas para saber dnde hay que aadirle las instrucciones nops a los procedimientos, si antes o despus de realizar la espera (que normalmente vendr definido por un 31*200, excepto en el Start Bit que vendr definido por un bucle de 31*250, ya que realizar un salto de un marco y medio de bit para centrarse a la mitad del primer bit a recibir). Start Bit: Emisor 2 + ((31*200) + 2 + 2 + 3) + 2 + 2 = 6213
funcin Pulso funcin Pulso1 o Pulso0

Receptor (31*250 = 7750) + 2

Como se puede ver, el emisor y el receptor estn claramente desequilibrados en el Start Bit, pero esto es normal. Es normal puesto que lo que debe de hacer el receptor es colocarse a mitad del pulso siguiente cuando recibe el Start Bit, por lo tanto, tendr que esperar durante ms tiempo que el emisor par poder recibir el primer bit. Por ello no haremos modificaciones en el Start Bit. Centrmonos en los puntos importantes, que es donde se ir acumulando el retardo. Estos puntos importantes en los programas son los etiquetados como LeeBit en el receptor y como LeerByte en el emisor. Emisor ( 5 + (2 + (3 + 2 + 31*200 + 2 ) + 2) + 3)*8 - 1 Receptor (5 + 2 + 2 + 31*200 + 3)*8 - 1

Se puede ver como el emisor necesita ms instrucciones que el receptor para enviar el bit. Por lo tanto habr que rellenar el receptor mediante nops para que no se retrase en la transmisin. El nmero de nops que habra que ponerle seran unos tres antes de realizar la espera (antes del 31*200, que sera el marco de bit, el receptor solo tiene 9 instrucciones mientras que el emisor tiene tres instrucciones ms que el receptor, unas 12 instrucciones). Adems, vemos que realizar la espera el receptor tiene 4 instrucciones menos que el emisor, por lo tanto habra que aadrselas como nops.

Otro punto peligroso es al recibir los stop bits, ya que se recibirn 9 Stop Bits con el consiguiente peligro de una desincronizacin. Veamos que nmero de instrucciones hay en el Stop Bit. Emisor 4 + ((2 + (3 + 2 + 31*200 + 2) + 2) + 3 )*11 - 1 Receptor 2 + (4 + 2 + 31*200 + 2 + 3) * 9 - 1

Hay un bucle tanto en el emisor como en el receptor para enviar los Stop Bits a cero. En el emisor el bucle es de 11, ya que ste emitir 11 Stop Bits mientras que el receptor solo comprobar 9 Stop Bits de esos 11 que enviar el emisor. El emisor enviar ms Stop Bits de los que realimente se comprobarn para dar tiempo al receptor a prepararse para recibir el siguiente byte. Se puede comprobar que en el Stop Bit, dentro del bucle (lo que se est multiplicando por 11), hay una instruccin ms en el emisor antes de la emisin del bit (la emisin del bit se realiza durante el 31*200) que en el receptor antes de realizar la espera (antes del 31*200). Por lo tanto tan solo habra que aadirle una instruccin nop al receptor dentro del bucle (lo que se est multiplicando por 9) antes de realizar la espera. Despus de la emisin del bit por parte del emisor y de la espera por parte del receptor hay dos instrucciones ms en el emisor que en el receptor, por lo tanto habr que aadirle dos instrucciones nops ms al receptor despus de este punto. Con estas modificaciones hechas ya podemos reducir bastante el marco de bit sin miedo a una desincronizacin, ya que los desfases entre el receptor y el emisor sern prcticamente inexistentes.

6.9 Implementacin del nivel bajo con paridad.


Para nuestra prctica tenemos que hay un registro denominado Fallo en el receptor del nivel bajo que nos indica cuando no se ha recibido correctamente un byte. Pero por que no se haya recibido correctamente un byte nos referimos hasta ahora con que haya habido un fallo de sincronizacin entre el emisor y el receptor (que el receptor no haya pillado la recepcin de un byte desde el principio, producindose un fallo que se detecta con el primer Stop Bit, ya que el receptor no recibir el primer Stop Bit a uno). En nuestro protocolo hemos aadido unos instrumentos que nos permiten resolver situaciones de error en la recepcin de un byte cuando no se ha sincronizado correctamente, pero no tenemos herramientas implementadas que nos permitan analizar el byte recibido y decidir si la recepcin de ese byte ya obtenido bajo una correcta sincronizacin es el byte que deberamos haber recibido o no. Si queremos aadirle robustez a la comunicacin entre los dos PICs debemos implementar sistemas que nos permitan analizar el byte recibido a posteriori y decidir si ese byte recibido es o no correcto segn el anlisis mediante esas herramientas.

El sistema de este tipo ms simple que se puede implementar es el sistema basado en la paridad. Cada vez que recibamos un byte, comprobaremos el bit que recibiremos con l que nos indicar si el nmero de bits a uno que hemos recibido es un nmero par o impar. Si lo que nos dice ese bit recibido coincide con la comprobacin que hacemos a posteriori significar que hemos recibido, o mejor dicho, hay una alta posibilidad de haber recibido correctamente el byte que estamos analizando. Si por el contrario, el bit recibido no coincide con la paridad de la cuenta de los unos que hemos recibido indicar que hay una alta posibilidad de que lo que hayamos recibido sea incorrecto. En este caso se podra utilizar la redundancia que hemos impuesto en el nivel alto para poder enmendar este error intentando recibir el prximo byte con el mismo contenido que el fallido que enve el emisor (la redundancia). Tambin se podran intentar implementar otro tipo de actuaciones sobre los bytes recibidos, ya que lo nico que habra que tener en cuenta para que los niveles superiores siguieran funcionando es que los nuevos archivos implementados en el nivel bajo tuvieran la misma interfaz que los archivos originales (mismos nombres de procedimientos, misma utilizacin de ciertos registros como puede ser el registro Fallo...). En verdad, hemos estado intentando implementar una librera para el nivel bajo que implementara la paridad, pero debido a que se nos echaba la fecha de la entrega encima no hemos podido hacer que funcionaran estos archivos. Pero para que se vea que lo hemos intentado, vamos a explicar un poco la filosofa de estos archivos que hemos creado, aunque no funcionan. Partamos de los archivos originales, los que usbamos para implementar la librera del nivel bajo. Nuestra intencin era aadir la paridad tanto en el receptor como en el emisor sin utilizar muchos registros dems, solo los necesarios. Esta intencin ha sido tambin nuestra desdicha. Creemos que debido a la mala utilizacin de los registros, que ya utilizbamos antes, pero que intentemos adaptar para poderlos utilizar en la paridad sin quitarles las funcionalidades que tenan antes, todava no hemos resuelto la prctica. La idea fue la siguiente:

6.9.1 Emisor
Como ya se ha explicado, en el programa del emisor hay un registro denominado Banderilla que utilizamos para implementar las alternativas de RecibirSincronismo y de Recibir_Trama. En este registro se especificaba si lo que queramos que realizara el emisor era un byte, una trama o un Sincronismo. Pues bien, la idea fue que podramos utilizar este mismo registro para contar la paridad de los bytes que furamos a emitir. Para ello primero se emitiran dos pulsos a 1 antes de emitir el byte con todo a 1, si era un sincronismo (bit 0 de banderilla activado. Se puede observar como emitimos dos pulsos y el byte con todo a 1, esto es porque necesitamos diferenciarlo de una recepcin de un byte todo a uno con el bit de paridad errneo, a uno. Debido a esto el Emitir_Trama emitir 11 bits a 1 en lugar de 10, como en los archivos originales).

Despus, se comprobar si el bit 1 del registro Banderilla est activado, en cuyo caso se enviar otro bit a uno para emitir la trama, por lo que si haba un tres en banderilla habremos emitido 2 + 1 bits antes de los 8 bits, que sera la trama. Con esto controlaramos si queremos enviar un byte normal, un sincronismo o una trama y adems tendramos el registro Banderilla listo para ser utilizado para contar la paridad, ya que ya habra servido a su propsito, que era identificar el tipo de byte que se quera enviar. El cdigo sera el siguiente:
btfsss Banderilla,0 goto empezar_lec

; si bit 0 =1 --> sincronismo(pulso1)


call

Pulso1

; En la paridad tanto el sincronismo como la trama llevan un bit ms que sin la paridad.
call Pulso1 btfsc Banderilla,1 call Pulso1 goto LeerByte empezar_lec LeerByte CLRF Banderilla ...

; si bit 1 =0 --> toca StopBit ; si bit 0 =1 --> trama(pulso1).

Como se puede observar, solo inicializamos el registro banderilla en caso de que haya que enviar un byte, para empezar a contar el nmero de unos que tiene el byte. No lo inicializamos en los otros casos porque como veremos ms adelante, utilizaremos la ventaja de que cuenta los 8 bits a 1 y adems a esto le suma el 1 o el 3 a que est al entrar en el procedimiento para poder diferenciarlo del byte, y decidir si enviar bit de paridad o no, teniendo en cuenta que tanto la trama como el sincronismo habrn dado como resultado en el registro banderilla despus de enviar los 8 bits un nmero de 1 mayor que 8. Si esto ha sucedido, no habr que enviar paridad. Es por ello por lo que antes de enviar la paridad comprobaremos lo siguiente: ; Si es sincronismo o trama se saltar el bit de paridad
BTFSS Banderilla, 3 GOTO BitParidad BTFSS Banderilla, 0 GOTO BitParidad GOTO StopBit

Se puede ver como comprobamos si el registro banderilla es mayor que 8 comprobando el bit 3 y el bit 0, ya que al final tendremos que si tenemos que enviar una trama o un sincronismo tendremos un valor para el registro Banderilla de 9 u 11 (ya que comenzbamos con Banderilla a un valor de 1 o 3), para los cuales tanto el bit 0 como el 3 estarn activos. A continuacin se muestran los diagramas ASM de estos puntos del cdigo, ms el punto del cdigo en el que realiza el conteo de la paridad.

Control de Banderilla: No
Bit 0 de Banderilla activado?

Si

ir a empezar_lec

Pulso1

Pulso1

No

Bit 1 de Banderilla activado?

Si

Ir a Leer_byte

Pulso1

Control de Conteo de la paridad: No


Bit a transmitir es un 1?

Si

Pulso0

Pulso1

Incrementar Banderilla

Control de envo de paridad: No Si

Bit 3 de Banderilla activado?

Ir a BitParidad

No

Bit 0 de Banderilla activado?

Si

Ir a BitParidad

Ir a StopBit

No

Bit 0 de Banderilla activado?

Si

Pulso0

Pulso1

6.9.2 Receptor:
El receptor lo implementemos de una forma ms simple. En ste no encontremos otra alternativa que utilizar un registro de ms que realizara el conteo de la paridad en el byte que se estaba recibiendo. El procedimiento RecibirSincronismo y Recibir_Trama sern totalmente iguales a los originales, excepto por que ahora tendrn que recibir 10 y 11 bit para el sincronismo y la trama respectivamente en lugar de los 9 y 10 que reciban antes. Lo nico que tendr el RecibirByte de diferente es que contar el nmero de unos que recibe en el byte mientras est recibiendo los bits, almacenndolo en un registro nuevo que se denomina ContPar, y comparar el conteo con el bit de paridad que reciba para comprobar si ha recibido el byte correctamente o si debe activar el bit cero del registro Fallo en caso de no haberlo recibido correctamente. Esta vez si que podremos inicializar el registro ContPar desde el principio para poder contar el nmero de unos que recibe el byte.

7 Manual de instrucciones
A continuacin se explicar brevemente como ha de utilizarse el material utilizado en esta prctica.

7.1 implementacin fsica:


El diodo emisor de infrarrojos deber ir conectado al bit 0 del puerto B. El cable que sale del puerto B deber ir a una resistencia conectada en serie con el diodo. La resistencia deber de ser de menos de 200 ohmios, y a ser posible deber ser un potencimetro, sobretodo si queremos utilizar las libreras en las que el nmero de bytes en el paquete es variable. La tierra, evidentemente deber ir conectada a una de las patas del diodo emisor y puede ser la tierra que nos proporciona el bus IR2C. El sensor de infrarrojos deber de tener su patilla de salida conectada a la entrada del puerto A, al bit 4, con el circuito de acondicionamiento que se ha explicado anteriormente en el apartado del sensor.

7.2

implementacin software:

Todos los ficheros necesarios los tenemos almacenados en la capeta de entrega. Su estructura es la siguiente: Una carpeta denominada otras libreras y cabeceras, en la cual encontraremos los ficheros cabecera y las libreras de la LCD, del teclado, y un fichero de constantes, denominado constantes.inc, definidas para los procedimientos creados para la comunicacin por infrarrojos.

Una carpeta llamada nivel bajo. En ella encontraremos las libreras y los ficheros fuentes y cabecera de las distintas implementaciones para el nivel bajo. En esta carpeta se encuentran las carpetas: o nivel bajo normal: contiene las libreras, ficheros fuente y cabeceras de los procedimientos del nivel bajo original. o nivel bajo rpido: Esta carpeta contendr los ficheros de la versin rpida del nivel bajo. o nivel bajo paridad: Carpeta que contiene los ficheros fuente de la versin del nivel bajo con paridad. Estos ficheros no funcionan correctamente y es por ello por lo que no hay ficheros cabecera ni libreras, solo los ficheros fuente. Una carpeta denominada nivel paquete. En ella se encuentran los dos tipos de procedimientos que hemos implementado para el nivel bajo. Estn contenidos en las carpetas:

nivel paquete N bytes fijo: contendr la librera y el fichero cabecera del nivel paquete con un nmero de bytes por paquete determinado en tiempo de compilacin mediante el valor NBytes_Paquete especificado en el fichero constantes.inc. nivel paquete N bytes no fijo: contendr la librera y el fichero cabecera del nivel paquete con un nmero de bytes por paquete determinado en tiempo de ejecucin.
Una carpeta a la que hemos llamado Nivel Alto. Esta carpeta contendr ejemplos de programas que utilizan el nivel paquete y el nivel bajo. En esta carpeta habr un receptor y emisor que utiliza el nivel paquete con un nmero de bytes fijo para los paquetes, y otro receptor y emisor que utilizan el nivel paquete con un nmero de bytes variable. Seguidamente vamos a explicar como preparar el entorno de trabajo para poder utilizar los ficheros implementados. Para cualquier librera que se desee usar de las implementadas deber incluirse el fichero cabecera pic16f84.inc, puesto que hemos optado por usar los nombres estndares de los registros de propsito especfico del microcontrolador, a fin de mejora la legibilidad del cdigo.

1 Implementar un programa utilizando el nivel bajo: Si queremos implementar un programa en nivel bajo, primero debemos saber qu libreras son las que queremos utilizar. Hay dos opciones, utilizar la librera nivel bajo

normal o la librera nivel bajo rpido. Pero la nica diferencia entre utilizar una u otra es la librera que se utiliza, ya que los ficheros cabecera son los mismos. Para empezar, deberemos cargar como ficheros cabecera los ficheros constantes.inc (que se encuentra en la carpeta otras libreras y cabeceras) y nivel_bajo.inc (que ser el mismo para los dos niveles bajos). A continuacin cargaremos la librera que queramos utilizar del nivel bajo, pudiendo elegir entre la librera del nivel bajo rpido o del nivel bajo normal. Con estos ficheros cargados ya podramos utilizar las funciones especificadas en el fichero cabecera del nivel bajo. 2 Implementar un programa utilizando el nivel paquete: Los ficheros necesarios para crear un programa que utilice los procedimientos del nivel paquete se encuentran en la carpeta Nivel Paquetes. En ellos podemos encontrar las libreras y ficheros cabecera que necesitamos. Se pueden distinguir dos niveles de paquetes distintos: nivel de paquetes con nmero de bytes seleccionable en ejecucin, o nivel de paquetes con nmero de bytes prefijados en el fichero de constantes.inc. Para utilizar estos procedimientos debemos incluir los ficheros que necesitbamos para usar el nivel bajo ms dems la librera y fichero cabecera propios del nivel de paquetes que queramos utilizar. 3 Ejemplo de utilizacin de recursos de ambos tipos de libreras: Unos ejemplos de implementacin de programas que utilizan las funciones que nos ofrece el nivel bajo y el nivel paquete son los ficheros almacenados en la carpeta Nivel Alto. En esta carpeta se pueden encontrar dos programas diferentes: 1) Un primer programa usa la librera de nivel de paquetes cuyo tamao est prefijado de antemano en el fichero cabecera Constantes.inc (mediante NBytes_Paquetes). Es importante, a la hora de elegir una librera de las implementadas, ver como funcionan sus funciones y los requisitos bsicos. Leer los comentarios hecho sobre los propios ficheros *.asm. No debe pasar inadvertido incluir esta serie de ficheros: Para el nivel bajo har falta incluir todos los ficheros que antes especificamos, una vez hayamos decidido que tipo de librera de nivel bajo queremos usar. Para el nivel de paquetes remitirse tambin a lo antes especificado. Finalmente, no debe olvidarse incluir las libreras y cabeceras correspondientes al manejo de la LCD, que

podemos encontrar en el directorio Otras libreras y cabeceras. Todo esto, ms el fichero correspondiente al programa en s, incluidos todos en un mismo directorio, ya es apto para poder ser compilado.

2) Un segundo programa usa la librera de paquetes con tamao o nmero de bytes variable. Con este programa tenemos que hacer ms de lo mismo a la hora de compilarlo y trabajar con l, pero adems deberemos incluir el fichero cabecera y la librera correspondiente al teclado. Fjese que el programa tiene otro modo de tratar y trabajar con las libreras de nivel paquete. Esto es debido a que cada librera del nivel de paquete tiene sus especificaciones, que deben de ser ledas antes de su uso indiscriminado.

8 Restricciones del sistema de comunicacin por infrarrojos.


En el desarrollo de la presente prctica, se han detectado ciertas restricciones en el uso de este sistema de comunicacin. A saber: Los bytes a cero, son utilizados como fin de mensaje. Por tanto ningn mensaje que enviemos podr incluir un cero ya que el mensaje se cortara justo por ese punto. En el emisor, utilizamos la memoria de datos para almacenar mensajes por tanto el mensaje no puede ser todo lo largo que queramos. Haciendo un recuento del nmero de registros usados tanto en las libreras del nivel bajo como en las del nivel de paquete ms los registros que usamos en nuestro programa, y sabiendo la capacidad de memoria de datos que nos ofrece el PIC. el usuario tendr que tratar mensajes que quepan en el espacio libre de esa memoria de datos. En el receptor el problema es menor, pues solo hace falta tanta memoria de datos como el nmero de bytes que tenga el paquete (que siempre se supondr menor que el nmero de bytes que contendr el paquete). Aun as, tambin debe calcularse el espacio libre que hay en la memoria de datos para tal fin (tarea del programador de nivel alto). La pila del microcontrolador PIC contiene un mximo de 8 llamadas a funciones. Esta estructura modular que hemos propuesto tiene el inconveniente de tener demasiadas llamadas a funciones, por lo que el programador deber tener cuidado y estudiar cuntos niveles de pila implica la llamada a cada funcin de cada librera para no socavar dichos lmites y encontrarse con comportamientos atpicos. Hemos diseado un sistema de comunicacin a nivel alto destinado a enviar un nico mensaje ya que ponemos como ejemplo que el receptor

al trmino del mensaje pasa a un estado de consumo mnimo. Vase que no es una restriccin inherente a las libreras, por tanto un uso adecuado de las mismas podra solucionar dicha restriccin (modificando el programa a nivel alto).

9 Ejercicios Propuestos
A continuacin se proponen una serie de retos abarcables siempre que se haya ledo atentamente la presenta prctica: Ejercicio1: Disear libreras que doten al sistema de comunicacin de deteccin de errores y correccin mediante el uso del cdigo de Hamming. Ejercicio 2: Disear un sistema de comunicacin que permita manejar paquetes de tamao variable. Ntese que en la presente prctica, una vez definido (en tiempo de ejecucin o de compilacin) el tamao del paquete todos los envos de paquetes se hacen con el mismo tamao. Proponemos que cada paquete diferente pueda poseer tamao diferente, pero en un conjunto redundante, al ser todos el mismo paquete, deben de ser todos los paquetes del mismo tamao (solo puede cambiar el tamao de paquete entre paquetes diferentes). Pista: Las tramas y Sincronizaciones no poseen ninguna informacin til. Podra dotrselas de informacin. Ejercicio 3: Disear un sistema de comunicacin, usando las libreras proporcionadas en la prctica, que permita enviar Mensajes Infinitos (es decir, que sea independiente de la restriccin impuesta por el tamao de la memoria de datos). Ejercicio 4: Disear un sistema de comunicacin cuya correccin de errores no este basada en la redundancia. Proponer por tanto un sistema de HandShaking, donde el emisor solo tenga que repetir los mensajes que no han llegado bien al receptor, y que lo repita tantas veces como haga falta. Pista: usar dos parejas de emisor de infrarrojo / receptor de infrarrojo, para que cada PIC este dotado de herramientas para leer datos y comunicar.

10 Referencias bibliogrficas
Para el desarrollo de la presente prctica hemos empleado bsicamente el manual de referencia del microcontrolador PIC 16f84 del que disonemos en la pgina de la asignatura y en el laboratorio. As y todo, tambin hemos usado los siguientes documentos encontrados va internet: Datasheet TFMS 5360 (sensor receptor infrarrojos) Tfms.pdf (* Recomendado)

Diodo emisor infrarrojos. Ir97.pdf Tsip520_.pdf Leds.pdf Pginas webs recomendadas.(referente a protocolos estndares): Introduction to IrDA Digital Modulation Schemes (* Recomendado)

También podría gustarte