Sie sind auf Seite 1von 197

Proyecto Final de Carrera

Gestión Basada en Microcontrolador de un


Tablero de Ajedrez Adaptado para Ciegos

MEMORIA

Titulación: Enginyeria Tècnica Industrial en Electrònica Industrial

AUTOR: Carlos Vidal García.


DIRECTOR: José Luís Ramírez Falo.

Septiembre / 2005.
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Índice

Índice

1. Memoria Descriptiva. 4

1.1. Objeto del Proyecto. 5

1.2. Antecedentes. 5

1.3. Posibles Soluciones y Solución Adoptada. 6

1.3.1. Elección del Microcontrolador. 6

1.3.2. Reproducción de Mensajes de Voz. 7

1.3.3. Dispositivo Visualizador 8

1.3.4. Detección de las Piezas. 8

1.3.5. Comunicación con PC. 10

1.3.6. Alimentación. 11

1.4. Descripción General del Equipo 11

1.4.1. Diagrama de Bloques 12

1.4.2. Características Básicas. 13

1.4.3. Aspecto General. 13

1.5. Descripción General de la Solución Adoptada. 14

1.5.1. Microcontrolador PIC16F877 de Microchip. 14

1.5.1.1. Control de Tiempos con el Microcontrolador. 15

1.5.1.2. Conexión de los Botones al Puerto B 16

1.5.1.3. Etapa de Comunicaciones: Módulo USART 17

1.5.2. Tablero Adaptado. 18

1.5.3. Dispositivos ISD2560 (Grabación/Reproducción de 20


Audio).

1.5.4. Módulo LCD de Caracteres de 16x1. 24

1
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Índice

1.5.5. Circuito MAX232 (Comunicación Serie). 25

1.5.6. Alimentación. 26

1.5.6.1. Circuito Detector de Batería Baja. 26

1.6. Resultados. 28

1.7. Conclusiones. 29

2. Memoria de Cálculo. 31

2.1. Inicialización. 32

2.2. Programa Principal. 34

2.3. Rutina de Atención a la Interrupción TMR0. 39

2.4. Reproducción de Mensajes de Audio. 42

2.5. Control del Tablero Adaptado. 48

2.6. Rutinas Auxiliares. 58

3. Planos. 62

3.1. Aspecto del Prototipo L1

3.2. Conexionado Sensores. L2

3.3. Esquema Eléctrico Placa 1. L3

3.4. Esquema Eléctrico Placa 2. L4

3.5. Aspecto de las Máscaras de C.I. 63

3.5.1. Situación de Componentes Placa 1. 63

3.5.2. Máscara de Cara Componentes Placa 1. 63

3.5.3. Máscara de Cara Soldadura Placa 1. 64

3.5.4. Situación de Componentes Placa 2. 64

3.5.5. Máscara de Cara Componentes Placa 2. 65

3.5.6. Máscara de Cara Soldadura Placa 2. 65

2
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Índice

4. Presupuesto. 66

4.1. Mediciones. 67

4.2. Cuadro de Precios. 74

4.3. Aplicación de Precios. 81

4.4. Resumen del Presupuesto del Prototipo. 88

4.5. Presupuesto de Puesta en Fabricación. 89

5. Bibliografía. 95

5.1. Libros Consultados. 96

5.2. Páginas Web Consultadas. 96

6. Anexos.
97
6.1. Manual de Usuario.
98
6.2. Código Fuente para PIC16F877.
104
6.3. Código Fuente del Programa Terminal.
190

3
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1. MEMORIA DESCRIPTIVA

4
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1. Memoria Descriptiva.

1.1. Objeto del Proyecto.


El objeto del presente proyecto es diseñar y montar un prototipo de tablero y
reloj digital de ajedrez para ciegos. Éste se basará en un sistema digital, controlado por
un microcontrolador de ocho bits, que será capaz de gestionar el tiempo en los relojes,
así como de controlar las jugadas realizadas en un tablero adaptado. Este prototipo
realizará las funciones básicas de un reloj de ajedrez convencional como son la
selección de los diferentes modos de funcionamiento y la presentación por pantalla del
tiempo restante. Asímismo también podrá controlar la legalidad de las jugadas
realizadas en el tablero de juego. A parte de estas funciones, también tendrá que
reproducir el tiempo restante para cada jugador y la última jugada realizada en forma de
voz por dos auriculares. Para el caso en que se encuentren dos jugadores invidentes la
reproducción de mensajes deberá de poder ser simultánea y de distinto contenido por
cada uno de los dos auriculares.

1.2. Antecedentes.
En el ajedrez de competición es esencial el uso de un reloj especial, el llamado
reloj de ajedrez. Este reloj sirve para controlar el tiempo de reflexión de los jugadores,
limitándolo para impedir una excesiva duración de la partida. Consta de una doble
esfera que indica el tiempo de juego que le queda a cada jugador. Todas las jugadas
deben realizarse en un periodo de tiempo determinado que no puede sobrepasarse
sopena de perder la partida.

La competición ajedrecística supone un serio handicap para el jugador invidente


que, además de no poder ver las jugadas realizadas sobre el tablero tampoco puede
hacer lo propio con el reloj que controla los tiempos de reflexión, para lo cual necesita
de la ayuda de instrumentos adaptados a sus necesidades.

Existen ya en las competiciones relojes adaptados que comunican el tiempo


restante de forma oral. Sin embargo, este avance aún no se ha hecho extensivo al tablero
físico para facilitar también la comunicación de las jugadas realizadas y, de paso,
controlar la legalidad de las mismas. Normalmente las jugadas deben comunicarse de
forma oral, siendo el jugador invidente quien las reproduce en su tablero. Queda claro,
pues, el carácter innovador de esta propuesta.

En enero del 2002 se presentó en la misma Escola Técnica Superior


d’Enginyeria (ETSE) el proyecto Reloj de ajedrez para ciegos, cuyo objetivo era
diseñar y construir un prototipo de reloj adaptado para invidentes, superior en
prestaciones a los ya existentes y con un menor coste económico. El presente proyecto
supone un paso más añadiendo el prototipo del tablero adaptado, el control de las
jugadas realizadas, el almacenamiento en memoria de las mismas y la mejora de algunas
de las prestaciones del reloj de ajedrez ya mencionado. Del mismo modo, el diseño se
ha realizado procurando reducir al mínimo los costes económicos.

5
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1.3. Posibles Soluciones y Solución Adoptada.


La solución adoptada está basada en un sistema digital con microcontrolador.
Los mensajes de audio se almacenan en dos dispositivos ISD. El microcontrolador
gestiona la reproducción de estos mensajes a petición del usuario, así como el control de
los tiempos de juego que se visualizarán mediante un display. A la vez también
controlará las jugadas realizadas en un tablero de juego, dotado expresamente de
sensores ópticos para la detección de las piezas.

1.3.1. Elección del Microcontrolador.

De entre el extenso listado de fabricantes de microcontroladores podemos


destacar: Intel, Motorola, Toshiba, Atmel y Microchip. Existen, por supuesto, otros
fabricantes pero estos son los más utilizados.

La elección del microcontrolador viene fijada por una serie de condicionantes.


De entrada necesitamos un bus de datos de 8 bits por sus prestaciones en cuanto a
velocidad de ejecución y tamaño de datos, suficientes para nuestro proyecto. Se trata,
además, de un bus extensamente utilizado, por lo que se garantiza su compatibilidad con
otros periféricos y una gran variedad de fabricantes de microcontroladores. Un bus más
grande implicaría un aumento de precio innecesario, mientras que un bus más pequeño
nos reduce los puertos de E/S, las fuentes de interrupción y capacidad de memoria.

También necesitamos garantizar una elevada velocidad de ejecución, necesaria


para el correcto funcionamiento del reloj, las encuestas al tablero y la gestión de
mensajes orales. Por otro lado, la manipulación de diversos periféricos hace necesario
disponer de un gran número de puertos de E/S.

Por todo ello, de las marcas anteriormente mencionadas, nos decantamos por
Microchip. Los llamados microcontroladores PIC ofrecen un gran número de ventajas
tecnológicas, son fáciles de utilizar y disponen de una gran documentación técnica.
También se ha tenido en cuenta la gran disponibilidad en el mercado de estos
dispositivos, así como la posibilidad de utilización en la escuela de un programador para
grabar el dispositivo y del software necesario para la generación y depuración del
código del programa.

Las características generales y comunes de las familias µC de 8 bits de


Microchip son:

• CPU con núcleo RISC.


• Arquitectura Harvard.
• 35 instrucciones.
• Ejecución de instrucciones en un ciclo (salvo las de salto de programa que son
dos ciclos).
• Frecuencias máximas de trabajo de hasta 20 MHz (en función de la familia
elegida).
• 14 bits de tamaño de instrucción.
• 8 bits de tamaño de datos.

6
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

• 15 registros de función especial.


• Stack de 8 niveles de profundidad.
• Modos de direccionamiento directo, indirecto y relativo.
• Address Pipeline.
• Varias fuentes de interrupción. (en función de la familia escogida).
• 1 millón de ciclos de borrado/escritura en EEPROM.
• Retención de datos en EEPROM >40 años.
• Amplia disponibilidad de pins de I/O (nº en función de la familia).
• Power On Reset (POR).
• Power por temporización (PWRT).
• Temporizador de comienzo por Oscilador (OST).
• Temporizador de “perro guardián” o Watchdog (WDT).
• Protección de código.
• Modo SLEEP para ahorro de energía.
• Programación del sistema por puerto serie de dos pines.

De las características anteriores se deduce que el sistema gozará de una alta


velocidad de ejecución. La arquitectura RISC (juego de instrucciones reducido) nos
garantiza una rápida ejecución de las instrucciones.

Como necesitamos un elevado número de puertas de E/S escogemos finalmente


el PIC16F877. A pesar de que el modelo PIC16F874 es un poco más económico, se
diferencia por tener una menor memoria, tanto de código como de datos: 4k y 192
bytes respectivamente, frente a los 8k y 368 bytes de nuestra elección. Como no
podemos asegurar, a priori, el tamaño que ocupará el código nos quedamos con el
16F877, sin perjuicio de poder cambiarlo en una posterior puesta en fabricación, si
realmente fuera posible.

1.3.2 Reproducción de Mensajes de Voz.

En el presente proyecto se ha optado por utilizar dos dispositivos de grabación y


reproducción de voz ISD (Information Storage Device). Estos dispositivos integran toda
la electrónica necesaria para la correcta reproducción de los mensajes de audio en un
solo chip, siendo necesarios solamente algunos componentes pasivos (resistencias y
condensadores) para su correcto funcionamiento.

La alternativa al uso de estos circuitos integrados (C.I.) pasa por implementar


una circuitería basada en una memoria EEPROM, que almacena los mensajes de forma
digital. Son necesarios un amplio número de componentes auxiliares para la
reproducción: conversores D/A, filtros, amplificadores, reloj, FPGA, etc.

En el proyecto anterior, Reloj de Ajedrez para Ciegos, se optó por esta última
opción. El motivo básico es que nuestro sistema debe ser capaz de reproducir dos
mensajes de voz de forma simultánea, sin que estos tengan que ser iguales. Las
características de las ISD no permiten realizar esto directamente, siendo necesario el uso
de dos de estos dispositivos. Esto duplica el coste, de manera que la elección se basó en
criterios económicos. Sin embargo, con el paso de los años, el precio de las ISD se ha
reducido. Actualmente, una implementación con memoria EEPROM y demás

7
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

componentes viene a costar unos 35,50 €, mientras que el coste de una sola ISD es de
unos 18 €. Si usamos dos de estos dispositivos nos situamos en unos 36 €,
prácticamente igual, por lo que el criterio de selección pasa ser cualitativo.

Los circuitos ISD presentan un fácil uso, grabado y reproducción en un mismo


C.I., alta calidad de reproducción, totalmente direccionable para grabar múltiples
mensajes y posibilidad de concatenación de mensajes con 100 ms de precisión. Además,
su capacidad de integración se transforma en un considerable ahorro de espacio en
placa.

1.3.3. Dispositivo Visualizador

Aunque las características fundamentales de nuestro prototipo están orientadas al


uso por parte de usuarios invidentes, también se prevé su utilización por usuarios sin
discapacidad visual. Para mostrar los tiempos de juego se utilizará un visualizador
(display) LCD de caracteres.

Existen otras opciones a tener en cuenta para esta elección, como son:

• Display tipo LED de siete segmentos.


• Display LCD de siete segmentos.

Los display basados en diodos emisores de luz (LED) presentan un consumo


mayor que el de los display de cristal líquido (LCD), del orden de 100 veces. Para una
posible alimentación mediante pilas sus características de consumo no suponen, pues,
una buena elección.

Los display LCD de siete segmentos se ajustán mejor a nuestras necesidades de


consumo. Sin embargo, es difícil encontrar en el mercado un modelo que presente 16
dígitos a pequeña escala y a un precio razonable. Su uso sería más adecuado para una
puesta en fabricación a gran escala, y no para la construcción de un prototipo. Además,
para el correcto funcionamiento de estos visualizadores se necesita cierta lógica
adicional (decodificadores, puertas de paso, etc.).

Las necesidades económicas y de consumo, así como el ahorro de espacio en


placa hacen que la elección más adecuada para nuestro prototipo sea un display LCD de
caracteres.

1.3.4. Detección de las Piezas.

Los tableros de ajedrez adaptados para invidentes tienen algunas características


que los diferencian de los tableros normales. Al no poder ver el tablero, los jugadores
necesitan palparlo para localizar las piezas. En un tablero normal esto no sería posible
por dos motivos:

• Al no estar las piezas sujetas al tablero, éstas podrían ser derribadas o


movidas involuntariamente al intentar tocarlas.
• No habría forma de distinguir el color de las piezas ni el de las casillas.

8
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Esto último se soluciona con un ligero relieve de las casillas negras sobre las
blancas, que lo hacen inconfundible al tacto. Asimismo, las piezas negras están dotadas
de una pequeña cabeza de alfiler metálico en su parte superior para distinguirlas de las
blancas.

La sujeción de las piezas viene solventada por una pequeña espiga que se situa
en la peana (ver figura 1). Si se práctica un agujero en el centro de cada casilla, esta
espiga puede introducirse, de manera que la pieza queda fijada al tablero y no puede
moverse o ser derribada, si no es expresamente.

PIEZA

TABLERO

ESPIGA
Figura 1. Sujeción de las piezas al tablero.

Esta última característica nos permitirá realizar el sensado del tablero. Para
poder determinar la situación de las piezas será necesario situar un sensor en cada
casilla del tablero. Un tablero de ajedrez contiene 64 casillas, de modo que hay que
buscar un sensor económico, fiable y de dimensiones reducidas. La solución adoptada
en el presente proyecto pasa por utilizar un sensor óptico (ver figura 2), modelo
OPB620. Estos pequeños sensores están dotados de un diodo emisor de luz y un
fototransistor NPN, situados en oposición. Cuando alimentamos el diodo, este realiza
una emisión que capta el transistor, situándose en zona de conducción. El transistor no
podrá captar la emisión si esta no existe o hay un obstáculo en medio que lo impida.

Figura 2. Sensores ópticos.

9
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Si situamos cada sensor en un agujero del tablero, de forma que se detecte la


situación de la espiga (ver figura 3) podremos saber si tenemos una pieza en esa casilla
o no. Sencillamente, al alimentar el diodo el transistor entrará en conducción
produciéndose un ‘1’ lógico ( no hay pieza ). En caso contrario, la misma espiga
interrumpe el paso de luz produciéndose un ‘0’ ( sí hay pieza ).

PIEZA

TABLERO

SENSOR
ESPIGA

Figura 3. Situación del sensor en el tablero.

Otra solución podría ser utilizar dos contactos flexibles y esmalte conductor en
la base de la peana, situando los cables de forma que se haga contacto al introducirse la
pieza en el ajujero. Esta solución, muy económica, es extremadamente poco fiable ya
que los cables pueden sufrir desgaste debido a un uso continuado. Los sensores ópticos
tienen la ventaja de no sufrir desgaste, ya que no se necesita un contacto físico con la
pieza para su detección.

Otros sensores como los de contacto o los magnéticos son más costosos y se
hace difícil integrarlos en la estructura del tablero.

1.3.5. Comunicación con PC.

Mediante sucesivos muestreos del tablero, el microcontrolador será capaz de


detectar los cambios en la posición de juego y la legalidad de los mismos. Cuando las
jugadas realizadas sean correctas, éstas se almacenarán en memoria, obteniendo, a la
postre, el desarrollo completo de la partida. Para que dichas jugadas almacenadas
puedan ser consultadas se ha optado por dotar al equipo de un sistema de comunicación
con un PC externo. Llegado el momento, el microcontrolador podrá transmitir a un
ordenador las jugadas realizadas vía puerto serie (RS232). Para dicha transmisión se
utilizará un C.I. MAX232. Este integrado ha sido especialmente creado para este tipo de
comunicaciones. Su función básica es la de adapatar los niveles de tensión de nuestro
sistema (0...5 V) a los utilizados por un puerto serie estándar (-15...-3 V, 3..15 V).

La inclusión de esta función está plenamente justificada. En las partidas de


competición, a menudo, surgen discrepancias entre los jugadores por errores en la
anotación de las jugadas o similares. En estos casos es necesaria la intervención de un
árbitro. Para facilitar esta tarea se podrán volcar las jugadas almacenadas en un
ordenador para su consulta. Así se podrá comprobar el curso correcto de la partida.

10
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1.3.6. Alimentación.

Teniendo en cuenta que nuestro sistema necesitará una alimentación continua


(DC), de 0 a 5 V podemos optar entre las siguientes soluciones:

• Conexión a la red eléctrica via transformador, rectificador, filtros,


estabilizador, etc.
• Uso de baterías recargables.
• Uso de pilas.

La primera solución es del todo incompatible con las características de


portabilidad que necesita nuestro sistema. No en todos los sitios se dispondrá de una
conexión eléctrica fácilmente accesible. Las baterías suponen un coste económico
imortante y cargarían excesivamente el prototipo por su peso.

Por todo esto se opta por la solución más sencilla: alimentación mediante pilas.
Teniendo en cuenta que el valor del voltaje de la mayoría de pilas convencionales es
múltiplo de 1,5 V, y que nuestro sistema se tiene que alimentar a 5 V, se optará por
utilizar una única pila de 9 V con un estabilizador del tipo LM7805 a su salida para
asegurar los 5 V requeridos.

1.4. Descripción General del Equipo


El equipo está formado por cinco grandes bloques. Algunos uno de estos bloques
contienen una serie de etapas o subcircuitos, formando un total siete de etapas:

Módulo de control:

• Interfase con los usuarios: pulsadores y conmutador de partida.


• Microcontrolador: PIC 16F877.

Módulo de audio:

• Almacenamiento y reproducción de los mensajes de audio: 2 x C.I. ISD2560.

Módulo de visualización:

• Display LCD 16x1 caracteres.

Módulo de tablero:

• Decodificación de direcciones del microcontrolador: decodificador


74HC4514N.
• Sensado de las casillas: sensores ópticos OPB620.

Módulo de comunicación serie:

• Comunicación con PC via puerto serie (RS-232): C.I. MAX232.

11
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1.4.1. Diagrama de Bloques

PULSADORES

DISPLAY LCD 16X1


MICRO
PIC16F877

DECODIFICADOR
ISD2560 ISD2560

SENSORES
TABLERO

COMUNICACIÓN SERIE

PC

12
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1.4.2. Características Básicas.

El aparato está diseñado para ser utilizado por dos usuarios en partidas de
competición de ajedrez. Estos dos usuarios podrán ajustar las opciones del tipo y tiempo
de partida y preparar el reloj para jugar. Asímismo, se podrá conectar el tablero
adaptado al reloj, realizándose así el control de las jugadas realizadas. Durante la partida
el reloj tendrá que mostrar por un display el tiempo restante y, mientras hace esto,
tendrá que reproducir, a petición de cualquiera de los dos usuarios o de los dos a la vez,
el tiempo restante de uno u otro jugador o la última jugada realizada en el tablero por el
auricular del usuario que ha hecho dicha petición. Aunque no es necesario que el
aparato cuente con una gran calidad de sonido los mensajes se oirán de una manera
clara e inteligible. Si el tablero está conectado las jugadas realizadas se almacenarán en
la memoria del microcontrolador, siendo posible su posterior volcado en un PC externo.

Basándonos en esto el prototipo dispone de:

• Un display LCD 16x1 (16 caracteres, 1 fila).


• Dos auriculares.
• Seis pulsadores para los usuarios, con funciones de ajuste de los parámetros
de la partida , petición de mensaje de audio o envío de la partida almacenada
en memoria a PC externo, dependiendo de si la partida ha empezado o no.
• Dos pulsadores para poner en marcha un temporizador o el otro.
• Un interruptor de encendido/apagado.
• Un tablero especialmente adaptado para poder desarrollar la partida.
• Dos LED’s: uno para avisar que se ha cometido algun error en las jugadas
realizadas y otro para alertar que la batería está baja.

1.4.3. Aspecto General.

El prototipo presenta el siguiente aspecto:

CONECTOR AURICULAR
INTERRUPTOR

LED BATERIA BAJA LED ERROR

PETICION AUDIO
JUGADAS

SET CONECTOR TABLERO


CONECTOR TABLERO NEXT

UP MODE

CONECTOR PC

(a)

CONMUTADOR PARTIDA

13
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

BOTONES

DISPLAY

(b)

Figura 4. Aspecto del reloj de ajedrez para ciegos. (a) Vista superior. (b)Vista frontal.

CONECTOR RELOJ

Figura 5. Aspecto del tablero adaptado.

1.5. Descripción General de la Solución Adoptada.


1.5.1. Microcontrolador PIC16F877 de Microchip.

El elemento que controla todo el sistema es un microcontrolador PIC16F877.


Este integrado de la familia microchip es un µC de ocho bits que cuenta con una
memoria de programa tipo FLASH (8 k x 14 word, word de 14 bits) y una de datos
RAM de 368 bytes, ambas internas, así como también una memoria EEPROM de datos
interna de 256 bytes. Puede tener hasta 14 fuentes de interrupción, de las cuáles sólo
vamos a utilizar una: la que acontece cuando se desborda uno de sus tres timers.
También cuenta con cinco puertos de entrada/salida: el puerto A, de 6 bits, los puertos
B, C y D, de 8 bits y el puerto E, de sólo 3 bits.

14
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Los pines de los cinco puertos pueden ser configurados como pines de entrada o
de salida, cada uno independientemente de los demás. La configuración de los pines que
hemos utilizado para nuestra aplicación es la siguiente:

Puerto A (RA [5..0]):

• RA [5] : Salida. Señal de Error. Enciende un led cuando se detecta un


movimiento erróneo durante la partida.

• RA [4,3] : No utilizado

• RA [2..0] : Salidas. Corresponden a las señales Ent (2), habilitación del


tablero adaptado; R/W (1) y RS (0), que sirven para controlar el display.

Puerto B (RB [7..0]):

• RB [7..0] : Entradas. Utilizaremos estas líneas para los 8 pulsadores del reloj.

Puerto C (RC [7..0]):

• RC [6..4,1,0] : Salidas. Por estos pines mandamos la señal Tx (6), que es la


encargada de realizar la transmisión de datos hacia el PC externo. Tambien
se mandan las señales PD (5,4) y P/R! (1,0) de control de los dos ISD.

• RC [7,3..2] : Entradas. Por aquí nos llegan las señales EOM! de fin de
mensaje de los dos ISD (3,2) y la señal de recepción Rx (7), que forma parte
del módulo de comunicaciones.

Puerto D (RD [7..0]):

• RD [7..0] : Salidas. Estos 8 pines se utilizan como bus de datos de 8 bits para
el display, los ISD y el tablero. Para el caso del tablero los 4 bits de más peso
serán entradas, y salidas los 4 restantes.

Puerto E (RE [2..0]):

• RE [2..0] : Salidas. Corresponden a las señales de habilitación del los dos


ISD (2,1) y del display (0).

1.5.1.1. Control de Tiempos con el Mmicrocontrolador.

Como ya hemos apuntado sólo utilizaremos una fuente de interrupción: la que


acontece cuando se desborda el Timer0, que nos servirá para controlar el tiempo de
juego. El Timer es un contador de 8 bits (0-255) que disminuye su cuenta en 1 unidad
cada 8 ciclos de instrucción. Cada instrucción tarda en ejecutarse 4 ciclos de reloj. De

15
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

este modo, si cargamos el Timer 0 con el valor máximo (255) y conectamos al


microcontrolador un reloj de 4 MHz:

4 µs
= 1µs ⋅ 256 = 256 µs (1)
4 ciclos reloj

Por otro lado, los registros del microcontrolador nos permiten seleccionar
distintos preescalados para el Timer0. El preescalado mínimo es 1:2. Nos queda:

256µs ⋅ 2 = 512 µs (2)

Nuestro Timer tardará 512 microsegundos en desbordarse e interrumpir al


microcontrolador. En el ajedrez de competición el tiempo de reflexión se muestra
segundo a segundo. Para un correcto control del tiempo de juego será suficiente con
mostrar segundo a segundo. De este modo, cada vez que salte una interrupción
ejecutaremos un código que se encargue de decrementar un contador. Cuando este
contador se desborde habrá pasado 1 segundo de tiempo. El valor a cargar en nuestro
contador será:

x ⋅ 512µs = 1000000 µs ⇒ x = 1953.13 (3)

Los registros de memoria del microcontrolador almacenan datos de 8 bits. Como


sólo podemos almacenar un valor máximo de 255, tendremos que dividir el valor
anterior en dos registros. Esos dos valores pueden ser 217·9 = 1953. Este valor no es
exactamente el que hemos calculado anteriormente. Aún así, la precisión de nuestro
reloj prácticamente no se verá afectada:

1953 ⋅ 512 µs = 0.999936s (4)

Esto nos da una precisión de:

Precisión = (1 − 0.999936) ⋅ 100 = 0.0064% (5)

En una partida de 2 horas, el error cometido sería de:

Error = 7200s ⋅ 0.0064% = 0.46 s (6)

Se trata de un error perfectamente admisible para nuestra aplicación.

1.5.1.2. Conexión de los Botones al Puerto B

Los seis botones de usuario, así como el conmutador de partida, van conectados
a los patas [0..7] del puerto B. Este puerto cuenta con una resistencia de pull-up en cada
una de sus patas. Así que para distinguir si un botón está o no pulsado basta con
conectarlo tal y como se puede ver en la siguiente figura.

16
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Figura 6. Conexión de un botón al puerto B del PIC.

De este modo, podremos saber si un botón está pulsado al detectar un 0 en la


correspondiente pata del puerto B del PIC.

1.5.1.3. Etapa de Comunicaciones: Módulo USART

Los microcontroladores PIC16F87x contienen un módulo de comunicaciones


serie de tipo síncrono y asíncrono: éste es el módulo USART (Universal Synchronous
Asynchronous Receiver Transmitter). El USART puede funcionar como un sistema de
comunicación bidireccional asíncrono, adáptandose a multitud de periféricos y
dispositivos que transfieren información de esta forma. Dadas nuestras necesidades de
comunicar el microcontrolador con un PC externo, éste módulo nos será útil para
realizar esta labor.

La transferencia se realiza mediante las señales: Tx (transmisión) y Rx


(recepción). Dichas señales se encuentran en las líneas RC6 y RC7 del
microcontrolador, respectivamente. En el protocolo de comunicación serie cada palabra
de información o dato se envía independientemente de los demás. Las palabras suelen
constar de 8 ó 9 bits y van precedidas por un bit de START y se finalizan con un bit de
STOP (ver figura ). Los bits se transfieren a una frecuencia fija y normalizada.

17
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Figura 7. Palabra de 8 bits.

La velocidad de transmisión en baudios (bits por segundo) a la que se realiza la


transferencia debe ser un valor normalizado. En nuestro caso utilizaremos una velocidad
de 9600 baudios. Para generarla, el USART dispone de un generador de frecuencia en
baudios, el BRG. Su valor es controlado por el contenido grabado en el registro
SPBRG.

Para transmitir un dato tenemos que depositarlo por software en el registro


TXREG. A continuación se traspasa al registro TSR, que va sacando los bits
secuencialmentea y a la frecuencia establecida. Él mismo también se encarga de poner
los bits de START y STOP al inicio y al final del byte a transferir. El primer bit que sale
es el de menos peso.
La transferencia empieza en cuanto se haya transmitido el bit de STOP del dato anterior.

1.5.2. Tablero Adaptado.

Como hemos comentado anteriormente utilizaremos sensores ópticos OPB620


para la detección de las piezas. Estos sensores están formados por un diodo emisor de
luz y un fototransistor tipo NPN (ver figura 9). Cuando se alimenta el diodo, éste emite
luz directamente hacia el transistor. Si el transistor recibe correctamente la emisión,
entrará en conducción, abriendo el camino hacia masa.

Figura 8. polarizacion del sensor OPB620

18
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Para determinar si existe o no una pieza situada en la casilla sólo nos interesan
dos estados de trabajo del transistor: no conducción (casilla ocupada, Vout = 5 V) y
conducción (casilla libre, Vout = 0 V). La elección de las resistencias de polarización
debe permitirnos, por un lado, la emisión de suficiente luz en el diodo para que el
transistor entre en conducción, y por otro, limitar la corriente en R2 para evitar un
consumo excesivo. Con los ensayos en laboratorio hemos podido determinar que los
valores que más se ajustan a estas condiciones son R1 = 2.2kΩ y R2 = 220kΩ
(conducción Vout = 5 V , I = 6 mA ; no conduccción Vout = 0, I = 0 mA).

El siguiente paso es ver como interconectar el conjunto de 64 sensores y como


conectarlos al microcontrolador. La forma más fácil de solventar el problema es tratar
el tablero como lo haríamos con una matriz 8x8 (ver figura ).

DECODIFICADOR 3:8 TABLERO (matriz 8x8)

O0
O1
SELECCIÓN

A0 O2
A1 O3
A2 O4
O5
E O6
O7

8 LINEAS DE INFORMACIÓN

Figura 9. tratamiento del tablero, solución 1.

El microcontrolador envía al decodificador sucesivamente las direcciones de


acceso. Esto supone alimentar una fila de 8 sensores cada vez. Cuando esto sucede se
obtiene la respuesta de los fototransistores en forma de 1 byte. De esta forma bastaría
con realizar 8 encuestas, una por cada fila, y almacenar los 8 bytes de respuesta leidos
por el microcontrolador. El inconveniente de esta solución es el elevado número de
líneas necesarias para su implementación. Se tendría que utilizar 3 lineas para la
decodificación, 8 para la lectura y una para el ‘enable’ del decodificador, haciendo un
total de 12. Esto son demasiadas lineas, sobretodo si tenemos en cuenta que nuestro
microcontrolador tiene un número de puertos E/S limitado y también hay que controlar
otros dispositivos. Por todo ello se ha optado por reordenar la matriz de sensores 8x8
por una 16x4 y utilizar un decodificador de 4 bits (ver figura 11).

19
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

DECODIFICADOR 4:16 TABLERO (matriz 16x4)

O0
O1
O2
O3
O4
A0 O5

SELECCIÓN
A1 O6
A2 O7
A3 O8
O9
O 10
E
O 11
O 12
O 13
O 14
O 15

4 LINEAS DE INFORMACIÓN

Figura 10. tratamiento del tablero, solución 2.

Así sólo son necesarias 9 líneas: 4 de decodificación, 4 de lectura y 1 enable. Las


8 lineas de decodificación y lectura se pueden compartir con otros dispositivos (ver
apartado 1.5.1.). Los inconvenientes de esta solución no son muy grandes. Existen en el
mercado decodificadores como el que necesitamos y el incremento de coste es mínimo.
Habrá que realizar 16 encuestas para poder muestrear todo el tablero (el doble que
antes), pero la velocidad de trabajo del microcontrolacor hace que esto no sea un
problema. El formato de la respuesta del tablero (4 bits de lectura cada vez) nos obligará
a complicar un poco el software, pero se puede realizar perfectamente. Por todo esto
hemos optado por la segunda solución, como más adecuada a nuestros propósitos de
economía.

1.5.3. Dispositivos ISD2560 (Grabación/Reproducción de Audio).

Se trata de una memoria ISD de la marca Winbond.

En la figura podemos ver el diagrama bloques del ISD2560; en el mismo se


aprecia que contiene toda la electrónica requerida para grabar y reproducir sonido.

Figura 11. Diagrama de bloques del ISD2560.

20
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

El dispositivo CMOS incluye oscilador interno, preamplificador de micrófono,


control automático de ganancia, filtros para el mejoramiento de la señal
(antialiasing,..etc), amplificador para altavoz y una matriz de alta densidad para el
almacenamiento multinivel. Así mismo, también resulta idóneo para su funcionamiento
gobernado bajo microcontrolador, permitiendo alcanzar complejos direccionamientos y
mensajes.

Las muestras se almacenan en una memoria no volátil de 480 Kb multinivel, la


cual permite una grabación máxima, haciendo un muestreo a 8KHz, de 60 segundos. Es
interesante señalar que los datos no se almacenan en sistema digital binario, sino con
uno de 256 niveles diferentes en cada célula de memoria. Esto nos da una densidad de
almacenamiento considerablemente mayor que la que es posible alcanzar con tecnología
digital binaria y una alta calidad de grabación.

Las entradas A0-A9 se utilizan para direccionar la memoria y determinar que


mensaje vamos a reproducir. Tambien podemos determinar si vamos a reproducir o a
grabar un mensaje (P/R), habilitar el dispositivo (CE!), detectar el fin de la reproducción
de un mensaje (EOM!) y poner el dispositivo en modo de bajo consumo (PD).

El conexionado del dispositivo que utilizamos es el recomendado por el


fabricante y se puede consultar en su manual (ver apartado 5).

Para poder reproducir los mensajes de tiempo restante se han grabado todos los
números del 1 al 20 y los números 30, 40 y 50. Para poder enlazar varios mensajes y
formar la hora completa también se han grabado los mensajes “veinti”, “treinta y”,
“cuarenta y”, “cincuenta y”, así como las unidades temporales horas, minutos y
segundos. De esta manera podemos formar todos las horas posibles por composición de
varios mensajes. Por ejemplo, para reproducir oralmente 52 minutos se enlazan los
mensajes “cincuenta y”, “dos”, “minutos”.

Para la reproducción oral de las jugadas se ha utilizado el sistema algebraico


extendido. Dicho sistema se basa en la definición de un sistema de coordenadas que
podemos ver en la figura 14. Su principal ventaja radica en que, además de ser fácil de
aprender, es uno de los más utilizados.

Figura 12. Sistema de coordenadas algebraico.

21
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

La jugada completa se define reproduciendo la pieza a mover, la coordenada de


origen (letra y número) y la coordenada de destino. Por ejemplo, en la posición de la
figura , si las blancas movieran su caballo g1 a la casilla f3 la jugada reproducida sería
“caballo g1-f3”. El avance del peón e2 dos casillas correspondería a “peón e2-e4”. Para
poder realizar la reproducción oral sólo será necesario grabar los mensajes
correspondientes a las letras (de la “a” a la “h”), ya que los números los tenemos de
antes, y las piezas “peón”, “torre”, “caballo”, “ alfil”, “dama” y “rey”.

También se ha considerado conveniente grabar el mensaje “jugada ilegal”, para


aquellas situaciones en las que un jugador realice un movimiento no permitido.

DIRECCIONAMIENTO ISD2560

MENSAJE A9-A0 DIRECCION DECIMAL


Un 0000000000 0
Dos 0000001010 10
Tres 0000010100 20
Cuatro 0000011110 30
Cinco 0000101000 40
Seis 0000110010 50
Siete 0000111100 60
Ocho 0001000110 70
Nueve 0001010000 80
Diez 0001011010 90
Once 0001100100 100
Doce 0001101110 110
Trece 0001111000 120
Catorce 0010000010 130
Quince 0010001100 140
Dieciseis 0010010110 150
Diecisiete 0010100000 160
Dieciocho 0010101010 170
Diecinueve 0010110100 180
Veinte 0010111110 190
Treinta 0011001000 200
Cuarenta 0011010010 210
Cincuenta 0011011100 220
Veinti 0011100110 230
Treinta y 0011110000 240
Cuarenta y 0011111010 250
Cincuenta y 0100000100 260
Una 0100001110 270
Hora 0100011000 280
Horas 0100100010 290
Minuto 0100101100 300
Minutos 0100110110 310
Segundos 0101000000 320

22
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

A 0101001010 330
B 0101010000 336
C 0101010110 342
D 0101011100 348
E 0101100010 354
F 0101101000 360
G 0101101110 366
H 0101110100 372
Torre 0101111010 378
Caballo 0110000110 390
Alfil 0110010010 402
Dama 0110011110 414
Rey 0110101010 426
Jugada Ilegal 0110110110 438
Uno 0111001010 458
Enroque 0111010100 468
Tabla 1. Direcciones de los mensajes almacenados en las ISD2560.

Se observará que los bits A9 y A0 están siempre a nivel 0. Esto es debido a que
para direccionar todos los mensajes sólo son necesarias ocho líneas. El
direccionamiento completo (utilizando las diez líneas) de los dispositivos ISD nos da
una resolución de 0.1 segundos. Sin embargo, para nuestra aplicación no es necesaria tal
resolución; nos basta con una de 0.2 segundos (como puede observarse en la tabla, todas
las direcciones de inicio son números pares). Podemos obtener dicha resolución
utilizando las líneas A1-A9, y dejando A0 conectada a masa. Por otro lado, el bit A9
sólo se utiliza para direccionamientos a partir de los 52.1 segundos de grabación. Puesto
que no hemos alcanzado dicho valor, también conectamos esta línea a masa, quedando
conectadas al microcontrolador A1-A8.

Una vez hecho esto, sólo se tendrá que respetar la secuencia de comandos para
realizar la reproducción de los mensajes. En la siguiente figura podemos ver el diagrama
temporal de dicha secuencia.

Figura 13. Secuencia de comandos para reproducción en un ISD2560.

23
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Siguiendo esta secuencia y teniendo en cuenta los tiempos mínimos se consigue


enlazar y reproducir correctamente los mensajes orales grabados en las ISD.

1.5.4. Módulo LCD de Caracteres de 16x1.

Se trata de un módulo LCD (cristal líquido) de 16 caracteres por 1 línea


compatible con la familia Hitachi LM016L.

A continuación podemos ver el diagrama de bloques del display y la función de


cada uno de sus pines.

Figura 14. Diagrama de bloques del display.

Tabla 2. Significado de los pines del display.

Si nos fijamos en el pin 6 podemos observar que se trata de una señal de


habilitación del módulo. Dicha señal no desconecta el display de la alimentación;
simplemente hace caso omiso de todo lo que hay en el bus de datos. De esta forma se
pueden compartir las lineas del bus de datos del display con las de otros módulos. En
nuestro caso dichas líneas se comparten con los dispositivos ISD y el tablero adaptado
(ver apartado 1.5.1.).

Otros pines de interés son los que corresponden a las señales RS y R/W. La
primera se refiere al contenido de lo que pasamos por el bus de datos. Si su valor es 1 se
trata de un dato, mientras que si su valor es 0 se trata de una instrucción. La señal R/W
identifica si la operación a realizar es de lectura (1) o de escritura (0). Para nuestra
aplicación esta señal estará siempre a 0.

24
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Por todo esto lo que se hará es mantener la señal de habilitación a 0 mientras no


se quiera operar con el display. Cuando sea necesario hacerlo se pondrá el
correspondiente valor en el puerto D (bus de datos del LCD), se seleccionará el valor de
la señal RS (según sean datos o instrucciones) y seguidamente se pondrá la señal de
enable a 1. Si se trata de instrucciones habrá que respetar un tiempo de ejecución antes
de quitar la señal de habilitación.

En nuestro diseño las características utilizadas son:

• Bus de datos de ocho bits.


• Matriz para el carácter de 5x10 puntos.
• Autoincremento de la posición del cursor.

Cada vez que tengamos que actualizar un dígito del reloj se borrará la pantalla y
a continuación se volverán a escribir todos los caracteres necesarios. Debido a la
velocidad de ejecución del programa en el microcontrolador apenas se apreciarán
parpadeos.

1.5.5. Circuito MAX232 (Comunicación Serie).

Para podernos comunicar con el PC externo utilizaremos la norma RS-232, que


es una de las más extendidas. Una de sus características es la de los rangos de tensión
que utiliza para representar los niveles lógicos. El nivel alto se representa con una
tensión comprendida entre –3 y –15 V, mientras que el nivel bajo utiliza el rango de +3
a +15 V. Dado que nuestro sistema, y en particular el microcontrolador, trabaja a
niveles de tensión comprendidos entre 0 y 5 V se hace necesaria la inclusión de una
etapa para adaptarse a la norma. Ésto se consigue mediante la utilización de un circuito
integrado MAX232. En la siguiente figura podemos ver cómo conectarlo para conseguir
nuestros propósitos.

Figura 15. Conexión del C. I. MAX232 a un conector DB25 estándar.

Como podemos observar, el MAX232 dispone de dos canales de entrada para


niveles TTL, que son el T1IN y el T2IN, con sus correspondientes salidas: T1OUT y
T2OUT. También posee dos canales de entrada para niveles RS-232 R1IN y R2IN y sus
correspondientes salidas, R1OUT y R2OUT. Se alimenta con +5 V.

25
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Para nuestra aplicación sólo será necesario el uso de un canal. El


microcontrolador transmite información a través de la linea T1IN, a nivel TTL, y
T1OUT, a nivel RS-232. Del mismo modo, el PC puede comunicarse con el
microcontrolador por las lineas R1IN y R1OUT.

1.5.6. Alimentación.

El sistema de alimentación de nuestro circuito está formado por un conjunto de


pila de 9 V y un regulador de tensión del tipo LM7805. La utilización de este tipo de
regulador supone una serie de ventajas, como son:

• Protección contra cortocircuitos


• Protección contra sobrecargas
• Regulación de linea del orden de 3 mV.
• Regulación de carga del orden de 10 mV.
• Corriente de reposo máxima de 8 mA.
• Resistencia de salida de 8mA.

Como se puede apreciar en la figura se trata de un dispositivo de tres terminales.


Uno es el de entrada de la tensión no regulada, otro es el de salida y el tercero es un
terminal común a la entrada y a la salida que suele estar conectado a tierra.

Nuestro regulador se encargará de estabilizar la tensión a su salida a un valor de


5 V. Para ello la tensión de entrada debe estar comprendida entre los 7 y los 20 V.
Asímismo requerirá una tensión de entrada mínima de 7.5 V para asegurar una
regulación de línea de 3 mV. Al utilizar una pila de 9 V en la entrada se asegura la
alimentación de 5 V a la salida del regulador.

El fabricante recomienda situar a la entrada y a la salida del regulador un


condensador para eliminar posibles rizados y ruidos de alta frecuencia. De este modo la
etapa de alimentación nos queda de esta forma:

Figura 16. Fuente de alimentación.

1.5.6.1. Circuito Detector de Batería Baja.

En el diseño de nuestro prototipo se ha considerado conveniente implementar


este pequeño circuito detector de batería baja, que nos permitirá detectar cuándo la pila
se está agotando.

26
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

Figura 17. Circuito detector de batería baja.

Se trata de un comparador con histéresis, que compara una tensión de referencia


(Vref) de 4.7 V, mantenida mediante un diodo Zener polarizado inversamente, con la
tensión de salida del regulador de tensión (LM7805). Como hemos mencionado
anteriormente, este regulador permite una tensión de entrada comprendida entre los 7 y
los 20 V. Cuando esta situación se cumple, la tensión teórica en su pata de salida es de 5
V (puede oscilar entre los 4.75 V y los 5.25 V : Regulación de línea).

Cuando la tensión a la salida del integrado LM7805 es inferior a 4.7 V, es que la


tensión de la pila de 9 V es inferior a 7 V. En esta situación, el amplificador operacional
se saturará, poniendo su salida a estado lógico 1 (aprox. 5V).

La función de transferencia del circuito es la que se muestra en la Figura

Figura 18. Función de transferencia del circuito detector de batería baja.

Analizando el circuito se deducen las siguientes ecuaciones:

R2
VL = Vref
R1 + R 2
(7)
R1 R2
VH = Vref + Vref
R1 + R 2 R1 + R 2

27
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

De donde se obtienen los valores para nuestro circuito:

19
VL = 4.7 = 4.465 V
1 + 19
(8)
1 19
VH = 4.7 + 4.7 = 4.7 V
1 + 19 1 + 19

Situaremos un LED a la salida del circuito que se encenderá cuando se la tensión


suministrada disminuya por debajo del límite. El objetivo es dar aviso al árbitro de la
competición de esta incidencia.

1.6. Resultados.
Una vez montado el prototipo y puesto totalmente en marcha los resultados
obtenidos son los siguientes:

Reloj de ajedrez completamente funcional con conmutación de tiempos y


posibilidad de parada en cualquier momento de la partida. Selección de siete modos de
funcionamiento que incluyen modos de tiempo usados en competición oficial.
Resolución de 0.5 ms (512 µs). Se muestra por pantalla información con los tiempos de
cada jugador (horas.minutos o minutos.segundos) así como el reloj que corre en cada
momento.

El módulo de audio es capaz de reproducir todos los tiempos posibles del reloj.
Los mensajes orales son claramente inteligibles. Posibilidad de reproducción simultánea
por dos auriculares con mensajes de distinto contenido. Modo automático cuando queda
menos de 1 minuto para alguno de los jugadores: se reproducen mensajes temporales sin
necesidad de pulsar el botón correspondiente. Reproducción de todas las jugadas legales
realizadas en el tablero en el formato pieza.coordenada origen.coordenada destino.
Control del volumen por medio de potenciómetro. Reproduce el mensaje “jugada ilegal”
cuando la jugada realizada en el tablero es incorrecta.

El tablero sensorial reconoce todas las jugadas legales posibles excepto la captura
al paso y la coronación a pieza distinta de la dama. Se realizan dos encuestas cada
segundo. La jugadas correctas se almacenan en memoria RAM del microcontrolador. El
espacio reservado para ello es de 192 bytes. Cada jugada completa ocupa 4 bytes (2
bytes semijugada), por lo que la memoria es capaz de almacenar 48 jugadas (96
semijugadas). Cuando se deteca un error en el tablero se enciende un LED de aviso en
el reloj, apagándose el mismo al salir del error.

Las jugadas almacenadas en memoria se pueden transmitir a PC externo via


conexión a puerto serie COM1 utilizando un cable con conectores DB9. Se realiza a una
velocidad de 9600 baud/s. Para la transmisión es necesario instalar en el PC el programa
Terminal, creado expresamente para esta aplicación. La transferencia se ha probado en
ordenador con sistema operativo Windows 98. El mismo programa, una vez recibida la
información, genera un archivo PGN con el listado de las jugadas que se han realizado
durante la partida. La anotación de las mismas se realiza en sistema algebraico
extendido.

28
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

1.7. Conclusiones.
A la vista de los resultados podemos concluir que, en general, se han alcanzado
los objetivos propuestos. El prototipo realiza correctamente las funciones de reloj de
ajedrez para ciegos y gestión de un tablero adaptado, así como algunas tareas
adicionales como el almacenamiento de jugadas en memoria y su transferencia a PC.
No obstante, todo se puede mejorar.

El reloj de ajedrez cuenta con una resolución más que suficiente para el uso al
que está destinado. No sufre retrasos importantes (ver apartado 1.5.1.1.). La
información que muestra por pantalla cubre las necesidades del jugador durante la
partida. Los modos de tiempo que tiene implementados son los más utilizados en
competición oficial e incluso en partidas amistosas a nivel de club. Por todo ello
consideramos que el reloj de ajedrez implementado es apto para los usos antes
mencionados. Aún así, podrían introducirsele algunas mejoras interesantes, como
aumentar el número de modos de funcionamiento, implementar configuración manual
del tiempo, aumentar la información mostrada por pantalla o contar las jugadas
realizadas por cada jugador (esto último muy interesante en las partidas con caída de
bandera). De cara a una posible puesta en venta habría que plantearse seriamente la
posibilidad de cambiar el display LCD por uno de siete segmentos. Para un prototipo el
display LCD es lo ideal, pero tal vez (esto ya dependería además de los proveedores)
podría salir más a cuenta rediseñar el sistema para un display menos práctico pero
posiblemente más económico para grandes tiradas.

Los mensajes orales reproducidos tienen una calidad aceptable puesto que son
claramente inteligibles y eso es suficiente para su uso. Se aprecia en la reproducción
una pequeña pausa entre mensajes. Esto es debido a que las encuestas del tablero
introducen un pequeño retardo, de unos 160ms cada encuesta. Esta pausa no supone un
grave problema, aunque podría mejorarse en futuras versiones. Una opción interesante
sería implementar una reproducción multilingüe. Se trataría de aumentar (prácticamente
doblar) la capacidad de almacenamiento de los ISD y programar el dispositivo para
poder escoger el idioma de locución deseado. Otro aspecto mejorable es la regulación
de volumen, implementada en este proyecto con un simple potenciómetro.

La gestión del tablero es correcta, se identifican todos los cambios y la mayoría


de las jugadas legales. Los sensores empleados se adaptan perfectamente a las
características del tablero. El número de encuestas es, en principio, suficiente. Dadas las
características físicas del tablero (piezas ensambladas con una espiga en la base) se hace
difícil que en algun caso puedan realizarse más de dos jugadas por segundo. Podría
mejorarse, lógicamente, el código examinando las únicas jugadas que no se han
implementado: captura al paso del peón y coronación a pieza distinta de dama. No
obstante, se trata de jugadas más bien extrañas en la práctica y el sistema es capaz de
controlar un gran número de partidas sin contradecir el reglamento. Otra posibilidad
interesante es ampliar el programa para que sea capaz de controlar dos tableros
adaptados. El prototipo está preparado para ello, pues cuenta con dos conectores a
tablero, uno a cada lado del reloj.

En cuanto a la transmisión a PC podemos decir, básicamente, que cumple su


cometido. La generación de un archivo PGN tiene una motivación evidente. Existen en

29
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria Descriptiva

el mercado varios programas que gestionan bases de datos de partidas de ajedrez. El


formato de archivo más usado para almacenar partidas es el PGN (Portable Game
Notation). Todos los gestores de partidas y bases de datos entienden y trabajan con este
formato que, además, es gratuito. La elección está, pues, justificada. La notación que
utilizamos es la algebraica extendida. No obstante, el tipo más utilizado en las
competiciones, así como en publicaciones especializadas, es el algebraico, un poco
distinto al que usamos aquí. Por simplicidad no se ha optado por implementar este
último en los archivos generados en PC. Los gestores de partidas a los que aludíamos
pueden traducir de uno formato a otro fácilmente. Aún así, sería interesante tener esto
en cuenta en versiones posteriores. Otro aspecto importante es el uso del puerto serie
para realizar la transferencia. Aunque aún hoy es un puerto utilizado por módems y
otros dispositivos, y es perfectamente útil a nuestros propósitos, está siendo rápidamente
desplazado por el USB. Por esto la transferencia implementada aquí corre peligro de
quedarse obsoleta en pocos años. Sería éste, pues, otro dato interesante para
modificaciones futuras.

Existen en la actualidad tableros sensoriales para jugadores sin discapacidad (es


decir, tableros no adaptados para ciegos) con conexión a PC. Se utilizan
fundamentalmente para la retransmisión en directo de partidas de torneo por internet.
Son muy prácticos y permiten, según el modelo, conexión via puerto serie o USB. Su
gran inconveniente es el precio: en torno a los 425 €. Siguiendo con la ya apuntado en la
transferencia a PC la retransmisión por internet es, quizá, una de las funciones más
potentes de las que se podría dotar al sistema en futuras versiones. Lo sorprendente es
que a nivel de circuito no harían falta muchos retoques (si no es con puerto USB). Se
trataría más bien de un problema a nivel de soft.

Tarragona, Septiembre 2005

Firmado: Carlos Vidal García


Ingeniero Técnico Industrial

30
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2. MEMORIA DE CÁLCULO

31
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2. Memoria de Cálculo.

En este apartado se explica el funcionamiento general del programa y la


estrategia de resolución adoptada. Para ello se incorporan una serie de diagramas de
flujo que facilitarán la comprensión del mismo. El código completo en lenguaje
ensamblador puede consultarse en el anexo de esta memoria.

Podemos dividir el programa en 3 partes fundamentales: control del tiempo


restante, control de las jugadas realizadas en el tablero y reproducción de los mensajes
de audio. Estas 3 partes están compuestas por una serie de subrutinas que iremos
mostrando a continuación.

Para controlar eficazmente el tiempo transcurrido utilizaremos la interrupción


que genera el TMR0 del microcontrolador. Este temporizador nos permitirá controlar
exactamente 1 segundo de tiempo para mantener los relojes actualizados. Asímismo,
también utilizaremos esta fuente de interrupción para determinar cuando hay que
encuestar el tablero adaptado en caso de que esté conectado al reloj.

La reproducción de los mensajes de audio no precisa de control temporal, ya que


los propios dispositivos ISD se encargan por sí mismos de realizar dicha reproducción.
Cuando se solicite la reproducción de un mensaje sólo será necesario determinar la
orden concreta y mandarla al dispositivo ISD. Éste realizará todo el proceso y advertirá
al microcontrolador de la finalización del mismo.

Además de las tareas comentadas el programa también permitirá al


microcontrolador almacenar las jugadas realizadas en memoria y transmitirlas a un PC
externo cuando se solicite.

No se han puesto todas las subrutinas para evitar redundancia de explicación,


debido a la analogía entre las del jugador A y las del jugador B.

2.1. Inicialización.
Una vez encendido el dispositivo el programa empezará a ejecutarse desde la
dirección 0x00 de la memoria de código. Lo primero que hacemos es llamar a una
subrutina encargada de inicializar convenientemente los puertos E/S del
microcontrolador, poner el preescaler del TMR0, incializar algunas variables y habilitar
las interrupciones. Los dispositivos ISD y el display LCD son incializados en este
punto. También será necesario habilitar las resistencias del pull-up del puerto B para
poder detectar correctamente las señales producidas al pulsar un botón.

32
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

INICIALIZAR PRINCIPAL

CO NFIG URAR PUERTO S E/S INICIALIZAR

INICIO

INICIALIZAR ISD'S

INICIALIZAR DISPLAY

PREESCALER DEL TMR0 A 1:2

HABILITA PULL-UPS PO RTB

HABILITA INTERRUPCIO NES

INICIALIZAR VARIABLES

INICIALIZAR OFFSET DE LA EEPRO M

RETURN

33
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2.2. Programa Principal.


Después de inicializar el dispositivo saltamos a la rutina de Inicio. Esta rutina se
ejecutará cada vez que se inicie una partida nueva. El primer paso es cargar el modo de
tiempo de la última partida jugada almacenado en la EEPROM del microcontrolador.
Esto se realiza con la rutina cogeree. Posteriormente comprobamos si tenemos el tablero
conectado al reloj o no. Esto lo realizaremos con la función comp_tablero. Después se
inicializan las variables de control de la partida, así como las de auido y los contadores
que se utilizarán en la rutina de atención a la interrupción. Posteriormente el programa
queda en espera de que se pulse algún botón de jugador (A o B) para dar comienzo a la
partida, o bien el botón set para configurar un modo de tiempo diferente, o el botón next
para solicitar transferencia al PC. Las variables juegaA y juegaB se encargan de
diferenciar de quién es el turno de juego.

Una vez se ha iniciado la partida el programa ejecuta alternativamente las


rutinas partida y cmp_set. La primera se encarga de comprobar los botones de jugador
A y B y, en caso de detectar una pulsación, actualizar las variables de juego o parar los
relojes según proceda. En caso de que nos hallemos en algun modo con incrementos de
tiempo (modo “Fischer”) se realiza una llamada a la función incrementoA o
incrementoB para actualizar los relojes con el tiempo correcto.

La rutina cmp_set comprueba los distintos botones de petición de audio. En caso


de que se pulse uno de ellos se llama a una función asociada encargada de determinar el
mensaje a reproducir y empezar el proceso de reproducción. Esta rutina también se
encarga de detectar si ya estamos reproduciendo un mensaje por una o las dos ISD, ya
sea en modo normal o automático. En ese caso se llama a las funciones asociadas
reproduceA, reproduceB o repsecA_A, repsecB_B. Tambien controlaremos si ya ha
transcurrido el tiempo suficiente para encuestar el tablero, caso de que esté conectado, y
empezar al proceso de detección de jugadas (ver apartado 2.5.).

Es interesante comentar que la detección del accionamiento de los distintos


pulsadores se ha hecho por flanco descendente. Esto se debe a que el sistema debe
controlar numerosos eventos, entre ellos la acción de dichos pulsadores. Sería un
inconveniente detectar los botones por nivel implementando un bucle para saber
cuando se suelta un botón previamente pulsado, pues correríamos es riesgo de no
atender otras acciones importantes como la reproducción de mensajes o el control del
tablero.

34
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

INICIO

CO G E RE E

CO M P _ TA B L E RO

INICIA LIZA R
V A RIA B L E S DE
P A RTIDA Y A UDIO

INICIA LIZA R
CO NTA DO RE S

TA B LE RO SI INICIA L IZA R V A RIA B L E S


CO NE CTA DO ? CO NTRO L TA B LE RO

NO

NO NO NO NO
B O TO N A B O TO N B B O TO N S E T B O TO N NE X T
P UL S A DO ? P UL S A DO ? P ULS A DO ? P ULS A DO ?

SI SI SI SI

juegaB =1 juegaA =1 S E TCUE NTA TX _RS232

INICIA LIZA TM R0 INICIA LIZA TM R0

P A RTIDA

35
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

P A RTIDA

NO NO
B O TO N A B O TO N B
CM P _ S E T
P ULS A DO ? P ULS A DO ?

SI SI

SI SI
V A RIA B LE V A RIA B LE
A CTUA LIZA DA ? A CTUA LIZA DA ?

NO NO

TA B LE RO NO TA B LE RO NO
CO NE CTA DO ? CO NE CTA DO ?

SI SI

NO NO
TURNO DE TURNO DE
LA S NE G RA S ? LA S B LA NCA S ?

SI SI

A CTUA LIZA R A CTUA LIZA R


V A RIA B LE S V A RIA B LE S

SI SI
M O DO M O DO
INCRE M E NTO A INCRE M E NTO B
FIS CHE R? FIS CHE R?

NO NO

A CTUA LIZA R A CTUA LIZA R


DIS P LA Y DIS P LA Y

NO NO
B O TO N B B O TO N A
P ULS A DO ? P ULS A DO ?

SI SI

P A RA R RE LO JE S P A RA R RE LO JE S

A CTUA LIZA R A CTUA LIZA R


DIS P LA Y DIS P LA Y

CM P _S E T

36
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

CM P _ S E T

M O DO R E P R O D. SI
A U TO M A TIC A RE P S E C A _A
P A RA A ?

NO

M O DO R E P R O D. SI
A U TO M A TIC A RE P S E C B _B
P A RA B ?

NO

SI
RE P RO DU CIE NDO
RE P RO D UCE A
P A RA A ?

NO

SI
RE P RO DU CIE NDO
RE P RO D UCE B
P A RA B ?

NO

SI NO
B O TO N S E T RE LO JE S
TIE M P O B _ B
P UL S A D O ? P A RA DO S ?

NO SI

INICIO

SI
B O TO N M O D E
TIE M P O A _B
P UL S A D O ?

NO

SI
B O TO N UP
TIE M P O B _A
P UL S A D O ?

NO

SI NO
B O TO N NE X T RE LO JE S
TIE M P O A _ A
P UL S A D O ? P A RA DO S ?

SI

TX _ RS 23 2

(C O NTINUA )

P A RTIDA

37
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

B O TO N SI
JU G A D A A R E P R O _ JU G A D A _ A
PULSADO?

NO

B O TO N SI
JU G A D A B R E P R O _ JU G A D A _ B
PULSADO?

NO

NO
TA B L E R O
C O N E C TA D O ?

SI

SI
TIE M P O D E
IN IC IO _ E N C U E S TA
E N C U E S TA ?

NO

P A R TID A

38
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2.3. Rutina de Atención a la Interrupción TMR0.


Esta rutina se encarga de mantener el control del tiempo de la partida. Se ejecuta
cuando se desborda el timer, o sea, cada 512 s. (ver apartado 1.5.1.1.). Cada vez que
entramos en la rutina de atención a la interrupción se comprueba si alguno de los
jugadores tiene el reloj en marcha (variables juegaA y juegaB). En caso de que así sea
se procede a decrementar el contador asociado a ese jugador. Cuando el contador llega a
0 sabemos que ya ha pasado 1 segundo, por lo que se llama a la subrutina cadasecA o
cadasecB para actualizar las variables de tiempo de juego del jugador afectado. En estas
subrutinas se detecta si ha finalizado el tiempo de juego o bien si se ha superado el
control de tiempo.

La rutina de atención a la interrupción también nos permite controlar el intérvalo


temporal entre encuestas del tablero adaptado. En caso de que el tablero se encuentre
conectado lo encuestaremos cada 0.5 segundos, tiempo suficiente para derectar las
jugadas realizadas. Igual que con el control de tiempo decrementaremos un contador
para saber cuando han pasado los 0.5 segundos. En ese caso actualizaremos una variable
que nos indicará, una vez fuera de la interrupción, que ha llegado el momento de
encuestar el tablero. Como hemos podido ver en el apartado anterior la rutina cmp_set
detectará la activación de esta variable y procederá a iniciar la encuesta del tablero.

39
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

IS R

SALVAR LOS
RE G IS TR O S
W , S TA TUS Y
P C L A TH

M IRA S I S E ÑA L E S
E O M A S E RTA DA S

NO
JUE G A A =1 ? IG UA L P A RA E L JUG A DO R B

SI

DE CRE M E NTA R
CO NTA DO R A

SI
CO N TA DO R A =0? C A D A S E CA

NO

RE INICIA R CO N TA D O R A

NO
TA B L E RO
CO NE CTA DO ?

SI

DE CRE M E NTA R
C O NTA DO R
TA B L E RO

SI A CTUA L IZA R
C O NTA DO R
V A RIA B L E
TA B L E RO =0 ?
A S O CIA DA

NO

RE INICIA R CO NTA DO R
TA B L E R O

RE S TA U RA R
W , S TA TU S
Y P CL A TH

L IM P IA R E L FL A G D E
INTE RRUP CIO N DE L TM R 0
INTCO N(T0 IF)

P E RM ITIR INTE RRUP CIO N


DE L TM R0 INTC O N(T0IE )

RE TFIE

40
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

CADASECA

DESHABILITAR
TABLERO

SI
FINA=1? RETURN

NO

DECREMENTAR 1 SEGUNDO
EL RELOJ DE A

CAMBIAR
CO NFIG PO RTD
Y ACTUALIZAR
DISPLAY

NO
RELO J DE A=0?

SI

SI
HA PASADO
YA EL CO NTRO L? FINA=1
(FLAG A=1?)

NO

NO
XTRTMPA=1?

SI

FLAG A=1

PO NER MO DO DE
REPRO DUCCIO N
XTRTMPA=0 AUTO MATICA

SI

VO LCAR VARIABLES NO
Q UEDA MENO S DE
DE FINISH EN VARIABLES RETURN
UN MINUTO ?
RELO J A

CAMBIAR
CO NFIG PO RTD
Y ACTUALIZAR
DISPLAY

41
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2.4. Reproducción de Mensajes de Audio.


Como ya hemos visto las peticiones de reproducción de mensajes orales vienen
dadas por la acción de uno de los pulsadores. La rutina cmp_set se encarga de detectar
dicha acción y llamar a la función correspondiente: tiempoA_A, tiempoA_B, tiempoB_A,
tiempoB_B, repro_jugadaA, repro_jugadaB. Cada una se encarga de determinar que
tipo de mensaje hay que reproducir y mandarlo por el auricular adecuado.

Dependiendo del tiempo restante para cada jugador, el mensaje oral reproducido
puede constar de horas y minutos, minutos y segundos o segundos solamente. A ese
efecto se han creado las subrutinas rephoraAA, repminAA, repsecAA y sus análogas para
las distintas combinaciones de A y B.

La reproducción puede constar de distintos submensajes para componer el


mensaje entero. Las subrutinas reproduceA y reproduceB se encargan de determinar
cuando se ha finalizado la reproducción de un submensaje y si procede a enviarse otro.
Dicha finalización nos la indican los dispositivos ISD asertando la linea EOM! (End Of
Message).

Puede darse el caso que en el momento de lanzar un mensaje para reproducción


el display esté muy próximo a actualizar el tiempo de un jugador. Dado que display e
ISD’s comparten el puerto D podríamos encontrarnos con un valor erroneo en el mismo
mientras lanzamos la reproducción. Para evitar esto se implementa un bucle de espera
antes de iniciar el proceso.

REPRODUCEA

NO
E O M =0 ?

SI

SI
C O N T2 A -@ M S G 2 A +1 =
R E P R O A =0
C O N TA ?

SI
D IS P L A Y P R O X IM O
A A C TU A L IZ A R S E ?

NO

CARGAR EL
S IG U IE N TE M E N S A JE R E TU R N
P A R A R E P R O D U C C IO N

42
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

TIE M P O A _ A

E S TA M O S E N SI
R E P R O D U C C IO N
A U TO M Á TIC A ?

NO

E S TA M O S SI
R E P R O D U C IE N D O
POR A?

NO

NO
H O R A S D E A =0 ? REPHORAAA

SI

NO
M IN U TO S D E A =0 ? R E P M IN A A

SI

NO
S E G U N D O S D E A =0 ? REPSECAA

SI

R E TU R N

43
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

RE P HO R A A A

CO N TA =0

M S G 1A =@ D E L N UM E RO
C O RR E S P O ND IE NTE A H O RA A
CO N TA ++

M S G 2A =@ P A LA B R A
"H O RA S "
CO N TA ++

SI
M INU TO S D E A =0?

NO

M S G 3 A =@ P A LA B R A
SI SI C O RR E S P O ND IE N TE
M INU NA =0?O
M IN UN A =0?
M IND E A =0? A M IN DE A
CO N TA ++
NO
NO

M S G 3A =@ P A LA B R A M S G 3A =@ P A LA B RA
M S G 4 A =@ P A LA B R A
C O RR E S P O ND IE NTE CO R RE S P O N DIE NTE
"M IN UTO S "
A M IN DE A A M INU NA
CO N TA ++
CO N TA ++ C O NTA ++

M S G 4A =@ P A LA B R A
C O RR E S P O ND IE NTE
A M IN UN A
CO N TA ++

M S G 5A =@ P A LA B R A
"M IN UTO S "
CO N TA ++

L A N ZA M O S M S G 1 A
A R E P RO DUC CIO N

C O N T2 A =M S G 2 A
RE P R O A =1

R E TUR N

44
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

REPMINAA

CO NTA=0

MSG1A=@ PALABRA
SI SI CO RRESPONDIENTE
MINUNA=0?O
MINUNA=0?
MINDEA=0? A MINDEA
CO NTA++
NO
NO

MSG1A=@ PALABRA MSG1A=@ PALABRA


MSG2A=@ PALABRA
CO RRESPONDIENTE CO RRESPONDIENTE
"MINUTO S"
A MINDEA A MINUNA
CO NTA++
CO NTA++ CO NTA++

MSG2A=@ PALABRA
CO RRESPONDIENTE MSG 3A=@ PALABRA
A MINUNA SI SI CO RRESPONDIENTE
SECUNA=0?O
SECUNA=0?
CO NTA++ SECDEA=0? A SECDEA
CO NTA++
NO
NO
MSG3A=@ PALABRA
"MINUTO S"
MSG3A=@ PALABRA MSG3A=@ PALABRA
CO NTA++ MSG 4A=@ PALABRA
CO RRESPONDIENTE CO RRESPONDIENTE
"SEG UNDO S"
A SECDEA A SECUNA
CO NTA++
CO NTA++ CO NTA++

MSG4A=@ PALABRA
CO RRESPONDIENTE
A SECUNA
CO NTA++

MSG4A=@ PALABRA
SI SI CO RRESPONDIENTE
SECUNA=0?O
SECUNA=0? MSG5A=@ PALABRA
SECDEA=0? A SECDEA
"SEG UNDO S"
CO NTA++
CO NTA++
NO
NO

MSG4A=@ PALABRA MSG4A=@ PALABRA


MSG5A=@ PALABRA
CO RRESPONDIENTE CO RRESPONDIENTE
"SEG UNDO S"
A SECDEA A SECUNA
CO NTA++
CO NTA++ CO NTA++

MSG5A=@ PALABRA
CO RRESPONDIENTE
A SECUNA
CO NTA++

MSG6A=@ PALABRA
"SEGUNDO S"
CO NTA++

LANZAMOS MSG1A
A REPRODUCCIO N

CO NT2A=MSG 2A
REPRO A=1

RETURN

45
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

RE PS ECAA

CO NTA=0

MSG 1A=@ PALABRA


SI SI CO RRE SP O NDIE NTE
S ECUNA =0?O
S ECUNA =0?
S ECDE A=0? A S ECDEA
CO NTA ++
NO
NO

MS G 1A =@ P ALAB RA MS G 1A=@ PA LAB RA


MSG 2A=@ PALABRA
CO RRES PO NDIE NTE CO RRE S PO NDIE NTE
"S EG UNDO S"
A S ECDE A A S E CUNA
CO NTA ++
CO NTA++ CO NTA++

MS G 2A =@ P ALAB RA
CO RRES PO NDIE NTE
A SE CUNA
CO NTA++

MS G 3A =@ P ALAB RA
LA NZA MO S MSG 1A
"SE G UNDO S "
A RE P RO DUCCION
CO NTA++

CO NT2A =MSG 2A
RE PROA =1

RE TURN

46
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

REPRO _JUG ADAA

SI
BASE_RAM=
RETURN
0X110?

NO

CO NTA=0

CARG AMO S
MENSAJE
"PIEZA" EN
MSG1A

BASE_RAM> BASE_RAM=
0X190? 0X190?

NO S SITUAMO S NOS SITUAMO S NO S SITUAMO S


EN BASE_RAM-2 EN BASE_RAM-2 EN BASE_RAM=
(BANCO 2) (BANCO3) 0X16E

CARG AMOS "FILA" CARGAMO S "FILA"


Y "CO LUMNA" Y "CO LUMNA"
ORIG EN EN O RIGEN EN
MSG 2A Y MSG3A MSG2A Y MSG 3A

CARG AMOS "FILA" CARGAMO S "FILA"


Y "CO LUMNA" Y "CO LUMNA"
DESTINOEN DESTINO EN
MSG 4A Y MSG5A MSG4A Y MSG 5A

LANZAMOS MSG 1A
A REPRO DUCCIÓN

RETURN

47
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2.5. Control del tablero adaptado.


Para controlar las jugadas realizadas en el tablero adaptado es necesario en
primer lugar realizar una encuesta del mismo. Realizando dicha encuesta almacenamos
el estado de cada casilla (ocupada o libre) en una tabla que llamamos actual.
Posteriormente, comparando los datos de esta tabla con una similar llamada anterior
(que contiene el estado de las casillas antes de realizar la encuesta) podemos deducir si
ha habido algun cambio en la posición del tablero. Las funciones que realizan esto son
encuesta y compara, respectivamente.

Una vez se ha detectado un cambio en el tablero es necesario determinar si se


trata de una jugada completa o no. Esto se debe a que para realizar una jugada
físicamente se traslada una pieza de una casilla a otra. El microcontrolador realiza las
encuestas rápidamente (dos veces por segundo), de modo que detectaríamos primero un
cambio de casilla ocupada a libre. Este cambio no implica una jugada completa y habrá
que esperar otro cambio distinto, casilla libre a ocupada, para poder comprobar si se
trata de una jugada correcta o no. La rutina compara también se encarga de detectar
cuando se ha realizado una jugada completa. En ese caso se almacenan las coordenadas
de origen y destino del cambio (coord_or1x, coord_or1y, coord_desx y coord_desy).

La rutina examina se encarga de comprobar si nos hallamos ante una jugada


correcta o una jugada ilegal. Para ello necesitamos conocer las coordenadas de origen y
destino del movimiento y una tabla generada previamente que llamamos pieza. En esta
tabla se almacenan todas las piezas que intervienen en el juego, su color (blanca o
negra), su estado (viva o muerta), y su posición (coordenadas fila y columna, x e y).
Sencillamente buscamos en esta tabla una pieza cuyas coordenadas de posición
coincidan con las coordenadas de origen del movimiento (sólo puede haber una).
Posteriormente comprobamos si su color coincide con el turno de juego y si existe sobre
el tablero (si está viva). Después se determina que tipo de pieza es y se comprueba si su
movimiento es acorde. Como las distintas piezas del juego se mueven de forma
diferente es necesario tratar cada caso por separado.

Cuando se mueve una pieza pueden darse varios casos especiales, como la
captura de una pieza enemiga o la jugada de enroque. Para ello la función examina
llamará, en determinados casos, a otras subrutinas que se encagarán de comprobar estos
casos especiales. La subrutina mira_captura comprueba si la casilla destino del
movimiento ya está ocupada por otra pieza. De ser así determina si esa pieza es del
bando enemigo, en cuyo caso es una captura, o del mismo bando, lo que daría lugar a un
error. Si es una captura se procede a eliminar la pieza capturada de la tabla pieza
mediante la función kill_pieza. Excepto el caballo, las demás piezas no pueden atravesar
una casilla que ya está ocupada, es decir, interceptando la trayectoria de su movimiento.
La subrutina mira_casilla se encarga de esto. Puede ocurrir que con la jugada realizada
uno de los reyes, ya sea el del propio bando o el enemigo, quede atacado. El primer caso
se trata de una jugada ilegal, para lo que hemos creado la subrutina jaque. Puesto que la
labor de determinar si un rey u otro están en jaque se reduce a comprobar si una pieza
del bando enemigo ataca la casilla en la que se ubica dicho rey, la subrutina jaque llama
con frecuencia a otra subrutina, ataque. Esta última recibe como parámetros de entrada
las coordenadas de la casilla afectada y el bando al que corresponde el turno de juego. A
continuación se recorre la tabla pieza, comprobando si alguna de las piezas de color
contrario y viva puede atacar la casilla en cuestión. Esta subrutina también es utilizada

48
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

por otra función, mira_enroque, que determinará si el movimiento de enrocar es acorde


con las reglas que le corresponden.

Cuando el sistema detecta una jugada ilegal se ejecuta la rutina pon_error. El


objetivo de esta rutina es, primeramente, advertir de la situación encendiendo un LED
de aviso. Si se solicita reproducción de la última jugada el mensaje que se escucha es
“jugada ilegal”. Durante un error no se puede conmutar el reloj de juego, es decir, sigue
contando el tiempo para el jugador infractor. Tampoco se prosigue con la comprobación
de más jugadas. Sólo es posible salir de esta situación volviendo a poner las piezas
como estaban antes del error y siguiendo la partida a partir de este punto.

IN IC IO _ E N C U E S TA

E N C U E S TA

COMPARA

NO
JU G A D A
C O M P L E TA ?

SI

E X A M IN A

P A R TID A

49
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

E N C U E S TA

C O N T_ FIL A =0

C O N FIG U R A R P O R TD
4 B ITS A L TO S IN
4 B ITS B A JO S O U T

C O N T_ FIL A ->P O R TD C O N T_ FIL A ->P O R TD


E N A B L E =0 E N A B L E =0

TE M P O R IZA C IO N 1 0 m s TE M P O R IZA C IO N 1 0 m s

SI SI
S E H A A C TU A L IZA D O S E H A A C TU A L IZA D O
E L D IS P L A Y? E L D IS P L A Y?

NO NO

E N A B L E =1 E N A B L E =1

S A L V A R B YTE S A L V A R B YTE
A L TO P O R TD E N A L TO P O R TD E N
B YTE B A JO B YTE A L TO
M E M O R IA M E M O R IA

C O N T_ FIL A ++ C O N T_ FIL A ++

NO
C O N T_ FIL A =1 6 ?

SI

C O N FIG U R A P O R TD
TO D O S A L ID A S

R E TU R N

50
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

COMPARA

A U X _ A C TU A L =A C TU A L
A U X _ A N TE R IO R =A N TE R IO R
B =0

NO NO SI
A U X _ A C TU A L (B )=
A U X _ A C TU A L (B )=1 ? B IT_ C A M B IO =0 ?
A U X _ A N TE R IO R (B )?

SI NO
SI

NO
B ++ B IT_ C A M B IO =0 ?
A U X _ A C TU A L ->C O O R D _ D E S X
B ->C O O R D _ D E S Y
SI

SI A U X _ A C TU A L ->C O O R _ O R 1 X
B =8 ?
B ->C O O R D _ O R 1 Y

NO
B =0
A U X _ A C TU A L ->C O O R _ O R 2 X
B ->C O O R D _ O R 2 Y

SI
A U X _ A C TU A L -
A C TU A L =7 ?

B IT_ C A M B IO =1
NO

A U X _ A C TU A L ++
A U X _ A N TE R IO R ++

R E TU R N

51
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

EXAMINA

BUSCAMOS LA PIEZA
Q UE SE ESTÁ MOVIENDO
EN LA TABLA 'PIEZA'

CO MPROBAR TURNO
DE JUEGO Y SI
PIEZA VIVA

DETERMINAR QUE
TIPO DE PIEZA SE
ESTA MOVIENDO

NO NO NO NO NO
PEO N? TORRE? CABALLO? ALFIL? DAMA?

SI SI SI SI SI

COMPROBAR CO MPROBAR CO MPRO BAR COMPRO BAR COMPROBAR


MOVIMIENTO MO VIMIENTO MO VIMIENTO MOVIMIENTO MOVIMIENTO
PEO N TORRE CABALLO ALFIL TORRE

COMPROBAR COMPRO BAR


DETERMINAR SI SE MOVIMIENTO MOVIMIENTO
HA LLEGADO A LA ALFIL REY
8ª/1ª FILA

NO
SE ENRO CA?

SI
MIRA_CAPTURA

MIRA_ENROQ UE

MIRA_JAQUE

GUARDA_RAM

ACTUALIZA
VARIABLES DE
CONTRO L

RETURN

52
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

M IRA _CA P TURA M IRA _ CA S ILL A (X ,Y)

M IRA _ CA S ILL A RECO RRE R


(DE S TINO X,Y) TAB L A PIEZA

SI CO M P RO B A R CO LO R NO
CA SILLA
P IE ZA CAS IL LA CO O RDE NA DA _ X = X ?
O CUPA DA ?
O CUPA DA

NO
SI

RETURN K IL L_ P IE ZA NO NO
FINA L
CO O RDENA DA _Y = Y?
TAB L AP IE ZA ?

SI SI

NO RETURN(0 )
P IE ZA V IV A ?

SI

RETURN(CO LO R PIEZA)

K ILL _P IE ZA

RE CO RRE R
TA BL A P IE ZA

NO
CO O RDE NADA _X =
CO O RDE NA _DE STINO X ?

SI

NO
CO O RDE NA DA_Y = NO
FINAL
CO O RDE NA _DE STINO Y?
TA BL A PIEZA?

SI
SI

NO
P IE ZA V IV A ?
PO N_E RRO R
SI

LIMP IA FLA G
PIEZA VIVA

RE TURN

53
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

MIRA_JAQ UE

NO
JUEGAN
BLANCAS?

SI

BUSCAMOS BUSCAMO S
LAS COO RDENADAS LAS CO ORDENADAS
DEL REY BLANCO DEL REY NEGRO

G UARDAMO S LAS GUARDAMO S LAS


CO O RDENADAS EN CO ORDENADAS EN
'FILA' Y 'CO LUMNA' 'FILA' Y 'COLUMNA'

ATAQ UE(FILA, ATAQUE(FILA,


CO LUMNA,NEG RAS) CO LUMNA,BLANCAS)

SI SI
ATAQ UE ATAQUE
PON_ERRO R PON_ERROR
RETORNA 1? RETO RNA 1?

BUSCAMOS RETURN BUSCAMO S RETURN


LAS COO RDENADAS LAS CO ORDENADAS
DEL REY NEG RO DEL REY BLANCO

G UARDAMO S LAS GUARDAMO S LAS


CO O RDENADAS EN CO ORDENADAS EN
'FILA' Y 'CO LUMNA' 'FILA' Y 'COLUMNA'

ATAQ UE(FILA, ATAQUE(FILA,


COLUMNA,BLANCAS) CO LUMNA,NEGRAS)

SI PON FLAG JAQ UE SI PO N FLAG JAQUE


ATAQ UE ATAQUE
RETORNA 1? REY NEG RO RETO RNA 1? REY BLANCO

NO NO

Q UITA FLAG JAQUE Q UITA FLAG JAQ UE


REY NEG RO REY BLANCO

RETURN

54
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

MIRA_ENRO Q UE

NO
ENRO Q UE IG UALPARA ENRO Q UE LARG O
CO RTO ?

SI

NO
JUEG AN
BLANCAS?

SI

ENRO Q UE NO NO ENRO Q UE
CO RTO CO RTO
PERMITIDO ? PERMITIDO ?

SI SI

SI SI
BLANCAS EN NEG RAS EN
JAQ UE? JAQ UE?

NO NO

CASILLAS DE SI SI CASILLAS DE
PASO OCUPADAS? PASO OCUPADAS?
(F1 Y G 1) (F8 Y G 8)

NO NO

ATAQ UE(F1, ATAQ UE(F8,


NEG RAS) BLANCAS)

ATAQ UE(G 1, ATAQUE(G 8,


NEG RAS) BLANCAS)

CASILLAS DE SI SI CASILLAS DE
PASO ATACADAS? PASO ATACADAS?
(F1 Y G 1) (F8 Y G 8)

NO NO

PO N_ERRO R

RETURN

55
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

ATA Q UE (FILA ,CO LUM NA,


CO LO R B ANDO A TACA NTE )

RE CO RRE
TA BLA PIE ZA

NO
PIE ZA
V IV A?

SI

NO
CO O RDE NA DA _X=
FILA?

SI

NO
CO O RDE NA DA_Y=
CO LUMNA ?

SI NO

NO SI
CO LO R P IE ZA = FINA L TA B LA
RE TURN(0)
BA NDO ATA CA NTE? PIE ZA ?

SI

DE TE RMINA R DE
Q UE P IE ZA
S E TRATA

NO NO NO NO NO
PE O N? TO RRE? CA BA LLO ? A LFIL? DAMA ?

SI SI SI SI SI

CO M PRO BA R CO MPRO B AR CO MPRO B AR CO MP RO B A R CO MP RO B A R


CAS ILLA S CAS ILLAS CA SILLAS CA SILLAS CA S ILLA S
A TAQ UE PE O N A TA Q UE TO RRE ATA Q UE CA BA LLO A TA Q UE A LFIL A TAQ UE TO RRE

NO
CAS ILLA
ATA CA DA ?

SI

RETURN(1)

56
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

P O N_ E R RO R

E N CIE NDE
L E D E R RO R

P O S IC IO N SI APAGA
TA B L E RO
L E D E RR O R
R E E S TA B L E CID A ?

NO

NO R E TU RN
P E TICIO N
A UDIO JUG A DA ?

SI

RE P R O DU CE
M E N S A JE
"JUG A DA IL E G A L "

57
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

2.6. Rutinas auxiliares.


A continuación incluimos los diagramas de algunas subrutinas que se ejecutan
durante la ejecución del código:

setcuenta: Nos permite cambiar la modalidad temporal al inicio de la partida.

guarda_ram: Almacena la jugada realizada en la memoria RAM del


microcontrolador si dicha jugada es correcta.

tx_232: Transmite el contenido de la memoria de jugadas a un PC externo.

58
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

S E TCU E NTA

O FFS E T=
O FFS E T + 12

O FFS E T= SI
P O S ICIO N 84 DE LA O FFS E T=0
E E P RO M DE L P IC?

NO

CO G E RE E

SI
B O TO N
S E T P ULS A DO ?

NO

B O TO N SI
JUG A DO R A
P ULS A DO ?

NO

G UA RDA M O S E L
B O TO N SI O FFS E T E N LA
JUG A DO R B
P O S ICIO N 0 DE LA
P ULS A DO ?
E E P RO M DE L P IC

NO
RE TURN

59
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

GUARDA_RAM

C O M P O N E M O S B YTE
C O O R D E N A DA O R IG E N
(HIG H: C O O R D Y, L O W C O O RD X )

SI SI
BASE_RAM> B A S E _R A M =
0X 1 90? 0X 1 E F?

NO NO

G U A R D A B YTE G U A R DA B YTE
O RIG E N E N RA M O R IG E N E N R A M

B A S E _R A M ++ B A S E _ R A M ++

C O M P O N E M O S B YTE CO M P O NE M O S B YTE
C O O R D E N A D A D E S TIN O C O O R DE N A D A DE S TINO

G U A R D A B YTE G U A R DA B YTE
D E S TIN O E N R A M D E S TINO E N R A M

NO
BASE_RAM=
0X 1 6F?

SI

B A S E _R A M =0X 1 90 B A S E _ R A M ++

RE TU R N

60
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Memoria de Cáculo

TX_RS232

SI FALLO
B ASE_RAM=
0X120? MEMO RIA VACIA

NO

RETURN
ACTIVA R USART
(RCSTA(SP EN)=1)

CO NFIG URAR USART


PARA TRA NSIMIS IO N
(TXSTA=0x24)

V ELOCIDA D=9600 BA UDIO S


(SPBRG=25)

ACTIVA R USART
(RCSTA(SP EN)=1)

INCREMENTAR NO
PUNTERO =
P UNTERO BAS E_RAM?
HAB ILITAR TRANSMISIO N
(TXS TA (TXEN)=1)
SI

TRA NSMITIR BYTE


0X FF
INICIALIZAR (FIN TRANSMISIO N)
P UNTERO A
ME MO RIA

NO
FIN DE TRA NSMISIO N?
(TXSTA(TRMT)=1?)
LEER CO NTENIDO
ME MO RIA RA M
SI

RETURN

TRANSMITIR B YTE SI
FIN DE TRANSMISIO N?
(TXREG ) (TXS TA (TRMT)=1?)

NO

61
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Planos

3. PLANOS

62
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Planos

3.5. Aspecto de las Máscaras de C.I.

3.5.1. Situación de Componentes Placa 1.

3.5.2. Máscara de Cara Componentes Placa 1.

63
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Planos

3.5.3. Máscara de Cara Soldadura Placa 1.

3.5.4. Situación de Componentes Placa 2.

64
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Planos

3.5.5. Máscara de Cara Componentes Placa 2.

3.5.6. Máscara de Cara Soldadura Placa 2.

65
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

4. PRESUPUESTO

66
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

4. Presupuesto.

4.1. Mediciones.

Capítulo 1: Horas de Diseño.

Nº Ud. Descripción Nº Partes Subtotal TOTAL

1.1 H HORAS DISEÑO PROTOTIPO

HORAS DE DISEÑO Y DESARROLLO 350 350


DEL PROTOTIPO 350

67
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 2: Componentes Electrónicos.

Nº Ud. Descripción Nº Partes Subtotal TOTAL

2.1 U MICROCONTROLADOR PIC16F877

MICROCONTROLADOR MODELO PIC16F877


DE MICROCHIP DE 8 K. DE MEMORIA DE
PROGRAMA, 33 PINES DE E/S 1 1
1
2.2 U ISD 2560

DISPOSITIVO GRABADOR/REPRODUCTOR
DE VOZ ISD2560, CON 60 SEGUNDOS DE
CAPACIDAD GRABACIÓN 2 2
2
2.3 U LCD 16X1

MODULO VISUALIZADOR DE CRISTAL


LÍQUIDO DE 16 CARACTERES, 1 FILA 1 1
1
2.4 U OPB620

SENSOR ÓPTICO MODELO OPB620 64 64


64
2.5 U 74HC4514N

DECODIFICADOR 1:16 MODELO 74HC4514N


CON 4 ENTRADAS DE SELECCIÓN, SALIDA
A NIVEL ALTO 1 1
1
2.6 U MAX232

C. I. MAX232 TRANSMISIÓN/RECEPCIÓN DE
SEÑALES TTL/232. 1 1
1
2.7 U OSCILADOR 4 MHz

CRISTAL DE CUARZO DE 4 MHz. 1 1


1
2.8 U LM7805

REGULADOR DE TENSIÓN MODELO LM7805 1 1


1
2.9 U PILA 9V

PILA ALCALINA DE 9V 1 1
1
2.10 U CONECTOR PILA 9V

PORTAPILAS PILA 9V 1 1
1

68
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Nº Ud. Descripción Nº Partes Subtotal TOTAL

2.11 U PULSADOR COLOR ROJO

PULSADOR MINIATURA COLOR ROJO 4 4


4
2.12 U PULSADOR COLOR AMARILLO

PULSADOR MINIATURA COLOR AMARILLO 2 2


2
2.13 U PULSADOR COLOR NEGRO

PULSADOR MINIATURA COLOR NEGRO 2 2


2
2.14 U AURICULAR MONO

AURICULAR MODELO UNI TONE 2 2


2
2.15 U INTERRUPTOR

INTERRUPTOR DE PALANCA DE CONTACTO


SIMPLE 1 1
1
2.16 U LED ROJO

DIODO EMISOR DE LUZ 3 MM COLOR ROJO 1 1


1
2.17 U LED AMARILLO

DIODO EMISOR DE LUZ 3 MM COLOR


AMARILLO 1 1
1
2.18 U DIODO ZENER

DIODO ZENER MODELO 1N750 4,7 V 1 1


1
2.19 U LM741

AMPLIFICADOR OPERACIONAL MODELO


LM741 1 1
1
2.20 U RESISTENCIA 1 kΩ

RESISTENCIA DE 1 kΩ1/4 W 4 4
4
2.21 U RESISTENCIA 10 kΩ

RESISTENCIA DE 10 kΩ1/4 W 1 1
1
2.22 U RESISTENCIA 100 Ω

RESISTENCIA DE 1 kΩ1/4 W 1 1
1
2.23 U RESISTENCIA 2,2 kΩ

RESISTENCIA DE 2,2 kΩ1/4 W 4 4


4

69
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Nº Ud. Descripción Nº Partes Subtotal TOTAL

2.24 U RESISTENCIA 220 kΩ

RESISTENCIA DE 220 kΩ1/4 W 4 4


4
2.25 U RESISTENCIA 18 kΩ

RESISTENCIA DE 18 kΩ1/4 W 1 1
1
2.26 U POTENCIÓMETRO 4,7 kΩ

POTENCIÓMETRO DE 4,7 kΩ1/4 W 3 3


3
2.27 U CONDENSADOR 100 nF

CONDENSADOR CERÁMICO 100 Nf 1 1


1
2.28 U CONDENSADOR 330 nF

CONDENSADOR CERÁMICO 330 Nf 1 1


1
2.29 U CONDENSADOR 22 pF

CONDENSADOR CERÁMICO 22 pF 2 2
2
2.30 U CONDENSADOR 22 µF

CONDENSADOR ELECTROLÍTICO 22 µF 4 4
4
2.31 U ZÓCALO 40 PINES

ZÓCALO 40 PINES TORNEADO 1 1


1
2.32 U ZÓCALO 28 PINES

ZÓCALO 28 PINES TORNEADO 2 2


2

70
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 3: Placas de Circuito Impreso.

Nº Ud. Descripción Nº Partes Subtotal TOTAL

3.1 U CIRCUITO IMPRESO

PLACA CIRCUITO IMPRESO DOBLE CARA 1 1


180 x 100 mm. 1

3.2 U CIRCUITO IMPRESO

PLACA CIRCUITO IMPRESO DOBLE CARA 1 1


70 x 40 mm. 1

71
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 4: Conectores y Cables.

Nº Ud. Descripción Nº Partes Subtotal TOTAL

4.1 U CONECTOR CABLE PLANO

CONECTOR CABLE PLANO MACHO DE 14


CONTACTOS 4 4
4
4.2 U CONECTOR CABLE PLANO

CONECTOR CABLE PLANO MACHO DE 16 1 1


CONTACTOS 1

4.3 U CONECTOR DB9

CONECTOR DB9 HEMBRA ACODADO 1 1


1
4.4 U CONECTOR AURICULAR

CONECTOR AURICULAR TIPO JACK 3,5


ESTEREO 2 2
2
4.5 U CABLE PLANO

CABLE PLANO 1 1
1

72
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 5: Varios.

Nº Ud. Descripción Nº Partes Subtotal TOTAL

5.1 U CAJA PLÁSTICO

CAJA DE PLÁSTICO COLOR NEGRO


200 x 140 x 90 mm 1 1
1

5.2 U TABLERO AJEDREZ

TABLERO DE AJEDREZ, LÁMINA DE


PLÁSTICO SERIGRAFIADA 400 x 410 mm 1 1
1

5.3 U PIEZAS AJEDREZ

PIEZAS DE AJEDREZ PARA INVIDENTES


MODELO STAUNTON Nº 4 1 1
1

73
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

4.2. Cuadro de precios.

Capítulo 1: Horas De Diseño.

Nº Ud. Descripción Precio (€)

1.1 H HORAS DISEÑO PROTOTIPO 38,84 TREINTA Y OCHO


EUROS CON
HORAS DE DISEÑO Y DESARROLLO OCHENTA Y
DEL PROTOTIPO CUATRO CÉNTIMOS

74
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 2: Componentes Electrónicos.

Nº Ud. Descripción Precio (€)

2.1 U MICROCONTROLADOR PIC16F877 9,70 NUEVE EUROS


CON SETENTA
MICROCONTROLADOR MODELO PIC16F877 CÉNTIMOS
DE MICROCHIP DE 8 K. DE MEMORIA DE
PROGRAMA, 33 PINES DE E/S

2.2 U ISD 2560 18,32 DIECIOCHO


EUROS CON
DISPOSITIVO GRABADOR/REPRODUCTOR TREINTA Y
DE VOZ ISD2560, CON 60 SEGUNDOS DE DOS
CAPACIDAD GRABACIÓN CÉNTIMOS

2.3 U LCD 16X1 12,15 DOCE EUROS


CON QUINCE
MODULO VISUALIZADOR DE CRISTAL CÉNTIMOS
LÍQUIDO DE 16 CARACTERES, 1 FILA

2.4 U OPB620 0,82 OCHENTA Y


DOS
SENSOR ÓPTICO MODELO OPB620 CÉNTIMOS

2.5 U 74HC4514N 1,21 UN EURO CON


VEINTIUN
DECODIFICADOR 1:16 MODELO 74HC4514N CÉNTIMOS
CON 4 ENTRADAS DE SELECCIÓN, SALIDA
A NIVEL ALTO

2.6 U MAX232 1,23 UN EURO CON


VEINTITRÉS
C. I. MAX232 TRANSMISIÓN/RECEPCIÓN DE CÉNTIMOS
SEÑALES TTL/232.
2.7 U OSCILADOR 4 MHz 0,84 OCHENTA Y
CUATRO
CRISTAL DE CUARZO DE 4 MHz. CÉNTIMOS
2.8 U LM7805 0,28 VEINTIOCHO
CÉNTIMOS
REGULADOR DE TENSIÓN MODELO LM7805
2.9 U PILA 9V 1,70 UN EURO CON
SETENTA
PILA ALCALINA DE 9V CÉNTIMOS

2.10 U CONECTOR PILA 9V 0,20 VEINTE


CÉNTIMOS
PORTAPILAS PILA 9V

75
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Nº Ud. Descripción Precio (€)

2.11 U PULSADOR COLOR ROJO 0,57 CINCUENTA Y


SIETE
PULSADOR MINIATURA COLOR ROJO CÉNTIMOS

2.12 U PULSADOR COLOR AMARILLO 0,57 CINCUENTA Y


SIETE
PULSADOR MINIATURA COLOR AMARILLO CÉNTIMOS

2.13 U PULSADOR COLOR NEGRO 0,57 CINCUENTA Y


SIETE
PULSADOR MINIATURA COLOR NEGRO CÉNTIMOS

2.14 U AURICULAR MONO 1,38 UN EURO CON


TREINTA Y
AURICULAR MODELO UNI TONE OCHO
CÉNTIMOS
2.15 U INTERRUPTOR 0,83 OCHENTA Y
TRES
INTERRUPTOR DE PALANCA DE CONTACTO CÉNTIMOS
SIMPLE

2.16 U LED ROJO 0,09 NUEVE


CÉNTIMOS
DIODO EMISOR DE LUZ 3 MM COLOR ROJO

2.17 U LED AMARILLO 0,09 NUEVE


CÉNTIMOS
DIODO EMISOR DE LUZ 3 MM COLOR
AMARILLO

2.18 U DIODO ZENER 0,08 OCHO


CÉNTIMOS
DIODO ZENER MODELO 1N750 4,7 V

2.19 U LM741 0,36 TREINTA Y


SEIS
AMPLIFICADOR OPERACIONAL MODELO CÉNTIMOS
LM741

2.20 U RESISTENCIA 1 kΩ 0,02 DOS


CÉNTIMOS
RESISTENCIA DE 1 kΩ1/4 W

2.21 U RESISTENCIA 10 kΩ 0,02 DOS


CÉNTIMOS
RESISTENCIA DE 10 kΩ1/4 W

2.22 U RESISTENCIA 100 Ω 0,02 DOS


CÉNTIMOS
RESISTENCIA DE 1 kΩ1/4 W

2.23 U RESISTENCIA 2,2 kΩ 0,02 DOS


CÉNTIMOS
RESISTENCIA DE 2,2 kΩ1/4 W

76
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Nº Ud. Descripción Precio (€)

2.24 U RESISTENCIA 220 kΩ 0,02 DOS


CÉNTIMOS
RESISTENCIA DE 220 kΩ1/4 W

2.25 U RESISTENCIA 18 kΩ 0,02 DOS


CÉNTIMOS
RESISTENCIA DE 18 kΩ1/4 W

2.26 U POTENCIÓMETRO 4,7 kΩ 0,12 DOCE


CÉNTIMOS
POTENCIÓMETRO DE 4,7 kΩ1/4 W

2.27 U CONDENSADOR 100 nF 0,11 ONCE


CÉNTIMOS
CONDENSADOR CERÁMICO 100 nF

2.28 U CONDENSADOR 330 nF 0,11 ONCE


CÉNTIMOS
CONDENSADOR CERÁMICO 330 nF

2.29 U CONDENSADOR 22 pF 0,08 OCHO


CÉNTIMOS
CONDENSADOR CERÁMICO 22 pF

2.30 U CONDENSADOR 22 µF 0,13 TRECE


CÉNTIMOS
CONDENSADOR ELECTROLÍTICO 22 µF

2.31 U ZÓCALO 40 PINES 0,63 SESENTA Y


TRES
ZÓCALO 40 PINES TORNEADO CÉNTIMOS

2.32 U ZÓCALO 28 PINES 0,57 CINCUENTA Y


SIETE
ZÓCALO 28 PINES TORNEADO CÉNTIMOS

77
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 3: Placas de Circuito Impreso.

Nº Ud. Descripción Precio (€)

3.1 U CIRCUITO IMPRESO 4,60 CUATRO


EUROS CON
PLACA CIRCUITO IMPRESO DOBLE CARA SESENTA
180 x 100 mm. CÉNTIMOS

3.2 U CIRCUITO IMPRESO 1,54 UN EURO CON


CINCUENTA Y
PLACA CIRCUITO IMPRESO DOBLE CARA CUATRO
70 x 40 mm. CÉNTIMOS

78
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 4: Conectores y Cables.

Nº Ud. Descripción Precio (€)

4.1 U CONECTOR CABLE PLANO 0,28 VEINTIOCHO


CÉNTIMOS
CONECTOR CABLE PLANO MACHO DE 14
CONTACTOS

4.2 U CONECTOR CABLE PLANO 0,28 VEINTIOCHO


CÉNTIMOS
CONECTOR CABLE PLANO MACHO DE 16
CONTACTOS

4.3 U CONECTOR DB9 0,66 SESENTA Y


SEIS
CONECTOR DB9 HEMBRA ACODADO CÉNTIMOS

4.4 U CONECTOR AURICULAR 0,22 VEINTIDOS


CÉNTIMOS
CONECTOR AURICULAR TIPO JACK 3,5
ESTEREO

4.5 U CABLE PLANO 0,63 SESENTA Y


TRES
CABLE PLANO CÉNTIMOS

79
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 5: Varios.

Nº Ud. Descripción Precio (€)

5.1 U CAJA PLÁSTICO 3,16 TRES EUROS


CON
CAJA DE PLÁSTICO COLOR NEGRO DIECISEIS
200 x 140 x 90 mm CÉNTIMOS

5.2 U TABLERO AJEDREZ 3,50 TRES EUROS


CON
TABLERO DE AJEDREZ, LÁMINA DE CINCUENTA
PLÁSTICO SERIGRAFIADA 400 x 410 mm CÉNTIMOS

5.3 U PIEZAS AJEDREZ 12,00 DOCE EUROS

PIEZAS DE AJEDREZ PARA INVIDENTES


MODELO STAUNTON Nº 4

80
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

4.3. Aplicación de precios.

Capítulo 1: Horas de Diseño.

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

1.1 H HORAS DISEÑO PROTOTIPO 350 38,84 13594,00

HORAS DE DISEÑO Y DESARROLLO


DEL PROTOTIPO

TOTAL CAPÍTULO 1 13594,00 €

81
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 2: Componentes Electrónicos.

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

2.1 U MICROCONTROLADOR PIC16F877 1 9,70 9,70

MICROCONTROLADOR MODELO PIC16F877


DE MICROCHIP DE 8 K. DE MEMORIA DE
PROGRAMA, 33 PINES DE E/S

2.2 U ISD 2560 2 18,32 36,64

DISPOSITIVO GRABADOR/REPRODUCTOR
DE VOZ ISD2560, CON 60 SEGUNDOS DE
CAPACIDAD GRABACIÓN

2.3 U LCD 16X1 1 12,15 12,15

MODULO VISUALIZADOR DE CRISTAL


LÍQUIDO DE 16 CARACTERES, 1 FILA

2.4 U OPB620 64 0,82 52,48

SENSOR ÓPTICO MODELO OPB620

2.5 U 74HC4514N 1 1,21 1,21

DECODIFICADOR 1:16 MODELO 74HC4514N


CON 4 ENTRADAS DE SELECCIÓN, SALIDA
A NIVEL ALTO

2.6 U MAX232 1 1,23 1,23

C. I. MAX232 TRANSMISIÓN/RECEPCIÓN DE
SEÑALES TTL/232.
2.7 U OSCILADOR 4 MHz 1 0,84 0,84

CRISTAL DE CUARZO DE 4 MHz.


2.8 U LM7805 1 0,28 0,28

REGULADOR DE TENSIÓN MODELO LM7805


2.9 U PILA 9V 1 1,70 1,70

PILA ALCALINA DE 9V

2.10 U CONECTOR PILA 9V 1 0,20 0,20

PORTAPILAS PILA 9V

82
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

2.11 U PULSADOR COLOR ROJO 4 0,57 2,28

PULSADOR MINIATURA COLOR ROJO

2.12 U PULSADOR COLOR AMARILLO 2 0,57 1,14

PULSADOR MINIATURA COLOR AMARILLO

2.13 U PULSADOR COLOR NEGRO 2 0,57 1,14

PULSADOR MINIATURA COLOR NEGRO

2.14 U AURICULAR MONO 2 1,38 2,76

AURICULAR MODELO UNI TONE

2.15 U INTERRUPTOR 1 0,83 0,83

INTERRUPTOR DE PALANCA DE CONTACTO


SIMPLE

2.16 U LED ROJO 1 0,09 0,09

DIODO EMISOR DE LUZ 3 MM COLOR ROJO

2.17 U LED AMARILLO 1 0,09 0,09

DIODO EMISOR DE LUZ 3 MM COLOR


AMARILLO

2.18 U DIODO ZENER 1 0,08 0,08

DIODO ZENER MODELO 1N750 4,7 V

2.19 U LM741 1 0,36 0,36

AMPLIFICADOR OPERACIONAL MODELO


LM741

2.20 U RESISTENCIA 1 kΩ 4 0,02 0,08

RESISTENCIA DE 1 kΩ1/4 W

2.21 U RESISTENCIA 10 kΩ 1 0,02 0,02

RESISTENCIA DE 10 kΩ1/4 W

2.22 U RESISTENCIA 100 Ω 1 0,02 0,02

RESISTENCIA DE 1 kΩ1/4 W

2.23 U RESISTENCIA 2,2 kΩ 4 0,02 0,08

RESISTENCIA DE 2,2 kΩ1/4 W

83
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

2.24 U RESISTENCIA 220 kΩ 4 0,02 0,08

RESISTENCIA DE 220 kΩ1/4 W

2.25 U RESISTENCIA 18 kΩ 1 0,02 0,02

RESISTENCIA DE 18 kΩ1/4 W

2.26 U POTENCIÓMETRO 4,7 kΩ 3 0,12 0,36

POTENCIÓMETRO DE 4,7 kΩ1/4 W

2.27 U CONDENSADOR 100 nF 1 0,11 0,11

CONDENSADOR CERÁMICO 100 nF

2.28 U CONDENSADOR 330 nF 1 0,11 0,11

CONDENSADOR CERÁMICO 330 nF

2.29 U CONDENSADOR 22 pF 2 0,08 0,16

CONDENSADOR CERÁMICO 22 pF

2.30 U CONDENSADOR 22 µF 4 0,13 0,52

CONDENSADOR ELECTROLÍTICO 22 µF

2.31 U ZÓCALO 40 PINES 1 0,63 0,63

ZÓCALO 40 PINES TORNEADO

2.32 U ZÓCALO 28 PINES 2 0,57 1,14

ZÓCALO 28 PINES TORNEADO

TOTAL CAPÍTULO 2 128,53 €

84
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 3: Placas de Circuito Impreso.

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

3.1 U CIRCUITO IMPRESO 1 4,60 4,60

PLACA CIRCUITO IMPRESO DOBLE CARA


180 x 100 mm.

3.2 U CIRCUITO IMPRESO 1 1,54 1,54

PLACA CIRCUITO IMPRESO DOBLE CARA


70 x 40 mm.

TOTAL CAPÍTULO 3 6,14 €

85
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 4: Conectores y Cables.

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

4.1 U CONECTOR CABLE PLANO 4 0,28 1,12

CONECTOR CABLE PLANO MACHO DE 14


CONTACTOS

4.2 U CONECTOR CABLE PLANO 1 0,28 0,28

CONECTOR CABLE PLANO MACHO DE 16


CONTACTOS

4.3 U CONECTOR DB9 1 0,66 0,66

CONECTOR DB9 HEMBRA ACODADO

4.4 U CONECTOR AURICULAR 2 0,22 0,44

CONECTOR AURICULAR TIPO JACK 3,5


ESTEREO

4.5 U CABLE PLANO 1 0,63 0,63

CABLE PLANO

TOTAL CAPÍTULO 4 2,57 €

86
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Capítulo 5: Varios.

Nº Ud. Descripción Cantidad Precio (€) TOTAL (€)

5.1 U CAJA PLÁSTICO 1 3,16 3,16

CAJA DE PLÁSTICO COLOR NEGRO


200 x 140 x 90 mm

5.2 U TABLERO AJEDREZ 1 3,50 3,50

TABLERO DE AJEDREZ, LÁMINA DE


PLÁSTICO SERIGRAFIADA 400 x 410 mm

5.3 U PIEZAS AJEDREZ 1 12,00 12,00

PIEZAS DE AJEDREZ PARA INVIDENTES


MODELO STAUNTON Nº 4

TOTAL CAPÍTULO 5 18,66 €

87
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

4.4. Resumen del Presupuesto del Prototipo.

Para desarrollar este proyecto se han utilizado los siguientes elementos:

• Fuente de alimentación asimétrica: +5 V, GND.


• Grabador PIC16F877
• PC
• Software de generación y depuración del código: MPLAB.

La escuela ya disponía de estos elementos, por lo que no se ha tenido que hacer ningún
tipo de inversión específica en los mismos.

No obstante, teniendo en cuenta una amortización a cinco años de los aparatos


utilizados:

Aparato Precio Precio por mes Meses de Coste de


amortización 5 utilización amortización
años
Fuente de alimentación 250 € 4,16 € 6 24,96 €
PC 1.100 € 18,33 € 6 109,98 €
TOTAL 134,94 €

Finalmente, el presupuesto es:

Total capítulo 1 13594,00 €


Total capítulo 2 128,53 €
Total capítulo 3 6,14 €
Total capítulo 4 2,57 €
Total capítulo 5 18,66 €
Amortización a 5 años 134,94 €

TOTAL 13884,84 €

TRECE MIL OCHOCIENTOS OCHENTA Y CUATRO EUROS CON


OCHENTA Y CUATRO CÉNTIMOS.

Tarragona, Septiembre 2005

Firmado: Carlos Vidal García


Ingeniero Técnico Industrial

88
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

4.5. Presupuesto de Puesta en Fabricación.

Para una posible puesta en fabricación del producto se elabora un nuevo presupuesto.
En el mismo tenemos en cuenta una disminución del coste material por la compra de un
gran número de unidades.

Asímismo, la inversión específica a realizar para la fabricación del producto será


mínima debido a la flexibilidad de las líneas de producción de circuito impreso y de
conexión de comonentes. Por ello sólo tendremos en cuenta el coste de la línea de
producción y el de montaje del circuito por parte de un operario ( carcasa y placas de
circuito impreso).

Se realiza el nuevo presupuesto para una previsión de vendas de 3.500 unidades.

Ud. Descripción Cantidad Precio (€) TOTAL (€)

U MICROCONTROLADOR PIC16F877 1 7,70 7,70

MICROCONTROLADOR MODELO PIC16F877


DE MICROCHIP DE 8 K. DE MEMORIA DE
PROGRAMA, 33 PINES DE E/S

U ISD 2560 2 14,65 29,30

DISPOSITIVO GRABADOR/REPRODUCTOR
DE VOZ ISD2560, CON 60 SEGUNDOS DE
CAPACIDAD GRABACIÓN

U LCD 16X1 1 9,70 9,70

MODULO VISUALIZADOR DE CRISTAL


LÍQUIDO DE 16 CARACTERES, 1 FILA

U MAX232 1 0,90 0,90

C. I. MAX232 TRANSMISIÓN/RECEPCIÓN DE
SEÑALES TTL/232.
U OSCILADOR 4 MHz 1 0,64 0,64

CRISTAL DE CUARZO DE 4 MHz.


U LM7805 1 0,21 0,21

REGULADOR DE TENSIÓN MODELO LM7805


U PILA 9V 1 1,40 1,40

PILA ALCALINA DE 9V

U CONECTOR PILA 9V 1 0,18 0,18

PORTAPILAS PILA 9V

89
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Ud. Descripción Cantidad Precio (€) TOTAL (€)

U PULSADOR COLOR ROJO 4 0,45 1,80

PULSADOR MINIATURA COLOR ROJO

U PULSADOR COLOR AMARILLO 2 0,45 0,90

PULSADOR MINIATURA COLOR AMARILLO

U PULSADOR COLOR NEGRO 2 0,45 0,90

PULSADOR MINIATURA COLOR NEGRO

U AURICULAR MONO 2 1,10 2,20

AURICULAR MODELO UNI TONE

U INTERRUPTOR 1 0,65 0,65

INTERRUPTOR DE PALANCA DE CONTACTO


SIMPLE

U LED ROJO 1 0,07 0,07

DIODO EMISOR DE LUZ 3 MM COLOR ROJO

U LED AMARILLO 1 0,07 0,07

DIODO EMISOR DE LUZ 3 MM COLOR


AMARILLO

U DIODO ZENER 1 0,06 0,06

DIODO ZENER MODELO 1N750 4,7 V

U LM741 1 0,24 0,24

AMPLIFICADOR OPERACIONAL MODELO


LM741

U RESISTENCIA 1 kΩ 4 0,01 0,04

RESISTENCIA DE 1 kΩ1/4 W

U RESISTENCIA 10 kΩ 1 0,01 0,01

RESISTENCIA DE 10 kΩ1/4 W

U RESISTENCIA 100 Ω 1 0,01 0,01

RESISTENCIA DE 1 kΩ1/4 W

U RESISTENCIA 18 kΩ 1 0,01 0,01

RESISTENCIA DE 18 kΩ1/4 W

90
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Ud. Descripción Cantidad Precio (€) TOTAL (€)

U POTENCIÓMETRO 4,7 kΩ 3 0,08 0,24

POTENCIÓMETRO DE 4,7 kΩ1/4 W

U CONDENSADOR 100 nF 1 0,08 0,08

CONDENSADOR CERÁMICO 100 nF

U CONDENSADOR 330 nF 1 0,08 0,08

CONDENSADOR CERÁMICO 330 nF

U CONDENSADOR 22 pF 2 0,06 0,12

CONDENSADOR CERÁMICO 22 pF

U CONDENSADOR 22 µF 4 0,09 0,36

CONDENSADOR ELECTROLÍTICO 22 µF

U ZÓCALO 40 PINES 1 0,50 0,50

ZÓCALO 40 PINES TORNEADO

U ZÓCALO 28 PINES 2 0,46 0,92

ZÓCALO 28 PINES TORNEADO

U CIRCUITO IMPRESO 1 3,60 3,60

PLACA CIRCUITO IMPRESO DOBLE CARA


180 x 100 mm.
U CONECTOR CABLE PLANO 3 0,22 0,66

CONECTOR CABLE PLANO MACHO DE 14


CONTACTOS

U CONECTOR CABLE PLANO 1 0,22 0,22

CONECTOR CABLE PLANO MACHO DE 16


CONTACTOS

U CONECTOR DB9 1 0,50 0,50

CONECTOR DB9 HEMBRA ACODADO

U CONECTOR AURICULAR 2 0,18 0,36

CONECTOR AURICULAR TIPO JACK 3,5


ESTEREO

91
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

Ud. Descripción Cantidad Precio (€) TOTAL (€)

U CAJA PLÁSTICO 1 2,52 2,52

CAJA DE PLÁSTICO COLOR NEGRO


200 x 140 x 90 mm

COSTE MATERIAL 67,15 €

BENEFICIO INDUSTRIAL (6%) 4,02 €

AMORTIZACIÓN HORAS DE DISEÑO (13.594 / 3.500) = 3,88 €

LINEA DE PRODUCCIÓN C.I. + MANO DE OBRA 10,00 €

TOTAL 85,05 €

El presupuesto de puesta en fabricación para una previsión de vendas de tres mil


quinientas unidades asciende a ochenta y cinco euros con cinco céntimos.

Tarragona, Septiembre 2005

Firmado: Carlos Vidal García


Ingeniero Técnico Industrial

92
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

A continuación se presupuesta la puesta en fabricación del tablero adaptado únicamente.


Esto se hace atendiendo a la posibilidad de poder adquirir un reloj y varios tableros por
separado. No se incluye el coste de las piezas de juego, puesto que pueden aprovecharse
unas normales.

Ud. Descripción Cantidad Precio (€) TOTAL (€)

U OPB620 64 0,65 41,60

SENSOR ÓPTICO MODELO OPB620

U 74HC4514N 1 0,95 0,95

DECODIFICADOR 1:16 MODELO 74HC4514N


CON 4 ENTRADAS DE SELECCIÓN, SALIDA
A NIVEL ALTO

U RESISTENCIA 2,2 kΩ 4 0,01 0,04

RESISTENCIA DE 2,2 kΩ1/4 W

U RESISTENCIA 220 kΩ 4 0,01 0,04

RESISTENCIA DE 220 kΩ1/4 W

U CIRCUITO IMPRESO 1 1,23 1,23

PLACA CIRCUITO IMPRESO DOBLE CARA


70 x 40 mm.
U CONECTOR CABLE PLANO 1 0,22 0,22

CONECTOR CABLE PLANO MACHO DE 14


CONTACTOS

U CABLE PLANO 1 0,54 0,54

CABLE PLANO

U TABLERO AJEDREZ 1 2,80 2,80

TABLERO DE AJEDREZ, LÁMINA DE


PLÁSTICO SERIGRAFIADA 400 x 410 mm

93
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Presupuesto

COSTE MATERIAL 47,42 €

BENEFICIO INDUSTRIAL (6%) 2,84 €

AMORTIZACIÓN HORAS DE DISEÑO (13.594 / 3.500) = 3,88 €

LINEA DE PRODUCCIÓN C.I. + MANO DE OBRA 10,00 €

TOTAL 64,14 €

El presupuesto de puesta en fabricación para una previsión de vendas de tres mil


quinientas unidades asciende a sesenta y cuatro euros con catorce céntimos.

Tarragona, Septiembre 2005

Firmado: Carlos Vidal García


Ingeniero Técnico Industrial

94
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Bibliografía

5. BIBLIOGRAFÍA

95
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Bibliografía

5. Bibliografía

5.1. Libros Consultados.

[1] Ángulo Usategui, J. M. Angulo Martínez, I. “Microcontroladores Pic. Diseño Práctico de


Aplicaciones”. Ed: Mc Graw-Hill, 1997. ISBN: 84-481-1238-5.

[2] Ángulo Usategui, J. M. Angulo Martínez, I. Romero Yesa, S. “Microcontroladores Pic. Diseño
Práctico de Aplicaciones. Segunda Parte: Pic 16F87X”. Ed: Mc Graw-Hill, 2000. ISBN: 84-841-
2858-3.

[3] Floyd, Thomas. “Fundamentos de Sistemas Digitales”. Ed: Prentice-Hall, 2000. ISBN: 84-205-
2994-X.

[4] Buchanan, William. “PC Interfacing, Communications and Windows Programming”. Ed:
Addison-Wesley, 1999. ISBN: 0-201-17818-4.

[5] Martínez Salamero, L. Poveda López, A. García de Vicuña, L. Guinjoan Gispert, F. Sánchez
García, A. F. Sánchez Robert, F. J. “Funcions Electròniques”. Ed: UPC, 1993. ISBN: 84-8301-
012-7.

[6] PFC: Massa Amado, Carlos. “Reloj de Ajedrez Para Ciegos”. URV, 2002.

[7] PFC: Trancón Teijeira, Lorenzo N. “Calculadora Parlante”. URV, 2003.

[8] PIC16F877 Data Sheet. Microchip. 2002.

5.2. Páginas Web Consultadas.

[9] http://www.microchip.com. [Software de simulación y depuración de código ensamblamdor


para PIC’s (MPLAB), Data Sheet 16F877].

[10] http://www.isd.com. [Data Sheet dispotivos ISD2560].

[11] http://www.x-robotics.com. [Información funcionamiento displays alfanuméricos y conexión


microcontrolador-PC].

[12] http://www.micropik.com. [Consulta de precios y compra de componenetes electrónicos].

96
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

6. ANEXOS

97
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

6. Anexos.
6.1. Manual de Usuario.

6.1.1. Diagrama del Prototipo.

CONECTOR AURICULAR
INTERRUPTOR

LED BATERIA BAJA LED ERROR

PETICION AUDIO
JUGADAS

SET CONECTOR TABLERO


CONECTOR TABLERO NEXT

UP MODE

CONECTOR PC

(a)

CONMUTADOR PARTIDA

BOTONES

DISPLAY

(b)

Figura 1. Diagrama del reloj de ajedrez para ciegos. (a) Vista superior. (b) Vista frontal.

98
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

CONECTOR RELOJ

Figura 2. Diagrama del tablero adaptado.

Como se puede observar en la figura 1, el reloj cuenta con los siguientes botones
y conectores:

• Dos botones con la función de conmutador de partida: detienen el reloj


correspondiente al jugador que los pulsa. Son de color negro.

• Cuatro botones para pedir el tiempo restante propio y del adversario, así
como para configurar el tiempo de la partida e iniciar la transferencia a PC.
Son de color rojo.

• Dos botones para pedir la última jugada realizada en el tablero adaptado. Son
de color amarillo.

• Un interruptor de Encendido / Apagado.

• Dos conectores para dos auriculares.

• Dos conectores al tablero adaptado.

• Un conector a PC externo.

• Dos LED’s. Uno, de color amarillo, se encenderá cuando la batería esté


próxima a agotarse. El otro, de color rojo, se encenderá cuando se realice una
jugada ilegal en el tablero adaptado.

• Un display LCD de 16 caracteres donde se muestra el tiempo restante para


cada jugador.

La pantalla está dividida en dos grupos de ocho dígitos cada uno. Los ocho de la
izquierda muestran información para el jugador A y los ocho de la derecha para el

99
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

jugador B. Para mostrar el tiempo se usan cuatro dígitos por jugador, dando información
en formato horas.minutos o minutos.segundos. Los dos dígitos centrales sirven para
indicar que reloj está corriendo.

En la figura 2 observamos que el tablero adaptado cuenta con un único conector


cuya función es permitir la conexión al reloj.

6.1.2. Uso del Reloj de Ajedrez.

6.1.2.1. Como Iniciar una Partida.

Para empezar a jugar cambie el interruptor de Encendido / Apagado a la posición


de encendido. El display mostrará el tiempo que se configuró para la última partida. Si
desea jugar con el tiempo que se muestra en pantalla, pulse uno de los botones de
conmutador de partida. El tiempo del jugador contrario empezará a correr.

6.1.2.2. Como Configurar un Nuevo Modo de Partida.

Después de encender el reloj pulse el botón set para cambiar la configuración de


la partida. Observará como los dígitos mostrados en pantalla cambian sucesivamente
con cada nueva pulsación. Puede configurarse cualquiera de los siete modos que vienen
predefinidos con el reloj. La secuencia de configuraciones que se mostrarán en pantalla
es la siguiente:

2 horas 90 m inutos 30 m inutos 5 m inutos


+ 1 hora finish + 1 hora finish finish finish

4 m inutos 25 m inutos 90 m inutos


+ 2 seg/jugada + 10 seg/jugada + 30 seg/jugada

Para seleccionar cualquiera de estos modos y empezar una nueva partida pulse el
botón set hasta que aparezca en la pantalla. Posteriormente pulse uno de los botones de
conmutador de partida. El reloj empezará a correr con el tiempo seleccionado.

6.1.2.3. Como Parar el Reloj.

Para detener el reloj pulse simultáneamente los dos botones de conmutador de


partida. Observará que los dos dígitos centrales se quedan en blanco, señal de que el
reloj se ha detenido. Para reanudar la partida vuelva a pulsar uno de los botones de
conmutador de partida. Si, por el contrario, desea iniciar una nueva partida pulse el
botón set y siga las instrucciones del apartado 2.2. Esta prestación es útil cuando se
requiere la intervención del árbitro para solucionar una situación conflictiva durante la
partida.

100
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

6.1.3. Uso del Tablero Adaptado.

6.1.3.1. Como Conectar el Tablero.

Para utilizar el tablero adaptado coloque las piezas en la posición de inicio de


partida (ver figura 3). Después conecte el tablero al reloj con el cable suministrado. La
conexión puede realizarse en cualquiera de los dos conectores de que dispone el reloj.

Figura 3. Posición de las piezas al inicio de la partida.

Para que el reloj detecte el tablero es necesario conectarlos antes de encender el


reloj.

6.1.3.2. Como Empezar la Partida.

Encienda el reloj y configure el modo de tiempo de desee (ver apartado 2.2).


Después pulse el botón de conmutador de partida correspondiente al jugador B (negras)
para poner en marcha el reloj del jugador A (blancas). En este momento la partida ha
empezado y el sistema está examinando las jugadas realizadas.

Cuando el tablero está conectado no se puede conmutar el reloj si el bando que


mueve no ha realizado primero su jugada sobre el tablero.

6.1.3.3. Que Hacer Cuando se Produce un Error.

Si durante la partida se hace una jugada ilegal o se desconecta el tablero del reloj
se encenderá el LED rojo, notificando que se ha producido un error en el tablero. Si en
este momento se realiza una petición de audio de última jugada el mensaje que se
escuchará es “jugada ilegal”. No será posible conmutar el reloj de juego, siguiendo la
cuenta del jugador infractor. Para poder reanudar la partida es necesario volver a poner
las piezas en la posición anterior al error o bién volver a conectar el tablero. Un vez
hecho esto el LED rojo se apagará.

101
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

6.1.3.4. Como Finalizar la Partida.

Cuando la partida finalice pare el reloj (ver apartado 2.3). Con el reloj parado el
sistema no examina el tablero. Si quiere reanudar la partida vuelva a pulsar el botón de
conmutador de juego correspondiente. Si quiere empezar una nueva partida resitue las
piezas en la posición inicial y pulse el botón set para volver a configurar el modo de
tiempo del reloj.

6.1.4. Reproducción de Mensajes Orales.

Para poder escuchar mensajes orales conecte un auricular en cada conector.


Cada jugador tiene tres botones: uno para escuchar su tiempo restante, otro para
escuchar el tiempo de su contrincante y un tercero para escuchar la última jugada
realizada en el tablero. Pulsando el botón que se encuentra más cercano al conmutador
de partida escuchará el tiempo restante del contrincante en el formato horas.minutos o
minutos.segundos. Pulsando el siguiente botón escuchará el tiempo restante propio. El
botón más lejano al conmutador de partida sirve para escuchar la última jugada
realizada si el tablero está conectado. El formato del mensaje es pieza
movida.coordenada origen.coordenada destino.

Cuando queda menos de un minuto de tiempo para un jugador, se entra en modo


de reproducción automática. En este modo, el auricular de dicho jugador emite la cuenta
atrás del minuto restante sin que el usuario tenga la necesidad de pulsar ningún botón.

6.1.5. Comunicación del Reloj con PC Externo.

6.1.5.1. Como Configurar el PC.

Para poder transmitir la información del reloj se necesita el programa Terminal


(ver CD adjunto), un PC con sistema operativo Windows y un cable de conexión para
puerto serie DB9. Copie el archivo Terminal.exe en su disco duro. Posteriormente
asegúrese de que la configuración de su PC es correcta. Diríjase a Inicio ->
Configuración -> Panel de control -> Sistema -> Administrador de dispositivos. Haga
click en Puertos COM y LPT -> Puerto de comunicaciones COM1 -> Configuración de
puerto. Los datos que deben aparecer son:

Bits por segundo : 9600


Bits de datos : 8
Paridad : ninguna
Bits de parada : 1
Control de flujo : ninguno

6.1.5.2. Como Realizar la Transmisión.

Una vez configurado el PC use el cable de conexión para conectar el reloj con el
PC en el puerto COM1. Aségurese de que el reloj está parado (ver apartado 2.3), sino no

102
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

podrá realizarse la transmisión. Ejecute el programa Terminal. Aparecerá una ventana


con el mensaje “Comunicación 232 con PIC”, “Esperando transmisión”. En este
momento pulse el botón next del reloj. Esto dará inicio a la transmisión. No pulse
ninguna tecla del ordenador ya que esto finalizaría inmediatemente el programa. Una
vez hecha la transmisión podrá leer el mensaje “Fin de transmisión. Generando pgn”.
Cuando se ha recibido toda la información del reloj el programa procede a generar un
archivo pgn (las siglas PGN corresponden a Portable Game Notation) que contiene
todas las jugadas almacenadas en la memoria del reloj. Finalmente aparecerá el mensaje
“pgn generado!” y se finalizará el programa. Desconecte el cable que une reloj y PC y
cierre la ventana del programa. Observará que en el mismo directorio donde tiene el
archivo Terminal.exe ha aparecido un nuevo archivo llamado partida.pgn.

Si durante la transmisión aparece el mensaje “Error: memoria vacía” cierre la


ventana del programa. Esto significa que no había jugadas almacenadas en el reloj y por
lo tanto no se ha generado ningun archivo.

103
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

6.2. Código Fuente para PIC16F877.


;****************************************************************************
; PROGRAMA: PFC.ASM
; Realiza las tareas propias de un reloj de ajedrez de competición adaptado
; para ciegos. Controla las jugadas realizadas en tablero, almacena jugadas en
; memoria y las transmite a PC via protocolo RS232.
;
; Autor: CARLOS VIDAL GARCIA caviga12@yahoo.es Septiembre 2005
;
; Programa para PIC16F877
; Frecuencia Reloj: 4 MHz Reloj Instrucción: 1 MHz (1us)
; Watch Dog: deshabilitado Tipo Reloj: XT
; Protección de código: deshabilitado
;****************************************************************************

LIST P=16F877
#include "p16f877.inc"

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_OFF & _LVP_OFF
& _BODEN_OFF

;---------------------------------------------------------------------------;
; Definicion de variables ;
;---------------------------------------------------------------------------;

horaA EQU H'20' ; en estas variables guardaremos el tiempo


mindeA EQU H'21' ; que queda para el jugador A
minunA EQU H'22'
secdeA EQU H'23'
secunA EQU H'24'
ehoraA EQU H'25' ; estas variables son para guardar el tiempo
emindeA EQU H'26' ; de Finish, mientras no ha caído la bandera
eminunA EQU H'27'
esecdeA EQU H'28'
esecunA EQU H'29'
juegaA EQU H'2A' ; nos indica si está jugando el jugador A
flagA EQU H'2B' ; nos indica si ha caído la bandera de A
finA EQU H'2C' ; nos indica si ha terminado el tiempo de A
ticsA EQU H'2D' ; contador para calcular el tiempo que pasa
ticsA1 EQU H'2E' ; y una variable auxiliar para este cálculo
nsecmov EQU H'2F' ; para el modo Fischer
xtrtmpA EQU H'30' ; nos indica si es partida a Finish o Control +
Finish
horaB EQU H'31' ; en estas variables guardaremos el tiempo
mindeB EQU H'32' ; que queda para el jugador B
minunB EQU H'33'
secdeB EQU H'34'
secunB EQU H'35'
ehoraB EQU H'36' ; estas variables son para guardar el tiempo
emindeB EQU H'37' ; que queda después de la caída de bandera
eminunB EQU H'38'
esecdeB EQU H'39'
esecunB EQU H'3A'
juegaB EQU H'3B' ; nos indica si está jugando el jugador B
flagB EQU H'3C' ; nos indica si ha caído la bandera de B
finB EQU H'3D' ; nos indica si ha terminado el tiempo de B
ticsB EQU H'3E' ; contador para calcular el tiempo que pasa
ticsB1 EQU H'3F' ; y una variable auxiliar para este cálculo
xtrtmpB EQU H'40' ; para el modo Fischer
pclath_temp EQU H'41' ; nos indica si es partida a Finish o Control+Finish
auxAA EQU H'42'
w_temp EQU H'7F'
status_temp EQU H'44'
offset EQU H'45'

104
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

cont_ms EQU H'46'


cont_us EQU H'47'

; variables relativas a tablero


cambio EQU H'48'
coord_or1x EQU H'49' ; x fila; y columna
coord_or1y EQU H'4A'
cont_fila EQU H'4B'
auxBB EQU H'4C'
aux_actual EQU H'4D'
aux_anterior EQU H'4E'
aux_piezas EQU H'4F'
coord_desx EQU H'50'
coord_desy EQU H'51'
control EQU H'52'
aux_x EQU H'53'
aux_y EQU H'54'
fila EQU H'55'
columna EQU H'56'
enroque EQU H'57'
bit EQU H'58'
auxAA1 EQU H'59'
auxCC EQU H'5A'
coord_or2x EQU H'5B'
coord_or2y EQU H'5C'
tics_tab EQU H'5D'
tics_tab1 EQU H'5E'

; variables relativas al modulo de audio


reproA EQU H'5F'
reproB EQU H'60'
auto EQU H'61'
contA EQU H'62'
cont2A EQU H'63'
msg1A EQU H'64'
msg2A EQU H'65'
msg3A EQU H'66'
msg4A EQU H'67'
msg5A EQU H'68'
msg6A EQU H'69'
contB EQU H'6A'
cont2B EQU H'6B'
msg1B EQU H'6C'
msg2B EQU H'6D'
msg3B EQU H'6E'
msg4B EQU H'6F'
msg5B EQU H'70'
msg6B EQU H'71'

; otras variables
base_ram EQU H'72'
aux_anterior0 EQU 0x73 ; tabla anterior0 77:7E banco 0
offset_piezas EQU 0x74
offset_captura EQU 0x75
pieza_jugada EQU 0x76
estado_botones EQU 0x43

#DEFINE DIS_RW D'1' ; PORTA


#DEFINE DIS_RS D'0' ; PORTA
#DEFINE DIS_E D'0' ; PORTE
#DEFINE b_jugA D'6' ; PORTB
#DEFINE b_jugB D'7' ; PORTB
#DEFINE b_set D'5' ; PORTB B_B
#DEFINE b_up D'4' ; PORTB B_A
#DEFINE b_mode D'3' ; PORTB A_B
#DEFINE b_next D'2' ; PORTB A_A
#DEFINE b_jugadaA D'1' ; PORTB
#DEFINE b_jugadaB D'0' ; PORTB

105
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

#DEFINE eom_isd1 D'2' ; PORTC


#DEFINE eom_isd2 D'3' ; PORTC
#DEFINE pr_isd1 D'0' ; PORTC
#DEFINE pr_isd2 D'1' ; PORTC
#DEFINE pd_isd1 D'4' ; PORTC
#DEFINE pd_isd2 D'5' ; PORTC
#DEFINE ce_isd1 D'2' ; PORTE
#DEFINE ce_isd2 D'1' ; PORTE
#DEFINE enable D'3' ; PORTA ent1
#DEFINE enable2 D'2' ; PORTA ent2
#DEFINE led_error D'5' ; PORTA
#DEFINE RETARDO1 D'15'
#DEFINE RETARDO2 D'200'
#DEFINE RETARDO3 D'100'
#DEFINE b_ram h'10' ; direccion base ram
#DEFINE anterior0 0x77 ; tabla anterior0 0x77:0x7E, banco 0
#DEFINE anterior 0xE8 ; tabla anterior 0xE8:0xEF
#DEFINE actual 0xE0 ; tabla actual 0xE0:0xE7
#DEFINE piezas 0xA0 ; @ inicial array piezas A0:DF banco 1 (64B)
#DEFINE una B'10000111' ;@ DE UNA
#DEFINE hora B'10001100' ;@ DE HORA
#DEFINE horas B'10010001' ;@ DE HORAS
#DEFINE minuto B'10010110' ;@ DE MINUTO
#DEFINE minutos B'10011011' ;@ DE MINUTOS
#DEFINE segundos B'10100000' ;@ DE SEGUNDOS
#DEFINE jug_ilegal B'11011011' ;@ de jugada ilegal

;-------------------------------------------------------------------------;
; Definición de macros ;
;-------------------------------------------------------------------------;

banco0 macro ; salta al banco 0


bcf STATUS,RP0
bcf STATUS,RP1
endm

banco1 macro ; salta al banco 1


bsf STATUS,RP0
bcf STATUS,RP1
endm

banco2 macro ; salta al banco 2


bcf STATUS,RP0
bsf STATUS,RP1
endm

banco3 macro ; salta al banco 3


bsf STATUS,RP0
bsf STATUS,RP1
endm

pagina0 macro
bcf PCLATH,4
bcf PCLATH,3
endm

pagina1 macro
bcf PCLATH,4
bsf PCLATH,3
endm

pagina2 macro
bsf PCLATH,4
bcf PCLATH,3
endm

leer_puntero macro
bcf STATUS,IRP ; accede al banco 0

106
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf FSR
bcf FSR,7
movf INDF,W
endm

escribe_puntero macro
bcf STATUS,IRP ; accede al banco 0
movwf FSR
bcf FSR,7
movf auxAA,W
movwf INDF
endm

leer_punterob1 macro
bcf STATUS,IRP ; accede al banco 1
movwf FSR
bsf FSR,7
movf INDF,W
endm

escribe_punterob1 macro
bcf STATUS,IRP ; accede al banco 1
movwf FSR
bsf FSR,7
movf auxAA,W
movwf INDF
endm

leer_punterob2 macro
bsf STATUS,IRP ; accede al banco 2
movwf FSR
bcf FSR,7
movf INDF,W
endm

escribe_punterob2 macro
bsf STATUS,IRP ; accede al banco 2
movwf FSR
bcf FSR,7
movf auxAA,W
movwf INDF
endm

leer_punterob3 macro
bsf STATUS,IRP ; accede al banco 3
movwf FSR
bsf FSR,7
movf INDF,W
endm

escribe_punterob3 macro
bsf STATUS,IRP ; accede al banco 3
movwf FSR
bsf FSR,7
movf auxAA,W
movwf INDF
endm

absoluto macro
btfss STATUS,C ; calcula el valor absoluto del numero
goto $+3 ; pasado por W. Se devuelve por auxAA.
movwf auxAA
goto $+4
movwf auxAA
comf auxAA,f
incf auxAA,f
endm

107
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

mira_reproduce macro
btfss reproA,0 ; estamos reproduciendo por A?
goto $+3 ; no
btfss PORTC,eom_isd1 ; fin de mensaje A?
bsf reproA,1 ; si
btfss reproB,0 ; no, estamos reproduciendo por B?
goto $+3 ; no
btfss PORTC,eom_isd2 ; si, fin de mensaje B?
bsf reproB,1 ; si
endm

;-------------------------------------------------------------------------;
; Direccion de inicio del programa principal y la de la rutina de
; atencion a la interrupcion
;-------------------------------------------------------------------------;

ORG 0
goto principal

ORG 4
movwf w_temp ; salvamos el registro W
swapf STATUS,W ; y el registro de estado
banco0
movwf status_temp ; no hemos cambiado ningún flag
movf PCLATH,W ; salva parte alta del contador de programa
movwf pclath_temp
clrf PCLATH
goto isr

;-------------------------------------------------------------------------;
; Rutina de Inicialización ;
;-------------------------------------------------------------------------;

inicializar banco0
clrf PORTA
clrf PORTB ; inicializamos los puertos
clrf PORTD ; limpiando los latches de salida
clrf PORTE
banco1 ; vamos al banco 1 de memoria
movlw H'06' ; configuramos PORTA como
movwf ADCON1 ; I/O digital
clrf TRISA ; PORTA todo salidas
movlw H'FF' ; PORTB todo entradas
movwf TRISB ;
clrf TRISD ; PORTD todo salidas
movlw b'10001100'
movwf TRISC ; PORTC [2:3,7] entradas, [0:1]y[4:6] salidas

clrf TRISE ; PORTE todo salidas

banco0 ; vuelve al banco 0

bsf PORTA,enable ; enable=1 tablero deshabilitado


bsf PORTA,enable2
bsf PORTC,pr_isd1
bsf PORTC,pr_isd2 ; pr_isd1=1, pr_isd2=1 por precaucion
bsf PORTE,ce_isd1
bsf PORTE,ce_isd2 ; ce_isd1=ce_isd2=1, deshabilitado

bsf PORTC,pd_isd1 ; duerme ISD1


bsf PORTC,pd_isd2 ; duerme ISD2

call configura_lcd ; configuracion del lcd

banco1
movlw H'00' ; ponemos el preescaler del TMR0
movwf OPTION_REG ; a 1:2 y habilitamos los pull-ups del PORTB
banco0 ; volvemos al banco 0

108
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw H'00' ; inicializacion de variables


movwf juegaA
movwf juegaB
movwf xtrtmpA
movwf xtrtmpB
movwf nsecmov
movwf auto
movwf reproA
movwf reproB
movwf pieza_jugada

movlw h'FF'
movwf estado_botones
clrf control ; inicializa control (bit0=0, juegan
blancas)
clrf cambio
movlw h'0F'
movwf enroque
movlw d'8' ; encuestas cada 0.5 segundos
movwf tics_tab1
movlw d'122'
movwf tics_tab
clrf PCLATH

movlw H'A0' ; habilitamos interrupciones:


movwf INTCON ; GIE y T0IE = 1, T0IF = 0

movlw H'00'
call leeree ; inicializamos el offset de la EEPROM
con
movwf offset ; el valor de la dirección de la ultima
cuenta
return

;-------------------------------------------------------------------------;
; isr: interrupciones cada 512us
;-------------------------------------------------------------------------;

isr mira_reproduce
btfss juegaA,0 ; Corre el reloj del jugador A?
goto quienjuega2 ; no, continúa
decfsz ticsA,f ; si, decrementa el contador de tiempo
A
goto si_tablero ; si no ha llegado a 0 continua
decfsz ticsA1
goto contaA
call cadasecA ; si es 0 ejecutar cadasecA
movlw D'217' ; y poner ticsA al valor inicial
movwf ticsA ; ticsA = 217
movlw D'9'
movwf ticsA1
goto si_tablero ; no

quienjuega2 btfss juegaB,0 ; corre el reloj del jugador B?


goto si_tablero ; no, volver de la ISR
decfsz ticsB,f ; si, decrementa el contador de tiempo
B
goto si_tablero ; si no ha llegado a 0 continua
decfsz ticsB1
goto contaB
call cadasecB ; si es 0 ejecutar cadasecB
movlw D'217' ; y poner ticsB al valor inicial
movwf ticsB ; ticsB = 217
movlw D'9'
movwf ticsB1
goto si_tablero ; volver de la ISR

109
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

contaA movlw D'217' ; y poner ticsA al valor inicial


movwf ticsA
goto si_tablero
contaB movlw D'217' ; y poner ticsB al valor inicial
movwf ticsB

si_tablero btfsc cambio,7 ; tablero conectado?


goto $+3 ; si
btfss cambio,4 ; no, tablero 2 conectado?
goto restaura ; no
btfsc juegaA,0 ; si, juega A?
goto $+3 ; no
btfss juegaB,0 ; juega B?
goto restaura ; no
decfsz tics_tab,f
goto restaura
decfsz tics_tab1,f
goto si_tablero1
bsf cambio,6 ; bit(6) cambio=1
movlw d'8' ; encuestas cada 0.5 segundos
movwf tics_tab1
si_tablero1 movlw d'122'
movwf tics_tab

restaura banco0
movf pclath_temp,W
movwf PCLATH
swapf status_temp,W ; restauramos registro de estado
original
movwf STATUS ; y lo guardamos en el registro de
estado
swapf w_temp,f ; restauramos el registro W
swapf w_temp,W ; sin variar los flags
bcf INTCON,T0IF ; limpiamos el flag de interrupción del TMR0
bsf INTCON,T0IE ; permitimos la interrupción del TMR0
retfie ; y salimos de la ISR

;-------------------------------------------------------------------------;
; Esta rutina se llama desde la ISR cada ;
; segundo que pasa para el jugador A. ;
;-------------------------------------------------------------------------;

cadasecA bsf PORTA,enable ; enable=1 tablero deshabilitado


bsf PORTA,enable2
btfsc finA,0 ; se ha terminado el tiempo total de A?
return ; si, volver sin hacer nada.
decf secunA,f ; no, decremento un segundo el contador
incfsz secunA,W ; eran las unidades de segundo = 0?
goto cadasecA_1 ; no, actualizar variables
movlw H'09' ; si, poner las unidades a 9
movwf secunA
decf secdeA,f ; y decrementar las decenas de segundo
incfsz secdeA,W ; eran las decenas de segundo = 0?
goto cadasecA_1 ; no, actualizar variables
movlw H'05' ; si, poner las decenas a 5
movwf secdeA
decf minunA,f ; decrementar las unidades de minuto
incfsz minunA,W ; eran las unidades de minuto = 0?
goto cadasecA_1 ; no, actualizar variables
movlw H'09' ; si, poner las unidades a 9
movwf minunA
decf mindeA,f ; decrementar las decenas de minuto
incfsz mindeA,W ; eran las decenas de minuto = 0?
goto cadasecA_1 ; no, actualizar variables
movlw H'05' ; si, poner las decenas a 5
movwf mindeA
decf horaA,f ; y decrementar la hora
cadasecA_1 btfss PORTE,ce_isd1

110
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

bsf PORTE,ce_isd1
bsf cambio,5 ; se ha cambiado la configuracion del puerto
D
banco1
clrf TRISD ; PORTD todo salidas
banco0
clrf PORTD ; si, fin de la encuesta
call lcd_tiempoA ; actualizamos las variables

movf secunA,f ; comprobamos si el contador es = 0


btfss STATUS,Z
goto autoA
movf secdeA,f
btfss STATUS,Z
goto autoA
movf minunA,f
btfss STATUS,Z
goto autoA
movf mindeA,f
btfss STATUS,Z
goto autoA
movf horaA,f
btfss STATUS,Z
goto autoA ; si no lo es volvemos
bcf auto,0 ; si el contador = 0
btfss flagA,0 ; miramos si está bandera puesta
goto extraA ; si no, comprobamos si hay tiempo de
Finish
fiA bsf finA,0
return
extraA btfss xtrtmpA,0 ; comprobamos si hay tiempo de Finish
goto fiA ; no hay
bsf flagA,0 ; si hay, ponemos la bandera
bcf xtrtmpA,0 ; quitamos el indicador de tiempo de finish
movf esecunA,W ; y volcamos las variables de tiempo de
Finish
movwf secunA ; en las variables de tiempo de
Control, que son
movf esecdeA,W ; las que maneja el programa en todo momento
movwf secdeA
movf eminunA,W
movwf minunA
movf emindeA,W
movwf mindeA
movf ehoraA,W
movwf horaA
btfss PORTE,ce_isd1
bsf PORTE,ce_isd1
bsf cambio,5 ; se ha cambiado la configuracion del puerto
D
banco1
clrf TRISD ; PORTD todo salidas
banco0
clrf PORTD ; si, fin de la encuesta
call lcd_tiempoA ; actualizamos las variables
return

autoA movf horaA,f


btfss STATUS,Z
return
movf minunA,f
btfss STATUS,Z
return
movf mindeA,f
btfss STATUS,Z
return
bsf auto,0
return

111
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------;
; Esta rutina se llama desde la ISR cada ;
; segundo que pasa para el jugador B. ;
;-------------------------------------------------------------------------;

;--------------- Comentarios análogos a la función cadasecA --------------;

cadasecB bsf PORTA,enable ; enable=1 tablero deshabilitado


bsf PORTA,enable2
btfsc finB,0
return
decf secunB,f
incfsz secunB,W
goto cadasecB_1
movlw H'09'
movwf secunB
decf secdeB,f
incfsz secdeB,W
goto cadasecB_1
movlw H'05'
movwf secdeB
decf minunB,f
incfsz minunB,W
goto cadasecB_1
movlw H'09'
movwf minunB
decf mindeB,f
incfsz mindeB,W
goto cadasecB_1
movlw H'05'
movwf mindeB
decf horaB,f
cadasecB_1 btfss PORTE,ce_isd1
bsf PORTE,ce_isd1
bsf cambio,5 ; se ha cambiado la configuracion del puerto
D
banco1
clrf TRISD ; PORTD todo salidas
banco0
clrf PORTD ; si, fin de la encuesta
call lcd_tiempoB ; actualizamos las variables

movf secunB,f
btfss STATUS,Z
goto autoB
movf secdeB,f
btfss STATUS,Z
goto autoB
movf minunB,f
btfss STATUS,Z
goto autoB
movf mindeB,f
btfss STATUS,Z
goto autoB
movf horaB,f
btfss STATUS,Z
goto autoB
bcf auto,1
btfss flagB,0
goto extraB
fiB bsf finB,0
return
extraB btfss xtrtmpB,0
goto fiB
bsf flagB,0
bcf xtrtmpB,0
movf esecunB,W

112
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf secunB
movf esecdeB,W
movwf secdeB
movf eminunB,W
movwf minunB
movf emindeB,W
movwf mindeB
movf ehoraB,W
movwf horaB
btfss PORTE,ce_isd1
bsf PORTE,ce_isd1
bsf cambio,5 ; se ha cambiado la configuracion del puerto
D
banco1
clrf TRISD ; PORTD todo salidas
banco0
clrf PORTD ; si, fin de la encuesta
call lcd_tiempoB ; actualizamos las variables
return

autoB movf horaB,f


btfss STATUS,Z
return
movf minunB,f
btfss STATUS,Z
return
movf mindeB,f
btfss STATUS,Z
return
bsf auto,1
return

;-------------------------------------------------------------------------;
; principal ;
;-------------------------------------------------------------------------;

principal call inicializar ; configuramos puertos, TMR0, etc.

inicio clrf auto


call cogeree ; ponemos constantes de la eeprom en las
var's de juego
pagina1
call comp_tablero ; mira si tablero conectado

pagina0
movlw H'00' ; inicializacion variables de partida y audio
movwf finA
movwf finB
movwf flagA
movwf flagB

movlw b_ram ; @ base ram 0x110 banco 2


movwf base_ram
movlw D'217' ; inicializa contadores
movwf ticsA ; ticsA=217, ticsB=217
movwf ticsB
movlw D'9' ; ticsA1=ticsB1=9
movwf ticsA1
movwf ticsB1
movlw h'C7'
call lcd_i
btfsc cambio,7 ; tablero conectado?
goto $+3 ; si
btfss cambio,4 ; no, tablero 2 conectado?
goto botones ; no
pagina2 ; si
call inicio_anterior ; inicializa la tabla anterior
call inicio_piezas ; inicializa la tabla piezas

113
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

pagina0

botones btfsc cambio,7 ; tablero conectado?


goto botones2 ; si
btfsc cambio,4 ; tablero 2 conectado?
goto botones2 ; si
btfss PORTB,b_jugA ; no, boton A pulsado?
goto empiezaB ; si, saltamos a empiezaB
botones2 btfss PORTB,b_jugB ; boton B pulsado?
goto empiezaA ; si, saltamos a empiezaA
btfss PORTB,b_set ; boton set pulsado?
call setcuenta ; si, ejecutamos setcuenta
btfsc PORTB,b_next ; boton next pulsado?
goto $+d'10'
btfss estado_botones,b_next
goto botones
bcf estado_botones,b_next
pagina1 ; si, se inicia transferencia 232
call tx_rs232
pagina0
goto botones
call cont_20ms
btfsc PORTB,b_next
bsf estado_botones,b_next
goto botones

;-------------------------------------------------------------------------;
; empiezaA, empiezaB
;-------------------------------------------------------------------------;

empiezaA bsf juegaA,0 ; indicamos que juega el jugador A


clrf TMR0 ; inicializa TMR0
call lcd_jugA
goto partida ; y entramos en el bucle de partida

empiezaB bsf juegaB,0 ; indicamos que juega el jugador B


clrf TMR0 ; inicializa TMR0
call lcd_jugB
goto partida ; y entramos en el bucle de partida

;-------------------------------------------------------------------------;
; partida, cmpset
;-------------------------------------------------------------------------;

partida btfsc PORTB,b_jugA ; boton jugador A pulsado?


goto $+5 ; no
btfss estado_botones,b_jugA
goto $+6
bcf estado_botones,b_jugA
goto jugB ; si, juega B
call cont_20ms
btfsc PORTB,b_jugA
bsf estado_botones,b_jugA

btfsc PORTB,b_jugB ; boton jugador B pulsado?


goto $+5 ; no
btfss estado_botones,b_jugB
goto cmp_set
bcf estado_botones,b_jugB
goto jugA ; si, juega A
call cont_20ms
btfsc PORTB,b_jugB
bsf estado_botones,b_jugB
goto cmp_set

jugA btfsc juegaA,0 ; variable actualizada?


goto jugA_1 ; si la var ya esta actualizada saltamos
btfsc cambio,7 ; tablero conectado?

114
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto $+3
btfss cambio,4 ; no, tablero2 conectado?
goto $+3
btfsc control,0 ; turno de las blancas?
goto jugA_1
bsf juegaA,0 ; si no, se actualiza juegaA=1, juegaB=0
bcf juegaB,0
btfss nsecmov,0 ; estamos en algun modo fischer?
goto $+4
pagina1
call incrementoB ; si, incrementar var tiempo B
call lcd_jugA ; no, actualizar display señal quien juega
jugA_1 btfsc estado_botones,b_jugA
goto partida
bcf juegaA,0
bcf juegaB,0
call lcd_nojug
goto partida

jugB btfsc juegaB,0 ; variable actualizada?


goto jugB_1 ; si la var ya esta actualizada saltamos
btfsc cambio,7 ; tablero conectado?
goto $+3
btfss cambio,4 ; no, tablero2 conectado?
goto $+3
btfss control,0 ; turno de las negras?
goto jugB_1
bsf juegaB,0 ; si no, se actualiza juegaA=1, juegaB=0
bcf juegaA,0
btfss nsecmov,0 ; estamos en algun modo fischer?
goto $+4
pagina1
call incrementoA ; si, incrementar var tiempo A
call lcd_jugB ; no, actualizar display señal quien juega
jugB_1 btfsc estado_botones,b_jugB
goto partida
bcf juegaA,0
bcf juegaB,0
call lcd_nojug
goto partida

cmp_set btfsc reproA,0 ; estamos reproduciendo para el jugador A?


goto cmp_1 ; si, saltamos
cmp_2 btfsc reproB,0 ; estamos reproduciendo para el jugador B?
goto cmp_3 ; si, saltamos
cmp_4 btfss auto,0 ; modo autoA?
goto $+5 ; no
btfsc reproA,0
goto $+3
btfsc juegaA,0
call repsecA_A
btfss auto,1 ; no, modo autoB?
goto cmp_set1 ; no
btfsc reproB,0
goto cmp_set1
btfss juegaB,0
goto cmp_set1
pagina1 ; si
call repsecB_B
pagina0
goto cmp_set1
cmp_1 pagina1
call reproduceA
pagina0
goto cmp_2
cmp_3 pagina1
call reproduceB
pagina0

115
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto cmp_4

cmp_set1 btfsc PORTB,b_set ; miramos si boton pulsado


goto $+6
btfss estado_botones,b_set
goto $+7
bcf estado_botones,b_set
goto boton_set
goto $+4
call cont_20ms
btfsc PORTB,b_set
bsf estado_botones,b_set

btfsc PORTB,b_mode
goto $+6
btfss estado_botones,b_mode
goto $+7
bcf estado_botones,b_mode
call tiempoA_B
goto $+4
call cont_20ms
btfsc PORTB,b_mode
bsf estado_botones,b_mode

btfsc PORTB,b_up
goto $+6
btfss estado_botones,b_up
goto $+7
bcf estado_botones,b_up
call tiempoB_A
goto $+4
call cont_20ms
btfsc PORTB,b_up
bsf estado_botones,b_up

btfsc PORTB,b_next
goto $+d'17'
btfss estado_botones,b_next
goto cmp_set4
bcf estado_botones,b_next
btfsc juegaA,0
goto $+9
btfsc juegaB,0
goto $+7
pagina1 ; si, se inicia transferencia 232
call tx_rs232
pagina0
goto cmp_set4
call tiempoA_A
goto cmp_set4
goto $+4
call cont_20ms
btfsc PORTB,b_next
bsf estado_botones,b_next

cmp_set4 btfsc PORTB,b_jugadaA


goto $+6
btfss estado_botones,b_jugadaA
goto $+7
bcf estado_botones,b_jugadaA
goto cmp_set2
goto $+4
call cont_20ms
btfsc PORTB,b_jugadaA
bsf estado_botones,b_jugadaA

btfsc PORTB,b_jugadaB
goto $+6

116
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

btfss estado_botones,b_jugadaB
goto $+7
bcf estado_botones,b_jugadaB
goto cmp_set3
goto $+4
call cont_20ms
btfsc PORTB,b_jugadaB
bsf estado_botones,b_jugadaB
goto tiempo_encuesta

boton_set btfsc juegaA,0 ; juegaA=1?


goto boton_set1 ; si, se repruduce un mensaje
btfsc juegaB,0 ; juegaB=1?
goto boton_set1 ; si, se repruduce un mensaje
goto inicio ; iniciar nueva partida
boton_set1 call tiempoB_B ; los relojes han de estar parados para
iniciar
goto partida ; una nueva partida

tiempo_encuesta btfsc cambio,7 ; tablero conectado?


goto $+3
btfss cambio,4
goto partida
btfss cambio,6 ; tiempo de encuesta?
goto partida
pagina2
goto inicio_encuesta ; inicia la encuesta
tiempo_enc1 bcf cambio,6
goto partida ; no, repite el bucle

cmp_set2 pagina1
call repro_jugadaA
pagina0
goto partida
cmp_set3 pagina1
call repro_jugadaB
pagina0
goto partida

;-------------------------------------------------------------------------;
; setcuenta: pone la cuenta inicial de la proxima partida
;-------------------------------------------------------------------------;

setcuenta movlw D'12' ; aumentamos offset


addwf offset,f ; para mostrar el siguiente modo
movlw D'84' ; hemos llegado al modo 84?
subwf offset,W ; será cero si hemos llegado
btfsc STATUS,Z
clrf offset ; si, offset=0
call cogeree
call espera_set ; esperamos a que se suelte el boton set
setcuenta_1 btfss PORTB,b_jugA ; si se pulsa algun boton A o B salimos
goto salir
btfss PORTB,b_jugB
goto salir
btfss PORTB,b_set ; boton set pulsado?
goto setcuenta
goto setcuenta_1

salir movf offset,W ; guardamos el offset


banco2
movwf EEDATA ; para que la próxima vez que
movlw H'00' ; se encienda el reloj, se empiece
movwf EEADR ; con la cuenta seleccionada
call escribiree
return

;-------------------------------------------------------------------------

117
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

; espera_set: espera a que se suelte el boton set


;-------------------------------------------------------------------------

espera_set btfss PORTB,b_set ; boton set pulsado?


goto $-1 ; si, salta
call cont_20ms ; no, temporiza 20ms por si hay rebotes
btfss PORTB,b_set ; boton set pulsado?
goto $-4 ; si, salta
return

;-------------------------------------------------------------------------;
; Rutina para coger de la EEPROM del PIC la cuenta inicial. ;
;-------------------------------------------------------------------------;

cogeree movlw H'01' ; 1a posición de la eeprom +


addwf offset,W ; offset desde el principio en W
call leeree ; leemos un byte de la EEPROM
movwf nsecmov ; y lo ponemos en el registro.
movlw H'02' ; hacemos lo mismo sucesivamente para
addwf offset,W ; todos los registros de los dos jugadores
call leeree
movwf xtrtmpA
movwf xtrtmpB
movlw H'03'
addwf offset,W
call leeree
movwf horaA
movwf horaB
movlw H'04'
addwf offset,W
call leeree
movwf mindeA
movwf mindeB
movlw H'05'
addwf offset,W
call leeree
movwf minunA
movwf minunB
movlw H'06'
addwf offset,W
call leeree
movwf secdeA
movwf secdeB
movlw H'07'
addwf offset,W
call leeree
movwf secunA
movwf secunB
movlw H'08'
addwf offset,W
call leeree
movwf ehoraA
movwf ehoraB
movlw H'09'
addwf offset,W
call leeree
movwf emindeA
movwf emindeB
movlw H'0A'
addwf offset,W
call leeree
movwf eminunA
movwf eminunB
movlw H'0B'
addwf offset,W
call leeree
movwf esecdeA
movwf esecdeB

118
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw H'0C'
addwf offset,W
call leeree
movwf esecunA
movwf esecunB
call lcd_tiempoA
call lcd_tiempoB
return

;-------------------------------------------------------------------------;
; Rutina para leer un byte de la memoria de datos EEPROM
;-------------------------------------------------------------------------;

leeree banco2 ; vamos al banco 2 de memoria


movwf EEADR ; ponemos la dirección a leer en EEADR
banco3
bcf EECON1,EEPGD ; apuntamos a la memoria de datos
bsf EECON1,RD ; empezamos la operación de lectura
banco2 ; volvemos al banco 2
movf EEDATA,W ; ponemos al byte leído en W
banco0
return

;-------------------------------------------------------------------------;
; Rutina para escribir un byte en la memoria de datos EEPROM
;-------------------------------------------------------------------------;

escribiree banco3 ; vamos al banco 3 de memoria


bcf EECON1,EEPGD ; apuntamos a la memoria de datos
bsf EECON1,WREN ; habilitamos la escritura
bcf INTCON,GIE ; deshabilitamos interrupciones
movlw H'55' ; secuencia de instrucciones
movwf EECON2 ; especial requerida por
movlw H'AA' ; Microchip
movwf EECON2
bsf EECON1,WR ; empezar la operación de escritura
bsf INTCON,GIE ; habilitamos interrupciones
bcf EECON1,WREN ; deshabilitamos la escritura
btfsc EECON1,WR ; esperamos a que termine la
goto $-1 ; operación de escritura
banco0
return

;-------------------------------------------------------------------------
; configura_lcd: configuracion inicial del display
;-------------------------------------------------------------------------

configura_lcd bcf PORTA,DIS_RW ; escribir en el módulo LCD


call borra_pantalla ; reset inicial
movlw b'00110000' ; trabajamos con bus de 8 bits, matriz 5x7
dots
call lcd_i
movlw b'00111000' ; activacion de dos lineas
call lcd_i
movlw b'00001100' ; enciende pantalla, cursor apagado
call lcd_i
movlw b'00000110' ; incremento del cursor, no desplazamiento
del texto
call lcd_i
call borra_pantalla
return

;-------------------------------------------------------------------------
; borra_pantalla: borra la pantalla del display
;-------------------------------------------------------------------------

borra_pantalla movlw b'00000001' ; Borra la pantalla


call lcd_i

119
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

call cont_20ms
movlw b'00000010' ; Nos situamos en la posicion 0 de la memoria
DDRAM
call lcd_i
call cont_20ms
return

;-------------------------------------------------------------------------;
; lcd_jugA : actualiza indicador de tiempo jugador A
;-------------------------------------------------------------------------;

lcd_jugA movlw h'C0' ; direccion 40h, instruccion b'11000000'


call lcd_i
movlw ' '
call lcd_c
movlw h'87' ; direccion 07h
call lcd_i
movlw '>'
call lcd_c
return

;-------------------------------------------------------------------------;
; lcd_jugB : actualiza indicador de tiempo jugador B
;-------------------------------------------------------------------------;

lcd_jugB movlw h'C0' ; direccion 40h, instruccion b'11000000'


call lcd_i
movlw '<'
call lcd_c
movlw h'87' ; direccion 07h
call lcd_i
movlw ' '
call lcd_c
return

;-------------------------------------------------------------------------;
; lcd_nojug : quita los indicadores de tiempo
;-------------------------------------------------------------------------;

lcd_nojug movlw h'C0' ; direccion 40h, instruccion b'11000000'


call lcd_i
movlw ' '
call lcd_c
movlw h'87' ; direccion 07h
call lcd_i
movlw ' '
call lcd_c
return

;-------------------------------------------------------------------------;
; actualiza display tiempo A
;-------------------------------------------------------------------------;

lcd_tiempoA movlw h'80' ; direccion 00h


call lcd_i
movlw ' '
call lcd_c
movlw ' '
call lcd_c

movf horaA,f ; horaA=0?


btfsc STATUS,Z
goto act_minA
movlw ' '
call lcd_c
movlw d'48'
addwf horaA,w
call lcd_c

120
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw ':'
call lcd_c
movlw d'48'
addwf mindeA,w
call lcd_c
movlw d'48'
addwf minunA,w
call lcd_c
return

act_minA movlw d'48'


addwf mindeA,w
call lcd_c
movlw d'48'
addwf minunA,w
call lcd_c
movlw ':'
call lcd_c
movlw d'48'
addwf secdeA,w
call lcd_c
movlw d'48'
addwf secunA,w
call lcd_c
return

;-------------------------------------------------------------------------;
; actualiza display tiempo B
;-------------------------------------------------------------------------;

lcd_tiempoB movlw h'C1' ; direccion C1h


call lcd_i

movf horaB,f ; horaB=0?


btfsc STATUS,Z
goto act_minB
movlw ' '
call lcd_c
movlw d'48'
addwf horaB,w
call lcd_c
movlw ':'
call lcd_c
movlw d'48'
addwf mindeB,w
call lcd_c
movlw d'48'
addwf minunB,w
call lcd_c
goto lcd_tiempoB_1

act_minB movlw d'48'


addwf mindeB,w
call lcd_c
movlw d'48'
addwf minunB,w
call lcd_c
movlw ':'
call lcd_c
movlw d'48'
addwf secdeB,w
call lcd_c
movlw d'48'
addwf secunB,w
call lcd_c

lcd_tiempoB_1 return

121
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------
; cont_20ms: retardo de 20 milisegundos
;-------------------------------------------------------------------------

cont_20ms movlw RETARDO2


movwf cont_ms
cont_20_1 movlw RETARDO1 ;58µS
movwf cont_us
cont_58_4 nop
decfsz cont_us,f
goto cont_58_4
mira_reproduce
movlw RETARDO1 ;58µS
movwf cont_us
cont_58_5 nop
decfsz cont_us,f
goto cont_58_5
decfsz cont_ms,f
goto cont_20_1
return

;-------------------------------------------------------------------------
; funciones display
;-------------------------------------------------------------------------

lcd_c movwf PORTD


bsf PORTA,DIS_RS
bsf PORTE,DIS_E
movlw RETARDO1 ;58µS
movwf cont_us
cont_58_8 nop
decfsz cont_us,f
goto cont_58_8
bcf PORTE,DIS_E
return

lcd_i movwf PORTD


bcf PORTA,DIS_RS
bsf PORTE,DIS_E
movlw RETARDO1 ;58µS
movwf cont_us
cont_58_9 nop
decfsz cont_us,f
goto cont_58_9
bcf PORTE,DIS_E
return

;-------------------------------------------------------------------------;
; tiempoA_A : reproduce el tiempo restante del jugador A por
; el auricular de A
;-------------------------------------------------------------------------;

tiempoA_A btfsc auto,0 ; estamos en modo automatico?


goto tiempoA_A1
btfsc reproA,0 ; estamos reproduciendo por el auricular de
A?
goto tiempoA_A1

movf horaA,f
btfsc STATUS,Z ; horaA=0?
goto $+3
call rephoraA_A
goto tiempoA_A1

movf mindeA,f
btfsc STATUS,Z
goto $+3
call repminA_A

122
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto tiempoA_A1

movf minunA,f
btfsc STATUS,Z
goto $+3
call repminA_A
goto tiempoA_A1

movf secdeA,f
btfsc STATUS,Z
goto $+3
call repsecA_A
goto tiempoA_A1

movf secunA,f
btfsc STATUS,Z
goto $+2
call repsecA_A

tiempoA_A1 return

;-------------------------------------------------------------------------;
; tiempoB_A : reproduce el tiempo restante del jugador B por
; el auricular de A
;-------------------------------------------------------------------------;

tiempoB_A btfsc auto,0 ; estamos en modo automatico?


goto tiempoB_A1
btfsc reproA,0 ; estamos reproduciendo por el auricular de
A?
goto tiempoB_A1

movf horaB,f
btfsc STATUS,Z ; horaA=0?
goto $+3
call rephoraB_A
goto tiempoB_A1

movf mindeB,f
btfsc STATUS,Z
goto $+3
call repminB_A
goto tiempoB_A1

movf minunB,f
btfsc STATUS,Z
goto $+3
call repminB_A
goto tiempoB_A1

movf secdeB,f
btfsc STATUS,Z
goto $+3
call repsecB_A
goto tiempoB_A1

movf secunB,f
btfsc STATUS,Z
goto $+2
call repsecB_A

tiempoB_A1 return

;-------------------------------------------------------------------------;
; tiempoA_B : reproduce el tiempo restante del jugador A por
; el auricular de B
;-------------------------------------------------------------------------;

123
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

tiempoA_B btfsc auto,1


goto tiempoA_B1
btfsc reproB,0 ; estamos reproduciendo por el auricular de
A?
goto tiempoA_B1

movf horaA,f
btfsc STATUS,Z ; horaA=0?
goto $+3
call rephoraA_B
goto tiempoA_B1

movf mindeA,f
btfsc STATUS,Z
goto $+3
call repminA_B
goto tiempoA_B1

movf minunA,f
btfsc STATUS,Z
goto $+3
call repminA_B
goto tiempoA_B1

movf secdeA,f
btfsc STATUS,Z
goto $+3
call repsecA_B
goto tiempoA_B1

movf secunA,f
btfsc STATUS,Z
goto $+2
call repsecA_B

tiempoA_B1 return

;-------------------------------------------------------------------------;
; tiempoB_B : reproduce el tiempo restante del jugador B por
; el auricular de B
;-------------------------------------------------------------------------;

tiempoB_B btfsc auto,1


goto tiempoB_B1
btfsc reproB,0 ; estamos reproduciendo por el auricular de
A?
goto tiempoB_B1

movf horaB,f
btfsc STATUS,Z ; horaA=0?
goto $+7
pagina1
call rephoraB_B
pagina0
goto tiempoB_B1

movf mindeB,f
btfsc STATUS,Z
goto $+7
pagina1
call repminB_B
pagina0
goto tiempoB_B1

movf minunB,f
btfsc STATUS,Z
goto $+7

124
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

pagina1
call repminB_B
pagina0
goto tiempoB_B1

movf secdeB,f
btfsc STATUS,Z
goto $+7
pagina1
call repsecB_B
pagina0
goto tiempoB_B1

movf secunB,f
btfsc STATUS,Z
goto $+6
pagina1
call repsecB_B
pagina0

tiempoB_B1 return

;-------------------------------------------------------------------------;
; rephoraA_A : reproduce hora y minutos de A por A
;-------------------------------------------------------------------------;

rephoraA_A clrf contA


movlw h'01'
subwf horaA,W ; horaA=1?
btfss STATUS,Z
goto $+8 ; no, saltamos
movlw una
movwf msg1A ; si, cargamos @ de "una"
incf contA
movlw hora ; cargamos @ de "hora"
movwf msg2A
incf contA
goto rephoraAA4

movlw HIGH(tablaISD_un)
movwf PCLATH
movf horaA,W
call tablaISD_un
movwf msg1A
incf contA
movlw horas ; @ de "horas"
movwf msg2A
incf contA
pagina0

rephoraAA4 movf mindeA,f


btfss STATUS,Z
goto rephoraAA1
movf minunA,f ; minunA=0?
btfsc STATUS,Z
goto repA_A ; si, minunA=0 y mindeA=0, saltamos
movlw HIGH(tablaISD_un) ; no
movwf PCLATH
movf minunA,W
call tablaISD_un ; mindeA=0
movwf msg3A
incf contA
pagina0
movlw H'01'
subwf minunA,W
btfss STATUS,Z
goto repminutosAA
movlw minuto ; @ de "minuto"

125
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf msg4A
incf contA
goto repA_A

repminutosAA movlw minutos ; @ de "minutos"


movwf msg4A
incf contA
goto repA_A

rephoraAA1 movf minunA,f


btfss STATUS,Z
goto rephoraAA2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeA,W
call tablaISD_diez
movwf msg3A
incf contA
pagina0
goto repminutosAA

rephoraAA2 movlw H'01' ; mindea<>0, minunA<>0


subwf mindeA,W
btfss STATUS,Z ; mindea=1
goto rephoraAA3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunA,W
call tablaISD_once
movwf msg3A
incf contA
pagina0
goto repminutosAA

rephoraAA3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeA,W
call tablaISD_veinti
movwf msg3A
pagina0
incf contA
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un
movwf msg4A
pagina0
incf contA
movlw minutos ; @ de "minutos"
movwf msg5A
incf contA

repA_A btfss juegaA,0


goto repA_A1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repA_A1 btfss juegaB,0
goto repA_A2
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3

repA_A2 pagina1
call reset_isd1
pagina0

126
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movf msg1A,W ; lanzamos el primer mensaje


movwf PORTD ; para reproducir
call cont_20ms
bcf PORTE,ce_isd1 ; ce=0, habilitado
call cont_20ms
call cont_20ms
bsf PORTE,ce_isd1 ; ce=1, deshabilitado

movlw H'64' ; @ de la variable 'msg1A'


movwf cont2A
bsf reproA,0
return

;-------------------------------------------------------------------------;
; repminA_A : reproduce minutos y segundos de A por A
;-------------------------------------------------------------------------;

repminA_A clrf contA


movf mindeA,f
btfss STATUS,Z
goto repminAA1
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un
movwf msg1A
pagina0
incf contA
movlw H'01'
subwf minunA,W
btfss STATUS,Z
goto repminAA
movlw minuto ; @ de minuto en W
movwf msg2A
incf contA
goto repminAA4

repminAA movlw minutos ; @ de minutos en W


movwf msg2A
incf contA
goto repminAA4

repminAA1 movf minunA,f


btfss STATUS,Z
goto repminAA2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeA,W
call tablaISD_diez
movwf msg1A
pagina0
incf contA
goto repminAA

repminAA2 movlw H'01'


subwf mindeA,W
btfss STATUS,Z
goto repminAA3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunA,W
call tablaISD_once
movwf msg1A
pagina0
incf contA
goto repminAA

repminAA3 movlw HIGH(tablaISD_veinti)

127
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf PCLATH
movf mindeA,W
call tablaISD_veinti
movwf msg1A
pagina0
incf contA
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un
movwf msg2A
pagina0
incf contA
movlw minutos ; @ de minutos
movwf msg3A
incf contA

repminAA4 movf secdeA,f ; calculo de segundos


btfss STATUS,Z
goto repminAA6
movf secunA,f ; secunA=0?
btfsc STATUS,Z
goto repA_A ; si, secunA=0 y secdeA=0, saltamos
movlw HIGH(tablaISD_un) ; no
movwf PCLATH
movf secunA,W
call tablaISD_un
pagina0

repminAA5 movwf auxAA


movlw H'03'
subwf contA,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg4A
incf contA
movlw segundos ; @ de segundos
movwf msg5A
incf contA
goto repA_A

movf auxAA,W
movwf msg3A
incf contA
movlw segundos ; @ de segundos
movwf msg4A
incf contA
goto repA_A

repminAA6 movf secunA,f


btfss STATUS,Z
goto repminAA9
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeA,W
call tablaISD_diez
pagina0
goto repminAA5

repminAA9 movlw H'01'


subwf secdeA,W
btfss STATUS,Z
goto repminAA8
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunA,W
call tablaISD_once

128
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

pagina0
goto repminAA5

repminAA8 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeA,W
call tablaISD_veinti
movwf auxAA
pagina0
movlw H'03'
subwf contA,W
btfss STATUS,Z
goto $+5
movf auxAA,W
movwf msg4A
incf contA
goto $+4

movf auxAA,W
movwf msg3A
incf contA

movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un
movwf auxAA
pagina0
movlw H'04'
subwf contA,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg5A
incf contA
movlw segundos ; @ de segundos
movwf msg6A
incf contA
goto repA_A

movf auxAA,W
movwf msg4A
incf contA
movlw segundos ; @ de segundos
movwf msg5A
incf contA
goto repA_A

;-------------------------------------------------------------------------;
; repsecA_A : reproduce los segundos de A por A
;-------------------------------------------------------------------------;

repsecA_A clrf contA


movf secdeA,W
btfss STATUS,Z
goto repsecAA2
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un
repsecAA movwf msg1A
pagina0
incf contA
movlw segundos ; @ de segundos
movwf msg2A
incf contA
goto repA_A

129
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

repsecAA2 movf secunA,f


btfss STATUS,Z
goto repsecAA3
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeA,W
call tablaISD_diez
pagina0
goto repsecAA

repsecAA3 movlw H'01'


subwf secdeA,W
btfss STATUS,Z
goto repsecAA4
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunA,W
call tablaISD_once
pagina0
goto repsecAA

repsecAA4 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeA,W
call tablaISD_veinti
movwf msg1A
pagina0
incf contA
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un
movwf msg2A
pagina0
incf contA
movlw segundos ; @ de segundos
movwf msg3A
incf contA
goto repA_A

;-------------------------------------------------------------------------;
; rephoraB_A : reproduce hora y minutos de B por A
;-------------------------------------------------------------------------;

rephoraB_A clrf contA


movlw h'01'
subwf horaB,W ; horaB=1?
btfss STATUS,Z
goto $+8 ; no, saltamos
movlw una
movwf msg1A ; si, cargamos @ de "una"
incf contA
movlw hora ; cargamos @ de "hora"
movwf msg2A
incf contA
goto rephoraBA4

movlw HIGH(tablaISD_un)
movwf PCLATH
movf horaB,W
call tablaISD_un
movwf msg1A
incf contA
movlw horas ; @ de "horas"
movwf msg2A
incf contA
pagina0

130
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

rephoraBA4 movf mindeB,f


btfss STATUS,Z
goto rephoraBA1
movf minunB,f ; minunB=0?
btfsc STATUS,Z
goto repB_A ; si, minunB=0 y mindeB=0, saltamos
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un ; mindeB=0
movwf msg3A
incf contA
pagina0
movlw H'01'
subwf minunB,W
btfss STATUS,Z
goto repminutosBA
movlw minuto ; @ de "minuto"
movwf msg4A
incf contA
goto repB_A

repminutosBA movlw minutos ; @ de "minutos"


movwf msg4A
incf contA
goto repB_A

rephoraBA1 movf minunB,f


btfss STATUS,Z
goto rephoraBA2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeB,W
call tablaISD_diez
movwf msg3A
incf contA
pagina0
goto repminutosBA

rephoraBA2 movlw H'01' ; mindeB<>0, minunB<>0


subwf mindeB,W
btfss STATUS,Z ; mindeB=1
goto rephoraBA3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunB,W
call tablaISD_once
movwf msg3A
incf contA
pagina0
goto repminutosBA

rephoraBA3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeB,W
call tablaISD_veinti
movwf msg3A
pagina0
incf contA
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un
movwf msg4A
pagina0
incf contA
movlw minutos ; @ de "minutos"

131
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf msg5A
incf contA

repB_A btfss juegaA,0


goto repB_A1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repB_A1 btfss juegaB,0
goto repB_A2
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3

repB_A2 pagina1
call reset_isd1
pagina0
movf msg1A,W ; lanzamos el primer mensaje
movwf PORTD ; para reproducir
call cont_20ms
bcf PORTE,ce_isd1 ; ce=0, habilitado
call cont_20ms
call cont_20ms
btfsc PORTE,ce_isd1
goto $-7
bsf PORTE,ce_isd1 ; ce=1, deshabilitado

movlw H'64' ; @ de la variable 'msg1A'


movwf cont2A
bsf reproA,0
return

;-------------------------------------------------------------------------;
; repminB_A : reproduce minutos y segundos de B por A
;-------------------------------------------------------------------------;

repminB_A clrf contA


movf mindeB,f
btfss STATUS,Z
goto repminBA1
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un
movwf msg1A
pagina0
incf contA
movlw H'01'
subwf minunB,W
btfss STATUS,Z
goto repminBA
movlw minuto ; @ de minuto en W
movwf msg2A
incf contA
goto repminBA4

repminBA movlw minutos ; @ de minutos en W


movwf msg2A
incf contA
goto repminBA4

repminBA1 movf minunB,f


btfss STATUS,Z
goto repminBA2
movlw HIGH(tablaISD_diez)
movwf PCLATH

132
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movf mindeB,W
call tablaISD_diez
movwf msg1A
pagina0
incf contA
goto repminBA

repminBA2 movlw H'01'


subwf mindeB,W
btfss STATUS,Z
goto repminBA3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunB,W
call tablaISD_once
movwf msg1A
pagina0
incf contA
goto repminBA

repminBA3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeB,W
call tablaISD_veinti
movwf msg1A
pagina0
incf contA
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un
movwf msg2A
pagina0
incf contA
movlw minutos ; @ de minutos
movwf msg3A
incf contA

repminBA4 movf secdeB,f ; calculo de segundos


btfss STATUS,Z
goto repminBA6
movf secunB,f ; secunB=0?
btfsc STATUS,Z
goto repB_A ; si, secunB=0 y secdeB=0, saltamos
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
pagina0

repminBA5 movwf auxAA


movlw H'03'
subwf contA,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg4A
incf contA
movlw segundos ; @ de segundos
movwf msg5A
incf contA
goto repB_A

movf auxAA,W
movwf msg3A
incf contA
movlw segundos ; @ de segundos
movwf msg4A

133
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

incf contA
goto repB_A

repminBA6 movf secunB,f


btfss STATUS,Z
goto repminBA9
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeB,W
call tablaISD_diez
pagina0
goto repminBA5

repminBA9 movlw H'01'


subwf secdeB,W
btfss STATUS,Z
goto repminBA8
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunB,W
call tablaISD_once
pagina0
goto repminBA5

repminBA8 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeB,W
call tablaISD_veinti
movwf auxAA
pagina0
movlw H'03'
subwf contA,W
btfss STATUS,Z
goto $+5
movf auxAA,W
movwf msg4A
incf contA
goto $+4

movf auxAA,W
movwf msg3A
incf contA

movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
movwf auxAA
pagina0
movlw H'04'
subwf contA,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg5A
incf contA
movlw segundos ; @ de segundos
movwf msg6A
incf contA
goto repB_A

movf auxAA,W
movwf msg4A
incf contA
movlw segundos ; @ de segundos
movwf msg5A
incf contA
goto repB_A

134
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------;
; repsecB_A : reproduce los segundos de B por A
;-------------------------------------------------------------------------;

repsecB_A clrf contA


movf secdeB,W
btfss STATUS,Z
goto repsecBA2
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
repsecBA movwf msg1A
pagina0
incf contA
movlw segundos ; @ de segundos
movwf msg2A
incf contA
goto repB_A

repsecBA2 movf secunB,f


btfss STATUS,Z
goto repsecBA3
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeB,W
call tablaISD_diez
pagina0
goto repsecBA

repsecBA3 movlw H'01'


subwf secdeB,W
btfss STATUS,Z
goto repsecBA4
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunB,W
call tablaISD_once
pagina0
goto repsecBA

repsecBA4 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeB,W
call tablaISD_veinti
movwf msg1A
pagina0
incf contA
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
movwf msg2A
pagina0
incf contA
movlw segundos ; @ de segundos
movwf msg3A
incf contA
goto repB_A

;-------------------------------------------------------------------------;
; rephoraA_B : reproduce hora y minutos de A por B
;-------------------------------------------------------------------------;

rephoraA_B clrf contB


movlw h'01'

135
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

subwf horaA,W ; horaA=1?


btfss STATUS,Z
goto $+8 ; no, saltamos
movlw una
movwf msg1B ; si, cargamos @ de "una"
incf contB
movlw hora ; cargamos @ de "hora"
movwf msg2B
incf contB
goto rephoraAB4

movlw HIGH(tablaISD_un)
movwf PCLATH
movf horaA,W
call tablaISD_un
movwf msg1B
incf contB
movlw horas ; @ de "horas"
movwf msg2B
incf contB
pagina0

rephoraAB4 movf mindeA,f


btfss STATUS,Z
goto rephoraAB1
movf minunA,f ; minunA=0?
btfsc STATUS,Z
goto repA_B ; si, minunA=0 y mindeA=0, saltamos
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un ; mindeA=0
movwf msg3B
incf contB
pagina0
movlw H'01'
subwf minunA,W
btfss STATUS,Z
goto repminutosAB
movlw minuto ; @ de "minuto"
movwf msg4B
incf contB
goto repA_B

repminutosAB movlw minutos ; @ de "minutos"


movwf msg4B
incf contB
goto repA_B

rephoraAB1 movf minunA,f


btfss STATUS,Z
goto rephoraAB2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeA,W
call tablaISD_diez
movwf msg3B
incf contB
pagina0
goto repminutosAB

rephoraAB2 movlw H'01' ; mindeA<>0, minunA<>0


subwf mindeA,W
btfss STATUS,Z ; mindeA=1
goto rephoraAB3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunA,W

136
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

call tablaISD_once
movwf msg3B
incf contB
pagina0
goto repminutosAB

rephoraAB3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeA,W
call tablaISD_veinti
movwf msg3B
pagina0
incf contB
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un
movwf msg4B
pagina0
incf contB
movlw minutos ; @ de "minutos"
movwf msg5B
incf contB

repA_B btfss juegaA,0


goto repA_B1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repA_B1 btfss juegaB,0
goto repA_B2
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3

repA_B2 pagina1
call reset_isd2
pagina0
movf msg1B,W ; lanzamos el primer mensaje
movwf PORTD ; para reproducir
call cont_20ms
bcf PORTE,ce_isd2 ; ce=0, habilitado
call cont_20ms
call cont_20ms
bsf PORTE,ce_isd2 ; ce=1, deshabilitado

movlw H'6C' ; @ de la variable 'msg1B'


movwf cont2B
bsf reproB,0
return

;-------------------------------------------------------------------------;
; repminA_B : reproduce minutos y segundos de A por B
;-------------------------------------------------------------------------;

repminA_B clrf contB


movf mindeA,f
btfss STATUS,Z
goto repminAB1
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un
movwf msg1B
pagina0
incf contB

137
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw H'01'
subwf minunA,W
btfss STATUS,Z
goto repminAB
movlw minuto ; @ de minuto en W
movwf msg2B
incf contB
goto repminAB4

repminAB movlw minutos ; @ de minutos en W


movwf msg2B
incf contB
goto repminAB4

repminAB1 movf minunA,f


btfss STATUS,Z
goto repminAB2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeA,W
call tablaISD_diez
movwf msg1B
pagina0
incf contB
goto repminAB

repminAB2 movlw H'01'


subwf mindeA,W
btfss STATUS,Z
goto repminAB3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunA,W
call tablaISD_once
movwf msg1B
pagina0
incf contB
goto repminAB

repminAB3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeA,W
call tablaISD_veinti
movwf msg1B
pagina0
incf contB
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunA,W
call tablaISD_un
movwf msg2B
pagina0
incf contB
movlw minutos ; @ de minutos
movwf msg3B
incf contB

repminAB4 movf secdeA,f ; calculo de segundos


btfss STATUS,Z
goto repminAB6
movf secunA,f ; secunA=0?
btfsc STATUS,Z
goto repA_B ; si, secunA=0 y secdeA=0, saltamos

movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un

138
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

pagina0

repminAB5 movwf auxAA


movlw H'03'
subwf contB,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg4B
incf contB
movlw segundos ; @ de segundos
movwf msg5B
incf contB
goto repA_B

movf auxAA,W
movwf msg3B
incf contB
movlw segundos ; @ de segundos
movwf msg4B
incf contB
goto repA_B

repminAB6 movf secunA,f


btfss STATUS,Z
goto repminAB9
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeA,W
call tablaISD_diez
pagina0
goto repminAB5

repminAB9 movlw H'01'


subwf secdeA,W
btfss STATUS,Z
goto repminAB8
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunA,W
call tablaISD_once
pagina0
goto repminAB5

repminAB8 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeA,W
call tablaISD_veinti
movwf auxAA
pagina0
movlw H'03'
subwf contB,W
btfss STATUS,Z
goto $+5
movf auxAA,W
movwf msg4B
incf contB
goto $+4

movf auxAA,W
movwf msg3B
incf contB

movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un
movwf auxAA

139
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

pagina0
movlw H'04'
subwf contB,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg5B
incf contB
movlw segundos ; @ de segundos
movwf msg6B
incf contB
goto repA_B

movf auxAA,W
movwf msg4B
incf contB
movlw segundos ; @ de segundos
movwf msg5B
incf contB
goto repA_B

;-------------------------------------------------------------------------;
; repsecA_B : reproduce los segundos de A por B
;-------------------------------------------------------------------------;

repsecA_B clrf contB


movf secdeA,W
btfss STATUS,Z
goto repsecAB2
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un
repsecAB movwf msg1B
pagina0
incf contB
movlw segundos ; @ de segundos
movwf msg2B
incf contB
goto repA_B

repsecAB2 movf secunA,f


btfss STATUS,Z
goto repsecAB3
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeA,W
call tablaISD_diez
pagina0
goto repsecAB

repsecAB3 movlw H'01'


subwf secdeA,W
btfss STATUS,Z
goto repsecAB4
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunA,W
call tablaISD_once
pagina0
goto repsecAB

repsecAB4 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeA,W
call tablaISD_veinti
movwf msg1B

140
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

pagina0
incf contB
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunA,W
call tablaISD_un
movwf msg2B
pagina0
incf contB
movlw segundos ; @ de segundos
movwf msg3B
incf contB
goto repA_B

;************************************************************************

ORG 800 ; pagina 1

;************************************************************************

;-------------------------------------------------------------------------;
; rephoraB_B : reproduce hora y minutos de B por B
;-------------------------------------------------------------------------;

rephoraB_B clrf contB


movlw h'01'
subwf horaB,W ; horaB=1?
btfss STATUS,Z
goto $+8 ; no, saltamos
movlw una ; si, cargamos @ de "una"
movwf msg1B
incf contB
movlw hora ; cargamos @ de "hora"
movwf msg2B
incf contB
goto rephoraBB4

movlw HIGH(tablaISD_un)
movwf PCLATH
movf horaB,W
call tablaISD_un
movwf msg1B
incf contB
movlw horas ; @ de "horas"
movwf msg2B
incf contB

rephoraBB4 movf mindeB,f


btfss STATUS,Z
goto rephoraBB1
movf minunB,f ; minunB=0?
btfsc STATUS,Z
goto repB_B ; si, minunB=0 y mindeB=0, saltamos
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un ; mindeA=0
movwf msg3B
incf contB
movlw H'01'
subwf minunB,W
btfss STATUS,Z
goto repminutosBB
movlw minuto ; @ de "minuto"
movwf msg4B
incf contB
goto repA_B

141
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

repminutosBB movlw minutos ; @ de "minutos"


movwf msg4B
incf contB
goto repB_B

rephoraBB1 movf minunB,f


btfss STATUS,Z
goto rephoraBB2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeB,W
call tablaISD_diez
movwf msg3B
incf contB
goto repminutosBB

rephoraBB2 movlw H'01' ; mindeB<>0, minunB<>0


subwf mindeB,W
btfss STATUS,Z ; mindeB=1
goto rephoraBB3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunB,W
call tablaISD_once
movwf msg3B
incf contB
goto repminutosBB

rephoraBB3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeB,W
call tablaISD_veinti
movwf msg3B
incf contB
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un
movwf msg4B
incf contB
movlw minutos ; @ de "minutos"
movwf msg5B
incf contB

repB_B btfss juegaA,0


goto repB_B1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repB_B1 btfss juegaB,0
goto repB_B2
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3

repB_B2 call reset_isd2


movf msg1B,W ; lanzamos el primer mensaje
movwf PORTD ; para reproducir
pagina0
call cont_20ms
bcf PORTE,ce_isd2 ; ce=0, habilitado
call cont_20ms
call cont_20ms
bsf PORTE,ce_isd2 ; ce=1, deshabilitado
pagina1

142
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw H'6C' ; @ de la variable 'msg1B'


movwf cont2B
bsf reproB,0
return

;-------------------------------------------------------------------------;
; repminB_B : reproduce minutos y segundos de B por B
;-------------------------------------------------------------------------;

repminB_B clrf contB


movf mindeB,f
btfss STATUS,Z
goto repminBB1
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un
movwf msg1B
incf contB
movlw H'01'
subwf minunB,W
btfss STATUS,Z
goto repminBB
movlw minuto ; @ de minuto en W
movwf msg2B
incf contB
goto repminBB4

repminBB movlw minutos ; @ de minutos en W


movwf msg2B
incf contB
goto repminBB4

repminBB1 movf minunB,f


btfss STATUS,Z
goto repminBB2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf mindeB,W
call tablaISD_diez
movwf msg1B
incf contB
goto repminBB

repminBB2 movlw H'01'


subwf mindeB,W
btfss STATUS,Z
goto repminBB3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf minunB,W
call tablaISD_once
movwf msg1B
incf contB
goto repminBB

repminBB3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf mindeB,W
call tablaISD_veinti
movwf msg1B
incf contB
movlw HIGH(tablaISD_un)
movwf PCLATH
movf minunB,W
call tablaISD_un
movwf msg2B
incf contB

143
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw minutos ; @ de minutos


movwf msg3B
incf contB

repminBB4 movf secdeB,f ; calculo de segundos


btfss STATUS,Z
goto repminBB6
movf secunB,f ; secunB=0?
btfsc STATUS,Z
goto repB_B ; si, secunB=0 y secdeB=0, saltamos

movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un

repminBB5 movwf auxAA


movlw H'03'
subwf contB,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg4B
incf contB
movlw segundos ; @ de segundos
movwf msg5B
incf contB
goto repB_B

movf auxAA,W
movwf msg3B
incf contB
movlw segundos ; @ de segundos
movwf msg4B
incf contB
goto repB_B

repminBB6 movf secunB,f


btfss STATUS,Z
goto repminBB9
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeB,W
call tablaISD_diez
goto repminBB5

repminBB9 movlw H'01'


subwf secdeB,W
btfss STATUS,Z
goto repminBB8
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunB,W
call tablaISD_once
goto repminBB5

repminBB8 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeB,W
call tablaISD_veinti
movwf auxAA
movlw H'03'
subwf contB,W
btfss STATUS,Z
goto $+5
movf auxAA,W
movwf msg4B
incf contB

144
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto $+4

movf auxAA,W
movwf msg3B
incf contB

movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
movwf auxAA
movlw H'04'
subwf contB,W
btfss STATUS,Z
goto $+8
movf auxAA,W
movwf msg5B
incf contB
movlw segundos ; @ de segundos
movwf msg6B
incf contB
goto repB_B

movf auxAA,W
movwf msg4B
incf contB
movlw segundos ; @ de segundos
movwf msg5B
incf contB
goto repB_B

;-------------------------------------------------------------------------;
; repsecB_B : reproduce los segundos de B por B
;-------------------------------------------------------------------------;

repsecB_B clrf contB


movf secdeB,W
btfss STATUS,Z
goto repsecBB1
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
repsecBB movwf msg1B
incf contB
movlw segundos ; @ de segundos
movwf msg2B
incf contB
goto repB_B

repsecBB1 movf secunB,f


btfss STATUS,Z
goto repsecBB2
movlw HIGH(tablaISD_diez)
movwf PCLATH
movf secdeB,W
call tablaISD_diez
goto repsecBB

repsecBB2 movlw H'01'


subwf secdeB,W
btfss STATUS,Z
goto repsecBB3
movlw HIGH(tablaISD_once)
movwf PCLATH
movf secunB,W
call tablaISD_once

145
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto repsecBB

repsecBB3 movlw HIGH(tablaISD_veinti)


movwf PCLATH
movf secdeB,W
call tablaISD_veinti
movwf msg1B
incf contB
movlw HIGH(tablaISD_un)
movwf PCLATH
movf secunB,W
call tablaISD_un
movwf msg2B
incf contB
movlw segundos ; @ de segundos
movwf msg3B
incf contB
goto repB_B

;-------------------------------------------------------------------------;
; reproduceA: continua la reproduccion de audio por A
;-------------------------------------------------------------------------;

reproduceA btfss PORTC,eom_isd1 ; eom=0?


goto $+3 ; si
btfss reproA,1 ; no, reproA(1)=1?
return ; no

movlw H'64' ; @ del msg1A


subwf cont2A,W
movwf auxAA
incf auxAA
movf auxAA,W
subwf contA,W ; (cont2A-@msg1A)+1=contA?
btfss STATUS,Z
goto $+4
clrf reproA ; si, reproA=0, hemos acabado de reproducir
bsf PORTC,pd_isd1 ; duerme ISD1
return
incf cont2A ; no, cont2A++

repAA btfss juegaA,0


goto repAA1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repAA1 btfss juegaB,0
goto reproduceA1
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3
reproduceA1 call reset_isd1 ; si
movf cont2A,W
leer_puntero
movwf PORTD ; arranca la reproduccion en el ISD1
pagina0
call cont_20ms
bcf PORTE,ce_isd1 ; ce=0, habilitado
call cont_20ms
call cont_20ms
pagina1
bsf PORTE,ce_isd1 ; ce=1, deshabilitado

bcf reproA,1
return

146
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------;
; reproduceB: continua la reproduccion de audio por B
;-------------------------------------------------------------------------;

reproduceB btfss PORTC,eom_isd2 ; eom=0?


goto $+3 ; si
btfss reproB,1 ; no, reproA(1)=1?
return ; no

movlw H'6C' ; @ del msg1B


subwf cont2B,W
movwf auxAA
incf auxAA
movf auxAA,W
subwf contB,W ; (cont2A-@msg1A)+1=contA?
btfss STATUS,Z
goto $+4
clrf reproB ; si, reproB=0, hemos acabado de reproducir
bsf PORTC,pd_isd2 ; duerme ISD2
return
incf cont2B ; no, cont2A++

repBB btfss juegaA,0


goto repBB1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repBB1 btfss juegaB,0
goto reproduceB1
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3
reproduceB1 call reset_isd2
movf cont2B,W
leer_puntero
movwf PORTD ; arranca la reproduccion en el ISD1
pagina0
call cont_20ms
bcf PORTE,ce_isd2 ; ce=0, habilitado
call cont_20ms
call cont_20ms
pagina1
bsf PORTE,ce_isd2 ; ce=1, deshabilitado

bcf reproB,1
return

;-------------------------------------------------------------------------
; reset_isd: realiza un reset del dispositivo isd
;-------------------------------------------------------------------------

reset_isd1 bsf PORTC,pr_isd1 ; p/r=1 modo playback


bsf PORTE,ce_isd1 ; ce=1, deshabilitado
bcf PORTC,pd_isd1 ; activa ISD1
pagina0
call cont_20ms
pagina1
return

reset_isd2 bsf PORTC,pr_isd2 ; p/r=1 modo playback


bsf PORTE,ce_isd2 ; ce=1, deshabilitado
bcf PORTC,pd_isd2 ; activa ISD2
pagina0
call cont_20ms
pagina1
return

147
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------;
; direcciones de los mensajes temporales en el ISD
;-------------------------------------------------------------------------;

tablaISD_un addwf PCL,F


retlw b'00000000' ;@ DEL UN.
retlw b'00000000' ;@ DEL UN.
retlw b'00000101' ;@ DEL DOS.
retlw b'00001010' ;@ DEL TRES.
retlw b'00001111' ;@ DEL CUATRO.
retlw b'00010100' ;@ DEL CINCO.
retlw b'00011001' ;@ DEL SEIS.
retlw b'00011110' ;@ DEL SIETE.
retlw b'00100011' ;@ DEL OCHO.
retlw b'00101000' ;@ DEL NUEVE.

tablaISD_once addwf PCL,F


retlw b'00110010' ;@ DEL ONCE
retlw b'00110010' ;@ DEL ONCE
retlw b'00110111' ;@ DEL DOCE
retlw b'00111100' ;@ DEL TRECE
retlw b'01000001' ;@ DEL CATORCE
retlw b'01000110' ;@ DEL QUINCE
retlw b'01001011' ;@ DEL DIECISEIS
retlw b'01010000' ;@ DEL DIECISIETE
retlw b'01010101' ;@ DEL DIECIOCHO
retlw b'01011010' ;@ DEL DIECINUEVE

tablaISD_veinti addwf PCL,F


retlw b'01110011' ;@ DEL VEINTI
retlw b'01110011' ;@ DEL VEINTI
retlw b'01110011' ;@ DEL VEINTI
retlw b'01111000' ;@ DEL TREINTA Y
retlw b'01111101' ;@ DEL CUARENTA Y
retlw b'10000010' ;@ DEL CINCUENTA Y

tablaISD_diez addwf PCL,F


retlw b'00101101' ;@ DEL DIEZ
retlw b'00101101' ;@ DEL DIEZ
retlw b'01011111' ;@ DEL VEINTE
retlw b'01100100' ;@ DEL TREINTA
retlw b'01101001' ;@ DEL CUARENTA
retlw b'01101110' ;@ DEL CINCUENTA

;---------------------------------------------------------------------------
; repro_jugadaA: reproduce por audio ultima jugada realizada para jugador A
;---------------------------------------------------------------------------

repro_jugadaA movlw h'10'


subwf base_ram,W
btfsc STATUS,Z
return ; no hay jugadas almacenadas en RAM
clrf contA
movlw HIGH(tablaISD_pieza) ; cargamos el mensaje "pieza"

movwf PCLATH
movf pieza_jugada,W
call tablaISD_pieza
movwf msg1A
incf contA
movlw h'90'
subwf base_ram,W ; base_ram>0x190?
btfsc STATUS,C
goto rep_jugadaA2 ; si
movlw h'02' ; no, banco 2
subwf base_ram,W ; nos situamos en base_ram-2

148
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf auxBB
leer_punterob2
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg2A
incf contA
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg3A
incf contA
incf auxBB
movf auxBB,W
leer_punterob2
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg4A
incf contA
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg5A
incf contA
goto rep_jugadaA3

rep_jugadaA2 movlw h'90'


subwf base_ram,W
btfss STATUS,Z ; base_ram=190?
goto $+4 ; no
movlw h'6E'
movwf auxBB
goto $+4
movlw h'02'
subwf base_ram,W
movwf auxBB
leer_punterob3
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC

149
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg2A
incf contA
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg3A
incf contA
incf auxBB
movf auxBB,W
leer_punterob3
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg4A
incf contA
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg5A
incf contA

rep_jugadaA3 btfss juegaA,0


goto repAB1
movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repAB1 btfss juegaB,0
goto rep_jugadaA4
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3

rep_jugadaA4 call reset_isd1


movf msg1A,W ; lanzamos el primer mensaje
movwf PORTD ; para reproducir
pagina0
call cont_20ms
bcf PORTE,ce_isd1 ; ce=0, habilitado
call cont_20ms
call cont_20ms
pagina1
bsf PORTE,ce_isd1 ; ce=1, deshabilitado
movlw H'64' ; @ de la variable 'msg1A'
movwf cont2A
bsf reproA,0

150
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

return

;---------------------------------------------------------------------------
; repro_jugadaB: reproduce por audio ultima jugada realizada para jugador B
;---------------------------------------------------------------------------

repro_jugadaB movlw h'10'


subwf base_ram,W
btfsc STATUS,Z
return ; no hay jugadas almacenadas en RAM
clrf contB
movlw HIGH(tablaISD_pieza) ; cargamos el mensaje "pieza"

movwf PCLATH
movf pieza_jugada,W
call tablaISD_pieza
movwf msg1B
incf contB
movlw h'90'
subwf base_ram,W ; base_ram>0x190?
btfsc STATUS,C
goto rep_jugadaB2 ; si
movlw h'02' ; no, banco 2
subwf base_ram,W ; nos situamos en base_ram-4
movwf auxBB
leer_punterob2
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg2B
incf contB
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg3B
incf contB
incf auxBB
movf auxBB,W
leer_punterob2
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg4B
incf contB
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)

151
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg5B
incf contB
goto rep_jugadaB3

rep_jugadaB2 movlw h'90'


subwf base_ram,W
btfss STATUS,Z ; base_ram=190?
goto $+4 ; no
movlw h'6C'
movwf auxBB
goto $+4
movlw h'02'
subwf base_ram,W
movwf auxBB
leer_punterob3
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg2B
incf contB
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg3B
incf contB
incf auxBB
movf auxBB,W
leer_punterob3
movwf auxAA
movlw h'F0' ; cogemos la columna
andwf auxAA,W
movwf auxCC
swapf auxCC
incf auxCC
movlw HIGH(tablaISD_col)
movwf PCLATH
movf auxCC,W
call tablaISD_col
movwf msg4B
incf contB
movlw h'0F' ; cogemos la fila
andwf auxAA,W
movwf auxCC
incf auxCC
movlw HIGH(tablaISD_fila)
movwf PCLATH
movf auxCC,W
call tablaISD_fila
movwf msg5B
incf contB

rep_jugadaB3 btfss juegaA,0


goto repBA1

152
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movlw h'01'
subwf ticsA1,W
btfsc STATUS,Z
goto $-3
repBA1 btfss juegaB,0
goto rep_jugadaB4
movlw h'01'
subwf ticsB1,W
btfsc STATUS,Z
goto $-3

rep_jugadaB4 call reset_isd2


movf msg1B,W ; lanzamos el primer mensaje
movwf PORTD ; para reproducir
pagina0
call cont_20ms
bcf PORTE,ce_isd2 ; ce=0, habilitado
call cont_20ms
call cont_20ms
bsf PORTE,ce_isd2 ; ce=1, deshabilitado
pagina1
movlw H'6C' ; @ de la variable 'msg1B'
movwf cont2B
bsf reproB,0
return

;-------------------------------------------------------------------------
; direcciones de los mensajes de jugada en el ISD
;-------------------------------------------------------------------------

tablaISD_fila addwf PCL,F


retlw b'11100101' ;@ DEL UNO.
retlw b'11100101' ;@ DEL UNO.
retlw b'00000101' ;@ DEL DOS.
retlw b'00001010' ;@ DEL TRES.
retlw b'00001111' ;@ DEL CUATRO.
retlw b'00010100' ;@ DEL CINCO.
retlw b'00011001' ;@ DEL SEIS.
retlw b'00011110' ;@ DEL SIETE.
retlw b'00100011' ;@ DEL OCHO.

tablaISD_col addwf PCL,F


retlw b'10100101' ;@ DE A.
retlw b'10100101' ;@ DE A.
retlw b'10101000' ;@ DE B.
retlw b'10101011' ;@ DE C.
retlw b'10101110' ;@ DE D.
retlw b'10110001' ;@ DE E.
retlw b'10110100' ;@ DE F.
retlw b'10110111' ;@ DE G.
retlw b'10111010' ;@ DE H.

tablaISD_pieza addwf PCL,F


retlw b'11101010' ;@ DE PEON.
retlw b'10111101' ;@ DE TORRE.
retlw b'11000011' ;@ DE CABALLO.
retlw b'11001001' ;@ DE ALFIL.
retlw b'11001111' ;@ DE DAMA.
retlw b'11010101' ;@ DE REY.

;-------------------------------------------------------------------------
; tabla_piezas: inicializacion del array piezas
;-------------------------------------------------------------------------

ORG h'C10'

tabla_piezas addwf PCL,f


retlw h'00' ; peon blanco

153
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

retlw h'01' ; columna 0 fila 1


retlw h'00' ; peon blanco
retlw h'11' ; columna 1 fila 1
retlw h'00' ; peon blanco
retlw h'21' ; columna 2 fila 1
retlw h'00' ; peon blanco
retlw h'31' ; columna 3 fila 1
retlw h'00' ; peon blanco
retlw h'41' ; columna 4 fila 1
retlw h'00' ; peon blanco
retlw h'51' ; columna 5 fila 1
retlw h'00' ; peon blanco
retlw h'61' ; columna 6 fila 1
retlw h'00' ; peon blanco
retlw h'71' ; columna 7 fila 1
retlw h'01' ; torre dama blanca
retlw h'00' ; columna 0 fila 0
retlw h'02' ; caballo dama blanca
retlw h'10' ; columna 1 fila 0
retlw h'03' ; alfil dama blanca
retlw h'20' ; columna 2 fila 0
retlw h'04' ; dama blanca
retlw h'30' ; columna 3 fila 0
retlw h'05' ; rey blanca
retlw h'40' ; columna 4 fila 0
retlw h'03' ; alfil rey blanca
retlw h'50' ; columna 5 fila 0
retlw h'02' ; caballo rey blanca
retlw h'60' ; columna 6 fila 0
retlw h'01' ; torre rey blanca
retlw h'70' ; columna 7 fila 0

retlw h'08' ; peon negro


retlw h'06' ; columna 0 fila 6
retlw h'08' ; peon negro
retlw h'16' ; columna 1 fila 6
retlw h'08' ; peon negro
retlw h'26' ; columna 2 fila 6
retlw h'08' ; peon negro
retlw h'36' ; columna 3 fila 6
retlw h'08' ; peon negro
retlw h'46' ; columna 4 fila 6
retlw h'08' ; peon negro
retlw h'56' ; columna 5 fila 6
retlw h'08' ; peon negro
retlw h'66' ; columna 6 fila 6
retlw h'08' ; peon negro
retlw h'76' ; columna 7 fila 6
retlw h'09' ; torre dama negra
retlw h'07' ; columna 0 fila 7
retlw h'0A' ; caballo dama negro
retlw h'17' ; columna 1 fila 7
retlw h'0B' ; alfil dama negro
retlw h'27' ; columna 2 fila 7
retlw h'0C' ; dama negra
retlw h'37' ; columna 3 fila 7
retlw h'0D' ; rey negro
retlw h'47' ; columna 4 fila 7
retlw h'0B' ; alfil dama negro
retlw h'57' ; columna 5 fila 7
retlw h'0A' ; caballo dama negro
retlw h'67' ; columna 6 fila 7
retlw h'09' ; torre dama negra
retlw h'77' ; columna 7 fila 7

;-------------------------------------------------------------------------;
; rutina para aumentar el tiempo del reloj A en modo fischer
;-------------------------------------------------------------------------;

154
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

incrementoA movf esecunA,W


btfsc STATUS,Z ; secunA=0?
goto incrementoA1 ; si, saltamos
movlw h'08'
subwf secunA,W
btfsc STATUS,C ; secunA>=8?
goto $+4 ; si, saltamos
movf esecunA,W
addwf secunA,f ; secunA=secunA+esecunA
goto incrementoA4
movf secunA,W
andlw h'07'
movwf secunA ; secunA=secunA and 0111
movlw h'05'
subwf secdeA,W
btfsc STATUS,C ; secdeA>=5?
goto $+3 ; si, saltamos
incf secdeA ; secdA++
goto incrementoA4
clrf secdeA
goto incrementoA3

incrementoA1 movlw h'01'


subwf esecdeA,W
btfsc STATUS,Z ; esecdeA=1?
goto incrementoA2 ; si, saltamos
movlw h'03'
subwf secdeA,W
btfsc STATUS,C ; secdeA>=3?
goto $+4 ; si, saltamos
movlw h'03'
addwf secdeA,f
goto incrementoA4
movlw h'03'
subwf secdeA,f
goto incrementoA3

incrementoA2 movlw h'05'


subwf secdeA,W
btfsc STATUS,Z ; secdeA=5?
goto $+3 ; si, saltamos
incf secdeA
goto incrementoA4
clrf secdeA

incrementoA3 movlw h'09'


subwf minunA,W
btfsc STATUS,Z ; minunA=9?
goto $+3 ; si, saltamos
incf minunA
goto incrementoA4
clrf minunA
movlw h'05'
subwf mindeA,W
btfsc STATUS,C ; mindeA=5?
goto $+3 ; si, saltamos
incf mindeA
goto incrementoA4
clrf mindeA
incf horaA

incrementoA4 pagina0
call lcd_tiempoA
return

;-------------------------------------------------------------------------;
; rutina para aumentar el tiempo del reloj B en modo fischer

155
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------;

incrementoB movf esecunB,W


btfsc STATUS,Z ; secunB=0?
goto incrementoB1 ; si, saltamos
movlw h'08'
subwf secunB,W
btfsc STATUS,C ; secunB>=8?
goto $+4 ; si, saltamos
movf esecunB,W
addwf secunB,f ; secunB=secunB+esecunB
goto incrementoB4
movf secunB,W
andlw h'07'
movwf secunB ; secunB=secunB and 0111
movlw h'05'
subwf secdeB,W
btfsc STATUS,C ; secdeB>=5?
goto $+3 ; si, saltamos
incf secdeB ; secdA++
goto incrementoB4
clrf secdeB
goto incrementoB3

incrementoB1 movlw h'01'


subwf esecdeB,W
btfsc STATUS,Z ; esecdeB=1?
goto incrementoB2 ; si, saltamos
movlw h'03'
subwf secdeB,W
btfsc STATUS,C ; secdeB>=3?
goto $+4 ; si, saltamos
movlw h'03'
addwf secdeB,f
goto incrementoB4
movlw h'03'
subwf secdeB,f
goto incrementoB3

incrementoB2 movlw h'05'


subwf secdeB,W
btfsc STATUS,Z ; secdeB=5?
goto $+3 ; si, saltamos
incf secdeB
goto incrementoB4
clrf secdeB

incrementoB3 movlw h'09'


subwf minunB,W
btfsc STATUS,Z ; minunB=9?
goto $+3 ; si, saltamos
incf minunB
goto incrementoB4
clrf minunB
movlw h'05'
subwf mindeB,W
btfsc STATUS,C ; mindeB=5?
goto $+3 ; si, saltamos
incf mindeB
goto incrementoB4
clrf mindeB
incf horaB

incrementoB4 pagina0
call lcd_tiempoB
return

156
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;-------------------------------------------------------------------------
; tx_rs232: transmite las jugadas que componen la partida por el puerto
; serie del PIC.
; Serial port config: 9600 baudios,8 bits,paridad = none
;-------------------------------------------------------------------------

tx_rs232 banco0
clrf INTCON ; no interrupciones
bsf RCSTA,SPEN ; activa el USART
banco1
movlw b'00100100'
movwf TXSTA ; baja velocidad (BRGH=1)
movlw d'25'
movwf SPBRG ; velocidad 9600 baudios
bsf TXSTA,TXEN

movlw b_ram ; comprobamos si hay jugadas en memoria


subwf base_ram,W ; base_ram<>0?
btfsc STATUS,Z
goto fallo_mem

movlw b_ram ; @base memoria ram jugadas


movwf auxBB
bucle_tx movlw h'90'
subwf auxBB,W
btfss STATUS,C
goto bucle_tx2
movf auxBB,W
lee_punterob3
movwf TXREG ; no, envia el siguiente byte
goto bucle_tx3
bucle_tx2 movf auxBB,W
lee_punterob2
movwf TXREG
bucle_tx3 banco1
comp_tx btfss TXSTA,TRMT ;comprueba si acabo de Tx.
goto comp_tx
banco0
incf auxBB
movf base_ram,W ; si auxBB=base_ram fin de transmision
subwf auxBB,W
btfss STATUS,Z
goto bucle_tx4
fallo_mem movlw h'FF' ; mandamos caracter fin transmision
movwf TXREG
banco1
comp_tx2 btfss TXSTA,TRMT ;comprueba si acabo de Tx.
goto comp_tx2
banco0
pagina0
movlw H'A0' ; habilitamos interrupciones:
movwf INTCON ; GIE y T0IE = 1, T0IF = 0
return
bucle_tx4 movlw h'70'
subwf auxBB,W
btfss STATUS,Z
goto bucle_tx
movlw h'90'
movwf auxBB
goto bucle_tx

;-------------------------------------------------------------------------
; comp_tablero: comprueba si el tablero esta conectado al reloj
;-------------------------------------------------------------------------

comp_tablero bsf cambio,5 ; se ha cambiado la configuracion del puerto


D
clrf PORTD

157
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

banco1
movlw H'F0' ; PORTD 4 high entradas, 4 low salidas
movwf TRISD
banco0

movlw h'05' ; solo se comprueba una fila


movwf PORTD ; deberia devolver 4 1's (4 piezas)
bcf PORTA,enable ; habilitamos el tablero
pagina2
call cont_10ms ; temporizacion de 10ms
pagina1
movf PORTD,W
movwf auxAA
bsf PORTA,enable ; deshabilitamos el tablero

btfsc auxAA,7
goto comp_tablero1
btfsc auxAA,6
goto comp_tablero1
btfsc auxAA,5
goto comp_tablero1
btfsc auxAA,4
goto comp_tablero1
bsf cambio,7 ; tablero conectado
goto $+2
comp_tablero1 bcf cambio,7 ; tablero desconectado

movlw h'05' ; solo se comprueba una fila


movwf PORTD ; deberia devolver 4 1's (4 piezas)
bcf PORTA,enable2 ; habilitamos el tablero
pagina2
call cont_10ms ; temporizacion de 10ms
pagina1
movf PORTD,W
movwf auxAA
bsf PORTA,enable2 ; deshabilitamos el tablero

btfsc auxAA,7
goto comp_tablero2
btfsc auxAA,6
goto comp_tablero2
btfsc auxAA,5
goto comp_tablero2
btfsc auxAA,4
goto comp_tablero2
bsf cambio,4 ; tablero 2 conectado
goto $+2
comp_tablero2 bcf cambio,4

banco1
clrf TRISD
banco0
clrf PORTD
bcf cambio,5 ; retorno configuracion puerto D original
return

;-------------------------------------------------------------------------
; torre_enroque: comprueba el movimiento de torre en la jugada enroque
;-------------------------------------------------------------------------

torre_enroque btfss enroque,4 ; enroque corto blancas?


goto torre_enroque1 ; no
movlw h'00' ; si, comprobamos movimiento torre
subwf coord_or1x,W
btfss STATUS,Z
goto torre_enroque4
movlw h'07'
subwf coord_or1y,W

158
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

btfss STATUS,Z
goto torre_enroque4
movlw h'00'
subwf coord_desx,W
btfss STATUS,Z
goto torre_enroque4
movlw h'05'
subwf coord_desy,W
btfss STATUS,Z
goto torre_enroque4
pagina2 ; movimiento correcto
goto examina11

torre_enroque1 btfss enroque,5 ; enroque corto negras?


goto torre_enroque2 ; no
movlw h'07' ; si, comprobamos movimiento torre
subwf coord_or1x,W
btfss STATUS,Z
goto torre_enroque4
movlw h'07'
subwf coord_or1y,W
btfss STATUS,Z
goto torre_enroque4
movlw h'07'
subwf coord_desx,W
btfss STATUS,Z
goto torre_enroque4
movlw h'05'
subwf coord_desy,W
btfss STATUS,Z
goto torre_enroque4
pagina2 ; movimiento correcto
goto examina11

torre_enroque2 btfss enroque,6 ; enroque largo blancas?


goto torre_enroque3 ; no
movlw h'00' ; si, comprobamos movimiento torre
subwf coord_or1x,W
btfss STATUS,Z
goto torre_enroque4
movlw h'00'
subwf coord_or1y,W
btfss STATUS,Z
goto torre_enroque4
movlw h'00'
subwf coord_desx,W
btfss STATUS,Z
goto torre_enroque4
movlw h'03'
subwf coord_desy,W
btfss STATUS,Z
goto torre_enroque4
pagina2 ; movimiento correcto
goto examina11

torre_enroque3 movlw h'07' ; enroque largo negras


subwf coord_or1x,W ; comprobamos movimiento torre
btfss STATUS,Z
goto torre_enroque4
movlw h'00'
subwf coord_or1y,W
btfss STATUS,Z
goto torre_enroque4
movlw h'07'
subwf coord_desx,W
btfss STATUS,Z
goto torre_enroque4
movlw h'03'

159
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

subwf coord_desy,W
btfss STATUS,Z
goto torre_enroque4
pagina2 ; movimiento correcto
goto examina11

torre_enroque4 pagina2
goto pon_error

;************************************************************************

ORG 1000 ; pagina 2

;************************************************************************

;-------------------------------------------------------------------------
; cont_10ms: retardo de 10 milisegundos
;-------------------------------------------------------------------------

cont_10ms movlw RETARDO3


movwf cont_ms
cont_10_1 movlw RETARDO1 ;58µS
movwf cont_us
cont_58_2 nop
decfsz cont_us,f
goto cont_58_2
mira_reproduce
movlw RETARDO1 ;58µS
movwf cont_us
cont_58_3 nop
decfsz cont_us,f
goto cont_58_3
decfsz cont_ms,f
goto cont_10_1
return

;-------------------------------------------------------------------------
; inicio_anterior: inicializa la tabla anterior con la posicion inicial
;-------------------------------------------------------------------------

inicio_anterior movlw anterior0


movwf aux_anterior0 ; inicializa anterior0
movlw anterior
movwf auxBB ; @anterior->auxBB
clrf auxAA ; auxAA=0x00
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
movlw h'FF'
movwf auxAA
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
movf auxBB,W
escribe_punterob1

160
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
clrf auxAA
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
incf aux_anterior0
incf auxBB
movf auxBB,W
escribe_punterob1
movf aux_anterior0,W
escribe_puntero
return

;-------------------------------------------------------------------------
; inicio_piezas: inicializa el array piezas
;-------------------------------------------------------------------------

inicio_piezas movlw piezas


movwf aux_piezas
clrf auxBB
inicio_piezas1 movlw HIGH(tabla_piezas)
movwf PCLATH
movf auxBB,W
call tabla_piezas
movwf auxAA
pagina2
movf aux_piezas,W
escribe_punterob1
movlw h'DF'
subwf aux_piezas,W
btfsc STATUS,Z ; hemos llegado al final del array?
return
incf aux_piezas
incf auxBB
goto inicio_piezas1

;-------------------------------------------------------------------------
; inicio_encuesta: inicia el proceso de encuesta y comprobacion de jugadas
;-------------------------------------------------------------------------

inicio_encuesta call encuesta ; encuesta del tablero


call compara ; determina si ha habido cambios
btfss cambio,2 ; jugada completa?
goto $+2
call examina ; si
pagina0
goto tiempo_enc1

;-------------------------------------------------------------------------
; encuesta: realiza la encuesta del tablero
;-------------------------------------------------------------------------

161
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

encuesta bcf cambio,5


clrf cont_fila ; cont_fila=0
movlw actual ; direccion base de actual
addlw h'07'
movwf auxBB ; auxBB= @ base de 'actual' + 7
clrf PORTD
banco1
movlw H'F0' ; PORTD 4 high entradas, 4 low salidas
movwf TRISD
banco0

encuesta_1 movf cont_fila,W ; cont_fila->PORTD


movwf PORTD
btfss cambio,7
goto $+3
bcf PORTA,enable ; habilitamos el tablero
goto $+2
bcf PORTA,enable2 ; habilitamos el tablero2
call cont_10ms ; temporizacion de 10ms
btfsc cambio,5 ; se ha actualizado el dislay?
goto encuesta ; si, volvemos a empezar
movf PORTD,W
movwf auxAA
btfss cambio,7
goto $+3
bsf PORTA,enable ; deshabilitamos el tablero
goto $+2
bsf PORTA,enable2 ; deshabilitamos el tablero2
comf auxAA,f ; complemento auxAA
movlw h'F0'
andwf auxAA,f ; aplicamos mascara F0
swapf auxAA,f ; intercambio de los 4 bits altos por
los bajos
incf cont_fila ; cont_fila++
movf cont_fila,W
movwf PORTD
btfss cambio,7
goto $+3
bcf PORTA,enable ; habilitamos el tablero
goto $+2
bcf PORTA,enable2 ; habilitamos el tablero2
call cont_10ms ; temporizacion de 10ms
btfsc cambio,5 ; se ha actualizado el dislay?
goto encuesta ; si, volvemos a empezar
movf PORTD,W
movwf auxAA1
btfss cambio,7
goto $+3
bsf PORTA,enable ; deshabilitamos el tablero
goto $+2
bsf PORTA,enable2 ; deshabilitamos el tablero2
comf auxAA1 ; complemento auxAA1
movlw h'F0'
andwf auxAA1,f ; aplicamos mascara F0
movf auxAA1,W
addwf auxAA,f
movf auxBB,W
escribe_punterob1 ; guardamos en la @auxBB
incf cont_fila ; cont_fila++
decf auxBB ; auxBB--
movlw d'16'
subwf cont_fila,W
btfss STATUS,Z ; cont_fila=16?
goto encuesta_1 ; no, volvemos

banco1
clrf TRISD ; PORTD todo salidas
banco0

162
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

clrf PORTD ; si, fin de la encuesta


bcf cambio,5 ; retorno configuracion puerto D original
return

;-------------------------------------------------------------------------
; compara: compara actual con anterior y mira si hay cambios
;-------------------------------------------------------------------------

compara movlw actual


movwf aux_actual
movlw anterior
movwf aux_anterior

compara1 movf aux_anterior,W


leer_punterob1
movwf auxAA ; contenido de la @ aux_anterior en auxAA
movf aux_actual,W
leer_punterob1
movwf auxBB ; contenido de la @ aux_actual en auxBB
clrf bit

comparab0 btfsc auxBB,0 ; posicion 0 de actual=0?


goto comparabb0
btfsc auxAA,0 ; si, posicion 0 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab1 incf bit
btfsc auxBB,1 ; posicion 1 de actual=0?
goto comparabb1
btfsc auxAA,1 ; si, posicion 1 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab2 incf bit
btfsc auxBB,2 ; posicion 2 de actual=0?
goto comparabb2
btfsc auxAA,2 ; si, posicion 2 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab3 incf bit
btfsc auxBB,3 ; posicion 3 de actual=0?
goto comparabb3
btfsc auxAA,3 ; si, posicion 3 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab4 incf bit
btfsc auxBB,4 ; posicion 4 de actual=0?
goto comparabb4
btfsc auxAA,4 ; si, posicion 4 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab5 incf bit
btfsc auxBB,5 ; posicion 5 de actual=0?
goto comparabb5
btfsc auxAA,5 ; si, posicion 5 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab6 incf bit
btfsc auxBB,6 ; posicion 6 de actual=0?
goto comparabb6
btfsc auxAA,6 ; si, posicion 6 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
comparab7 incf bit
btfsc auxBB,7 ; posicion 7 de actual=0?
goto comparabb7
btfsc auxAA,7 ; si, posicion 7 de anterior=0?
goto cambio10 ; no, es un cambio 1->0
goto compara8

comparabb0 btfss auxAA,0


goto cambio01
goto comparab1
comparabb1 btfss auxAA,1
goto cambio01
goto comparab2

163
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

comparabb2 btfss auxAA,2


goto cambio01
goto comparab3
comparabb3 btfss auxAA,3
goto cambio01
goto comparab4
comparabb4 btfss auxAA,4
goto cambio01
goto comparab5
comparabb5 btfss auxAA,5
goto cambio01
goto comparab6
comparabb6 btfss auxAA,6
goto cambio01
goto comparab7
comparabb7 btfss auxAA,7
goto cambio01

compara8 movlw actual ; si, miramos si hemos acabado de recorrer el array


subwf aux_actual,W
movwf auxAA
movlw H'07'
subwf auxAA,W
btfss STATUS,Z ; aux_actual-actual=7?
goto $+3
call actualiza ; si, no hay cambios, se actualiza
anterior=actual
return
incf aux_actual
incf aux_anterior
goto compara1

cambio01 btfsc cambio,0 ; bit0 de 'cambio'=0?


goto cambio01_1 ; no
movlw actual ; si, guardamos coord_or1x
subwf aux_actual,W
movwf coord_or1x
movf bit,W
movwf coord_or1y ; b->coord_or1y
bsf cambio,0 ; cambio, bit0=1
call actualiza
return

cambio01_1 btfsc cambio,1 ; bit1 de 'cambio' = 1?


goto pon_error ; si, las dos var's de origen estan ocupadas
movlw actual ; no, guardamos coord_or2x
subwf aux_actual,W
movwf coord_or2x ; b->coord_or2y
movf bit,W
movwf coord_or2y
bsf cambio,1 ; cambio, bit1=1
call actualiza
return

cambio10 btfss cambio,0 ; bit0 de cambio =1?


goto pon_error
btfsc cambio,2 ; bit2 de 'cambio' =0?
goto pon_error ; no, error
movlw actual ; si, guardamos coord_desx
subwf aux_actual,W
movwf coord_desx
movf bit,W
movwf coord_desy ; b->coord_or1y
bsf cambio,2 ; cambio, bit2=1 jugada completa
call actualiza
return

;-------------------------------------------------------------------------

164
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

; actualiza: actualiza anterior con actual


;-------------------------------------------------------------------------

actualiza movlw actual


movwf aux_actual
movlw anterior
movwf aux_anterior

actualiza1 movf aux_actual,W


leer_punterob1
movwf auxAA
movf aux_anterior,W
escribe_punterob1
movlw anterior ; miramos si hemos acabado de recorrer el
array
subwf aux_anterior,W
movwf auxAA
movlw H'07'
subwf auxAA,W
btfsc STATUS,Z ; aux_actual-actual=7?
return
incf aux_actual
incf aux_anterior
goto actualiza1

;-------------------------------------------------------------------------
; actualiza_a0: actualiza anterior0 con actual
;-------------------------------------------------------------------------

actualiza_a0 movlw actual


movwf aux_actual
movlw anterior0
movwf aux_anterior0

actualiza_a01 movf aux_actual,W


leer_punterob1
movwf auxAA
movf aux_anterior0,W
escribe_puntero
movlw anterior0 ; miramos si hemos acabado de recorrer el
array
subwf aux_anterior0,W
movwf auxAA
movlw H'07'
subwf auxAA,W
btfsc STATUS,Z ; aux_actual-actual=7?
return
incf aux_actual
incf aux_anterior0
goto actualiza_a01

;-------------------------------------------------------------------------
; pon_error: enciende led de error y entra en un bucle
;-------------------------------------------------------------------------

pon_error bsf PORTA,led_error

loop1 call encuesta ; esperamos a que se restablezca la posicion


pagina2
movlw actual ; en el tablero (actual=anterior0)
movwf aux_actual
movlw anterior0
movwf aux_anterior0

compara11 movf aux_anterior0,W


leer_puntero
movwf auxAA ; contenido de la @ aux_anterior0 en auxAA
movf aux_actual,W

165
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

leer_punterob1
subwf auxAA,W
btfss STATUS,Z ; contenido igual?
goto pon_error1 ; no
movlw anterior0
subwf aux_anterior0,W
movwf auxAA
movlw h'07'
subwf auxAA,W ; hemos llegado al final del array?
btfsc STATUS,Z
goto compara12 ; si, reiniciamos el proceso
incf aux_actual ; no
incf aux_anterior0
goto compara11

pon_error1 btfss PORTB,b_jugadaA ; mira si hay peticion de audio


goto rep_errorA
btfss PORTB,b_jugadaB
goto rep_errorB
goto loop1

compara12 btfsc control,7 ; se ha dado un jaque?


goto compara13 ; si
compara14 call actualiza ; actualiza anterior con actual
bcf cambio,0
bcf cambio,1
bcf cambio,2
movlw h'01'
andwf control,f
bcf PORTA,led_error
nop
return

compara13 movlw piezas ; hay que corregir array piezas


addwf offset_piezas,f
movf coord_or1y,W
movwf auxAA
swapf auxAA,f
movf coord_or1x,W
addwf auxAA,f
movf offset_piezas,W
escribe_punterob1
btfss control,4 ; ademas se ha producido una captura?
goto compara14 ; no
movlw piezas
addwf offset_captura,f
decf offset_captura
movf offset_captura,W
leer_punterob1
movwf auxAA
bcf auxAA,4
movf offset_captura,W
escribe_punterob1
goto compara14

rep_errorA pagina1
call reset_isd1
pagina2
movlw jug_ilegal
movwf PORTD
pagina0
call cont_20ms
bcf PORTE,ce_isd1 ; ce=0, habilitado
call cont_20ms
call cont_20ms
bsf PORTE,ce_isd1 ; ce=1, deshabilitado
pagina2
goto loop1

166
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

rep_errorB pagina1
call reset_isd2
pagina2
movlw jug_ilegal
movwf PORTD
pagina0
call cont_20ms
bcf PORTE,ce_isd2 ; ce=0, habilitado
call cont_20ms
call cont_20ms
bsf PORTE,ce_isd2 ; ce=1, deshabilitado
pagina2
goto loop1

;-------------------------------------------------------------------------
; examina: comprueba si la jugada realizada es correcta
;-------------------------------------------------------------------------

examina btfss cambio,1 ; bit cambio1=1?


goto examina0 ; no
movf coord_or1x,W ; si
subwf coord_desx,W
btfss STATUS,Z ; coord_or1x=coord_desx?
goto examina0 ; no
movf coord_or1y,W ; si
subwf coord_desy,W
btfss STATUS,Z ; coord_or1y=coord_desy?
goto examina0 ; no
movf coord_or2x,W
movwf coord_or1x
movf coord_or2y,W
movwf coord_or1y

examina0 movf coord_or1x,W


subwf coord_desx,W
btfss STATUS,Z
goto $+5
movf coord_or1y,W
subwf coord_desy,W
btfsc STATUS,Z
return
movlw h'F0'
andwf enroque,W
btfsc STATUS,Z
goto $+8
pagina1
goto torre_enroque
examina11 movlw h'0F'
andwf enroque,f
call actualiza_array
goto turno_juego1

clrf offset_piezas
movlw piezas ; buscamos pieza en array 'piezas'
movwf aux_piezas
examina1 incf aux_piezas
incf offset_piezas
movf aux_piezas,W
leer_punterob1
movwf auxAA
andlw h'0F' ; aplica mascara para seleccionar coord x
subwf coord_or1x,W ; igual a coord_or1x?
btfsc STATUS,Z
goto examina2 ; si
movlw h'DF' ; no
subwf aux_piezas,W ; hemos llegado al final del array?
btfsc STATUS,Z

167
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto pon_error ; si, es un error


incf aux_piezas ; no
incf offset_piezas
goto examina1

examina2 movf auxAA,W


andlw h'F0' ; aplica mascara para seleccionar coord y
movwf auxAA
swapf auxAA,W
subwf coord_or1y,W ; igual a coord_or1y?
btfsc STATUS,Z
goto examina3 ; si
incf aux_piezas ; no
incf offset_piezas
goto examina1

examina6 incf aux_piezas


incf aux_piezas
incf offset_piezas
incf offset_piezas
goto examina1

examina3 decf aux_piezas ; miramos turno juego y pieza viva


movf aux_piezas,W
leer_punterob1
movwf auxAA
btfsc auxAA,3 ; la pieza es blanca (=0)?
goto examina4 ; no
btfsc auxAA,4 ; si, miramos si pieza viva (=0)
goto examina6 ; no
btfsc control,0 ; si, comprobamos turno de juego
goto pon_error ; no coincide
goto examina5 ; si, seguimos el proceso
examina4 btfsc auxAA,4 ; pieza viva?
goto examina6 ; no
btfss control,0 ; pieza negra (=1)
goto pon_error

examina5 movlw h'07' ; determina que pieza es


andwf auxAA,W
movwf auxBB
movwf pieza_jugada ; guardamos copia de la pieza jugada (audio)
movlw h'05' ; es un rey?
subwf auxBB,W
btfsc STATUS,Z
goto examina_rey
movlw h'04' ; es una dama?
subwf auxBB,W
btfsc STATUS,Z
goto examina_dama
movlw h'03' ; es un alfil?
subwf auxBB,W
btfsc STATUS,Z
goto examina_alfil
movlw h'02' ; es un caballo?
subwf auxBB,W
btfsc STATUS,Z
goto examina_caballo
movlw h'01' ; es una torre?
subwf auxBB,W
btfsc STATUS,Z
goto examina_torre

;***********************************************************************

examina_peon movf aux_piezas,W ; miramos el color del peon


leer_punterob1

168
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf auxAA
btfsc auxAA,3
goto peon_negro
movf coord_desy,W ; peon blanco
subwf coord_or1y,W
btfss STATUS,Z ; coordenadas y (columna) iguales?
goto captura_peonb ; no
movf coord_or1x,W
subwf coord_desx,W
movwf auxAA
decf auxAA
btfsc STATUS,Z ; avance una posicion?
goto examina_peon1 ; si, miramos si casilla destino ocupada

decf auxAA ; no, avance 2 posiciones?


btfss STATUS,Z
goto pon_error ; no
movlw h'01' ; si, miramos si fila inicial es 1

subwf coord_or1x,W
btfss STATUS,Z
goto pon_error
decf coord_desx,W
movwf aux_x
movf coord_or1y,W
movwf aux_y
call mira_casilla ; miramos si casilla de paso ocupada
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto pon_error ; si
goto examina_peon1 ; no, miramos si casilla destino ocupada

captura_peonb movf coord_desy,W ; nos movemos a una casilla lateral?


subwf coord_or1y,W
absoluto
decf auxAA
btfss STATUS,Z
goto pon_error
movf coord_or1x,W ; avance una posicion?
subwf coord_desx,W
movwf auxAA
decf auxAA
btfss STATUS,Z
goto pon_error
movf coord_desy,W ; comprobamos captura pieza enemiga
movwf aux_y
movf coord_desx,W
movwf aux_x
goto mira_captura_p

peon_negro movf coord_desy,W ; peon negro


subwf coord_or1y,W
btfss STATUS,Z ; coordenadas y (columna) iguales?
goto captura_peonn ; no
movf coord_desx,W
subwf coord_or1x,W
movwf auxAA
decf auxAA
btfsc STATUS,Z ; avance una posicion?
goto examina_peon1 ; si, miramos si casilla destino ocupada

decf auxAA ; no, avance 2 posiciones?


btfss STATUS,Z
goto pon_error ; no
movlw h'06' ; si, miramos si fila inicial es 6

subwf coord_or1x,W
btfss STATUS,Z

169
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto pon_error
incf coord_desx,W
movwf aux_x
movf coord_or1y,W
movwf aux_y
call mira_casilla ; miramos si casilla de paso ocupada
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto pon_error ; si
goto examina_peon1 ; miramos si casilla destino ocupada

captura_peonn movf coord_or1y,W ; nos movemos a una casilla lateral?


subwf coord_desy,W
absoluto
decf auxAA
btfss STATUS,Z
goto pon_error
movf coord_desx,W ; avance una posicion?
subwf coord_or1x,W
movwf auxAA
decf auxAA
btfss STATUS,Z
goto pon_error
movf coord_desy,W ; comprobamos captura pieza enemiga
movwf aux_y
movf coord_desx,W
movwf aux_x
goto mira_captura_p

examina_peon1 movf coord_desy,W ; comprobamos casilla destino ocupada


movwf aux_y
movf coord_desx,W
movwf aux_x
call mira_casilla ; miramos si casilla de paso ocupada
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto pon_error ; si
examina_peon2 btfss control,0 ; no, juegan blancas
goto $+7 ; si
movlw h'00' ; no
subwf coord_desx,W ; fila destino 0? (corona)
btfss STATUS,Z
goto mira_jaque ; no
bsf control,6 ; si, lo indicamos en control
goto mira_jaque
movlw h'07'
subwf coord_desx,W ; fila destino 7? (corona)
btfss STATUS,Z
goto mira_jaque ; no
bsf control,6 ; si, lo indicamos en control
goto mira_jaque

;***********************************************************************

examina_torre movf coord_or1x,W ; comprobamos geometria del movimiento


subwf coord_desx,W ; coordenadas x iguales?
btfsc STATUS,Z
goto examina_torre1 ; si
movf coord_or1y,W ; no, coordenadas y iguales?
subwf coord_desy,W
btfsc STATUS,Z
goto examina_torre2 ; si
btfss control,5 ; no, mueve una dama?
goto pon_error ; no
goto examina_alfil ; si

examina_torre1 movf coord_or1y,W ; comprobamos casillas de paso y

170
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf auxBB
examina_ty movf coord_or1y,W
subwf coord_desy,W
btfss STATUS,C ; coord_or1y > coord_desy ?
goto $+3 ; si
incf auxBB ; no
goto $+2
decf auxBB
movf auxBB,W
subwf coord_desy,W ; coincide con la casilla destino ?
btfsc STATUS,Z
goto quita_enroquet ; si
movf auxBB,W
movwf aux_y
movf coord_or1x,W
movwf aux_x
call mira_casilla ; miramos si la casilla esta ocupada
movwf auxAA
btfsc auxAA,0 ; ocupada ?
goto pon_error ; si
goto examina_ty

examina_torre2 movf coord_or1x,W ; comprobamos casillas de paso x


movwf auxBB
examina_tx movf coord_or1x,W
subwf coord_desx,W
btfss STATUS,C ; coord_or1x > coord_desx ?
goto $+3 ; si
incf auxBB ; no
goto $+2
decf auxBB
movf auxBB,W
subwf coord_desx,W ; coincide con la casilla destino ?
btfsc STATUS,Z
goto quita_enroquet ; si
movf auxBB,W
movwf aux_x
movf coord_or1y,W
movwf aux_y
call mira_casilla ; miramos si la casilla esta ocupada
movwf auxAA
btfsc auxAA,0 ; ocupada ?
goto pon_error ; si
goto examina_tx

quita_enroquet movlw h'00'


subwf coord_or1x,W
btfss STATUS,Z
goto quita_enroquet2
movlw h'07'
subwf coord_or1y,W
btfss STATUS,Z
goto quita_enroquet1
bcf enroque,0
goto mira_captura
quita_enroquet1 movlw h'00'
subwf coord_or1y,W
btfss STATUS,Z
goto mira_captura
bcf enroque,2
goto mira_captura
quita_enroquet2 movlw h'07'
subwf coord_or1x,W
btfss STATUS,Z
goto quita_enroquet3
movlw h'07'
subwf coord_or1y,W
btfss STATUS,Z

171
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto mira_captura
bcf enroque,1
goto mira_captura
quita_enroquet3 movlw h'00'
subwf coord_or1y,W
btfss STATUS,Z
goto mira_captura
bcf enroque,3
goto mira_captura

mira_captura_p call mira_casilla


movwf auxAA
btfss auxAA,0 ; casilla ocupada?
goto pon_error ; no
btfss auxAA,1 ; si, color captura
goto $+4
btfsc control,0 ; captura pieza negra, juegan blancas?
goto pon_error ; no
goto mira_captura_p1 ; si
btfss control,0 ; captura pieza blanca, juegan negras?
goto pon_error ; no
mira_captura_p1 btfss control,0 ; si, juegan blancas
goto $+7 ; si
movlw h'00' ; no
subwf coord_desx,W ; fila destino 0? (corona)
btfss STATUS,Z
goto mira_captura1 ; no
bsf control,6 ; si, lo indicamos en control
goto mira_captura1
movlw h'07'
subwf coord_desx,W ; fila destino 7? (corona)
btfss STATUS,Z
goto mira_captura1 ; no
bsf control,6 ; si, lo indicamos en control
goto mira_captura1

mira_captura movf coord_desx,W ; miramos si casilla destino ocupada.


movwf aux_x
movf coord_desy,W
movwf aux_y
call mira_casilla
movwf auxAA
btfss auxAA,0 ; casilla ocupada?
goto mira_jaque ; no, miramos jaques
mira_captura2 btfss auxAA,1 ; si, color captura
goto $+4
btfsc control,0 ; captura pieza negra, juegan blancas?
goto pon_error ; no
goto mira_captura1 ; si
btfss control,0 ; captura pieza blanca, juegan negras?
goto pon_error ; no
goto mira_captura1 ; si
mira_captura1 call kill_pieza ; eliminamos pieza capturada del array
goto mira_jaque

;***********************************************************************

examina_caballo movf coord_desy,W ; comprobamos geometria del movimiento


subwf coord_or1y,W
absoluto
movlw h'01'
subwf auxAA,W ; desplazamiento lateral=1?
btfss STATUS,Z
goto examina_caba2 ; no
movf coord_desx,W
subwf coord_or1x,W ; si, desplazamiento horizontal=2?

172
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

absoluto
movlw h'02'
subwf auxAA,W
btfss STATUS,Z
goto pon_error ; no, error
goto mira_captura ; si

examina_caba2 movlw h'02'


subwf auxAA,W ; desplazamiento lateral=2?
btfss STATUS,Z
goto pon_error ; no
movf coord_desx,W
subwf coord_or1x,W ; si, desplazamiento horizontal=1?
absoluto
movlw h'01'
subwf auxAA,W
btfss STATUS,Z
goto pon_error ; no, error
goto mira_captura ; si

;***********************************************************************

examina_alfil movf coord_desy,W ; comprobamos geometria del movimiento

subwf coord_or1y,W
absoluto
movf auxAA,W
movwf auxBB
movf coord_desx,W
subwf coord_or1x,W
absoluto
movf auxAA,W
subwf auxBB,W
btfss STATUS,Z ; incrementoX = incrementoY?
goto pon_error ; no

movf coord_or1x,W ; comprobamos casillas de paso


movwf aux_x
movf coord_or1y,W
movwf aux_y
examina_alfil1 movf coord_or1x,W
subwf coord_desx,W
btfss STATUS,C ; coord_or1x > coord_desx ?
goto $+3 ; si
incf aux_x ; no
goto $+2
decf aux_x
movf coord_or1y,W
subwf coord_desy,W
btfss STATUS,C ; coord_or1y > coord_desy ?
goto $+3 ; si
incf aux_y ; no
goto $+2
decf aux_y
movf aux_x,W
subwf coord_desx,W ; coincide con la casilla destino ?
btfsc STATUS,Z
goto mira_captura ; si
call mira_casilla ; no, miramos si la casilla esta ocupada
movwf auxAA
btfsc auxAA,0 ; ocupada ?
goto pon_error ; si
goto examina_alfil1

;***********************************************************************

examina_dama bsf control,5 ; indicamos que mueve una dama


goto examina_torre ; se mira el movimiento de torre o alfil

173
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;***********************************************************************

examina_rey movf coord_desx,W ; comprobamos geometría del movimiento

subwf coord_or1x,W
btfss STATUS,Z ; coordenadas x iguales?
goto examina_rey1 ; no
movf coord_desy,W ; si
subwf coord_or1y,W
absoluto
movlw h'01'
subwf auxAA,W
btfss STATUS,Z ; desplazamiento y = 1?
goto mira_enroque ; no
goto quita_enroque ; si
examina_rey1 movf coord_desx,W
subwf coord_or1x,W
absoluto
movlw h'01'
subwf auxAA,W
btfss STATUS,Z ; desplazamiento x = 1?
goto pon_error ; no
movf coord_desy,W ; si
subwf coord_or1y,W
btfsc STATUS,Z ; coordenadas y iguales?
goto quita_enroque ; si
movf coord_desy,W ; no
subwf coord_or1y,W
absoluto
movlw h'01'
subwf auxAA,W
btfss STATUS,Z ; desplazamiento y=1?
goto pon_error ; no
quita_enroque btfsc control,0 ; si, juegan blancas?
goto quita_enroque1 ; no
bcf enroque,0 ; si
bcf enroque,2
goto mira_captura
quita_enroque1 bcf enroque,1
bcf enroque,3
goto mira_captura

;***********************************************************************

mira_jaque call actualiza_array ; actualiza array piezas


goto jaque ; mira si se da algun jaque
turno_juego call guarda_ram
turno_juego1 bcf cambio,0
bcf cambio,1
bcf cambio,2
bcf control,4
bcf control,7
call actualiza_a0 ; actualiza array anterior0
movlw h'f0' ; enroque en proceso?
andwf enroque,W
btfss STATUS,Z
return ; si
btfss control,0 ; no, actualiza turno de juego
goto $+5
bcf control,0
bcf control,5
bcf control,6
return
bsf control,0
bcf control,5
bcf control,6
return

174
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

;***********************************************************************

mira_enroque btfsc control,0 ; juegan blancas?


goto mira_enroque2
movlw h'06' ; si, comprobamos casilla destino
subwf coord_desy,W
btfss STATUS,Z
goto mira_enroque1
movlw h'00'
subwf coord_desx,W
btfss STATUS,Z
goto pon_error
btfss enroque,0 ; enroque corto blancas permitido?
goto pon_error ; no
btfsc control,2 ; si, esta el rey en jaque?
goto pon_error ; si
movlw h'00' ; no, miramos si casillas de paso ocupadas
movwf aux_x
movlw h'05'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'06'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'00' ; miramos si casillas paso atacadas
movwf fila
movlw h'05'
movwf columna
movlw h'01'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'06'
movwf columna
movlw h'01'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
bsf enroque,4 ; enroque en proceso (falta mover torre)
bcf enroque,0
call actualiza_array
goto turno_juego
mira_enroque1 movlw h'02' ; comprobamos casilla destino
subwf coord_desy,W
btfss STATUS,Z
goto pon_error
movlw h'00'
subwf coord_desx,W
btfss STATUS,Z
goto pon_error
btfss enroque,2 ; enroque largo blancas permitido?
goto pon_error ; no
btfsc control,2 ; si, esta el rey en jaque?
goto pon_error ; si
movlw h'00' ; no, miramos si casillas de paso ocupadas
movwf aux_x
movlw h'03'
movwf aux_y
call mira_casilla

175
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'02'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'00' ; miramos si casillas paso atacadas
movwf fila
movlw h'03'
movwf columna
movlw h'01'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'02'
movwf columna
movlw h'01'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
bsf enroque,6 ; enroque en proceso (falta mover torre)
bcf enroque,2
call actualiza_array
goto turno_juego

mira_enroque2 movlw h'06' ; comprobamos casilla destino


subwf coord_desy,W
btfss STATUS,Z
goto mira_enroque3
movlw h'07'
subwf coord_desx,W
btfss STATUS,Z
goto pon_error
btfss enroque,1 ; enroque corto negras permitido?
goto pon_error ; no
btfsc control,1 ; si, esta el rey en jaque?
goto pon_error ; si
movlw h'07' ; no, miramos si casillas de paso ocupadas
movwf aux_x
movlw h'05'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'06'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'07' ; miramos si casillas paso atacadas
movwf fila
movlw h'05'
movwf columna
movlw h'00'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'06'
movwf columna
movlw h'00'

176
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
bsf enroque,5 ; enroque en proceso (falta mover torre)
bcf enroque,1
call actualiza_array
goto turno_juego
mira_enroque3 movlw h'02' ; comprobamos casilla destino
subwf coord_desy,W
btfss STATUS,Z
goto pon_error
movlw h'07'
subwf coord_desx,W
btfss STATUS,Z
goto pon_error
btfss enroque,3 ; enroque largo negras permitido?
goto pon_error ; no
btfsc control,1 ; si, esta el rey en jaque?
goto pon_error ; si
movlw h'07' ; no, miramos si casillas de paso ocupadas
movwf aux_x
movlw h'03'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'02'
movwf aux_y
call mira_casilla
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'07' ; miramos si casillas paso atacadas
movwf fila
movlw h'03'
movwf columna
movlw h'00'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
movlw h'02'
movwf columna
movlw h'00'
call ataque
movwf auxAA
btfsc auxAA,0
goto pon_error
bsf enroque,7 ; enroque en proceso (falta mover torre)
bcf enroque,3
call actualiza_array
goto turno_juego

;-------------------------------------------------------------------------
; mira_casilla: dadas las coordenadas aux_x, aux_y miramos si esa
; casilla esta ocupada. devuelve por W bit0 ocupada,
; bit1 color pieza
;-------------------------------------------------------------------------

mira_casilla movlw piezas ; buscamos pieza en array 'piezas'


movwf auxAA1
mira_casilla1 incf auxAA1
movf auxAA1,W
leer_punterob1
movwf auxAA
andlw h'0F' ; aplica mascara para seleccionar coord x

177
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

subwf aux_x,W ; igual a aux_x?


btfsc STATUS,Z
goto mira_casilla2 ; si
mira_casilla5 movlw h'DF' ; no
subwf auxAA1,W ; hemos llegado al final del array?
btfsc STATUS,Z
retlw h'00' ; si, casilla vacia
incf auxAA1 ; no
goto mira_casilla1

mira_casilla2 movf auxAA,W


andlw h'F0' ; aplica mascara para seleccionar coord y
movwf auxAA
swapf auxAA,W
subwf aux_y,W ; igual a aux_y?
btfsc STATUS,Z
goto mira_casilla3 ; si
goto mira_casilla5 ; no

mira_casilla3 decf auxAA1 ; miramos pieza viva y color


movf auxAA1,W
leer_punterob1
movwf auxAA
btfsc auxAA,4 ; pieza viva (=0)?
goto mira_casilla4 ; no
btfsc auxAA,3 ; si, la pieza es blanca (=0)?
retlw h'03' ; no
retlw h'01' ; si

mira_casilla4 incf auxAA1 ; recorremos todo el array


goto mira_casilla5

;-------------------------------------------------------------------------
; kill_pieza: elimina pieza capturada del array
;-------------------------------------------------------------------------

kill_pieza clrf offset_captura


bsf control,4
movlw piezas ; buscamos pieza en array 'piezas'
movwf aux_piezas
kill_pieza1 incf aux_piezas
incf offset_captura
movf aux_piezas,W
leer_punterob1
movwf auxAA
andlw h'0F' ; aplica mascara para seleccionar coord x
subwf coord_desx,W ; igual a coord_desx?
btfsc STATUS,Z
goto kill_pieza2 ; si
kill_pieza5 movlw h'DF' ; no
subwf aux_piezas,W ; hemos llegado al final del array?
btfsc STATUS,Z
goto pon_error ; si
incf aux_piezas ; no
incf offset_captura
goto kill_pieza1

kill_pieza2 movf auxAA,W


andlw h'F0' ; aplica mascara para seleccionar coord y
movwf auxAA
swapf auxAA,W
subwf coord_desy,W ; igual a coord_desy?
btfsc STATUS,Z
goto kill_pieza3 ; si
goto kill_pieza5 ; no

kill_pieza3 decf aux_piezas


movf aux_piezas,W

178
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

leer_punterob1
movwf auxAA
btfsc auxAA,4 ; pieza muerta?
goto kill_pieza4 ; si
bsf auxAA,4 ; no, bit4=1, pieza muerta
movf aux_piezas,W
escribe_punterob1
return

kill_pieza4 incf aux_piezas


incf offset_captura
goto kill_pieza5

;-------------------------------------------------------------------------
; actualiza_array: actualiza el array piezas con la jugada introducida
;-------------------------------------------------------------------------

actualiza_array movlw piezas ; buscamos pieza en array 'piezas'


movwf aux_piezas
actualiza_ar1 incf aux_piezas
movf aux_piezas,W
leer_punterob1
movwf auxAA
andlw h'0F' ; aplica mascara para seleccionar coord x
subwf coord_or1x,W ; igual a coord_or1x?
btfsc STATUS,Z
goto actualiza_ar2 ; si
actualiza_ar7 movlw h'DF' ; no
subwf aux_piezas,W ; hemos llegado al final del array?
btfsc STATUS,Z
goto pon_error ; si
incf aux_piezas ; no
goto actualiza_ar1

actualiza_ar2 movf auxAA,W


andlw h'F0' ; aplica mascara para seleccionar coord y
movwf auxAA
swapf auxAA,W
subwf coord_or1y,W ; igual a coord_or1y?
btfsc STATUS,Z
goto actualiza_ar3 ; si
goto actualiza_ar7 ; no

actualiza_ar3 decf aux_piezas


movf aux_piezas,W
leer_punterob1
movwf auxAA
btfsc auxAA,4 ; pieza muerta?
goto actualiza_ar4 ; si
btfsc control,6 ; no, peon corona?
goto actualiza_ar5 ; si
actualiza_ar6 incf aux_piezas ; no
movf coord_desx,W ; actualizamos coordenadas pieza movida
movwf auxAA
swapf coord_desy,W
addwf auxAA,f
movf aux_piezas,W ; direccion a escribir
escribe_punterob1
return

actualiza_ar4 incf aux_piezas


goto actualiza_ar7

actualiza_ar5 bsf auxAA,2


bcf auxAA,1
bcf auxAA,0
movf aux_piezas,W ; peon=dama
escribe_punterob1

179
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto actualiza_ar6

;-------------------------------------------------------------------------;
; jaque: mira si el bando que mueve deja a su rey en jaque al hacerlo.
; si no ocurre, mira si da jaque al rey contrario
;-------------------------------------------------------------------------;

jaque bsf control,7


movlw piezas ; aux_piezas = @base array piezas
movwf aux_piezas
jaque1 movf aux_piezas,W ; buscamos un rey
leer_punterob1
andlw h'07' ; seleccionamos tipo pieza
movwf auxAA
movlw h'05'
subwf auxAA,W ; es un rey?
btfsc STATUS,Z
goto jaque2 ; si
movlw h'DE' ; no
subwf aux_piezas,W ; hemos llegado al final del array?
btfsc STATUS,Z
goto pon_error ; si
jaque3 incf aux_piezas ; no
incf aux_piezas
goto jaque1

jaque2 movf aux_piezas,W ; miramos el color


leer_punterob1
movwf auxAA
btfss auxAA,3 ; rey negro?
goto jaque4 ; no
btfss control,0 ; si, juegan negras?
goto jaque3 ; no
incf aux_piezas ; si, tomamos las coordenadas
movf aux_piezas,W
leer_punterob1
movwf auxAA
movlw h'07'
andwf auxAA,W
movwf fila ; selecciona coordenada x (fila)
swapf auxAA,f
movlw h'07'
andwf auxAA,W
movwf columna ; selecciona coordenada y (columna)
movlw h'00' ; bando q ataca blancas
call ataque ; mira si el rey negro esta atacado
movwf auxAA
btfsc auxAA,0 ; rey atacado?
goto pon_error ; si
bcf control,1 ; no
goto jaque_c

jaque4 btfsc control,0 ; rey blanco, juegan blancas?


goto jaque3 ; no
incf aux_piezas ; si, tomamos las coordenadas
movf aux_piezas,W
leer_punterob1
movwf auxAA
movlw h'07'
andwf auxAA,W
movwf fila ; selecciona coordenada x (fila)
swapf auxAA,f
movlw h'07'
andwf auxAA,W
movwf columna ; selecciona coordenada y (columna)
movlw h'01' ; bando q ataca negras
call ataque ; mira si el rey blanco esta atacado

180
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf auxAA
btfsc auxAA,0 ; rey atacado?
goto pon_error ; si
bcf control,2 ; no
; miramos si con la jugada realizada se da jaque al rey contrario

jaque_c movlw piezas ; aux_piezas = @base array piezas


movwf aux_piezas
jaque_c1 movf aux_piezas,W ; buscamos un rey
leer_punterob1
andlw h'07' ; seleccionamos tipo pieza
movwf auxAA
movlw h'05'
subwf auxAA,W ; es un rey?
btfsc STATUS,Z
goto jaque_c2 ; si
movlw h'DE' ; no
subwf aux_piezas,W ; hemos llegado al final del array?
btfsc STATUS,Z
goto pon_error ; si
jaque_c3 incf aux_piezas ; no
incf aux_piezas
goto jaque_c1

jaque_c2 movf aux_piezas,W ; miramos el color


leer_punterob1
movwf auxAA
btfss auxAA,3 ; rey negro?
goto jaque_c4 ; no
btfsc control,0 ; si, juegan blancas?
goto jaque_c3 ; no
incf aux_piezas ; si, tomamos las coordenadas
movf aux_piezas,W
leer_punterob1
movwf auxAA
movlw h'07'
andwf auxAA,W
movwf fila ; selecciona coordenada x (fila)
swapf auxAA,f
movlw h'07'
andwf auxAA,W
movwf columna ; selecciona coordenada y (columna)
movlw h'00' ; bando q ataca blancas
call ataque ; mira si el rey negro esta atacado
movwf auxAA
btfss auxAA,0 ; rey atacado?
goto $+3 ; no
bsf control,1 ; si
goto turno_juego
bcf control,1
goto turno_juego

jaque_c4 btfss control,0 ; rey blanco, juegan negras?


goto jaque_c3 ; no
incf aux_piezas ; si, tomamos las coordenadas
movf aux_piezas,W
leer_punterob1
movwf auxAA
movlw h'07'
andwf auxAA,W
movwf fila ; selecciona coordenada x (fila)
swapf auxAA,f
movlw h'07'
andwf auxAA,W
movwf columna ; selecciona coordenada y (columna)
movlw h'01' ; bando q ataca negras
call ataque ; mira si el rey blanco esta atacado
movwf auxAA

181
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

btfss auxAA,0 ; rey atacado?


goto $+3 ; no
bsf control,2 ; si
goto turno_juego
bcf control,2
goto turno_juego

;-------------------------------------------------------------------------;
; ataque: mira si alguna pieza del bando 'W' ataca la casilla de
; coordenadas 'fila' y 'columna'. Retorna W=0, no, y W=1, si.
;-------------------------------------------------------------------------;

ataque movwf auxCC


movlw piezas
movwf aux_piezas ; aux_piezas= @ base de array 'piezas'
ataque_1 movf aux_piezas,W
leer_punterob1
movwf auxAA
btfsc auxAA,4 ; pieza viva (=1)?
goto ataque_2 ; no, saltamos
btfsc auxCC,0 ; si, bando que ataca = blancas?
goto $+4 ; no, bando que ataca = negras
btfsc auxAA,3 ; si, pieza blanca?
goto ataque_2 ; no, saltamos
goto $+3 ; si, saltamos al switch

btfss auxAA,3 ; pieza negra?


goto ataque_2 ; no, saltamos

movf aux_piezas,W ; detectamos de que tipo de pieza se trata


leer_punterob1
movwf auxAA
movlw h'07'
andwf auxAA,f
movlw h'00'
subwf auxAA,W
btfsc STATUS,Z ; es un peon?
goto at_peon ; si, saltamos
movlw h'01'
subwf auxAA,W
btfsc STATUS,Z ; no, es una torre?
goto at_torre ; si, saltamos
movlw h'02'
subwf auxAA,W
btfsc STATUS,Z ; no, es un caballo?
goto at_caballo ; si, saltamos
movlw h'03'
subwf auxAA,W
btfsc STATUS,Z ; no, es un alfil?
goto at_alfil ; si, saltamos
movlw h'04'
subwf auxAA,W
btfss STATUS,Z ; no, es una dama?
goto ataque_2 ; no, es un rey pero este no puede dar jaque,
saltamos
goto at_torre ; si, saltamos primero a torre y despues a
alfil

ataque_2 movlw h'DE' ; hemos llegado al final del array?


subwf aux_piezas,W
btfsc STATUS,Z
retlw h'00' ; si, no hay ataque (W=0)
incf aux_piezas ; no
incf aux_piezas
goto ataque_1

ataque3 movlw h'DF' ; hemos llegado al final del array?


subwf aux_piezas,W

182
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

btfsc STATUS,Z
retlw h'00' ; si, no hay ataque (W=0)
incf aux_piezas ; no
goto ataque_1

;************************************************************

at_peon incf aux_piezas,W ; miramos si el peon se encuentra en


una columna
leer_punterob1 ; limite del tablero
movwf auxAA
swapf auxAA,f
movlw h'07'
andwf auxAA,f
btfsc STATUS,Z ; peon en columna 0?
goto at_peon_c0 ; si, saltamos
movlw h'07'
subwf auxAA,W
btfsc STATUS,Z ; no, peon en columna 7?
goto at_peon_c7 ; si, saltamos
incf auxAA,W ; no, miramos las casillas que ataca
(columna+1)
subwf columna,W
btfsc STATUS,Z ; coincide con la columna objetivo?
goto at_peon_1 ; si, saltamos
decf auxAA,W ; no, miramos columna-1
subwf columna,W
btfsc STATUS,Z ; coincide con la columna objetivo?
goto at_peon_1 ; si, saltamos
goto ataque_2 ; no, el peon no ataca la casilla objetivo

at_peon_1 movf aux_piezas,W


leer_punterob1
movwf auxAA
btfsc auxAA,3 ; es un peon blanco?
goto at_peon_2 ; no, saltamos
incf aux_piezas,W ; si, miramos fila+1
leer_punterob1
andlw h'0F'
movwf auxAA
incf auxAA
movf auxAA,W
subwf fila,W ; concide con la fila objetivo?
btfsc STATUS,Z
retlw h'01' ; si, el peon ataca la casilla objetivo,
retorno con 1
goto ataque_2 ; no, el peon no ataca la casilla objetivo,
at_peon_2 incf aux_piezas,W ; miramos fila-1
leer_punterob1
andlw h'0F'
movwf auxAA
decf auxAA
movf auxAA,W
subwf fila,W ; concide con la fila objetivo?
btfsc STATUS,Z
retlw h'01' ; si, el peon ataca la casilla objetivo,
retorno con 1
goto ataque_2 ; no, el peon no ataca la casilla objetivo,

at_peon_c0 incf auxAA,W


subwf columna,W
btfss STATUS,Z ; la columna objetivo es c=1?
goto ataque_2 ; no, pasamos a la siguiente
goto at_peon_1 ; si, miramos fila objetivo

at_peon_c7 decf auxAA,W


subwf columna,W
btfss STATUS,Z ; la columna objetivo es c=7?

183
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

goto ataque_2 ; no, pasamos a la siguiente


goto at_peon_1 ; si, miramos fila objetivo

;************************************************************

at_torre incf aux_piezas,W ; guardamos fila y columna de la posicion


leer_punterob1 ; del caballo en variables auxiliares
movwf aux_x
swapf aux_x,W
andlw h'07'
movwf aux_y
movlw h'07'
andwf aux_x,f

movf aux_x,W ; miramos si torre misma fila casilla


objetivo
subwf fila,W
btfss STATUS,Z ; se encuentra en la misma fila?
goto at_torre_c ; no, saltamos
movf columna,W ; si, miramos si hay algun obstaculo en esa
columna
subwf aux_y,W
btfsc STATUS,C ; aux_y > columna(torre)?
goto at_torre_2 ; si, saltamos
at_torre_1 incf aux_y,f ; no, miramos las casillas que barre la
torre
movf aux_y,W
subwf columna,W
btfsc STATUS,Z ; hemos llegado a la casilla objetivo?

retlw h'01' ; si, torre ataca casilla objetivo


call mira_casilla ; no
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto at_torre_5 ; si
goto at_torre_1 ; no, saltamos

at_torre_2 decf aux_y,f ; no, miramos las casillas que barre la


torre
movf aux_y,W
subwf columna,W
btfsc STATUS,Z ; hemos llegado a la casilla objetivo?

retlw h'01' ; si, torre ataca casilla objetivo


call mira_casilla ; en esa fila en adelante
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto at_torre_5 ; si
goto at_torre_2 ; no, saltamos

at_torre_c movf aux_y,W ; miramos si torre misma columna


casilla objetivo
subwf columna,W
btfss STATUS,Z ; se encuentra en la misma columna?
goto at_torre_5 ; no, saltamos
movf fila,W ; si, miramos si hay algun obstaculo en esa
columna
subwf aux_x,W
btfsc STATUS,C ; aux_x > fila(torre)?
goto at_torre_4 ; si, saltamos
at_torre_3 incf aux_x,f ; no, miramos las casillas que barre la
torre
movf aux_x,W
subwf fila,W
btfsc STATUS,Z ; hemos llegado a la casilla objetivo?

retlw h'01' ; si, torre ataca casilla objetivo


call mira_casilla ; en esa columna en adelante

184
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto at_torre_5 ; si
goto at_torre_3 ; no, saltamos

at_torre_4 decf aux_x,f ; no, miramos las casillas que barre la


torre
movf aux_x,W
subwf fila,W
btfsc STATUS,Z ; hemos llegado a la casilla objetivo?

retlw h'01' ; si, torre ataca casilla objetivo


call mira_casilla ; en esa columna en adelante
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto at_torre_5 ; si
goto at_torre_4 ; no, saltamos

at_torre_5 movf aux_piezas,W ; si la pieza es una dama saltamos ahora a


alfil
leer_punterob1
andlw h'07'
movwf auxAA
movlw h'04'
subwf auxAA,W
btfsc STATUS,Z ; es una dama?
goto at_alfil ; si, saltamos a alfil
goto ataque_2 ; no, seguimos con otra pieza

;************************************************************

at_caballo incf aux_piezas,W ; guardamos fila y columna de la posicion


leer_punterob1 ; del caballo en variables auxiliares
movwf aux_x
swapf aux_x,W
andlw h'07'
movwf aux_y
movlw h'07'
andwf aux_x,f

movlw h'01'
addwf aux_y,W
subwf columna,W
btfss STATUS,Z ; columna+1 = columna?
goto at_caballo_1 ; no, saltamos
movlw h'02'
addwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; si, fila+2 = fila?
retlw h'01' ; si, retorno con 1
movlw h'02' ;no
subwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; no, fila-2 = fila?
retlw h'01' ; si, retorno con 1
goto ataque_2 ; no, seguimos con otra pieza

at_caballo_1 movlw h'02'


addwf aux_y,W
subwf columna,W
btfss STATUS,Z ; columna+2 = columna?
goto at_caballo_2 ; no, saltamos
movlw h'01'
addwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; si, fila+1 = fila?
retlw h'01' ; si, retorno con 1
movlw h'01'

185
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

subwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; no, fila-1 = fila?
retlw h'01' ; si, retorno con 1
goto ataque_2 ; no, seguimos con otra pieza

at_caballo_2 movlw h'01'


subwf aux_y,W
subwf columna,W
btfss STATUS,Z ; columna-1 = columna?
goto at_caballo_3 ; no, saltamos
movlw h'02'
addwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; si, fila+2 = fila?
retlw h'01' ; si, retorno con 1
movlw h'02'
subwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; no, fila-2 = fila?
retlw h'01' ; si, retorno con 1
goto ataque_2 ; no, seguimos con otra pieza

at_caballo_3 movlw h'02'


subwf aux_y,W
subwf columna,W
btfss STATUS,Z ; columna-2 = columna?
goto ataque_2 ; no, saltamos
movlw h'01'
addwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; si, fila+1 = fila?
retlw h'01' ; si, retorno con 1
movlw h'01'
subwf aux_x,W
subwf fila,W
btfsc STATUS,Z ; no, fila-1 = fila?
retlw h'01' ; si, retorno con 1
goto ataque_2 ; no, seguimos con otra pieza

;************************************************************

at_alfil incf aux_piezas,W ; guardamos fila y columna de la posicion


leer_punterob1 ; del alfil en variables auxiliares
movwf auxAA
movf auxAA,W
andlw h'07'
movwf aux_x
swapf auxAA,W
andlw h'07'
movwf aux_y

movf aux_x,W ; miramos si la casilla objetivo se


encuentra
subwf fila,W ; en la misma diagonal superior derecha
btfss STATUS,C ; fila > aux_x?
goto at_alfil_d2 ; no
movwf auxAA ; si
movf aux_y,W
subwf columna,W
btfss STATUS,C ; columna > aux_y?
goto at_alfil_d2 ; no
subwf auxAA,W ; si
btfss STATUS,Z ; (fila - aux_x)=(columna-aux_y) ?
goto at_alfil_d2 ; no, saltamos
at_alfil_1 incf aux_x,f ; si, recorremos la diagonal mirando si
incf aux_y,f ; hay algun obstaculo entre el alfil y
la

186
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

movf aux_x,W ; casilla objetivo


subwf fila,W ; aux_x++, aux_y++
btfsc STATUS,Z ; hemos llegado a la casilla destino?
retlw h'01' ; si, retorno con 1
call mira_casilla ; no, miramos si hay obstaculos
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto ataque_2 ; si, saltamos
goto at_alfil_1 ; no, seguimos recorriendo la diagonal

at_alfil_d2 movf fila,W ; miramos si la casilla objetivo se encuentra


subwf aux_x,W ; en la misma diagonal inferior derecha
btfss STATUS,C ; aux_x > fila?
goto at_alfil_d3 ; no
movwf auxAA ; si
movf aux_y,W
subwf columna,W
btfss STATUS,C ; columna > aux_y?
goto at_alfil_d3 ; no
subwf auxAA,W ; si
btfss STATUS,Z ; (aux_x - fila)=(columna-aux_y) ?
goto at_alfil_d3 ; no, saltamos
at_alfil_2 decf aux_x,f ; si, recorremos la diagonal mirando si
incf aux_y,f ; hay algun obstaculo entre el alfil y
la
movf aux_x,W ; casilla objetivo
subwf fila,W ; aux_x++, aux_y++
btfsc STATUS,Z ; hemos llegado a la casilla destino?
retlw h'01' ; si, retorno con 1
call mira_casilla ; no, miramos si hay obstaculos
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto ataque_2 ; si, saltamos
goto at_alfil_2 ; no, seguimos recorriendo la diagonal

at_alfil_d3 movf fila,W ; miramos si la casilla objetivo se encuentra


subwf aux_x,W ; en la misma diagonal inferior
izquierda
btfss STATUS,C ; fila > aux_x?
goto at_alfil_d4 ; no
movwf auxAA ; si
movf columna,W
subwf aux_y,W
btfss STATUS,C ; columna > aux_y?
goto at_alfil_d4 ; no
subwf auxAA,W ; si
btfss STATUS,Z ; (aux_x - fila)=(aux_y-columna) ?
goto at_alfil_d4 ; no, saltamos
at_alfil_3 decf aux_x,f ; si, recorremos la diagonal mirando si
decf aux_y,f ; hay algun obstaculo entre el alfil y
la
movf aux_x,W ; casilla objetivo
subwf fila,W ; aux_x++, aux_y++
btfsc STATUS,Z ; hemos llegado a la casilla destino?
retlw h'01' ; si, retorno con 1
call mira_casilla ; no, miramos si hay obstaculos
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto ataque_2 ; si, saltamos
goto at_alfil_3 ; no, seguimos recorriendo la diagonal

at_alfil_d4 movf aux_x,W ; miramos si la casilla objetivo se


encuentra
subwf fila,W ; en la misma diagonal superior izquierda
movwf auxAA
btfss STATUS,C ; fila > aux_x?
goto ataque_2 ; no
movf columna,W ; si

187
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

subwf aux_y,W
btfss STATUS,C ; columna > aux_y?
goto ataque_2 ; no
subwf auxAA,W ; si
btfss STATUS,Z ; (fila - aux_x)=(aux_y-columna) ?
goto ataque_2 ; no, saltamos
at_alfil_4 incf aux_x,f ; si, recorremos la diagonal mirando si
decf aux_y,f ; hay algun obstaculo entre el alfil y
la
movf aux_x,W ; casilla objetivo
subwf fila,W ; aux_x++, aux_y++
btfsc STATUS,Z ; hemos llegado a la casilla destino?
retlw h'01' ; si, retorno con 1
call mira_casilla ; no, miramos si hay obstaculos
movwf auxAA
btfsc auxAA,0 ; casilla ocupada?
goto ataque_2 ; si, saltamos
goto at_alfil_4 ; no, seguimos recorriendo la diagonal

;-------------------------------------------------------------------------
; guarda_ram: almacena las jugadas realizadas en memoria RAM
; 2 Bytes semijugada. High: coordenada y, Low: coordenada x
;-------------------------------------------------------------------------

guarda_ram movf coord_or1y,W ; componemos el byte coordenada origen


movwf auxAA
swapf auxAA,f
movf coord_or1x,W
addwf auxAA,f
movlw h'90'
subwf base_ram,W ; base_ram>0x190?
btfsc STATUS,C
goto guarda_ram2 ; si
movf base_ram,W ; no
escribe_punterob2
incf base_ram
movf coord_desy,W ; componemos el byte coordenada destino
movwf auxAA
swapf auxAA,f
movf coord_desx,W
addwf auxAA,f
movf base_ram,W
escribe_punterob2
movlw h'6f' ; base_ram=0x16f final banco 2?
subwf base_ram,W
btfss STATUS,Z
goto $+4 ; no
movlw h'90' ; si
movwf base_ram
return
incf base_ram
return

guarda_ram2 movlw h'EF'


subwf base_ram,W
btfsc STATUS,Z ; fin del banco 3?
return ; si, no salvamos nada
movf base_ram,W ; no
escribe_punterob3
incf base_ram
movf coord_desy,W ; componemos el byte coordenada destino
movwf auxAA
swapf auxAA,f
movf coord_desx,W
addwf auxAA,f
movf base_ram,W
escribe_punterob3
incf base_ram

188
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

return

;-------------------------------------------------------------------------;
; Definimos los valores iniciales de los dígitos ;
; en la memoria de datos EEPROM del PIC ;
;-------------------------------------------------------------------------;

ORG H'2100'

; orden variables:
;
nsecmov,xtrtmp,hora,minde,minun,secde,secun,ehora,eminde,eminun,esecde,esecun

DE 0 ; offset
DE 0, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0 ; m1. 2h + 1h finish
DE 0, 1, 1, 3, 0, 0, 0, 1, 0, 0, 0, 0 ; m2. 90m + 1h finish
DE 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 ; m3. 30 mimutos
DE 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0 ; m4. 5 minutos
DE 1, 0, 1, 3, 0, 0, 0, 0, 0, 0, 3, 0 ; m5. 90m + 30s/jug
DE 1, 0, 0, 2, 5, 0, 0, 0, 0, 0, 1, 0 ; m6. 25m + 10s/jug
DE 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 2 ; m7. 4m + 2s/jug
DE "Copyright","Carlos Vidal Garcia"

end

189
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

6.3. Código Fuente del Programa Terminal.


/******************************************************************/
/* Programa: Terminal */
/* */
/* Redactado en lenguaje C++ */
/* Gestiona la comunicacion entre el PC y el microcontrolador por */
/* el puerto serie COM_1. Recibe la informacion (jugadas) que */
/* transmite el microcontrolador y genera un archivo *.pgn . */
/* */
/* PFC: Carlos Vidal Garcia caviga12@yahoo.es Septiembre 2005 */
/******************************************************************/

#define COM1BASE 0x3F8


#define TXDATA COM1BASE
#define LSR (COM1BASE+5)
#define LCR (COM1BASE+3)
#define LIMITE 192 /*limite del vector 'inchar'*/
#define carac_final -1
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <conio.h>

void configura_serie(void);
char get_character(void);
void genera_pgn(void);

/***********variables globales*************************************/

char inchar[LIMITE]; /*en este vector se guardan las jugadas*/

/*----------------------------------------------------------------*/
/* programa principal */
/*----------------------------------------------------------------*/
int main(void)
{
int x=0;

printf("Comunicacion 232 con PIC\n\n");

configura_serie();
printf("Esperando Transmision \n\n");

while(inchar[x]!=carac_final && x<LIMITE)


{
inchar[x]=get_character();
if(inchar[x]!=carac_final) x++;
else
{
if(inchar[x]==carac_final && x==0)
{
printf("Error: Memoria vacia\n\n");
exit(1);
}
}
if(kbhit()) exit(1);
}

printf("Fin de transmision\nGenerando pgn\n\n");


genera_pgn(); /* una vez volcados todos los datos se genera el archivo
pgn*/
printf("pgn generado!");
return(0);
}

190
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

/*----------------------------------------------------------------*/
/* configura_serie : configuracion del puerto serie */
/*----------------------------------------------------------------*/
void configura_serie(void)
{
outportb(LCR,0x80); /*line control bit7=1, accedemos a baud rate
divisor*/
outportb(TXDATA,0x0C);
outportb(TXDATA+1,0x00); /*frecuencia del cuarzo 1.8432 MHz*/
outportb(LCR,0x03); /*configuracion de la linea: no bit de paridad,
1 bit de stop, palabra
de 8 bits*/
}

/*----------------------------------------------------------------*/
/* get_character : obtiene un dato entrante por el COM_1 */
/*----------------------------------------------------------------*/
char get_character(void)
{
int status;

do
{
status=inportb(LSR)&0x01; /*data ready=1?*/
if(kbhit()) exit(1);
}while(status!=0x01); /*repetir hasta que se obtiene un dato*/

return((char)inportb(TXDATA));
}

/*----------------------------------------------------------------*/
/* genera_pgn : convierte los bytes transmitidos en un archivo */
/* de partida pgn. */
/*----------------------------------------------------------------*/
void genera_pgn(void)
{
FILE *fp;
int x=0, jugada=1;
char origen=1, negras=0, columna, fila;

fp=fopen("partida.pgn","w+");
if (fp==NULL)
{
printf("Error: no se puede abrir partida_1.pgn\a");
exit(1);
}
fprintf(fp,"[Event \" \"]\n"); /*Escribe los datos de la cabecera del
pgn*/
fprintf(fp,"[Site \" \"]\n");
fprintf(fp,"[Date \" \"]\n");
fprintf(fp,"[Round \" \"]\n");
fprintf(fp,"[White \" \"]\n");
fprintf(fp,"[Black \" \"]\n");
fprintf(fp,"[Result \" \"]\n\n");

while(inchar[x]!=carac_final && x<LIMITE)


{
if(kbhit()) exit(1);
if(origen==0 && negras==1)
{
columna=((inchar[x]&0xF0)>>4)+97;
fprintf(fp,"%c",columna);
fila=(inchar[x]&0x0F)+1;
fprintf(fp,"%d ",fila);
if(inchar[x]!=carac_final) x++;
origen=1;
negras=0;

191
Gestión Basada en Microcontrolador de un Tablero de Ajedrez Adaptado para Ciegos Anexos

}
else
{
if(origen==1 && negras==1)
{
columna=((inchar[x]&0xF0)>>4)+97;
fprintf(fp,"%c",columna);
fila=(inchar[x]&0x0F)+1;
fprintf(fp,"%d-",fila);
if(inchar[x]!=carac_final) x++;
origen=0;
}
else
{
if(origen==0 && negras==0)
{
columna=((inchar[x]&0xF0)>>4)+97;
fprintf(fp,"%c",columna);
fila=(inchar[x]&0x0F)+1;
fprintf(fp,"%d ",fila);
if(inchar[x]!=carac_final) x++;
origen=1;
negras=1;
}
else
{
if(origen==1 && negras==0)
{
fprintf(fp,"%d. ",jugada);
columna=((inchar[x]&0xF0)>>4)+97;
fprintf(fp,"%c",columna);
fila=(inchar[x]&0x0F)+1;
fprintf(fp,"%d-",fila);
jugada++;
if(inchar[x]!=carac_final) x++;
origen=0;
}
}
}
}
}
fclose(fp);
}

192

Das könnte Ihnen auch gefallen