Informe - Escuela de Ingeniería Eléctrica

Anuncio
Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ingeniería Eléctrica
IE – 0502 Proyecto Eléctrico
Implementación de un codificador y decodificador
fuente para un sistema de comunicación digital
Por:
Luis Felipe Córdoba Morales
Ciudad Universitaria Rodrigo Facio
Setiembre del 2007
Implementación de un codificador y decodificador
fuente para un sistema de comunicación digital
Por:
Luis Felipe Córdoba Morales
Sometido a la Escuela de Ingeniería Eléctrica
de la Facultad de Ingeniería
de la Universidad de Costa Rica
como requisito parcial para optar por el grado de:
BACHILLER EN INGENIERÍA ELÉCTRICA
Aprobado por el Tribunal:
_________________________________
Ing. Diego Castro Hernández
Profesor Guía
_________________________________
Ing. Lucía Acuña Avendaño
Profesor lector
_______________________________
Ing. Victor Hugo Chacón Prendas, M.Sc.
Profesor lector
i
DEDICATORIA
A mis padres, por su apoyo, su esfuerzo, su trabajo…
ii
RECONOCIMIENTOS
A Jaime Escalona, estudiante de la Escuela de Ingeniería Eléctrica,
por la ayuda brindada en la adquisición de la tarjeta del
microcontrolador.
iii
ÍNDICE GENERAL
ÍNDICE DE FIGURAS......................................................................................vi
ÍNDICE DE TABLAS.......................................................................................vii
NOMENCLATURA.........................................................................................viii
RESUMEN..........................................................................................................ix
CAPÍTULO 1: Introducción..............................................................................1
1.1 Objetivos...........................................................................................................................5
1.2 Metodología......................................................................................................................6
CAPÍTULO 2: Desarrollo teórico......................................................................7
2.1Generalidades de Probabilidad .........................................................................................7
2.2Fuentes de información .....................................................................................................8
2.2.1Medida de la información en las fuentes de información ............................................12
2.3Codificación fuente .........................................................................................................15
2.3.1Teorema de codificación fuente ...................................................................................16
2.4Técnicas de compresión .................................................................................................18
2.4.1Técnicas de compresión sin pérdidas............................................................................18
2.4.1.1Compresores estadísticos...........................................................................................18
2.4.1.1.1 Codificación Shannon - Fano ............................................................................18
2.4.1.1.2 Codificación Huffman .......................................................................................20
2.4.1.1.3 Codificación Aritmética......................................................................................23
2.4.1.1.4 Codificación Predictiva.......................................................................................26
2.4.1.1.5 Codificación de Golomb y Codificación Rice....................................................27
2.4.1.2Compresores sustitucionales......................................................................................28
2.4.1.2.1LZ77, LZ78 y demás variaciones...........................................................................28
2.4.1.3Otros tipos de codificación .......................................................................................30
2.4.1.3.1Codificación Run-length.........................................................................................30
2.4.1.3.2 Codificación Burrows - Wheeler...........................................................................30
2.4.1.3.3Técnicas varias........................................................................................................31
CAPÍTULO 3: Microcontrolador MC68HC11..............................................33
3.1 Introducción ..................................................................................................................33
3.2 Especificaciones generales .............................................................................................34
3.3 Puerto D y la Interfaz de comunicación serial asíncrona ...............................................37
3.4 Mecanismo de interrupciones del SCI............................................................................38
CAPÍTULO 4. Implementación del Codificador Fuente ..............................42
iv
4.1 Escogencia de los símbolos............................................................................................42
4.2 Codificación....................................................................................................................45
4.3 Implementación...............................................................................................................48
4.4 Software de interfaz con el usuario.................................................................................49
4.5 Programa de codificación y decodificación ...................................................................53
4.5.4 Subrutinas: ..................................................................................................................54
4.6 Manual de usuario de la aplicación.................................................................................61
4.6.1 Modos de uso...............................................................................................................61
............................................................................................................................64
CAPÍTULO 5: Conclusiones y recomendaciones...........................................65
BIBLIOGRAFÍA...............................................................................................69
APÉNDICES......................................................................................................70
ANEXOS............................................................................................................98
v
ÍNDICE DE FIGURAS
Figura 2.1 Digitalización de una señal analógica............................................11
Figura 2.2 Planos de información según Schouten.........................................12
Figura 2.3 Descomposición de una decisión de tres posibilidades................13
Figura 2.4 Entropía en el caso de dos posibilidades con probabilidades p y
(1-p).....................................................................................................................14
Figura 2.5 Construcción del árbol de Huffman con dos símbolos codificados
.............................................................................................................................22
Figura 3.1 Familia 68HC11..............................................................................35
Figura 3.2 Velocidades de comunicación configurables para la SCI del
MC68HC11........................................................................................................40
.............................................................................................................................41
Figura 3.3 Bits relativos a la interrupción producida por la SCI1 .............41
vi
ÍNDICE DE TABLAS
Tabla 2.1 Ensemble de la fuente A ..................................................................19
Tabla 2.1 Ensemble de la fuente A codificado................................................20
Tabla 4.1 Símbolos del texto en español y su probabilidad aproximada de
aparición.............................................................................................................43
Tabla 4.2 Símbolos de texto en español y su codificación..............................46
Tabla 4.4 Símbolos del teclado de la computadora sin codificar .................49
vii
NOMENCLATURA
PAM
Pulse Amplitud Modulation (Modulación por
amplitud de pulso). Señal de valor continuo y
M-ARY PAM
BCD
tiempo discreto.
Señal PAM con M niveles de cuantización
Binary Coded Decimal (Decimal codificado en
minario) Sistema de numeración binario, en que
se representan las unidades, decenas, etc., con
MCU
números binarios.
Micro
Controller
Controladora)
viii
Unit
(Unidad
Micro
RESUMEN
El objetivo general de este proyecto fue implementar un codificador y decodificador
fuente utilizando un microcontrolador de la familia MC68HC11. Se hizo una investigación
sobre codificación fuente, mostrando la evolución histórica, presentando algunos de los
distintos tipos de códigos que existen, sus principios de funcionamiento, diferencias, ventajas
y desventajas, y algunos algoritmos de implementación. Además realizó el estudio necesario
para conocer la forma en que debía programarse el dispositivo que se propuso para éste fin.
Se definió como metodo de codificación el de Huffman, para un conjunto de 108
símbolos, correspondientes a caracteres que normalmente aparecen en los textos en español.
Se desarrolló un código fuente de intercambio de datos tanto para el MCU como para
la computadora, además de una interfaz con el usuario. Finalmente se procedió a escribir un
Manual de usuario para futuras referencias.
Entre los resultados alcanzados se obtuvo tasas de compresión de hasta 40%, sin
embargo una de las principales conclusiones fue que el desempeño de la compresión depende
del origen del texto, pues el cálculo de las probabilidades de los símbolos se realizó para un
texto mayormente constituido por letras minúsculas. En este sentido, se puede obtener tasas
de compresión negativas, si los textos a comprimir poseen solamente caracteres en
mayúscula. Además el tamaño del texto generador de las probabilidades debió ser bastante
grande para obtener resultados confiables. Finalmente se propone el desarrollo de los demás
bloques del sistema de comunicación de manera que se pueda realizar el proceso de
transmisión y recepción en su totalidad.
ix
CAPÍTULO 1: Introducción
El siglo XX se ha visto caracterizado desde sus inicios por grandes avances
tecnológicos en distintas áreas del quehacer humano. En el campo de las telecomunicaciones,
se incursionó en la transmisión de información como la voz, en aplicaciones como la radio y
el teléfono, el video producido por la incipiente industria televisiva, y datos como en el
telégrafo y más adelante en redes de computadoras.
En 1948, Claude Elwood Shannon, publicó su trabajo "Una Teoría Matemática de la
Comunicación", donde demostró, entre otras cosas, que las fuentes de información se pueden
medir y que el mensaje transmitido consiste básicamente en una parte sin información y una
parte que contiene toda la información necesaria para reconstruirlo.
Aparecen así los conceptos de redundancia e irrelevancia. El primero corresponde a
las partes del mensaje que son conocidas por el receptor y por lo tanto no es necesario
transmitirlas. Se podría decir entonces que al suprimirlas, no se afectará la integridad del
mensaje. Esta eliminación de información se logra a través de técnicas de compresión sin
pérdidas.
El segundo término corresponde a la parte de un mensaje que se puede eliminar sin
temor a perder información del mismo, pues son “elementos que carecen de importancia o
significación”1, o sea, son excepciones de alguna información que no es indispensable para la
comprensión del mensaje. Esta eliminación de información se logra a través de técnicas de
compresión con pérdidas. Un ejemplo claro de esto es la telefonía, que utiliza un modelo
auditivo con un ancho de banda de apenas 3000 Hz, a pesar de que un ser humano puede
producir sonidos de entre 20 Hz y 20000 Hz.
1
Adaptado de Irrelevante. Diccionario Océano Uno, edición 2001
1
La eliminación de redundancias e irrelevancias disminuye notablemente el tamaño del
mensaje, sin afectar considerablemente la información que se desea transmitir.
La publicación igualmente hace referencia a la relación entre la potencia de la señal y
el ruido presente en el canal. Según esto se puede determinar la tasa de datos máxima a la cual
se puede transmitir en un canal ruidoso. Este ruido es energía no deseada introducida a la
señal transmitida por fuentes ajenas al transmisor
Además, se menciona el compromiso entre la cantidad de información que se desea
enviar y la capacidad de transmisión del medio utilizado, pues ningún medio tiene un ancho
de banda infinito.
Toda esta teoría es fundamental en el estudio y desarrollo de los sistemas de
comunicación digital, que son sistemas que manipulan una señal, generalmente analógica,
convirtiéndola en una sucesión de símbolos binarios con un determinado índice de
transmisión (cuya unidad son
bits
/segundo) que serán transmitidos por algún medio, ya sea hilos
de cobre, hilos de fibra óptica o el aire.
Este tipo de sistema de comunicación puede ser divido en el transmisor, compuesto
por la fuente, el codificador fuente, el codificador de canal y el modulador; y el receptor, que
lo forman el decodificador fuente, el decodificador de canal, el demodulador y el destino.
Finalmente está el canal, que no pertenece ni al transmisor ni al receptor.
La fuente es quien genera la información que se desea transmitir. En este bloque
también se incluye la parte que digitaliza la señal.
El codificador fuente comprime la señal digital, eliminando las redundancias y las
irrelevancias.
2
El decodificador fuente restituye las redundancias eliminadas por el codificador
fuente. Las irrelevancias no son estrictamente necesarias para la compresión del mensaje;
además no hay manera de restituirlas.
El codificador de canal agrega bits a la trama de datos, para que el decodificador de
canal detecte y/o corrija errores que pueda presentar la señal al recibirla. Estos errores son
producto del ruido presente en el canal de comunicación.
El canal, que es el medio por el cual se transmite la información.
El modulador adapta la señal digital (discreta) para que pueda ser transmitida por un
canal continuo. El demodulador convierte esta señal adaptada en un flujo de símbolos binarios
nuevamente. Se puede considerar que al incluir el modulador y el demodulador, el canal
continuo se convierte en un canal discreto.
Por último, el destino es quien recibe e interpreta la información enviada. En este
bloque se incluye también la parte que, de ser necesario, convierte la señal a analógica.
En este trabajo, se estudiará uno de los bloques antes citados: el codificador fuente,
con sus distintas técnicas de codificación. Además, se implementará un sistema basado en el
microcontrolador MC68HC11 de Freescale para realizar las funciones de codificación y
decodificación fuente.
El propósito de la codificación fuente es la transmisión rápida de la información,
proporcionando una secuencia de bits que represente fielmente la información de la fuente
eliminando la redundancia y la irrelevancia y asignando códigos que representen distorsiones
mínimas si hay errores en la transmisión. Existen varias técnicas de codificación, las cuales
serán descritas en este trabajo. Luego, se utilizará una de ellas para implementarla el sistema.
3
Se tomará como la fuente de información una de tipo discreta sin memoria. A pesar de
existir más tipos de fuentes, este tipo supone cierta facilidad a la hora de implementar el
algoritmo de codificación ya que no considera la dependencia que pueda existir entre los
símbolos que ya han aparecido y los que están por aparecer.
4
1.1
Objetivos
1.1.1
Objetivo general
Implementar un codificador y decodificador fuente utilizando un microcontrolador de la
familia MC68HC11
1.1.2
Objetivos específicos
1. Realizar una investigación bibliográfica acerca de los diferentes algoritmos de
codificación y decodificación fuente.
2. Describir la evolución histórica de este tipo de codificación.
3. Implementar el codificador y decodificador fuente para un sistema de comunicación
digital, considerando una fuente discreta sin memoria.
4. Implementar un sistema de prueba del codificador y decodificador fuente
implementado.
5. Desarrollar un manual de usuario para el sistema implementado que describa el uso
tanto del dispositivo como del mecanismo de prueba.
5
1.2
Metodología
Se hará la investigación sobre codificación fuente, mostrando la evolución histórica,
presentado los distintos tipos de códigos que existen, mostrando sus principios de
funcionamiento, diferencias, ventajas y desventajas y finalmente en los casos que ameriten, su
algoritmo de implementación. Además se realizará el estudio necesario para conocer la forma
en que debe programarse el dispositivo. Esto es, la lectura de las hojas de datos del chip, el
manual de la tarjeta entrenadora con la que se desarrollará el sistema, la AD11C24DXSP32K,
de Technological Arts, Canadá; y los manuales de programación de 68HC11 disponibles en
Internet.
Una vez determinado cual algoritmo de codificación se implementará, basado en la
extensión del programa, la complejidad de la implementación del algoritmo y los recursos
disponibles en la tarjeta entrenadora, se escribirá un programa para el dispositivo
preferiblemente en lenguaje ensamblador y se realizarán las pruebas necesarias para
depurarlo. En el momento en que el programa desarrollado cumpla las expectativas, será
grabado en la memoria del módulo y se realizarán las pruebas necesarias en el sistema
implementado y se redactará el Manual de Usuario del sistema desarrollado.
6
CAPÍTULO 2: Desarrollo teórico
2.1
Generalidades de Probabilidad
La teoría de la probabilidad es la teoría matemática que modela los fenómenos
aleatorios2. En los sistemas de comunicación digital esta teoría es necesaria para describir las
fuentes de información.
Se dice que un espacio de eventos I está constituido por una serie de eventos
elementales ak ({a1,a2,…,ak,,…,aK}). Un evento A es un subconjunto de I, y cada vez que se de
un evento elemental ak que pertenezca a A, entonces sucedió A.
La probabilidad se puede definir desde un punto de vista estadístico, según Richard
von Mises, como sigue:
n N ( A)
N →∞
N
p ( A) = lim hN ( A) = lim
N →∞
(2.1-1)
Esto es, que la probabilidad de un evento A es igual al límite cuando N tiende a
infinito del cociente entre el numero de veces que se dio el evento A, tras la realización de N
experimentos, y el numero de estos experimentos (N). O visto de otra forma, la frecuencia
relativa de un evento aproxima hasta lograr igualar a la probabilidad de ocurrencia del mismo,
conforme el número de experimentos es muy grande.
La independencia estadística, de eventos simples, se define como:
p (u N / u N −1 ) = p (u N )
(2.1-2)
La independencia estadística, de eventos conjuntos, se define como:
p (u N , u N −1 ,..., u1 ) = p (u N ) ⋅ p (u N −1 ) ⋅ ... ⋅ p (u1 )
2
http://es.wikipedia.org/wiki/Teor%C3%ADa_de_la_probabilidad
7
(2.1-3)
Entonces, la probabilidad de un evento simple N dado el evento N-1, es igual a la
probabilidad de solo el evento N, o sea, su probabilidad de ocurrencia no depende de la
ocurrencia de otro(s) eventos. Esta definición se extiende para la probabilidad conjunta, donde
la ocurrencia de varios eventos simultáneamente corresponde al producto de las
probabilidades independientes.
En las fuentes discretas sin memoria, se considera como eventos independientes los
distintos elementos del alfabeto que esta entrega.
2.2
Fuentes de información
Una fuente de información es un elemento que entrega una señal, que contiene
información acerca de la naturaleza o comportamiento de algún fenómeno. Esta señal puede
ser analógica, como una señal de audio o video, o puede ser digital, como los datos de un
disco compacto. Es importante resaltar las fuentes digitales, pues en sus salidas solo se da un
número finito de valores en determinados instantes de tiempo.
Las fuentes pueden clasificarse basándose en la variable independiente tiempo, en:
•
Fuentes de tiempo continuo: la función está definida para cualquier valor de la
variable independiente.
•
Fuentes de tiempo discreto: la función sólo está definida para un conjunto
contable de instantes de tiempo.
Pero se pueden clasificar también según el rango de valores que cubren las señales, en
este caso:
8
•
Fuentes continuas o de amplitud continua: el valor de la función toma un rango
continuo de valores.
•
Fuentes discretas o de amplitud discreta: el valor de la función sólo toma un
conjunto finito de valores. A cada uno de estos valores lo llamamos símbolo.
El conjunto de todos los símbolos se suele llamar alfabeto. La elección del
alfabeto es, en cierto modo, arbitraria.
Estas dos clasificaciones son ortogonales, o sea, existen fuentes continuas de tiempo
continuo, fuentes continuas de tiempo discreto, fuentes discretas de tiempo continuo y fuentes
discretas de tiempo discreto. A pesar de esto, en la práctica sólo se encuentran dos tipos: las
llamadas fuentes analógicas, que son fuentes continuas de tiempo continuo; y las llamadas
fuentes digitales, que son fuentes discretas de tiempo discreto3.
Como se mencionó anteriormente, una fuente digital posee un número limitado de
códigos de salida. Al conjunto de estos códigos se les llama alfabeto.
Las fuentes digitales se suelen clasificar según la relación que tenga un símbolo del
alfabeto con los que le preceden de la siguiente manera:
•
Fuentes sin memoria: los símbolos son estadísticamente independientes entre sí.
De esta manera, los símbolos que hayan aparecido hasta el momento no van a
condicionar al símbolo presente ni a posteriores.
•
Fuentes con memoria: la aparición de los símbolos no es estadísticamente
independiente. Es decir, si han aparecido M–1 símbolos, el símbolo M-ésimo está
condicionado por los anteriores.
3
En realidad no existen fuentes digitales. El concepto de fuente digital se fundamenta en la manera de interpretar
la señal que entrega la fuente.
9
En este proyecto se trabajará con Fuentes discretas sin memoria.
Estos símbolos que aparecen a la salida del bloque fuente, son generalmente producto
de una serie de procesos que se dan en el bloque fuente, mas específicamente en su
convertidor de señales analógicas a digitales.
Estos procesos son:
•
Muestreo: corresponde a tomar muestras de la señal original, en intervalos de
tiempo definidos, convirtiendo la señal a una señal de valor continuo pero de
tiempo discreto. Se le conoce como señal PAM.
•
Cuantización: Corresponde a asignar cierto valor fijo a los valores de la señal
PAM que estén dentro de un intervalo de cuantización L. Se le conoce como señal
M-ARY PAM, donde M es el número de niveles de cuantización (L+1).
•
Codificación binaria: Corresponde a la asignación de un código de longitud fija a
cada uno de los niveles asignados a la señal M-ARY PAM. Este proceso convierte
la señal M-ARY PAM a una secuencia de unos y ceros. Comúnmente se le llama
señal PCM. El conjunto de todos los posibles códigos se conoce como el alfabeto.
10
Figura 2.1 Digitalización de una señal analógica
11
2.2.1 Medida de la información en las fuentes de información
A una fuente la caracterizan su alfabeto y la probabilidad de aparición de cada uno de
los símbolos (códigos) de ese alfabeto. La información que representa este conjunto de
símbolos se puede dividir en cuatro partes, a saber: la conocida o redundante, la desconocida
o no redundante, la relevante o significativa y la irrelevante o no significativa. La figura 2.2
muestra un diagrama de la división de la información en planos (Schouten).
De estos planos, solamente la parte que es a la vez relevante y no redundante, o sea la
parte interesante, debe transmitirse al receptor. Cada una de estas partes puede definirse
matemáticamente con ayuda de la teoría de la información.
Redundante
No redundante
Irrelevante
Relevante
Interesante
Figura 2.2 Planos de información según Schouten
12
“Supóngase que se tiene un grupo de n eventos con probabilidades de ocurrencia p1,p2,
…,pn. Estas probabilidades es lo único que conocemos del evento a ocurrir. ¿Podemos
encontrar una medida de cuanta “elección” está involucrada en la selección del evento o de
cuanta incertidumbre se tiene de la salida?
Si esa medida existiera, digamos H ( pi ) , es razonable que esta requiera cumplir con:
•
H debe ser continua en pi
•
Si todos los pi son iguales, p i =
1
, entonces H debe ser una función monotónica
n
creciente en pi. Con eventos igualmente probables, hay más incertidumbre cuando
hay más eventos posibles.
•
Si una elección fuera dividida en dos elecciones sucesivas, el valor original de H
debería ser la suma ponderada de los valores individuales de H. Esto se ilustra en
la figura 2.3
1 1 1
1 1 1  2 1
H , ,  = H ,  + H , 
2 3 6
 2 2 2  3 3
Figura 2.3 Descomposición de una decisión de tres posibilidades
13
El coeficiente de 1/2 esta ahí pues la elección entre 2/3 y 1/3 ocurre solo la mitad de
las veces.
Teorema: La única H que satisface las 3 suposiciones arriba citadas es de la forma
n
H = − K ∑ pi log( pi )
2.2.1-1
i =1
;donde K es una constante positiva, pi es la probabilidad del símbolo i-ésimo del
alfabeto y log(pi) es la cantidad de información que contiene el mismo. A esta cantidad se le
conoce como entropía de la fuente.
(…) La entropía en el caso de dos posibilidades con probabilidades p y q=1-p, tiene
una gráfica de la siguiente forma:
Figura 2.4 Entropía en el caso de dos posibilidades con probabilidades p y (1-p)
14
La cantidad H tiene un número de propiedades interesantes que la sustentan como una
medida razonable de la decisión o la información.
•
H = 0 si y solo si todas la pi son cero excepto una, que tiene valor unitario. Así,
solo cuando estamos seguros de la salida, H desaparece. De otra forma es positiva.
•
Para un n dado, H es máximo e igual a log(n) cuando todas las pi son iguales. Esta
es intuitivamente la situación más incierta. Entonces, la entropía H siempre es
menor o igual al logaritmo del número de símbolos n del alfabeto. El contenido de
decisión Ho, referido a un solo símbolo del alfabeto, se da en la condición de
igualdad en la ecuación 2.2.1-2. Se utiliza un logaritmo en base 2 para que las
unidades sean bits/símbolo
H ≤ log 2 K
(2.2.1-2)
”4
El contenido de decisión Ho está constituido por la entropía de la fuente y por la
redundancia. El teorema de codificación fuente demuestra que una fuente discreta sin
memoria puede representarse sin pérdidas de información con un índice de transmisión no
menor a la entropía de la fuente. Esto significa que podría eliminarse por completo la
redundancia de la fuente.
2.3
4
Codificación fuente
Adaptado de: Shannon, C.E. “A mathematical theory of communication” p.10-11
15
Cuando una señal es digitalizada5, a la salida del bloque fuente se obtiene un número
definido de posibles niveles. Codificar esta señal consiste en asignar una y solamente una
palabra de código a cada uno de estos niveles.
Esta asignación de códigos es completamente arbitraria, y en este sentido existen
muchos códigos, por ejemplo el código binario puro, el código BCD, el código Gray. Estos
códigos tienen una característica en común: dado un número de niveles de cuantización, todas
las palabras de código poseen la misma longitud.
En comunicaciones, esta no es una característica muy deseable, pues los datos
requerirían mucha capacidad en el canal de comunicación.
Existen técnicas para asignar códigos de longitud variable a estas palabras de longitud
fija, de manera que se le asignen palabras de código cortas a los elementos mas probables, o
sea, los que poseen menos información y palabras de código mas largas a los elementos
menos probables, que contienen mayor cantidad de información.
Estas técnicas se conocen como técnicas de codificación fuente y proveen algoritmos
con los cuales se elimina por completo, o casi por completo, la redundancia de la fuente.
2.3.1 Teorema de codificación fuente
A los códigos de una fuente discreta sin memoria A con un alfabeto de n símbolos se
les puede asignar palabras de un código prefijo, tal que la longitud media x de las palabras
de código satisface la siguiente relación:
H ( A)
H ( A)
≤x<
+1
log 2 ( n )
log 2 ( n )
5
La señal también puede ser una señal digital y no requerir digitalización.
16
(2.3.1-1)
Donde:
K
x = ∑ p ( ak ) ⋅ xk
(2.3.1-2)
k =1
;p(ak) es la probabilidad de ocurrencia del k-ésimo símbolo fuente y x k es el número de
elementos de código utilizados en las palabras de código.
En un código prefijo la parte inicial de todas las palabras de código son diferentes,
esto es una condición suficiente pero no necesaria para que el código pueda decodificarse en
forma inequívoca.
Una condición necesaria para la construcción de este tipo de códigos es que las
longitudes de las palabras de código satisfagan (2.3.1-3)
K
∑n
−xk
≤1
(2.3.1-3)
k =1
donde n es la cantidad de símbolos de código (si es binario n=2).
La redundancia R por símbolo fuente es:
R = H o − H = log 2 K − H = x ⋅ log 2 n − H
(2.3.1-4)
Cuando la codificación es de longitud variable, se sustituye x por x en (2.3.1-4) y se
obtiene lo que se conoce como redundancia residual Rc. Cuando los códigos no tienen
redundancia residual, se dice que son códigos óptimos, en caso contrario, son códigos no
óptimos. Esto sucede cuando las probabilidades de los símbolos del alfabeto son potencias
enteras de D
17
2.4
Técnicas de compresión
Las técnicas de compresión consisten básicamente en dos algoritmos:
•
Compresión: Lleva la información original X a una representación Xc que
requiere menos bits que X.
•
Descompresión: A partir de Xc genera una reconstrucción Y de la información
original X.
En general, se puede hablar de dos tipos de compresión:
•
Compresión sin pérdidas: La reconstrucción Y es idéntica a X, se utiliza donde
no sea permitida la pérdida de información, por ejemplo textos.
•
Compresión con pérdidas: La reconstrucción Y tiene menos información que X,
introduciendo distorsiones tolerable, entonces la pérdida de información no es
perceptible; por ejemplo en la compresión de voz para sistemas telefónicos
móviles.
Cada uno de estos tipos de compresión utiliza distintas bases para su aplicación.
2.4.1 Técnicas de compresión sin pérdidas
2.4.1.1Compresores estadísticos
Los compresores estadísticos se fundamentan en la probabilidad de aparición de los
símbolos para asignar los nuevos códigos.
2.4.1.1.1
Codificación Shannon - Fano
18
Es una técnica de compresión no óptima, propuesta por C.E. Shannon en el
documento “A Mathematical Theory of Communication” en 1948 y produce códigos prefijo.
Utiliza un alfabeto de símbolos de longitud fija y sus probabilidades para construir los nuevos
códigos de la siguiente manera:
1. Para una lista de símbolos, debe obtenerse la frecuencia de aparición de cada uno.
2. Ordenar los símbolos de izquierda a derecha en orden descendente de ocurrencia
3. Divida la lista en dos partes, de manera que la suma de las frecuencias de cada
mitad sea lo más cercana a la otra.
4. A la mitad de la izquierda se le asigna el bit 0, mientras que a la de la derecha el 1
5. Repetir los pasos 3 y 4 en cada una de las mitades, hasta que cada símbolo sea una
hoja del árbol de codificación.
Ej:
Sean los siguientes símbolos con sus respectivas frecuencias de aparición
Tabla 2.1 Ensemble de la fuente A
A1 A2 A3 A4 A5
2
5
9
7
10
1. A5
A4 A3 A2 A1
2. A5 A3 (0) / A4 A2 A1 (1)
3. A5 (00) / A3 (01) // A4 (10)/ A2 A1 (11)
4. A5 (00) / A3 (01) /// A4 (10) // A2 (110) /A1 (111)
Finalmente
19
Tabla 2.1 Ensemble de la fuente A codificado
A1
11
1
2.4.1.1.2
A2
11
0
A3 A4 A5
01 10 00
Codificación Huffman
Fue desarrollada por David A. Huffman durante sus estudios de doctorado en el
Instituto Técnico de Massachusetts y publicada en 1952 en el documento "A Method for the
Construction of Minimum-Redundancy Codes”
En 1951 el profesor Robert Fano permitió a Huffman y sus compañeros en el curso
“Teoría de la Información” escoger entre realizar un examen final o presentar un trabajo, cuyo
objetivo era encontrar un código binario más eficiente. Huffman finalmente logró encontrar
un algoritmo más eficiente que los existentes, solucionando la mayor parte de los errores en el
algoritmo de Shannon – Fano. La solución se basa en construir un árbol binario, pero desde la
raíz.
En el documento original, Huffman plantea una serie de restricciones para crear
códigos de redundancia mínima:
“Las siguientes restricciones básicas serán impuestas en un código de ensemble:
1. Dos mensajes no pueden consistir en un arreglo idéntico de dígitos de
codificación.
2. Los códigos de mensaje serán construidos de tal manera que ninguna
indicación adicional es necesaria para especificar donde un mensaje empieza y
20
termina una vez que el punto de inicio de la secuencia de mensajes es
conocida.
La restricción 2 implica que ningún mensaje sea codificado de manera que sus dígitos
aparezcan en el mismo orden de los primeros dígitos de un código mas grande.(…)
3. L(1) ≤ L( 2 ) ≤ ...L( N −1) = L( N ) ; donde L es el largo del n-ésimo mensaje
4. Al menos dos, y no mas de D mensajes con tamaños de código L(N) tienen
códigos que difieren solamente en su dígito final.
5. Cualquier secuencia de L(N) – 1 dígitos debe ser usada como un código de
mensaje o debe tener uno de sus prefijos usados como código de mensaje.”6
Es importante destacar que es su publicación, Huffman aplica este método no solo
para alfabetos binarios (D = 2), sino que lo generaliza para alfabetos n-arios (D = n)
El algoritmo de codificación de Huffman es muy similar al de Shannon – Fano, y
consiste en lo siguiente
1. Empezar con tantas hojas como símbolos halla.
2. Ordene en fila todos los símbolos del símbolo menos probable al más probable
3. Mientras haya mas de un nodo en la fila:
1. Separe los dos nodos con menor peso.
2. Cree un nuevo nodo interno con los dos nodos removidos como ramas y la
suma de sus pesos como el nuevo peso.
6
Adaptado de D.A. Huffman, “Proceedings of the I.R.E.”, sept 1952
21
3. Ordene este nuevo nodo dentro de la fila anterior (que ya no tiene los nodos
removidos
4. El último nodo es el nodo raíz. El árbol está completado
La figura 2.5 ilustra el proceso de construcción del árbol
Luego, los códigos pueden asignarse escribiendo un cero en el elemento superior de la
llave, y un uno en el inferior, como lo muestra la figura 2.5. También puede asignarse de
manera inversa, el uno arriba y el cero abajo. Es indispensable que la manera escogida se
aplique por igual en todos los nodos, de lo contrario se obtendrán resultados erróneos.
La codificación de Huffman, además, tiene las siguientes variaciones:
•
n-ario: Es la extensión para un D > 2, que se considera en el trabajo original de
D.A. Huffman.
•
Adaptativo: Construye el código mientras lee los símbolos fuente en cada
transmisión.
Figura 2.5 Construcción del árbol de Huffman con dos símbolos codificados
22
Existen además propuestas de variaciones de codificaciones Huffman, pero no poseen
algoritmo de implementación;
•
De longitud limitada: hace lo mismo que la técnica original, pero tiene una
restricción en cuanto a la longitud máxima de palabra de código.
•
De costo desigual de letras: En el código Morse, transmitir un espacio toma más
tiempo de transmisión que transmitir un punto, por lo que es más costoso. De igual
forma, las palabras del alfabeto codificado pueden no tener longitud uniforme
debido al medio de transmisión. La técnica de peso desigual de letras busca
minimizar también este efecto.
2.4.1.1.3
Codificación Aritmética
A diferencia de la codificación Huffman, donde es necesario que la probabilidad de
los símbolos sea una potencia negativa de dos para eliminar la redundancia residual, la
codificación aritmética codifica una secuencia de entrada de símbolos del alfabeto fuente
mediante un número representado en punto flotante.
Estos códigos son especialmente útiles cuando se trabaja con alfabetos pequeños o con
distribuciones de probabilidad muy sesgadas.
El primer código aritmético fue ideado por Meter Elías antes de 1963, en un trabajo no
publicado. La primera publicación del código Elías aparece en el texto Information theory
and coding 7 de N. Abramson; sin embargo, hay muchos esquemas prácticos de codificación.
El primero de ellos no estuvo disponible sino hasta 1976, en un trabajo por Jorma Rissanen y
Richard Pasco
7
N. Abramson, Information theory and coding. New York: McGraw-Hill, 1963.
23
El proceso de codificación aritmética se basa en asignar a cada símbolo un intervalo
entre 0 y 1, de forma que la amplitud de cada intervalo sea igual a la probabilidad de cada
símbolo. La suma de las amplitudes de los intervalos debe ser igual a la unidad.
Previamente es necesario establecer un orden entre los símbolos. No es necesario
seguir algún criterio especial para establecer un orden entre los símbolos del alfabeto fuente,
pero el orden establecido debe ser conocido por el decodificador para poder hacer una
correcta decodificación en la recepción.
Para realizar la codificación de una determinada cadena de entrada se siguen los
siguientes pasos:
1. Se selecciona el primer símbolo de la secuencia de entrada y localizar el intervalo
asociado a ese símbolo.
2. A continuación se selecciona el siguiente símbolo y se localiza su intervalo. Se
multiplican los extremos de este intervalo por la longitud del intervalo asociado al
símbolo anterior (es decir, por la probabilidad del símbolo anterior) y los resultados se
suman al extremo inferior del intervalo asociado al símbolo anterior para obtener unos
nuevos extremos inferior y superior.
3. El paso anterior se repite hasta que todos los símbolos del mensaje hayan sido
procesados.
Para el símbolo i-ésimo se calcula su intervalo de la siguiente forma:
Inf i = Inf i −1 + ( Supi −1 − Inf i −1 ) ⋅ Inf i −1
Supi = Inf i −1 + ( Supi −1 − Inf i −1 ) ⋅ Supi −1
24
4. Por último se selecciona un valor dentro del intervalo del último símbolo de la
secuencia. Este valor representará la secuencia que queremos enviar.
Cuando se transmite un valor al receptor es necesario indicar cuantos símbolos se han
enviado para que el receptor sepa cuando debe finalizar el proceso de descompresión. Para
indicar esto existen dos técnicas. La primera consiste en enviar antes del valor elegido el
número de símbolos que se han comprimido en binario. De esta forma el receptor sabrá
cuantos símbolos han sido comprimidos antes de comenzar el proceso de descompresión. La
segunda técnica consiste en utilizar en el alfabeto un símbolo más con una probabilidad
asociada. Este símbolo será un símbolo especial que indicará el final de una secuencia de
símbolos comprimidos. Al igual que el resto, éste será comprimido por el emisor después del
último símbolo que se quiere comprimir. El receptor sabrá cuando debe finalizar el proceso de
descompresión al interpretar el último símbolo descomprimido como un símbolo especial.
En el proceso de decodificación se utiliza la tabla original en la que se habían
asignado unos intervalos iniciales a cada símbolo.
El receptor recibe a través del canal un número decimal en punto flotante. Lo primero
que se hace es comprobar en la tabla a que intervalo pertenece ese valor y el símbolo al que se
le ha asociado ese intervalo será el primer símbolo que se ha transmitido. A continuación se le
resta al número recibido el extremo inferior del intervalo al que pertenece, y el resultado se
divide por la longitud del intervalo.
Con el número obtenido repetimos el proceso anterior.
Este proceso se repite hasta que todos los símbolos del mensaje hayan sido
procesados.
25
Por último, debemos tener en cuenta dos problemas relacionados con esa técnica de
codificación. El primer problema está en que el número de decimales aumenta con la cantidad
de símbolos del alfabeto fuente.
El segundo problema relacionado con el uso de esta técnica es que cuando los
extremos inferior y superior de un intervalo están muy próximos pueden producirse errores al
asignar el intervalo en la fase de decodificación.
2.4.1.1.4
Codificación Predictiva
Este tipo de codificación, al contrario de las anteriores, es completamente adaptativa.
Estos procuran predecir el siguiente mensaje de la entrada tomando como referencia tomando
como base el conocimiento de la entrada procesada hasta el momento. Si el mensaje actual
coincide con el predicho, éste se codificará con un número menor de bits. En caso contrario,
su codificación se hará con más bits, que permitirán entonces sincronizar el descompresor
para que mantenga sus tablas internas iguales a las del compresor, sin pasárselas
explícitamente.
En general son más rápidos y fáciles de implementar que los anteriores, por lo que se
convierten en una solución barata para sistemas en tiempo real, con relaciones de compresión
aceptables.
El Predictor, creado en 1987 por Timo Raita y Jukka Teuhola, de la Universidad de
Turku, Finlandia; es quizá el más rápido jamás diseñado. Éste funciona básicamente de la
siguiente manera:
26
•
Crea una matriz de 256 filas y 256 columnas donde guarda en la casilla mi,j, el
byte que siguió a las dos anteriores salidas ASCII i y j. Si la predicción de esta
salida es correcta, la salida será un bit puesto a 1, de lo contrario será cero.
Además actualiza la tabla para que la siguiente vez, sea capaz de predecir ese
mismo evento. Así también se sincroniza el descompresor.
•
El descompresor parte de una tabla vacía. Al recibir un 1 sabe que el mensaje
recibido es el que se encuentra en la tabla en la posición indicada por los dos
últimos mensajes resultado de la descompresión realizada hasta el momento. Si
recibe un cero, la información recibida será el mensaje puro, y podrá actualizar
la tabla (igual que el compresor)
2.4.1.1.5
Codificación de Golomb y Codificación Rice
La codificación de Golomb fue inventada por Solomon W. Golomb en 1966, y
responde óptimamente para alfabetos con distribuciones geométricas, esto es, cuando los
valores pequeños son muchísimo mas probables que los valores grandes.
La codificación Rice es una variación de la codificación Golomb, que inventado y
desarrollado independientemente por Robert F. Rice. Es un código donde el parámetro
variable es una potencia de dos. Esto lo hace extremadamente eficiente para uso en
computadoras, pues la división es un desplazamiento de bits y la operación residuo se
convierte en un enmascaramiento de bits. Se utiliza en compresión sin pérdida de audio e
imágenes.
27
2.4.1.2Compresores sustitucionales
En la práctica, a menudo existe una estructura en los datos, es decir secuencias
repetitivas o patrones en la información. Las técnicas basadas en diccionario explotan la
estructura de los datos para incrementar la cantidad de compresión. En este sentido, cuando la
información tiene pocas cadenas de símbolos muy repetitivas, este es un mecanismo de
compresión muy provechoso.
Hay dos posibles tipos de diccionarios, los estáticos y los dinámicos.
El primer tipo es apropiado cuando se conoce la estructura repetitiva de los datos. En
él, se almacenan los patrones más frecuentes y las palabras de código. Durante la compresión,
si el patrón que ocurre no está en el diccionario, se codifica separadamente cada símbolo del
patrón.
El segundo tipo es adecuado para compresores generales aplicables a fuentes de
distintas características, construyen el diccionario conforme procesan la entrada y el
descompresor reconstruye el mismo diccionario
La gran mayoría de técnicas basadas en diccionario son variantes de los métodos
propuestos por Jacob Ziv y Abrahan Lempel en dos artículos de 1977 y 1978, de ahí, los
nombres de dichos algoritmos: LZ77 y LZ78
2.4.1.2.1 LZ77, LZ78 y demás variaciones
El algoritmo LZ77 logra la compresión reemplazando porciones de datos con
referencias de datos que ya han pasado por el codificador (o el decodificador). Una referencia
es codificada como un par de números conocidos como par longitud – distancia. Esto es, que
la siguiente longitud es igual al que esta exactamente distancia caracteres atrás en la cadena.
28
Tanto el codificador como el decodificador, deben tener un registro de la información
más reciente (2kB – 32kB). A este registro se le llama ventana deslizante.
El algoritmo LZ78 trata de trabajar con información futura. Lo hace buscando por
adelantado en el buffer de entrada y lo compara con su diccionario. Se buscará en el buffer
hasta que no pueda encontrar una coincidencia con el diccionario; entonces, la salida será la
localización en el diccionario, si hay alguna disponible, la longitud de la coincidencia y el
carácter que causo la no coincidencia. La palabra resultante se agrega al diccionario.
A pesar de su popularidad inicial, esta cayó abruptamente pues en las primeras
decadas luego de su aparición, algunas partes del LZ78 fueron patentadas.
Las variaciones más populares de estos algoritmos son:
•
LZW, creada por Terry Welch en 1984. Se utiliza en el formato de imagen GIF y
TIFF, y actualmente en software de Adobe Acrobat.
•
LZSS, creada en 1982 por James Storer y Thomas Szymanski. Su principal diferencia
es que en LZ77 la referencia del diccionario puede ser mas larga que la cadena a
reemplazar mientras en LZSS dichas referencias son omitidas si la longitud es menor
que un punto de quiebre. Además, LZSS usa banderas de un bit para indicar cuando el
próximo trozo de datos es literal o una referencia a un par distancia – longitud.
•
LZMA, en desarrollo desde 1998, presenta una alta razón de compresión y un
diccionario de compresión de tamaño variable. Se basa en el LZ77 y un range
encoger (codificación similar a la aritmética). Forma parte de las herramientas de
compresión 7z y 7-Zip
29
•
DEFLATE, originalmente definido por Phil Katz a finales de los años 80, que usa una
combinación del LZ77 y codificación Huffman, y es parte de la herramienta de
compresión PKZIP.
2.4.1.3Otros tipos de codificación
2.4.1.3.1 Codificación Run-length
Consiste en una técnica de compresión donde segmentos de datos repetidos son
codificados como un solo valor y una cuenta, en lugar del segmento original.
2.4.1.3.2 Codificación Burrows - Wheeler
Fue inventada por Michael Burrows y David Wheeler en 1994 y está basada en una
transformada (BWT) descubierta por Wheeler en 1983.
Cuando una cadena de caracteres es transformada por la BWT, ninguno de sus
caracteres cambia de valor. La transformación permuta el orden de los caracteres. Si la cadena
original tiene muchas subcadenas que se repiten, entonces la cadena transformada tendrá
muchos lugares donde un mismo carácter es repetido muchas veces en la línea. Esto es
deseable para compresión facilita la aplicación de técnicas como la transformada mover al
frente o la codificación run-length.
30
2.4.1.3.3 Técnicas varias
Compresión de audio
•
Técnica sin pérdidas de Apple – ALAC (Apple Lossless Audio Codec)
•
Codificación de Audio sin pérdidas, también conocido como as MPEG-4 ALS
•
Transferencia directa de Flujo – DST (Direct Stream Transfer)
•
Dolby de Verdadera Alta Definición - Dolby TrueHD
•
Sistema de Teatro Digital de alta definición Audio Maestro – DTS-HD Master Audio
•
Codec de Audio Gratis sin Pérdidas – Free Lossless Audio Codec – FLAC
•
Empaquetamiento sin Pérdidas Meridiano – Meridian Lossless Parking – MLP
•
Monkey's Audio – APE
•
OptimFROG
•
RealAudio sin pérdidas
•
Shorten – SHN
•
True Audio sin pérdidas – TTA
•
WavPack sin perdidas
•
Windows Media sin pérdidas
Compresión de gráficos
•
Optimizacion binaria adaptativa - Adaptive Binary Optimization – ABO
•
Formato de intercambio de gráficos (Sin pérdida, pero contiene un rango limitado de
colores) – Graphics interchange format – GIF
31
•
Estandar del Joint Bi-level Image Experts Group (compresión con o sin pérdida para
imágenes blanco y negro ) - JBIG2
•
Estandar del Joint Photographic Expert Group (Estandar de compresión sin pérdida o
con muy poca) – JPEG – LS
•
incluye un metodo de compresion sin pérdida, demostrado por Sunil Kumar, Prof de la
Universidad Estatal de San Diego - JPEG 2000
•
Archivo de gráficos progresivo (con o sin pérdida) – Progressive Graphics File PGF
•
Red de gráficos portátil – Portable Network Graphics – PNG
•
Codec sin pérdidas Qbit - Qbit Lossless Codec
•
Formato de archivo de imagen etiquetado – Tagged Image File Format – TIFF
•
incluye un método de compresión sin pérdida – WMPhoto
Compresión de video
•
Codec de animación – Animation codec
•
Codec de video CamStudio - CamStudio Video Codec
•
Codec de video RGB sin pérdidas, basado en compresión de imagen PNG - CorePNG
•
Codec de Video FF 1 codificador experimental de alta compresión sin ppérdidas FFV1
•
Estándar capaz de proporcionar una buena calidad de imagen con tasas binarias
notablemente inferiores a los estándares previos (MPEG-2, H.263 o MPEG-4 parte 2)
- H.264/MPEG-4 AVC
•
Codec de video “open source” - Lagarith
•
Codec de video sin pérdidas de la Universidad de Moscú - MSU Lossless Video
Codec
32
CAPÍTULO 3: Microcontrolador MC68HC11
3.1
Introducción
Recibe el nombre de controlador el dispositivo que se emplea para el gobierno de uno o
varios procesos. Aunque este concepto ha permanecido invariable a través del tiempo, su
implementación física ha variado frecuentemente. Un microcontrolador es un circuito
integrado de alta escala de integración que incorpora la mayor parte de los elementos que
configuran un controlador. Un microcontrolador dispone normalmente de los siguientes
componentes:
•
Procesador o CPU o Unidad Central de Procesamiento, por sus siglas en inglés.
•
Memoria RAM para almacenar los datos temporales generados por el programa
•
Memoria para almacenar el programa principal. Ésta puede ser tipo ROM,
PROM, EPROM o EEPROM. En algunos casos, la aplicación también podría guarda
datos importantes que se desea permanezcan aunque se desenergice la aplicación en
memoria tipo EEPROM.
•
Líneas de E/S para comunicarse con el exterior. A los grupos que forman estas líneas
se les denomina puertos. En algunos casos, como en la familia HC11, estas líneas
pueden estar compartidas por algún otro recurso del microcontrolador, como se verá
mas adelante.
•
Diversos módulos para el control de periféricos como temporizadores, interfaz de
comunicación serie o paralela, convertidores analógico/digital y digital/analógico,
entre otros.
33
•
Generador de impulsos de reloj que sincronizan el funcionamiento de todo el
sistema.
La incorporación de un microcontrolador en aplicaciones presenta ventajas como:
•
Aumento de prestaciones pues poseer un mayor control sobre un determinado
elemento representa una mejora considerable en el mismo.
•
Aumento de la fiabilidad pues al reemplazar un elevado número de elementos por
un microcontrolador se disminuye el riesgo de averías y se precisan menos ajustes.
•
Reducción del tamaño en el producto acabado dado que la integración del
microcontrolador en un solo chip disminuye el volumen y la mano de obra.
•
Mayor flexibilidad: las características de control están programadas por lo que su
modificación sólo necesita cambios en el programa de instrucciones.
El microcontrolador es en definitiva un circuito integrado que incluye todos los componentes
de un computador. Debido a su reducido tamaño es posible montar el controlador en el propio
dispositivo al que gobierna. En este caso el controlador recibe el nombre de controlador
empotrado (embedded controller).
3.2
Especificaciones generales
La familia Motorola 68HC11 también conocida como HC11 o 6811 es una familia de
microcontroladores, derivada del microprocesador Motorola 6800. Estos dispositivos siguen
la Arquitectura Eckert-Mauchly, en la que la memoria de programa, de datos y de
entrada/salida se direcciona en un único mapa de memoria. En la figura 3.1 se pueden ver
algunas de las variantes de la familia HC11 con sus principales características.
34
Todos los microcontroladores de la familia 68HC11 poseen dos acumuladores de ocho
bits cada uno, conocidos como A y B, además de un acumulador virtual D, que es la
concatenación de A y B, dando como resultado un registro de 16 bits, con A como la parte
alta del mismo. También se tienen dos registros índice de 16 bits conocidos como X y Y.
Finalmente, posee también un registro de banderas, de cuyo estado dependen las instrucciones
de saltos condicionales, un puntero de pila (esta pila se direcciona generalmente en el tope de
la memoria RAM, aunque puede hacerse en cualquier lugar de ésta) y un contador de
programa.
Figura 3.1 Familia 68HC11
35
Los 68HC11 tienen cinco puertos externos nombrados con las letras A, B, C, D y E, cada
uno de ocho bits excepto el D, que es de seis bits. A continuación se describe cada uno de los
puertos, junto con los recursos del microcontrolador están compartidos en ellos:
•
El puerto A dispone de 3 pines de entrada, 4 pines de salida y uno configurable como
entrada o como salida. Se encuentra mapeado en memoria en la dirección 1000 h. Los
pines del puerto A están compartidos por los siguientes recursos: comparadores,
acumulador de pulsos y capturadores.
•
El puerto B tiene 8 bits de salida. En el modo no expandido del MCU se comporta
como un puerto de salida. Si el microcontrolador se utiliza en modo expandido (para
acceder memoria externa al chip) el puerto B se utiliza para manejar el byte alto del
bus de direcciones. Su dirección es la 1004h.
•
El puerto C es un puerto de entrada/salida. En el modo no expandido sus 8 bits
pueden actuar como entradas o salidas independientes, según cómo se configuren los
bits en el registro DDRC (1007h). Un cero en un bit del registro DDRC configura el
pin correspondiente para entrada. Un uno lo hace para salida. La dirección del puerto
C es 1003h.
Si el microcontrolador funciona en modo expandido el puerto C actúa como la parte
baja del bus de direcciones multiplexada con el bus de datos.
•
El puerto E es un puerto de 8 bits de entrada. Está situado en la dirección 100Ah y
comparte pines con los 8 canales del convertidor A/D
36
Existe un dispositivo integrado de TEKMOS cuyo número de parte es TK68HC24 y
permite el uso del modo extendido y la función de líneas de entrada/salida digital de los
puertos B y C conjuntamente.
3.3
Puerto D y la Interfaz de comunicación serial asíncrona
Al igual que el puerto C, D es un puerto de entrada o salida pero de solamente seis
bits, al que se pueden configurar independientemente estas líneas como entrada o salida. El
puerto esta mapeado en la dirección. 1088h. Además de esta función, también se pueden
establecer protocolos de comunicación serie síncrona y asíncrona.
La Interfaz Serie Asíncrona, o SCI por sus siglas en inglés, permite que dos
dispositivos establezcan comunicación serial. El Bit 0 del puerto D corresponde al bit de
recepción (Rx) y por esta línea ingresan los bits de datos desde el dispositivo externo. El Bit 1
corresponde al bit de transmisión (Tx) y por esta línea salen los bits de datos hacia el
dispositivo externo.
La SCI es un sistema asíncrono tipo UART full-duplex, que utiliza un formato
estándar sin-regreso-a-cero (NRZ, por sus siglas en inglés), esto es un bit de inicio, ocho de
datos (o nueve, según se configure) y uno de parada. Un generador de baud rate deriva
valores estándar de comunicación a partir del reloj principal del microcontrolador.
Este sistema se configura, controla y monitorea a través de cinco registros que se
detallan a continuación:
•
BAUD: Normalmente éste registro se escribe una vez durante la inicialización del
microcontrolador para fijar el baud rate de la comunicación. Esta velocidad es la
misma para transmisión y recepción y se deriva del reloj del bus del microcontrolador.
37
Para este fin, se utiliza un divisor de dos etapas. La figura 3.2 contiene la lista de
posibles configuraciones para la velocidad del SCI. Los bits SPx y SCRx son parte del
registro BAUD.
•
SCCR1: Es el registro de control 1 y se encarga de configurar la cantidad de bits de
datos, tanto para el transmisor como para el receptor. Además, configura la opción de
WAKE UP, en que el receptor se queda con las interrupciones inhibidas esperando un
evento hardware externo, (asociado a la línea de recepción), que le devuelva al estado
activo con interrupciones. Esta opcion se recomienda para aumentar la eficiencia en
sistemas multireceptores pero de poco tráfico. Si el bit WAKE esta activado entonces
se espera hasta detectar una marca de dirección, si por el contrario esta desactivado se
espera hasta detectar que la línea de recepción esta vacía.
•
SCCR2: Es el registro de control 2 y determina si las interrupciones de transmisión y
recepción están activadas o no y permite habilitar el transmisor y el receptor.
•
SCSR: Es un registro de estado que activa las banderas para que se ejecuten las
interrupciones habilitadas con el SCCR2
•
SCDR: Es el registro al cual se escriben y del cual se leen los datos que se
intercambian por la SCI.
3.4
Mecanismo de interrupciones del SCI.
Existen cuatro causas de interrupción en el SCI, al aparecer alguna de estas se activa
su bit correspondiente en el registro de estado. El SCI sólo tiene asociado un vector de
interrupción por lo que sólo existe una rutina de servicio. Esta rutina de servicio tiene que leer
38
el registro de estado (SCSR) y detectar cuál de las 4 causas de interrupción ha ocurrido.
Según la cual bifurcará a una rutina o a otra. Finalmente se retornará con RTI.
Es importante hacer notar que siempre que haya un bit a 1 en el registro de estado, la
CPU lo interpretará como una petición de interrupción y llamará a la rutina de servicio del
SCI, por lo tanto es muy importante poner el bit correspondiente a cero para que al terminar la
rutina de servicio la CPU no se vuelva a interrumpir por la permanencia de dicho bit todavía
en estado alto.
Esto último es un punto muy importante. Supónganse que se produce una interrupción
en el SCI porque se ha recibido un carácter. El bit correspondiente del registro de estado se
pondrá en alto indicando el evento. La CPU detecta que este bit está activado y pasa a ejecutar
la rutina de servicio del SCI. Si esta rutina no pone a cero este bit, al terminar la subrutina el
bit seguirá activado y la CPU lo tomará como una nueva interrupción que se ha producido,
con lo que se volverá a ejecutar la rutina de servicio. Así permanecerá la CPU en un ciclo
infinito ejecutando constantemente la rutina de servicio del SCI hasta que se produzca un
reset externo.
Los bits del registro de estado no se pueden poner a cero directamente. Para ponerlos a
cero es preciso leer el registro SCSR y a continuación leer el registro de datos SCDR.
La figura 3.3 muestra las causas de interrupción, el bit del registro de estado asociado
a cada una y el bit del registro de control 2 que las enmascara.
39
Figura 3.2 Velocidades de comunicación configurables para la SCI del MC68HC118
8
Microcontrolador 68HC11: Fundamentos, recursos y programación. Doblado A, Cristina et al.
40
Figura 3.3 Bits relativos a la interrupción producida por la SCI1
41
CAPÍTULO 4. Implementación del Codificador Fuente
4.1
Escogencia de los símbolos
El fin principal de la aplicación es mostrar de una manera clara el resultado de un
proceso de codificación y decodificación fuente. Se decidió entonces que utilizar texto para
dicho fin era una buena opción pues los caracteres se representan en una computadora como
códigos de ocho bits. Los símbolos que se codificaron se encuentran en la tabla 4.1 y
corresponden a las letras que comúnmente aparecen en textos en español y a algunos símbolos
de un teclado con distribución latinoamericana que podrían introducirse como parte de un
texto. Además se incluyó los correspondientes a la estructura del texto, o sea, espacios, saltos
de línea y tabulaciones.
Para determinar las probabilidades de los símbolos se analizó, con un programa escrito
en lenguaje C, cuyo código fuente puede consultarse en la sección de anexos; un texto de
aproximadamente treinta y cinco mil caracteres contando los espacios, y se utilizó la relación
(2.1-1) donde h(n) es cada carácter y N el total de caracteres en el texto. Además, para
determinar las probabilidades de los símbolos que no aparecían en el texto, se tomo la
probabilidad residual y se dividió entre estos.
Debe recordarse que los símbolos representados en las computadoras corresponden a
códigos binarios de ocho bits, como se mencionó anteriormente, llamado Código Americano
Estándar para Intercambio de Información ASCII, por sus siglas en inglés (American
Standard Code for Information Interchange) en una de sus versiones extendidas, pues la
versión original de siete bits no contemplaba caracteres especiales de otros idiomas, como por
ejemplo las vocales tildadas.
42
Tabla 4.1 Símbolos del texto en español y su probabilidad aproximada de aparición
Símbolo Probabilidad
a
A
Á
á
e
E
É
é
i
I
Í
í
o
O
Ó
ó
u
U
Ú
ú
b
B
c
C
d
D
f
F
g
G
h
H
j
J
k
K
l
L
m
M
n
N
p
P
q
Q
r
R
0,086825
0,000673
0,000035
0,002624
0,111618
0,002296
0,000017
0,001968
0,052261
0,000328
0,000134
0,003505
0,067022
0,000311
0,000134
0,005421
0,033615
0,000242
0,000134
0,000898
0,009237
0,000466
0,037914
0,000691
0,039485
0,000380
0,005697
0,000224
0,009030
0,000276
0,005404
0,000363
0,002521
0,000086
0,000242
0,000035
0,046512
0,001347
0,022013
0,001019
0,057976
0,000570
0,020027
0,000742
0,008581
0,000121
0,048998
0,000242
Símbolo Probabilidad
s
S
t
T
v
V
w
W
x
X
y
Y
z
Z
ñ
Ñ
ü
Ü
espacio
,
.
tabulación
salto de
línea
;
:
?
¿
¡
!
"
‘
1
2
3
4
5
6
7
8
9
0
=
+
*
/
\
0,055783
0,001036
0,037448
0,000466
0,008788
0,000138
0,000397
0,000138
0,001916
0,000138
0,006388
0,000242
0,002486
0,000121
0,001416
0,00013448
0,00013448
0,00013448
0,162048
0,010411
0,006181
0,001105
0,001191
0,000414
0,000742
0,000242
0,000242
0,00013448
0,00013448
0,003021
0,000017
0,000829
0,000449
0,000173
0,000069
0,000294
0,000242
0,000224
0,00019
0,000535
0,000622
0,00013448
0,00013448
0,000483
0,00013448
0,000155
0,00013448
43
Símbol
o
Probabilidad
<
>
#
(
(
[
]
%
$
@
_
&
~
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
0,00013448
El análisis del texto y de los resultados tabulados en la tabla 4.1, brindó los siguientes
resultados:
•
Contenido de Decisión: La relación (2.2.1-2) indica el contenido de decisión
referido a un solo símbolo del alfabeto. Al aplicar esta relación se determina
cuantos bits por símbolo se necesitan para describir la información que en este
caso brindan los 108 símbolos escogidos. Entonces, con K = 108 se obtiene:
H0 = 6,7549 Bit/Símbolo
El contenido de decisión es igual a la suma de la redundancia del código y al
contenido medio de información, o sea,
Ho = R + H
•
(4.1-1)
Entropía de la fuente: La relación (2.2.1-1) indica la entropía de la fuente, o
sea, el mínimo índice de transmisión en bit por símbolo que se necesitan para
transmitir la información sin pérdidas. Debe recordarse que la información que
se transmitirá sin pérdidas es aquella que se conoce, o sea, para la cual fue
calculada el código Huffman. Si aparece un símbolo desconocido, este se
perderá debido a que no fue tomado en cuenta para generación del código. En
la relación (2.2.1-1) se sustituye el valor de K por 1, pues esta constante sólo
cuantifica una unidad de medida9.
9
“…(the constant K merely amounts to a choice of a unit of measure)…” Shannon, C.E. A mathematical theory
of communication. 1948, p-11
Luego de realizar toda la suma, se obtiene el siguiente resultado
H: 4,3743 Bit/Símbolo
•
Redundancia: La redundancia corresponde a la diferencia entre el máximo y
el mínimo de bit por símbolo que se requieren para describir la información, al
despejarla de (4.1-1). Para esta aplicación, la redundancia los caracteres ASCII
corresponde a
R = 2,3806 Bit/Símbolo
4.2
Codificación
Como se mencionó en el capítulo anterior, el algoritmo de Huffman consiste
básicamente en construir una lista con los símbolos y sus probabilidades, ordenados en forma
descendente, y sumar recursivamente las dos probabilidades más pequeñas, pudiendo ser una
de ellas, o ambas, el resultado de sumas anteriores. Para el desarrollo de esta aplicación, dicho
árbol se hizo a mano, y puede encontrarse la sección de anexos. La tabla 4.2 muestra los
resultados de esta codificación.
Tabla 4.2 Símbolos de texto en español y su codificación
Símbolo
Código
Símbolo
Código
Símbolo
Código
a
A
Á
á
e
E
É
é
i
I
Í
í
o
O
Ó
ó
u
U
Ú
ú
b
B
c
C
d
D
f
F
g
G
h
H
j
J
k
K
l
L
m
M
n
N
p
P
q
Q
r
R
s
1111
0000110001
00101101010100
00000011
011
101011011
0010110101010101
101010010
0100
00001101000
1010110010000
00101100
1001
00001100000
1010110010011
0000101
10100
101010011100
1010110010010
0010110111
1110001
00101101101
10111
0000110101
11101
00101001100
0000111
001011010100
1110000
101011010101
0000100
00001101001
00000010
0000000010011
101010001101
001011010101011
0001
000011001
00100
1010100110
1000
10101101011
111001
0010100101
1010101
1010100111010
0011
101010001100
0101
S
t
T
v
V
w
W
x
X
y
Y
z
Z
ñ
Ñ
ü
Ü
espacio
.
,
;
:
Salto de
línea
Tabulación
?
¿
¡
!
"
‘
1
2
3
4
5
6
7
8
9
0
=
+
*
/
\
<
>
1010110000
10110
00101101100
1010111
000000001000
00101001101
1010110101001
101010000
1010110101000
0010111
101010001111
00000001
0010110101011
000011011
1010110010101
1010110010100
1010110010111
110
0010101
000001
00101001111
0010100100
1010110100
#
(
)
[
]
%
$
@
_
&
~
1010110011111
1010110011110
1010110001001
1010110001000
1010110001011
1010110001010
1010110001101
1010110001100
1010110001111
1010110001110
1010100111011
000000000
101010001110
101010001011
1010110010110
1010110011001
00101000
0010110101010100
0010110100
00101101011
000011000011
0000000010010
00000000101
101010001010
001010011101
001010011100
10101001111
0000000011
1010110011000
1010110011011
10101000100
1010110011010
000011000010
1010110010001
1010110011101
1010110011100
A partir de los resultados mostrados en la tabla 4.2 se calculó lo siguiente:
•
Longitud media de las palabras de código: De la relación (2.3.1-2) se puede
calcular la longitud media de las palabras de código de los símbolos
codificados.
x = 4,4095 Bit/Símbolo
•
Redundancia
residual:
La redundancia
residual
aparece
cuando
las
probabilidades de ocurrencia de los símbolos originales son potencias enteras
negativas de 2, como 1/4,1/8, etc. En este caso, la redundancia residual del
código generado es
Rc = 0,0352 Bit/Símbolo
La redundancia residual puede reducirse codificando en bloques de caracteres,
en lugar de carácter por carácter, sin embargo el número de combinaciones es
1082 (este es el límite superior, pues algunas combinaciones tiene una
probabilidad muy pequeña, por ejemplo “wx” que puede aparecer en modelos
de productos en un catálogo) lo cual genera una larga lista de símbolos, y
mayor tiempo de procesamiento.
47
4.3
Implementación
El dispositivo implementado consiste de dos elementos:
4.3.1
El software de interfaz con el usuario: Un programa desarrollado en lenguaje C,
se encarga de manejar un menú en el que se direccionan los archivos que se van a
utilizar y se escoge entre cuatro opciones: codificar, decodificar, ver un archivo de
texto o salir del programa. Una vez escogida opción de codificación o
decodificación, el programa se encarga de enviar, uno por uno, los caracteres de un
archivo fuente de tipo texto para realizar la función escogida en el menú.
Finalmente, cuando se realiza la codificación o la decodificación, el programa
entrega la estadística de los archivos fuente y destino, en cuanto al tamaño de
ambos y la tasa de compresión.
4.3.2
El software de compresión y descompresión: Un programa desarrollado en
lenguaje ensamblador, y descargado en la memoria del microcontrolador
MC68HC11, se encarga de recibir los caracteres que envía la computadora y los
convierte según sea la función que esté realizando (codificación o
descodificación). En caso de que el símbolo a codificar sea desconocido por el
MCU, este devuelve el código del espacio, el cual se va a ver reflejado durante la
decodificación. Esto semeja la mensajería de texto a través de la red de telefonía
celular, en que algunos aparatos se presenta éste símbolo en lugar de algunos
caracteres cuando se recibe el mensaje. Por ejemplo, suponiendo que en el texto se
48
encuentre el símbolo “ç” como en la palabra “Barça”, el decodificador devolverá
la palabra “Bar a”. Esto representa una ventaja ante símbolos desconocidos, pues
al codificarlos como espacios en blanco, se disminuye el tamaño del símbolo de
ocho bits a solo tres. En la tabla 4.4 se encuentra una serie de símbolos que no se
tomaron en cuenta en el alfabeto codificado.
Tabla 4.4 Símbolos del teclado de la computadora sin codificar
Símbolo
4.4
º
ª
|
·
¬
`
^
{
}
¨
ç
€
Software de interfaz con el usuario
El programa de interfaz con el usuario posee dos partes importantes:
4.4.1
La inicialización: Crea algunas variables que se utilizaran dentro del programa y
configura el puerto serie para una adecuada comunicación. El puerto serie de la
computadora posee un grupo de registros a partir de su dirección base (3F8h para el
COM1), y es necesario configurar algunos de ellos para establecer los parámetros de
la transmisión y recepción antes de poder utilizar el puerto.
49
La función outportb del lenguaje C, da salida a un byte a través del registro escogido.
En el programa en cuestión, PORT1 corresponde a la dirección 3F8h que es el registro
de lectura y escritura del puerto serie (COM1); y desplazamientos relativos a esta
dirección seleccionan uno de los registros de estado o configuración. En total son siete
registros. En el caso de esta aplicación la selección del byte 000Ch para el baud-rate
determina una velocidad de transmisión y recepción de 9600 bits por segundo. Este
valor debe coincidir con la velocidad de transmisión seleccionada para el MCU.
Debido a las características de ambos dispositivos de transmisión serie, no puede
configurarse una velocidad de transferencia mayor.
Finalmente debe elegirse el modo de trabajo: Codificación, decodificación,
visualización de un archivo o salir del programa.
4.4.2
Intercambio de datos: El intercambio de datos se da de manera diferente para
codificación y decodificación. En el primer caso, el programa entra en un ciclo que se
ejecuta mientras no se haya encontrado el final del archivo. Durante este ciclo, el
programa toma del archivo fuente de la codificación el siguiente carácter a enviar, lo
escribe en el puerto de salida y luego entra en un ciclo de espera mientras confirma
una recepción. En el momento en que esto sucede, se lee el carácter entrante,
correspondiente a un uno o un cero que representarán alguno de los bits de la cadena,
el cual será inmediatamente escrito en el archivo destino de la codificación. En el
50
momento en que se dejen de recibir los caracteres de la cadena de unos y ceros, el
programa solicitará avanzar al siguiente caracter hasta finalizar el proceso.
En el caso de la decodificación, de nuevo se entra en un ciclo hasta encontrar el final
del archivo. Durante el ciclo, el programa envía un uno o cero desde el archivo fuente
de la decodificación (que debería coincidir con el archivo destino de la codificación
para un adecuado funcionamiento) y puede recibir dos posibles códigos: Un carácter
de control (06h) que indicará que se debe enviar otro caracter pues aún no se ha
encontrado una secuencia de bits apropiada dentro de la tabla de decodificación.
Cuando se recibe un código diferente de 06h el programa escribe dicho carácter en el
archivo destino de la decodificación. Finalmente, en caso de una falla en la
comunicación, existe una variable que mide la espera en la recepción de caracteres,
por lo que si ésta alcanza un límite fijo preprogramado, la aplicación termina,
indicando que hubo un error en la comunicación. La figura 4.1 muestra el diagrama
de flujo de dicho programa. Las decisiones son verdaderas hacia la izquierda.
El código fuente completo del software de interfaz, puede encontrarse en la sección de
anexos.
51
Inicialización
¿Codificar,
Decodificar,
Abrir archivo,
Salir ?
NO
NO
¿C?
NO
¿D?
SI
NO
¿A?
SI
SI
¿S?
SI
FIN
Ruta ORIGEN
Ruta DESTINO
Ruta ORIGEN
Ruta DESTINO
Ruta ORIGEN
¿Abrió?
¿Abrió?
¿Abrió?
SI
SI
Codificación
ORIGEN >>> DESTINO
NO
NO SI
Decodificación
ORIGEN >>> DESTINO
NO
“ORIGEN”
Figura 4.1 Diagrama de flujo del programa de interfaz con el usuario
52
4.5
Programa de codificación y decodificación
El programa descargado en el MCU consta de cinco secciones:
4.5.1
Definición de las variables y los parámetros de trabajo: se definen todas las
constantes, variables, direcciones de memoria y de los registros del puerto
serie del MCU, conocido como Interfaz de Comunicación Serie SCI, por sus
siglas en inglés; y algunas máscaras de configuración para el SCI.
4.5.2
Inicialización: se configura el SCI para una adecuada comunicación con la
computadora que le envía los símbolos. Esta configuración se logra
escribiendo las mascaras de configuración sobre los registros apropiados del
SCI del MCU.
4.5.3
Lazo principal del programa: El lazo principal del programa se encarga de
determinar el trabajo a realizar sobre los datos de entrada, ya sea codificarlos o
decodificarlos. En el caso de la codificación, el dispositivo compara el símbolo
de entrada contra una serie de símbolos tabulados en orden descendente de
probabilidad. Una vez determinado el símbolo de entrada, una subrutina envía
la cadena de unos y ceros correspondiente a dicho símbolo, y luego regresa a
esperar un nuevo caracter. Para la decodificación el proceso que se lleva a cabo
53
es un tanto diferente, pues al ser las cadenas de unos y ceros de longitud
variable, el dispositivo debe retener la secuencia que ha ido recibiendo, por lo
que se creó una subrutina de recepción de bits para evitar que el programa no
pierda la secuencia de bits previa. Una vez que el programa ha alcanzado el
final de una de las ramas del árbol de codificación, envía el caracter
correspondiente y regresa a la base del árbol para iniciar nuevamente el
proceso. En ambos casos, cuando se recibe el caracter escape (2710, 1Bh) el
programa finaliza el proceso y regresa a esperar que se le indique cual tarea
realizar. Mientras está realizándose la codificación o decodificación, el
dispositivo activa un led, para indicar que se esta en una de estas dos tareas.
4.5.4
Subrutinas:
Las subrutinas implementadas son las siguientes:
4.5.4.1 Enviar byte: Se encarga de colocar un byte en el registro de salida de la SCI
únicamente cuando éste se encuentre vacío, esto para evitar truncar una
transmisión saliente.
4.5.4.2 Enviar cadena: Se encarga de ir moviéndose a lo largo de las cadenas de
unos y ceros, enviando uno a uno los caracteres de la cadena llamando a la
subrutina Enviar Byte. Esta transmisión termina cuando la subrutina
encuentra el byte FFh.
54
4.5.4.3 Esperar bit: Se encarga de recibir los unos y ceros del archivo fuente de la
decodificación, además de abandonar la decodificación en caso de recibir el
codigo de la función escape. Esta subrutina es llamada en cada paso por una
bifurcación del árbol de codificación.
4.5.4.4 Atención a interrupciones del SCI: Esta subrutina es llamada por el MCU
cada vez que la bandera de recepción de datos por el SCI se pone en estado
alto. Esta bandera pertenece a uno de los registros propios de la SCI y
activación se da automáticamente cuando se llena el registro de recepción. La
subrutina se encarga de copiar el byte recibido al registro temporal
COMANDO ubicado en la memoria RAM para poder accesarlo cuando se
salga de la subrutina, además de activar una bandera temporal de recepción
llamada PENDIENTE para que el programa principal haga uso del byte
guardado en COMANDO.
4.5.5
Tabla: Se creó una tabla con los códigos de longitud variable correspondientes
a cada símbolo de entrada del dispositivo, pues al representar la compresión como texto, cada
uno y cada cero ocupa un byte en la memoria. De la tabla se hace uso cargando la dirección
donde esta el primer “bit” del código, y desplazándose mientras se está enviando del caracter
correspondiente hasta que se encuentra la secuencia FFh que indica que ahí finaliza la cadena.
Las siguientes figuras muestran el diagrama de flujo del lazo principal dicho programa
y de sus subrutinas. Todas las decisiones son verdaderas hacia la izquierda.
55
Inicializaci ón
Opción
NO
SI
¿C?
NO
¿D?
SI
SI
Recibe
Recibe
(esperar bit)
SI
¿Recibido
=
Tabulado?
NO
¿Recibido
=
Escape?
Carga X con
dirección de
cadena
Envía carácter
codifivado (enviar
cadena)
SI
NO
¿Recibido
≠
Escape?
SI
Carga X con la
dirección de
espacio
Envío de código
espacio para
carácter
desconocido
(Enviar cadena)
Envío carácter
decodificado
(Enviar byte)
NO
¿Secuencia
=
Tabulado?
NO
Envío carácter de
control (Enviar
byte)
Figura 4.2 Diagrama de flujo del programa de compresión y descompresión
56
NO
¿TDRE = 0?
SI
Cargar
(Transmite) byte
en SCDR
RTS
Figura 4.3 Diagrama de flujo de la subrutina enviar byte
¿Acumulador = FFh?
SI
NO
Cargar
(Transmite) byte
en SCDR
RTS
Incrementa índice
X (direcciona la
cadena)
Figura 4.4 Diagrama de flujo de la subrutina enviar cadena
57
NO
Cargar
PENDIENTE
¿Hay
PENDIENTE?
SI
Cargar
COMANDO
SI
¿COMANDO =
Salir?
Redireccionar
hacia MENU
NO
RTS
Figura 4.5 Diagrama de flujo de la subrutina esperar bit
58
Carga SCSR
Carga SCDR
Guarda en
COMANDO
Carga
VERDADERO
Guarda en
PENDIENTE
RTS
Figura 4.6 Diagrama de flujo de la subrutina de atención a interrupción de la SCI
59
4.6
Manual de usuario de la aplicación
Para utilizar el codificador y decodificador fuente, es necesario contar con el siguiente
equipo:
•
Una computadora con Microsoft® Windows o MS-DOS.
•
Programa de Terminal si desea usarse dicho modo de operación
•
Al menos un puerto de comunicación serial.
•
Un tomacorriente cercano disponible para conectar la fuente de potencia de la
tarjeta con el microprocesador
4.6.1 Modos de uso
El dispositivo implementado puede utilizarse de cualesquiera dos formas, y esto no
afectará su funcionamiento o desempeño, pero si reducirá las opciones. .
4.6.1.1 Modo Terminal: Si se quiere realizar una codificación en tiempo real, o la
verificación del código de un símbolo específico, sin necesidad de crear un archivo
fuente ni destino, se puede acceder al microprocesador directamente desde un
programa de terminal, como MGTEK MiniIDE o la hyperterminal del Windows.
Dentro de la terminal, deberá especificarse que tarea se desea realizar, codificación
o decodificación, con las teclas “c” o “d”. Para saber si se está dentro del ciclo, se
debe observar el estado del led incluido en la tarjeta del MCU y verificar si está
60
encendido o no. Una vez que se determina esto, se pueden introducir los datos
directamente desde el teclado y verificar los resultados.
4.6.1.1.1
Configuración: La terminal debe tener los siguientes valores de
configuración:
4.6.1.1.2

Baud Rate: 9600 Bps

Bits de datos (Data Bits): 8

Bits de parada (Stop Bits): 1

Paridad (Parity): sin paridad
Posibles errores: Si no se tuviera respuesta en la pantalla, o los datos
presentados no son los correctos, debe verificarse la velocidad de
transmisión configurada en la terminal y el puerto COM utilizado, la
alimentación de la tarjeta, la conexión y el estado del cable de
comunicación.
4.6.1.2 Modo Consola: Cuando se desea realizar la codificación o decodificación de un
texto sin preocuparse por introducir su contenido manualmente, debe utilizarse este
modo de operación, que implica iniciar la aplicación de interfaz con el usuario
CDFuente.exe. En ella, se despliega inicialmente una pantalla con las opciones del
menú (ver figura 4.7). En cualquiera de los tres casos, codificar, decodificar o abrir
un archivo; debe especificarse la ruta de los archivos con los que se desea trabajar.
61
El formato de la ruta es el siguiente:
<unidad de almacenamiento> :\ <directorio 1> \...\ <directorio N> \<nombre_archivo>.txt
; y no debe exceder los 80 caracteres.
Si al especificar la ruta solamente se indica el nombre del archivo, dicho archivo
tratará de ser abierto por la aplicación desde el mismo directorio en el que se encuentre el
archivo ejecutable.
Finalmente, aparte de los archivos de tipo TXT, también son compatibles las
extensiones .C y .H
4.6.1.2.1
Configuración: Para este modo de operación no se requiere ninguna
configuración, esta se hace automáticamente dentro del programa.
4.6.1.2.2
Posibles errores: Existe la posibilidad que al querer realizar alguna de las
tareas se presente un error. Si, luego de haber asignado una ruta, el
programa devuelva en la pantalla “Problemas con los ficheros”, puede
deberse a la ausencia del directorio especificado, a la ausencia del archivo
fuente especificado (si el archivo destino no existe, la aplicación lo crea); o
a que la ruta especificada excede los ochenta caracteres de longitud, y por
62
tanto se trunca eliminando los caracteres en exceso. En cualquier caso la
aplicación regresa al menú principal, asegurándose que si hay algún otro
fichero fue abierto, éste sea cerrado apropiadamente. Por otra parte, si la
apertura de los archivos es exitosa, pero la computadora no logra
comunicarse con el dispositivo, se genera un “Error de comunicación”
pues se vence el timeout preprogramado y de nuevo el programa regresa al
menú principal, asegurándose que cada fichero abierto, éste sea cerrado
apropiadamente. Las razones de este problema son: cable de comunicación
está desconectado de la computadora o de la tarjeta, mal conectado a la
tarjeta del MCU o cable dañado, el puerto escogido en la computadora no
corresponda al COM1, o que la tarjeta del MCU se encuentre apagada o
desenergizada del todo. Una vez corregido el problema, o si no se presentó
problema alguno, el dispositivo debe funcionar adecuadamente, y tras
realizar la tarea especificada devuelve una estadística del nivel de
compresión alcanzado.
63
CAPÍTULO 5: Conclusiones y recomendaciones
Dichosamente se logró cumplir con todos los objetivos que se plantearon para
desarrollar el proyecto. Tanto la investigación realizada, como la aplicación implementada,
permiten plantear un proyecto para dar seguimiento a éste. Con esta herramienta se espera que
los estudiantes del área de electrónica y telecomunicaciones, así como el público en general,
tengan a su disposición una herramienta de sencilla manipulación que permite observar de
una manera más clara un proceso de compresión y descompresión. Además, este proyecto
también permite asociar la codificación y decodificación fuente con la decodificación de
canal, pues se puede manipular externamente el archivo destino de la codificación para
simular errores en la transmisión cambiando los bits que se deseen en dicho archivo y
observar el resultado que generan estos errores de transmisión a la hora de decodificarlo.
Las principales conclusiones obtenidas son:
•
La teoría de la información permite realizar un análisis cuantitativo de los códigos
de longitud fija que pueda conformar algún alfabeto en particular y así poder
determinar cual es el máximo de bits por símbolo realmente necesarios en un
código (contenido de decisión por símbolo), cuantos bits por símbolo como
mínimo son necesarios para transmitir el mensaje (entropía de la fuente) sin perder
64
información y cuanto se “desperdicia” de espacio de almacenamiento o ancho de
banda si se guardara o transmitiera el mensaje sin comprimir (redundancia).
•
Los métodos de compresión de información son un avance muy importante en el
mundo del almacenamiento y transmisión de la información, pues permiten un
mayor aprovechamiento de los medios de almacenamiento y transmisión de datos,
al eliminar todo aquello que por alguna razón es innecesario incluir.
•
Los métodos de compresión estudiados contemplan solo una parte de la amplia
gama que actualmente existe, pues en este trabajo no se tomo en cuenta los
métodos de compresión con pérdidas. Sin embargo la robustez de algunos de estos
métodos hace que sean la base de implementación en sistemas de compresión de
uso frecuente, como lo es la técnica LZW utilizada en archivos de imagen tipo
GIF.
•
Actualmente la codificación Huffman, que se utilizó en el desarrollo de la
aplicación de este proyecto, comúnmente es utilizada como un método adicional
en algunos compresores. DEFLATE (algoritmo de PKZIP) y codecs multimedia
como JPEG y MP3 tienen un modelo principal, una cuantización y luego una
codificación Huffman.
•
Los microcontroladores son dispositivos muy versátiles y permiten implementar
una amplia gama de aplicaciones debido a todos los recursos que poseen. En la
realización de este proyecto fue indispensable que el microcontrolador contara con
65
la SCI para poder intercambiar datos con la computadora. Además, por esta misma
flexibilidad del dispositivo, fácilmente se puede mejorar la aplicación.
•
Es muy importante hacer un estudio lo suficientemente grande de los símbolos a
codificar para que la aproximación de probabilidades por frecuencias relativas sea
válida. En este caso, a pesar de que al principio se analizaron textos largos, los
resultados eran más consistentes conforme aumentaba el tamaño del texto
analizado. Fue necesario además, analizar varios textos para ratificar los resultados
obtenidos.
•
El desempeño de la compresión depende del origen del texto. Como las
probabilidades se calcularon a partir de textos estándar, si el texto a codificar
posee solo caracteres en mayúscula, o estos representan una gran mayoría de los
caracteres, la tasa de compresión puede resultar negativa. Esto se debe a que los
códigos Huffman asignados a muchos de estos caracteres poseen más de 8 bits, y
al realizar el cálculo de la diferencia de bits intercambiados esta resulta en un
número negativo.
•
La velocidad de los procesos de codificación y decodificación se ve afectada por
dos aspectos, primero, por que no puede configurarse una velocidad superior a los
9600 bps debido a la incompatibilidad entre las otras velocidades configurables del
puerto serie de la computadora y de la SCI; y segundo por las esperas que deben
hacer ambos programas a que los respectivos registros se llenen o se vacíen y que
se activen las banderas de estado para realizar las tareas pertinentes.
66
Además como en todo proceso de desarrollo es necesario realizar constantes
revisiones para una depuración y mejoramiento de los proyectos. En el caso de la
aplicación desarrollada, se puede pensar en aplicar una o varias de las
recomendaciones que a continuación se mencionan para así alcanzar un mejor
aprovechamiento de la herramienta
•
Realizar las mejoras necesarias al código fuente de ambos programas para mejorar
las velocidades de los procesos de codificación y decodificación.
•
Buscar la forma de lograr una aplicación modular, en la que también pueda
agregarse un codificador y decodificador de canal, de manera que el estudiante
pueda observar las dos aplicaciones funcionando conjuntamente.
•
Implementar otro tipo codificador fuente, siempre para texto en español, de
manera que el estudiante pueda comparar el desempeño de los distintos
codificadores.
•
Implementar la función de “aprender” los códigos, de manera que se pueda variar
el alfabeto de la fuente de una manera rápida y sencilla, haciendo que el
codificador y decodificador funcione con archivos de diferente naturaleza como lo
son las imágenes.
67
BIBLIOGRAFÍA
Libros:
1. Couch, L.W. “Sistemas de comunicación digitales y analógicos”, 5 edición, Prentice
Hall, 1998.
2. Proakis, J.G. “Digital Communications”, 4 edición, McGraw – Hill, 2001.
3. Stremler, F.G. “Sistemas de comunicación”, Alfaomega, México, 1989.
Publicaciones
4. Huffman, D.A. “A method for the construction of minimum-redundancy codes”
Setiembre, 1952.
5. Shannon, C.E. “A Mathematical Theory of Communication”, October, 1948.
6. Golomb, S.W. “Run-Length Encodings”, en IEEE Transactions on information
theory, Julio, 1966.
7. Said, A. “Introduction to Arithmetic Coding - Theory and Practice”, HP
Laboratories, 2004
8. Rissanen, J. Langdon, G.G. Jr. “Arithmetic Coding”, IBM Research Division
Laboratories, 1979.
9. Martin, G.N.N. “Range encoding, an algorithm for removing redundancy from a
digitised message”, IBM UK Scientific Center, 1979.
10. Burrows, M.Wheeler, D.J. “A Block-sorting Lossless Data Compression
Algorithm”, Systems Research Center, 1994.
11. Ziv, J. Lempel A. “A Universal Algorithm for Sequential Data Compression”, en
IEEE Transactions on information theory, Mayo, 1977.
68
Manuales de Referencia:
12. Freescale Semiconductors, Inc. “M68HC11 Microcontrollers Reference Manual”,
Rev. 6.1,2007.
13. Technological Arts. “Using your ADAPT11C24DX starter package”, Canada,
2001.
14. Doblado,
C.
Gónzalez,
J.
Prieto-Moreno,
A.
San
Martin,
J.
“MICROCONTROLADOR 68HC11: Fundamentos, recursos y programación”,
Páginas web:
15.
“Introducción
al
microcontrolador
MC68HC11”,
ttp://lc.fie.umich.mx/~jrincon/cur6811.pdf
16. “Interfacing the Serial / RS232 port” V5.0, http://www.senet.com.au/~cpeacock
17.
“Distorsión”,
http://cain.eie.fceia.unr.edu.ar/ftp/Comunicaciones/Teor%EDa
%20Tasa%20Distorsion.ppt
18. “Tema
7:
Cuantificación
escalar”
http://decsai.ugr.es/ccd/transparencias/07_cuantificacion_escalar_bn2.pdf
19. Material
vario
sobre
codificación
y
compresión
de
datos,
y
compresión
de
datos,
http://decsai.ugr.es/ccd/complementario.html
20. Material
vario
sobre
codificación
http://perseo.dif.um.es/~roque/ci/index.html#Apuntes
21. Definiciones varias en es.wikipedia.org
69
APÉNDICES
70
Apéndice A: Códigos fuente de los programas
Proba.CPP: Especifica la frecuencia de aparición de un caracter en un texto
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <io.h>
int main()
{
char seguir='s';
float caracter,total;
FILE *origen;
unsigned char temp,letra;
char ruta[40];
clrscr();
printf("Ruta del archivo, al terminar presione ENTER: ");
fflush(stdin);
origen=fopen(gets(ruta),"r");
if(origen==NULL) exit(1);
while(seguir=='s') //Este ciclo busca el caracter especificado e imprime su frecuencia relativa
de aparición respecto al total de caracteres
{
caracter=0;
total=0;
printf("\ncaracter a analizar, al terminar presione ENTER: ");
fflush(stdin);
scanf("%c",&letra);
rewind(origen);
while(feof(origen)==0)//Este ciclo asigna los valores para el cálculo de la frecuencia
relativa
{
temp=getc(origen);
if(temp==letra)
caracter++;
total++;
}
rintf("\nProbabilidad = %f\n",caracter/total);
printf("seguir con otro caracter? (s=si)");
fflush(stdin);
scanf("%c",&seguir);
}
return(0);
}
CDFuente.CPP: Programa de interfaz con el usuario
71
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <io.h>
#define PORT1 0x3F8
int main(void)
{
int c;
long timeout;
FILE *origen, *destino;
unsigned char letra, flush=' ', control;
char opcion,ruta_fuente[80], ruta_destino[80];
float char_enviado=0, char_recibido=0,bit_enviado=0,bit_recibido=0,tasa;
outportb(PORT1 + 1 , 0); /* Enciende las interrupciones del puerto 1 */
outportb(PORT1 + 3 , 0x80); /* activa el DLAB */
outportb(PORT1 + 0 , 0x0C); /* Configuacion del Baud rate - parte baja del la palabra del
Divisor Latch */
outportb(PORT1 + 1 , 0x00); /* parte alta del la palabra del Divisor Latch */
outportb(PORT1 + 3 , 0x03); /* 8 Bits, sin paridad, 1 Bit de parada, configuracion tradicional
*/
outportb(PORT1 + 2 , 0xC7); /* Registro de control FIFO */
outportb(PORT1 + 4 , 0x0B); /* Enciende DTR, RTS, y OUT2 */
clrscr();
outportb(PORT1,27);
flush=inportb(PORT1);
menu:
char_enviado=0; char_recibido=0;bit_enviado=0;bit_recibido=0,tasa;
printf("\n\tUniversidad de Costa Rica\n\tFacultad de Ingenier¡a\n\tEscuela de Ingenieria
El‚ctrica\n\tProyecto El‚ctrico IE-0502\n\tCodificador y Decodificador Fuente\n\tLuis Felipe C¢rdoba
MoralesA41675\n\tDiciembre 2007");
denuevo:
printf("\n\t\n\tQue desea hacer?\n\tC = Codificar\n\tD = Decodificar\n\tA =
Abrir y ver un archivo de texto\n\t\n\tS = Salir\n\t\n\tOpcion: ");
scanf("%c", &opcion);
if(opcion!='a'&&opcion!='A'&&opcion!='c'&&opcion!='C'&&opcion!='d'&&opcion!='D'&&opcion!
='s'&&opcion!='S')
{
fflush(stdin);
goto denuevo;
}
if(opcion=='c'||opcion=='C')
{
printf("\n\n\tIndique la ruta del archivo de texto que desea codificar,\n\tal terminar presione
ENTER: ");
fflush(stdin);
origen=fopen(gets(ruta_fuente),"r");
72
if (origen==NULL)
{
printf( "\n\tProblemas con la apertura del fichero %s\n",ruta_fuente );
outportb(PORT1,27);
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
printf("\n\n\tIndique la ruta del archivo de texto al que desea \n\tescribir la codificación,al
terminar presione ENTER:\n\n\t");
fflush(stdin);
destino=fopen(gets(ruta_destino),"w");
if (destino==NULL)
{
printf( "\n\tProblemas con la apertura del fichero %s\n",ruta_destino );
outportb(PORT1,27);
printf("\n\n\tPresione cualquier tecla para continuar");
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_fuente );
getch();
clrscr();
goto menu;
}
outportb(PORT1,'c');
goto Codificar;
}
if(opcion=='d'||opcion=='D')
{
printf("\n\n\tIndique la ruta del archivo de texto que desea decodificar,\n\tal terminar presione
ENTER: ");
fflush(stdin);
origen=fopen(gets(ruta_fuente),"r");
if (origen==NULL)
{
printf( "\n\tProblemas con la apertura del fichero %s\n",ruta_fuente );
outportb(PORT1,27);
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
printf("\n\n\tIndique la ruta del archivo de texto al que desea escribir\n\tla
decodificacion,tal terminar presione ENTER:\n\n\t ");
fflush(stdin);
destino=fopen(gets(ruta_destino),"w");
if (destino==NULL)
{
printf( "\n\tProblemas con la apertura del fichero %s\n",ruta_destino );
outportb(PORT1,27);
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_fuente );
73
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
outportb(PORT1,'d');
goto Decodificar;
}
if(opcion=='a'||opcion=='A')
{
printf("\n\n\tIndique la ruta del archivo de texto que desea abrir,\n\tal terminar presione
ENTER: ");
fflush(stdin);
origen=fopen(gets(ruta_fuente),"r");
if (origen==NULL)
{
printf( "Problemas al abrir el fichero %s\n",ruta_fuente );
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
printf("\n\n");
while(feof(origen)==0)
{
letra=getc(origen);
printf("%c",letra);
delay(3);
}
printf("\n\n\n\tPresione cualquier tecla para continuar");
getch();
if (fclose(origen)!=0)
{
printf( "Problemas con la cerradura del fichero.\n" );
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
clrscr();
goto menu;
}
if(opcion=='s'||opcion=='S')
{
goto Fin;
}
/*ESTA ES LA PARTE DE ENVIO DE CARACTERES Y RECEPCION DE UNOS Y CEROS */
char_enviado=0;
char_recibido=0;
bit_enviado=0;
bit_recibido=0;
Codificar:
74
printf("\n\tCodificando...");
letra=getc(origen);
timeout=0;
while (feof(origen)==0)
{
Enviar_char:
if(inportb(PORT1 + 5)==0x60)
{
outportb(PORT1,letra);
char_enviado++;
goto Recibir_char;
}
flush=inportb(PORT1);
goto Enviar_char;
Recibir_char:
if(inportb(PORT1 + 5)==0x61||inportb(PORT1 + 5)==0x21)
{
timeout=0;
letra=inportb(PORT1);
putc(letra,destino);
bit_recibido++;
RecibirSig_char:
if(inportb(PORT1 + 5)==0x61||inportb(PORT1 + 5)==0x21)
{
timeout=0;
letra=inportb(PORT1);
putc(letra,destino);
bit_recibido++;
goto RecibirSig_char;
}
timeout++;
if (timeout==2000000)
{
printf("\n\n\tERROR DE COMUNICACION!!!\n\n");
outportb(PORT1,27);
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_fuente );
if (fclose(destino)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_destino );
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
goto Siguiente_char;
}
timeout++;
if (timeout==2000000)
{
printf("\n\n\tERROR DE COMUNICACION!!!\n\n");
75
outportb(PORT1,27);
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_fuente );
if (fclose(destino)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_destino );
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
goto Recibir_char;
Siguiente_char:
letra=getc(origen);
}
outportb(PORT1,27);
fflush(stdin);
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero origen.txt\n" );
if (fclose(destino)!=0)
printf( "Problemas al cerrar el fichero destino.txt\n" );
printf("\n\tCodificacion terminada!");
tasa=(1-(bit_recibido/(char_enviado*8)))*100;
printf("\n\n\tSe enviaron %.0f bits de caracteres, se recibieron %.0f bits.\n\tLa tasa de
compresion es del %.2f %\n\n",char_enviado*8,bit_recibido,tasa);
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
/*ESTA ES LA PARTE DE ENVIO DE UNOS Y CEROS Y RECEPCION DE CARACTERES*/
Decodificar:
printf("\n\tDecodificando...");
letra=getc(origen);
timeout=0;
while (feof(origen)==0)
{
Enviar_bit:
if(inportb(PORT1 + 5)==0x60)
{
outportb(PORT1,letra);
bit_enviado++;
goto Recibir_bit;
}
flush=inportb(PORT1);
goto Enviar_bit;
Recibir_bit:
if(inportb(PORT1 + 5)==0x61||inportb(PORT1 + 5)==0x21)
{
76
timeout=0;
letra=inportb(PORT1);
if(letra!=6)
{
putc(letra,destino);
char_recibido++;
}
goto Siguiente_bit;
}
timeout++;
if (timeout==2000000)
{
printf("\n\n\tERROR DE COMUNICACION!!!\n\n");
outportb(PORT1,27);
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_fuente );
if (fclose(destino)!=0)
printf( "Problemas al cerrar el fichero %s\n",ruta_destino );
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
}
goto Recibir_bit;
Siguiente_bit:
letra=getc(origen);
}
outportb(PORT1,27);
fflush(stdin);
printf("\n\tDecodificacion terminada!");
tasa=(1-(bit_enviado/(char_recibido*8)))*100;
printf("\n\n\tSe enviaron %.0f bits, se recibieron %.0f bits de caracteres.\n\tLa tasa de
compresion era del %.2f %\n\n",bit_enviado,char_recibido*8,tasa);
if (fclose(origen)!=0)
printf( "Problemas al cerrar el fichero origen.txt\n" );
if (fclose(destino)!=0)
printf( "Problemas al cerrar el fichero destino.txt\n" );
printf("\n\n\tPresione cualquier tecla para continuar");
getch();
clrscr();
goto menu;
Fin:
flush=' ';
printf("\n%c",flush);
return (0);
}
77
baud
equ
rbase+$2b
rate control
sccr1 equ
rbase+$2c
register 1
sccr2 equ
rbase+$2d
register 2
scsr
equ
rbase+$2e
register
scdr
equ
rbase+$2f
read (rdr) and write (tdr)
CDFuente.ASM: Programa del MCU
; Universidad de Costa Rica
; Facultad de Ingenieria
; Escuela de Ingenieria Electrica
; Proyecto Eléctrico IE-0502
; Codificador y decodificador fuente
; Luis Felipe Córdoba Morales
A41675
; Diciembre 2007
;sci
baud
;sci control
;sci control
;sci
status
;sci
data,
; Direcciones del sistema
RAM
rbase
equ
$0000
equ
$1000
;Direccion base para los registros
STACK
equ
$00FF
;Direccion inicial de la Pila, en la parte alta de
la RAM
EEPROM
equ
$8000
;Direccion de la memoria EEPROM en
Sistemas Adapt11C24DX con 32K EEPROM
; Constantes
VERDADERO
equ
FALSO
equ
ACK
equ
arribo de bit y codigo incompleto
CODIFICAR
equ
DECODIFICAR
equ
SALIR
equ
Escape
CR
equ
carro
LF
equ
SP
equ
$FF
$00
$06 ;Indicador de
$63 ;tecla C
$64 ;tecla D
$1B ;Código Tecla
$D
;retorno
de
rmb
; Mascaras
bdmsk96
equ
%00110000
;
(baud) 9600 baud with 8 MHz crystal
bdmsk24
equ
%00110010
;
(baud) 2400 baud with 8 MHz crystal
bdmsk12
equ
%00110011
;
(baud) 1200 baud with 8 MHz crystal
ptdmsk
equ
%00000010
;
(ddrd) Direccion de las Entradas del puerto D,
excepto TXD
sc2msk2
equ
%00101100
;
(sccr2)enable tx & rx and Rx Interrupt
**********************************
Programa
*******************************
$A ;nueva linea
$20 ; espacio
org
EEPROM
init ;Direccion (etiqueta) a la que apunta el
vector de interrupcion RESET
org RAM
; Variables de sistema
COMANDO
Caracter
pprog equ
rbase+$3b
;Registro de
control de programacion de la EEPROM
hprio equ
rbase+$3c
;Mayor
prioridad de interrupcion
sei
1
;usado por Recibir
1
;usado
lds #STACK
puntero de pila
;inicializa el
ldaa #ptdmsk
;inicializa el
; Variables Booleanas
PENDIENTE
rmb
ProcessCommand
por
; Registros
portd equ
rbase+$08
communications
ddrd
equ
rbase+$09
register, portd
;portd,
;data
serial
direction
78
puerto D
staa ddrd
ldaa #bdmsk96
;baud=9600
staa baud
ldaa #sc2msk2
staa sccr2
;Habilita el
receptor y el transmisor del SCI y las
interrupciones de del receptor
ldaa scdr
buffer del receptor
;Lectura
para
vaciar
el
a:
clr PENDIENTE
clr COMANDO
cli
interrupciones
;habilita
o:
;comandos
n:
Inicio
ldaa PENDIENTE
recibidos via interrupción SCI
cmpa #VERDADERO
bne Inicio
MostrarEleccion
s:
clr
PENDIENTE
ldaa COMANDO
cmpa
beq
cmpa
beq
#'C'
Codificacion
#'c'
Codificacion
i:
cmpa
beq
cmpa
beq
#'D'
Deco
#'d'
Deco
r:
jmp Inicio
l:
Deco
jmp Decodificacion
Codificacion
ldaa $1000
eora #$40
staa $1000
d:
Esperarletra
ldaa
PENDIENTE
;comandos
recibidos via interrupcion del SCI
cmpa #VERDADERO
bne
Esperarletra
clr PENDIENTE
ldaa COMANDO
cmpa #' '
bne e
ldx #COD_ESPACIO
jsr EnviarCadena
jmp Esperarletra
e:
cmpa #'e'
bne a
ldx #COD_e
jsr EnviarCadena
c:
t:
u:
79
jmp Esperarletra
cmpa #'a'
bne o
ldx #COD_a
jsr EnviarCadena
jmp Esperarletra
cmpa #'o'
bne n
ldx #COD_o
jsr EnviarCadena
jmp Esperarletra
cmpa #'n'
bne s
ldx #COD_n
jsr EnviarCadena
jmp Esperarletra
cmpa #'s'
bne i
ldx #COD_s
jsr EnviarCadena
jmp Esperarletra
cmpa #'i'
bne r
ldx #COD_i
jsr EnviarCadena
jmp Esperarletra
cmpa #'r'
bne l
ldx #COD_r
jsr EnviarCadena
jmp Esperarletra
cmpa #'l'
bne d
ldx #COD_l
jsr EnviarCadena
jmp Esperarletra
cmpa #'d'
bne c
ldx #COD_d
jsr EnviarCadena
jmp Esperarletra
cmpa #'c'
bne t
ldx #COD_c
jsr EnviarCadena
jmp Esperarletra
cmpa #'t'
bne u
ldx #COD_t
jsr EnviarCadena
jmp Esperarletra
cmpa #'u'
bne m
ldx #COD_u
jsr EnviarCadena
jmp Esperarletra
m:
cmpa #'m'
bne p
ldx #COD_m
jsr EnviarCadena
jmp Esperarletra
p:
cmpa #'p'
bne coma
ldx #COD_p
jsr EnviarCadena
jmp Esperarletra
coma: cmpa
#','
bne b
ldx #COD_coma
jsr EnviarCadena
jmp Esperarletra
b: cmpa
#'b'
bne g
ldx #COD_b
jsr EnviarCadena
jmp Esperarletra
g:
cmpa #'g'
bne v
ldx #COD_g
jsr EnviarCadena
jmp Esperarletra
v:
cmpa #'v'
bne q
ldx #COD_v
jsr EnviarCadena
jmp Esperarletra
q: cmpa
#'q'
bne ye
ldx #COD_q
jsr EnviarCadena
jmp Esperarletra
ye:
cmpa #'y'
bne punto
ldx #COD_y
jsr EnviarCadena
jmp Esperarletra
punto cmpa #'.'
bne f
ldx #COD_punto
jsr EnviarCadena
jmp Esperarletra
f:
cmpa #'f'
bne otil
ldx #COD_f
jsr EnviarCadena
jmp Esperarletra
otil:
cmpa #'ó'
bne h
ldx #COD_otil
jsr EnviarCadena
jmp Esperarletra
h:
cmpa #'h'
bne itil
ldx #COD_h
jsr EnviarCadena
jmp Esperarletra
itil:
cmpa #'í'
bne comillas
ldx #COD_itil
jsr EnviarCadena
jmp Esperarletra
comillas cmpa #'”'
bne atil
ldx #COD_comillas
jsr EnviarCadena
jmp Esperarletra
atil
cmpa #'á'
bne j
ldx #COD_atil
jsr EnviarCadena
jmp Esperarletra
j:
cmpa #'j'
bne z
ldx #COD_j
jsr EnviarCadena
jmp Esperarletra
z:
cmpa #'z'
bne emay
ldx #COD_z
jsr EnviarCadena
jmp Esperarletra
emay: cmpa #'E'
bne etil
ldx #COD_emay
jsr EnviarCadena
jmp Esperarletra
etil:
cmpa #'é'
bne ex
ldx #COD_etil
jsr EnviarCadena
jmp Esperarletra
ex:
cmpa #'x'
bne n2
ldx #COD_x
jsr EnviarCadena
jmp Esperarletra
n2:
cmpa #'ñ'
bne lmay
ldx #COD_n2
jsr EnviarCadena
jmp Esperarletra
lmay: cmpa #'L'
bne NL_LF1
ldx #COD_lmay
jsr EnviarCadena
jmp Esperarletra
NL_LF1:
80
cmpa
#10
bne tabular
ldx #COD_NL_LF
jsr EnviarCadena
jmp Esperarletra
tabular: cmpa #9
bne smay
ldx #COD_tabular
jsr EnviarCadena
jmp Esperarletra
smay: cmpa #'S'
bne mmay
ldx #COD_smay
jsr EnviarCadena
jmp Esperarletra
mmay cmpa #'M'
bne util
ldx #COD_mmay
jsr EnviarCadena
jmp Esperarletra
util:
cmpa #'ú'
bne uno
ldx #COD_util
jsr EnviarCadena
jmp Esperarletra
uno:
cmpa #'1'
bne pmay
ldx #COD_uno
jsr EnviarCadena
jmp Esperarletra
pmay: cmpa #'P'
bne dospuntos
ldx #COD_pmay
jsr EnviarCadena
jmp Esperarletra
dospuntos:
cmpa #':'
bne cmay
ldx #COD_dospuntos
jsr EnviarCadena
jmp Esperarletra
cmay: cmpa #'C'
bne amay
ldx #COD_cmay
jsr EnviarCadena
jmp Esperarletra
amay cmpa #'A'
bne cero
ldx #COD_amay
jsr EnviarCadena
jmp Esperarletra
cero
cmpa #'0'
bne nmay
ldx #COD_cero
jsr EnviarCadena
jmp Esperarletra
nmay cmpa #'N'
bne nueve
ldx #COD_nmay
jsr EnviarCadena
jmp Esperarletra
nueve: cmpa #'9'
bne menos
ldx #COD_nueve
jsr EnviarCadena
jmp Esperarletra
menos: cmpa #'-'
bne bmay
ldx #COD_menos
jsr EnviarCadena
jmp Esperarletra
bmay: cmpa #'B'
bne tmay
ldx #COD_bmay
jsr EnviarCadena
jmp Esperarletra
tmay: cmpa #'T'
bne dos
ldx #COD_tmay
jsr EnviarCadena
jmp Esperarletra
dos:
cmpa #'2'
bne puntoycoma
ldx #COD_dos
jsr EnviarCadena
jmp Esperarletra
puntoycoma:
cmpa #';'
bne w
ldx #COD_puntoycoma
jsr EnviarCadena
jmp Esperarletra
w:
cmpa #'w'
bne dmay
ldx #COD_w
jsr EnviarCadena
jmp Esperarletra
dmay: cmpa #'D'
bne hmay
ldx #COD_dmay
jsr EnviarCadena
jmp Esperarletra
hmay: cmpa #'H'
bne imay
ldx #COD_hmay
jsr EnviarCadena
jmp Esperarletra
imay: cmpa #'I'
bne omay
ldx #COD_imay
jsr EnviarCadena
jmp Esperarletra
omay: cmpa #'O'
bne cinco
ldx #COD_omay
81
jsr EnviarCadena
jmp Esperarletra
cinco: cmpa #'5'
bne gmay
ldx #COD_cinco
jsr EnviarCadena
jmp Esperarletra
gmay: cmpa #'G'
bne umay
ldx #COD_gmay
jsr EnviarCadena
jmp Esperarletra
umay: cmpa #'U'
bne k
ldx #COD_umay
jsr EnviarCadena
jmp Esperarletra
k:
cmpa #'k'
bne rmay
ldx #COD_k
jsr EnviarCadena
jmp Esperarletra
rmay: cmpa #'R'
bne ymay
ldx #COD_rmay
jsr EnviarCadena
jmp Esperarletra
ymay: cmpa #'Y'
bne pregcierra
ldx #COD_ymay
jsr EnviarCadena
jmp Esperarletra
pregcierra:
cmpa #'?'
bne pregabre
ldx #COD_pregcierra
jsr EnviarCadena
jmp Esperarletra
pregabre cmpa #'¿'
bne seis
ldx #COD_pregabre
jsr EnviarCadena
jmp Esperarletra
seis:
cmpa #'6'
bne fmay
ldx #COD_seis
jsr EnviarCadena
jmp Esperarletra
fmay: cmpa #'F'
bne siete
ldx #COD_fmay
jsr EnviarCadena
jmp Esperarletra
siete: cmpa #'7'
bne ocho
ldx #COD_siete
jsr EnviarCadena
jmp Esperarletra
cmpa #'8'
bne tres
ldx #COD_ocho
jsr EnviarCadena
jmp Esperarletra
tres:
cmpa #'3'
bne slash
ldx #COD_tres
jsr EnviarCadena
jmp Esperarletra
slash: cmpa #'/'
bne vmay
ldx #COD_slash
jsr EnviarCadena
jmp Esperarletra
vmay: cmpa #'V'
bne wmay
ldx #COD_vmay
jsr EnviarCadena
jmp Esperarletra
wmay: cmpa #'W'
bne xmay
ldx #COD_wmay
jsr EnviarCadena
jmp Esperarletra
xmay: cmpa #'X'
bne backslash
ldx #COD_xmay
jsr EnviarCadena
jmp Esperarletra
backslash:
cmpa #'\'
bne imaytil
ldx #COD_backslash
jsr EnviarCadena
jmp Esperarletra
imaytil: cmpa #'Í'
bne omaytil
ldx #COD_imaytil
jsr EnviarCadena
jmp Esperarletra
omaytil: cmpa #'Ó'
bne umaytil
ldx #COD_omaytil
jsr EnviarCadena
jmp Esperarletra
umaytil: cmpa #'Ú'
bne n2may
ldx #COD_umaytil
jsr EnviarCadena
jmp Esperarletra
n2may: cmpa #'Ñ'
bne udir
ldx #COD_n2may
jsr EnviarCadena
jmp Esperarletra
ocho:
82
udir:
cmpa #'ü'
bne udirmay
ldx #COD_udir
jsr EnviarCadena
jmp Esperarletra
udirmay:
cmpa #'Ü'
bne admirabre
ldx #COD_udirmay
jsr EnviarCadena
jmp Esperarletra
admirabre:
cmpa #'¡'
bne admircierra
ldx #COD_admirabre
jsr EnviarCadena
jmp Esperarletra
admircierra:
cmpa #'!'
bne igual
ldx #COD_admircierra
jsr EnviarCadena
jmp Esperarletra
igual: cmpa #'='
bne mas
ldx #COD_igual
jsr EnviarCadena
jmp Esperarletra
mas:
cmpa #'+'
bne asterisco
ldx #COD_mas
jsr EnviarCadena
jmp Esperarletra
asterisco:
cmpa #'*'
bne menor
ldx #COD_asterisco
jsr EnviarCadena
jmp Esperarletra
menor: cmpa #'<'
bne mayor
ldx #COD_menor
jsr EnviarCadena
jmp Esperarletra
mayor: cmpa #'>'
bne numero
ldx #COD_mayor
jsr EnviarCadena
jmp Esperarletra
numero: cmpa #'#'
bne parabre
ldx #COD_numero
jsr EnviarCadena
jmp Esperarletra
parabre: cmpa #'('
bne parcierra
ldx #COD_parabre
jsr EnviarCadena
jmp Esperarletra
parcierra:
cmpa #')'
bne corcheteabre
ldx #COD_parcierra
jsr EnviarCadena
jmp Esperarletra
corcheteabre:
cmpa #'['
bne corchetecierra
ldx #COD_corcheteabre
jsr EnviarCadena
jmp Esperarletra
corchetecierra: cmpa #']'
bne porcentaje
ldx #COD_corchetecierra
jsr EnviarCadena
jmp Esperarletra
porcentaje:
cmpa #'%'
bne dolar
ldx #COD_porcentaje
jsr EnviarCadena
jmp Esperarletra
dolar: cmpa #'$'
bne arroba
ldx #COD_dolar
jsr EnviarCadena
jmp Esperarletra
arroba: cmpa #'@'
bne subraya
ldx #COD_arroba
jsr EnviarCadena
jmp Esperarletra
subraya: cmpa #'_'
bne andpers
ldx #COD_subraya
jsr EnviarCadena
jmp Esperarletra
andpers: cmpa #'&'
bne virgulilla
ldx #COD_and
jsr EnviarCadena
jmp Esperarletra
virgulilla:
cmpa #'~'
bne qmay
ldx #COD_virgulilla
jsr EnviarCadena
jmp Esperarletra
qmay: cmpa #'Q'
bne zmay
ldx #COD_qmay
jsr EnviarCadena
jmp Esperarletra
zmay: cmpa #'Z'
bne jmay
ldx #COD_zmay
jsr EnviarCadena
jmp Esperarletra
jmay: cmpa #'J'
bne cuatro
83
cuatro:
amaytil
kmay:
emaytil:
comilla
ldx #COD_jmay
jsr EnviarCadena
jmp Esperarletra
cmpa #'4'
bne amaytil
ldx #COD_cuatro
jsr EnviarCadena
jmp Esperarletra
cmpa #'Á'
bne kmay
ldx #COD_amaytil
jsr EnviarCadena
jmp Esperarletra
cmpa #'K'
bne emaytil
ldx #COD_kmay
jsr EnviarCadena
jmp Esperarletra
cmpa #'É'
bne comilla
ldx #COD_emaytil
jsr EnviarCadena
jmp Esperarletra
cmpa #"'"
bne SALIDA
ldx #COD_comilla
jsr EnviarCadena
jmp Esperarletra
SALIDA
bne
PrimerBit
jsr Esperarbit
cmpa #'1'
bne c0
jmp c1
c0:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00
jmp c01
c00:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c000
jmp c001
c000: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000
jmp c0001
c0000: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00000
jmp c00001
c00000: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c000000
jmp c000001
c000000:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000000
jmp c0000001
c0000000:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00000000
jmp c00000001
c00000000:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c000000000
jmp c000000001
cmpa #SALIR
Esperarletra2
PCX1
ldaa $1000
eora #$40
staa $1000
jmp
Inicio
Esperarletra2
ldx #COD_ESPACIO
jsr EnviarCadena
jmp Esperarletra
;
********************************************
*
;
DECODIFICACION
;
********************************************
*
Decodificacion
ldaa $1000
eora #$40
staa $1000
84
c000000000:
ldaa #13
jsr EnviarByte
ldaa #10
jsr EnviarByte
jmp PrimerBit
c1:
cmpa #'1'
bne c0010
ldaa #'r'
jsr EnviarByte
jmp PrimerBit
c0010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
beq c00101
ldaa #'m'
jsr EnviarByte
jmp PrimerBit
c00101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c001010
jmp c001011
c001010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0010100
ldaa #'.'
jsr EnviarByte
jmp PrimerBit
c0010100:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c00101001
ldaa #'"'
jsr EnviarByte
jmp PrimerBit
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10
jmp c11
c10:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c100
jmp c101
c100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1000
ldaa #'o'
jsr EnviarByte
jmp PrimerBit
c1000: ldaa #'n'
jsr EnviarByte
jmp PrimerBit
c01:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c010
jmp c011
c010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0100
ldaa #'s'
jsr EnviarByte
jmp PrimerBit
c0100: ldaa #'i'
jsr EnviarByte
jmp PrimerBit
c001:
c00101001:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c001010010
jmp c001010011
c001010010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0010100100
ldaa #'P'
jsr EnviarByte
jmp PrimerBit
c0010100100: ldaa #':'
jsr EnviarByte
jmp PrimerBit
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
c001010011:
ldaa #ACK
jsr EnviarByte
85
jsr Esperarbit
cmpa #'1'
bne c0010100110
jmp c0010100111
c0010100110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00101001100
ldaa #'w'
jsr EnviarByte
jmp PrimerBit
c00101001100: ldaa #'D'
jsr EnviarByte
jmp PrimerBit
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000000010
ldaa #'0'
jsr EnviarByte
jmp PrimerBit
c0000000010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00000000100
ldaa #'5'
jsr EnviarByte
jmp PrimerBit
c0001: ldaa #'l'
jsr EnviarByte
jmp PrimerBit
c00001: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c000010
jmp c000011
c00000000100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
beq c000000001001
ldaa #'V'
jsr EnviarByte
jmp PrimerBit
c000000001001: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000000010010
ldaa #'J'
jsr EnviarByte
jmp PrimerBit
c0000000010010:
ldaa #'4'
jsr EnviarByte
jmp PrimerBit
c000010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000100
ldaa #'ó'
jsr EnviarByte
jmp PrimerBit
c0000100: ldaa #'h'
jsr EnviarByte
jmp PrimerBit
c000001:
ldaa #','
jsr EnviarByte
jmp PrimerBit
c0000001:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00000010
ldaa #'á'
jsr EnviarByte
jmp PrimerBit
c00000010:
ldaa #'j'
jsr EnviarByte
jmp PrimerBit
c00000001:
ldaa #'z'
jsr EnviarByte
jmp PrimerBit
c000000001:
c011:
ldaa #'e'
jsr EnviarByte
jmp PrimerBit
c000011:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000110
ldaa #'f'
jsr EnviarByte
jmp PrimerBit
c0000110:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00001100
jmp c00001101
c00001100:
ldaa #ACK
jsr EnviarByte
ldaa #ACK
86
jsr Esperarbit
cmpa #'1'
bne c000011000
ldaa #'L'
jsr EnviarByte
jmp PrimerBit
c000011000:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000110000
ldaa #'A'
jsr EnviarByte
jmp PrimerBit
c0000110000: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c00001100001
ldaa #'O'
jsr EnviarByte
jmp PrimerBit
c00001100001: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c000011000010
ldaa #'3'
jsr EnviarByte
jmp PrimerBit
c000011000010: ldaa #'/'
jsr EnviarByte
jmp PrimerBit
jsr EnviarByte
jmp PrimerBit
c00001101000: ldaa #'I'
jsr EnviarByte
jmp PrimerBit
c001011:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0010110
ldaa #'y'
jsr EnviarByte
jmp PrimerBit
c0010110:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c00101101
ldaa #'í'
jsr EnviarByte
jmp PrimerBit
c00101101:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c001011010
jmp c001011011
c001011010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c0010110101
ldaa #'1'
jsr EnviarByte
jmp PrimerBit
c00001101:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c000011010
ldaa #'ñ'
jsr EnviarByte
jmp PrimerBit
c000011010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0000110100
ldaa #'C'
jsr EnviarByte
jmp PrimerBit
c0000110100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00001101000
ldaa #'H'
c0010110101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00101101010
ldaa #'2'
jsr EnviarByte
jmp PrimerBit
c00101101010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c001011010101
ldaa #'F'
jsr EnviarByte
jmp PrimerBit
c001011010101: ldaa #ACK
87
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0010110101010
ldaa #'Z'
jsr EnviarByte
jmp PrimerBit
c0010110101010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c00101101010101
ldaa #'Á'
jsr EnviarByte
jmp PrimerBit
c00101101010101:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c001011010101010
ldaa #'K'
jsr EnviarByte
jmp PrimerBit
c001011010101010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0010110101010100
ldaa #'É'
jsr EnviarByte
jmp PrimerBit
c0010110101010100:
ldaa #"'"
jsr EnviarByte
jmp PrimerBit
c0010100111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00101001110
ldaa #';'
jsr EnviarByte
jmp PrimerBit
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c0010110110
ldaa #'ú'
jsr EnviarByte
jmp PrimerBit
c0010110110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c00101101100
ldaa #'B'
jsr EnviarByte
jmp PrimerBit
c00101101100: ldaa #'T'
jsr EnviarByte
jmp PrimerBit
c11:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c111
ldaa #' '
jsr EnviarByte
jmp PrimerBit
c111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1110
ldaa #'a'
jsr EnviarByte
jmp PrimerBit
c1110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c11100
ldaa #'d'
jsr EnviarByte
jmp PrimerBit
c11100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c111000
ldaa #'p'
jsr EnviarByte
jmp PrimerBit
c111000:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1110000
ldaa #'b'
c00101001110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c001010011100
ldaa #'7'
jsr EnviarByte
jmp PrimerBit
c001010011100: ldaa #'8'
jsr EnviarByte
jmp PrimerBit
c001011011:
ldaa #ACK
88
jsr EnviarByte
jmp PrimerBit
c1110000:
ldaa #'g'
jsr EnviarByte
jmp PrimerBit
bne c101010001
ldaa #'x'
jsr EnviarByte
jmp PrimerBit
c101010001:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010100010
jmp c1010100011
c1010100010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c10101000101
ldaa #'-'
jsr EnviarByte
jmp PrimerBit
c10101000101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101010001010
ldaa #'¿'
jsr EnviarByte
jmp PrimerBit
c101010001010: ldaa #'6'
jsr EnviarByte
jmp PrimerBit
c1010100011: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101000110
jmp c10101000111
c10101000110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101010001100
ldaa #'k'
jsr EnviarByte
jmp PrimerBit
c101010001100: ldaa #'R'
jsr EnviarByte
jmp PrimerBit
c101:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c1011
jmp c1010
c1011: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10110
ldaa #'c'
jsr EnviarByte
jmp PrimerBit
c10110: ldaa #'t'
jsr EnviarByte
jmp PrimerBit
c1010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c10101
ldaa #'u'
jsr EnviarByte
jmp PrimerBit
c10101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101010
jmp c101011
c101010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010100
ldaa #'q'
jsr EnviarByte
jmp PrimerBit
c1010100:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101000
jmp c10101001
c10101000:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
c10101000111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101010001110
ldaa #'Y'
jsr EnviarByte
jmp PrimerBit
c101010001110: ldaa #'?'
89
jsr EnviarByte
jmp PrimerBit
c1010110:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c10101101
jmp c10101100
c10101101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011010
ldaa #'E'
jsr EnviarByte
jmp PrimerBit
c101011010:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c1010110101
ldaa #9
jsr EnviarByte
jmp PrimerBit
c1010110101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101101010
ldaa #'N'
jsr EnviarByte
jmp PrimerBit
c10101101010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011010100
ldaa #'G'
jsr EnviarByte
jmp PrimerBit
c101011010100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110101000
ldaa #'W'
jsr EnviarByte
jmp PrimerBit
c1010110101000:
ldaa #'X'
jsr EnviarByte
jmp PrimerBit
c10101100:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011000
jmp c101011001
c101011000: ldaa #ACK
c10101001:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c101010011
ldaa #'é'
jsr EnviarByte
jmp PrimerBit
c101010011:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c1010100111
ldaa #'M'
jsr EnviarByte
jmp PrimerBit
c1010100111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101001110
ldaa #'9'
jsr EnviarByte
jmp PrimerBit
c10101001110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c101010011101
ldaa #'U'
jsr EnviarByte
jmp PrimerBit
c101010011101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010100111010
ldaa #'~'
jsr EnviarByte
jmp PrimerBit
c1010100111010:
ldaa #'Q'
jsr EnviarByte
jmp PrimerBit
c101011:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110
ldaa #'v'
jsr EnviarByte
jmp PrimerBit
90
jsr EnviarByte
jsr Esperarbit
cmpa #'0'
bne c1010110001
ldaa #'S'
jsr EnviarByte
jmp PrimerBit
c1010110001: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101100010
jmp c10101100011
c10101100010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011000100
jmp c101011000101
c101011000100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110001000
ldaa #')'
jsr EnviarByte
jmp PrimerBit
c1010110001000:
ldaa #'['
jsr EnviarByte
jmp PrimerBit
c10101100011: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011000110
jmp c101011000111
c101011000110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110001100
ldaa #'$'
jsr EnviarByte
jmp PrimerBit
c1010110001100:
ldaa #'@'
jsr EnviarByte
jmp PrimerBit
c1010110001010:
ldaa #'%'
jsr EnviarByte
jmp PrimerBit
c101011000111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110001110
ldaa #'_'
jsr EnviarByte
jmp PrimerBit
c1010110001110:
ldaa #'&'
jsr EnviarByte
jmp PrimerBit
c101011001:
ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110010
jmp c1010110011
c1010110010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101100100
jmp c10101100101
c10101100100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011001000
jmp c101011001001
c101011001000: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110010000
ldaa #'\'
jsr EnviarByte
jmp PrimerBit
c1010110010000:
ldaa #'Í'
jsr EnviarByte
jmp PrimerBit
c101011001001: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110010010
ldaa #'Ó'
jsr EnviarByte
jmp PrimerBit
c1010110010010:
ldaa #'Ú'
jsr EnviarByte
jmp PrimerBit
c101011000101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110001010
ldaa #']'
jsr EnviarByte
jmp PrimerBit
91
c10101100101: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011001010
jmp c101011001011
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110011010
ldaa #'+'
jsr EnviarByte
jmp PrimerBit
c1010110011010:
ldaa #'*'
jsr EnviarByte
jmp PrimerBit
c101011001010: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110010100
ldaa #'Ñ'
jsr EnviarByte
jmp PrimerBit
c1010110010100:
ldaa #'ü'
jsr EnviarByte
jmp PrimerBit
c10101100111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011001110
jmp c101011001111
c101011001110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110011100
ldaa #'<'
jsr EnviarByte
jmp PrimerBit
c1010110011100:
ldaa #'>'
jsr EnviarByte
jmp PrimerBit
c101011001011: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110010110
ldaa #'Ü'
jsr EnviarByte
jmp PrimerBit
c1010110010110:
ldaa #'i'
jsr EnviarByte
jmp PrimerBit
c101011001111: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110011110
ldaa #'#'
jsr EnviarByte
jmp PrimerBit
c1010110011110:
ldaa #'('
jsr EnviarByte
jmp PrimerBit
c1010110011: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c10101100110
jmp c10101100111
c10101100110: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c101011001100
jmp c101011001101
c101011001100: ldaa #ACK
jsr EnviarByte
jsr Esperarbit
cmpa #'1'
bne c1010110011000
ldaa #'!'
jsr EnviarByte
jmp PrimerBit
c1010110011000:
ldaa #'='
jsr EnviarByte
jmp PrimerBit
;*********Procedimientos*********
EnviarByte
; Transmite un byte, contenido en el registro A,
al PC via el SCI.
SB1
ldab scsr;espera que el registro de
transmision de datos esté vacio empty (TDRE)
bpl SB1
staa scdr ;envia byte
rts
EnviarCadena
;X contiene la direccion inicial de la cadena
c101011001101: ldaa #ACK
92
RV1
COD_d
fcc
'11101'
fcb
$ff
cmpa #$FF
beq RVX
jsr EnviarByte
inx
jmp RV1
COD_c
fcc
'10111'
fcb
$ff
COD_t
fcc
'10110'
fcb
$ff
rts
COD_u
fcc
'10100'
fcb
$ff
COD_m
fcc
'00100'
fcb
$ff
COD_p
fcc
'111001'
fcb
$ff
ldaa 0,X
;$FF denota el final de la
cadena
RVX
Esperarbit
ldaa
PENDIENTE
;commands
received via SCI interrupt
cmpa #VERDADERO
bne
Esperarbit
clr PENDIENTE
ldaa COMANDO
COD_coma
'000001'
cmpa #SALIR
bne Retornar
ldaa $1000
eora #$40
staa $1000
pula
pula
ldx #Inicio
pshx
fcc
fcb
Retornar
COD_b
fcc
'1110001'
fcb
$ff
COD_g
fcc
'1110000'
fcb
$ff
COD_v
fcc
'1010111'
fcb
$ff
COD_q
fcc
'1010101'
fcb
$ff
COD_y
fcc
'0010111'
fcb
$ff
rts
;*********** Tabla de Codificacion *********
COD_ESPACIO
fcc
COD_e
fcc
COD_a
fcc
COD_o
COD_n
COD_s
fcc
fcc
fcc
'110'
fcb
'011'
fcb
'1111'
fcb
'1001'
fcb
'1000'
fcb
'0101'
fcb
$ff
$ff
COD_punto
'0010101'
$ff
fcc
fcb
COD_r
COD_l
fcc
fcc
fcc
$ff
$ff
COD_f
fcc
$ff
COD_otil
'0000101'
$ff
'0000111'
fcb
$ff
fcc
fcb
COD_i
$ff
'0100'
fcb
$ff
COD_h
'0011'
fcb
$ff
COD_itil
'00101100'
'0001'
fcb
$ff
fcc
'0000100'
fcb
$ff
fcc
fcb
93
$ff
$ff
COD_comillas
'10101000'
fcc
fcb
COD_pmay
'0010100101'
$ff
fcc
fcb
COD_atil
'00000011'
fcb
COD_dospuntos
'0010100100'
$ff
fcc
fcb
COD_j
COD_z
fcc
fcc
COD_emay
'101011011'
'00000010'
fcb
$ff
COD_smay
'1010110000'
COD_util
'0010110111'
fcb
COD_menos
'10101000100'
fcb
COD_bmay
'00101101101'
fcb
COD_tmay
'00101101100'
$ff
fcc
$ff
fcb
COD_dos
'00101101011'
$ff
fcc
$ff
fcb
COD_puntoycoma
'00101001111'
$ff
fcc
$ff
COD_w
$ff
fcc
$ff
fcc
$ff
fcc
$ff
fcc
$ff
fcc
$ff
fcc
fcb
$ff
fcb
$ff
fcc
'00101001101'
fcb
COD_uno
'0010110100'
COD_nueve
'10101001111'
fcc
fcb
$ff
fcc
fcb
fcc
fcb
COD_mmay
'1010100110'
fcc
COD_nmay
'10101101011'
fcc
fcb
$ff
$ff
fcc
fcb
COD_tabular
'1010110100'
COD_cero
'0000000011'
'101010000'
fcb
$ff
fcb
COD_NL_LF
'000000000'
fcc
fcb
fcc
$ff
$ff
fcc
fcb
COD_lmay
'000011001'
COD_amay
'0000110001'
fcb
fcb
$ff
fcc
fcb
fcc
COD_etil
'101010010'
COD_n2
'000011011'
COD_cmay
'0000110101'
'00000001'
fcb
$ff
fcb
COD_x
$ff
fcc
$ff
fcc
fcb
COD_dmay
'00101001100'
$ff
fcc
fcb
94
$ff
COD_hmay
'00001101001'
COD_imay
'00001101000'
fcc
COD_xmay
'1010110101000'
fcc
COD_backslash
'1010110010001'
COD_imaytil
'1010110010000'
$ff
COD_omaytil
'1010110010011'
$ff
$ff
COD_n2may
'1010110010101'
$ff
fcb
COD_udir
'1010110010100'
$ff
fcb
COD_udirmay
'1010110010111'
$ff
fcb
COD_admirabre
'1010110010110'
$ff
$ff
fcc
fcb
95
$ff
fcc
fcb
fcc
$ff
fcc
fcb
fcc
$ff
fcc
fcb
fcc
$ff
fcc
fcb
fcc
$ff
fcc
fcb
COD_umaytil
'1010110010010'
$ff
fcc
fcb
fcc
fcb
fcc
fcb
fcc
fcb
$ff
$ff
fcc
fcb
$ff
$ff
'101010001101'
fcb
$ff
fcb
COD_siete
'001010011101'
COD_wmay
'1010110101001'
fcb
fcc
$ff
$ff
fcc
fcb
$ff
fcc
fcb
COD_umay
'101010011100'
COD_fmay
'001011010100'
COD_vmay
'000000001000'
fcc
fcb
COD_seis
'101010001010'
fcc
fcb
COD_gmay
'101011010101'
$ff
$ff
fcc
fcb
COD_pregabre
'101010001011'
COD_slash
'000011000010'
fcb
COD_cinco
'00000000101'
COD_pregcierra
'101010001110'
fcc
$ff
fcc
fcb
COD_ymay
'101010001111'
COD_tres
'000011000011'
fcb
COD_omay
'00001100000'
$ff
$ff
fcc
fcb
COD_rmay
'101010001100'
fcc
fcb
fcb
COD_k
COD_ocho
'001010011100'
fcc
$ff
COD_admircierra
'1010110011001'
fcc
fcb
COD_igual
'1010110011000'
COD_menor
'1010110011101'
COD_corcheteabre
'1010110001000'
COD_zmay
'0010110101011'
$ff
$ff
$ff
$ff
$ff
COD_corchetecierra
'1010110001011'
$ff
fcb
COD_comilla
'0010110101010100'
$ff
fcb
;**********Rutina
de
interrupciones***********
atencion
$ff
fcc
fcb
a
; SCI Input Interrupt Handler
; Recibe bytes del SCI. Activa la bandera
COMANDO_PENDIENTE.
SerInputInt
COD_arroba
'1010110001100'
$ff
$ff
fcc
fcb
$ff
fcc
fcb
fcc
$ff
fcc
fcb
fcc
$ff
fcc
fcb
COD_emaytil
'0010110101010101'
$ff
fcc
fcb
COD_kmay
'001011010101011'
$ff
fcc
fcb
COD_amaytil
'00101101010100'
$ff
fcc
fcb
COD_cuatro
'0000000010010'
$ff
fcc
fcb
COD_jmay
'0000000010011'
$ff
fcc
fcb
fcc
fcb
COD_dolar
'1010110001101'
$ff
fcc
fcb
COD_porcentaje
'1010110001010'
COD_qmay
'1010100111010'
$ff
fcc
fcb
fcc
fcb
COD_parcierra
'1010110001001'
$ff
fcc
fcb
COD_parabre
'1010110011110'
COD_virgulilla
'1010100111011'
$ff
fcc
fcb
fcc
fcb
COD_numero
'1010110011111'
$ff
fcc
fcb
COD_mayor
'1010110011100'
COD_and
'1010110001110'
fcc
fcb
fcc
fcb
fcc
fcb
COD_asterisco
'1010110011010'
$ff
fcc
fcb
COD_mas
'1010110011011'
COD_subraya
'1010110001111'
$ff
ldaa
scsr
ldaa
scdr
RDRF
96
;limpia
staa
ldaa
staa
rti
COMANDO
#VERDADERO
PENDIENTE
;*********
Vector
de
reset******************
org
FDB
Interrupcion
y
$FFD6
SerInputInt ;vector SCI
org $FFFE
FDB
init ;vector reset
97
ANEXOS
98
Descargar