Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Computer
Architecture:
The MC9S08
Primera Edicin
Septiembre de 2014, V1.3d
Contenido
PRLOGO ........................................................................................................................................................................... 5
ABSTRACT............................................................................................................................................................. 5
INTRODUCCIN ................................................................................................................................................... 6
ARQUITECTURA DEL COMPUTADOR: QU DEBEMOS ESTUDIAR .................................................................. 6
Enfoque ......................................................................................................................................................................... 7
Observaciones sobre algunos trminos empleados ...................................................................................................... 7
INTRODUCCIN ................................................................................................................................................... 8
QU ES UNA INSTRUCCIN ..................................................................................................................................... 8
PRLOGO
CoDiDac, Computador Digital Didctico: In Memoriam.
ABSTRACT
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
INTRODUCCIN
ARQUITECTURA DEL COMPUTADOR: QU DEBEMOS ESTUDIAR
Es bastante conocida mi polmica opinin en relacin al objetivo de nuestro plan de estudios. Para
comenzar, permtaseme incluir una parfrasis:
Qu diramos de un mdico eminente que aplica los ltimos desarrollos de la instrumentacin electrnica para diagnosticar
acertadamente la pltora de pacientes que lo agobia, y que prescribiendo los ms modernos antibiticos de ltima generacin logra
mantener a raya difciles y dolorosas enfermedades; que interviene mediante tcnicas no invasivas a quienes no responden a los
medicamentos apropiadamente, para rescatarlos de la enfermedad y devolverles la salud pero que no tiene sino una superficial
aunque a todas vistas suficiente idea de los increbles principios fsicos que hacen funcionar el scanner y sus conocimientos de la
maravillosa qumica que se sintetiza en las cpsulas no le permitiran dirigir un laboratorio qumico, y que es completamente lego en relacin
al genial concurso que hacen la micromecnica, la ptica y la electrnica, aplicadas a las miniaturas que usa como utensilios quirrgicos?
Casi todos podramos convenir en que es un excelente mdico; sus pacientes lo veneran, los enfermos hacen lo imposible por ser
atendidos por l pero, probablemente de sus manos no salga el prximo CAT ni el tan esperado antibitico final, y tampoco lo
contratarn para disear el Escalpelo del Futuro. No ser un investigador, ni electrnico, ni qumico, ni micro-mecnico. Eso s, est al
tanto de conseguir y emplear las ltimas y ms certeras herramientas que se ofrecen para el ejercicio de su profesin Mdica.
Bueno, subyace aqu un dilema que en realidad parece sencillo: Qu queremos como egresado, un
cientfico, o un Ingeniero? Es claro que el ttulo que concedemos es el de Ingeniero...
Un ingeniero resuelve problemas en la industria (ojal que los de la USB lo hagan en Venezuela),
empleando dispositivos especializados y complejos, como el Core i7 de Intel, por ejemplo, que
cuando lo aplicamos no tenemos sino una muy aproximada idea de cmo est hecho un quadra-core.
Un ingeniero hace eso: aprende a usar la tecnologa como herramienta en su trabajo diario, y s que no
hay muchos de nosotros que pudiramos disear un Core i7 de Intel, ni ello resultara tampoco en gran
beneficio, pues Intel no adolece de profesionales en esa rea y Venezuela no tiene como prioridad
preparar ingenieros para trabajar en Intel
Quiero hacer las siguiente citas:
"A good Scientist is a person with original ideas. A good ENGINEER is a person who
makes a design that works with as few original ideas as possible. There are no prima
donnas in engineering. - Freeman Dyson (Nanotechnology father)" cfr en.wikipedia.org/wiki/Freeman_Dyson
Uno puede estar de acuerdo con esta afirmacin o rechazarla, pero todos debemos convenir en que, s,
es cierto que el mbito de accin de un cientfico no es el mismo que el de un Ingeniero, y que
nuestra carrera es la de Ingeniero Electrnico, no la de cientfico; ni siquiera la de profesor o docente.
Parafraseando a Martin Grimheden, del Royal Institute of Technology, que habla de la legitimidad de la
profesin:
The question of legitimacy is defined as the relation between the actual outcome of the educational efforts
undertaken by the university, and the actual demands that are put on the students abilities by the society and/or
industry at the end of the students education. To simplify: Why teach [electronics]? and What does the industry
want? (Y yo preguntara: qu quiere NUESTRA industria, para empezar...)
El artculo profundiza sobre knowledge and skills (teora y prctica): industries hiring
[electronics] engineers, search for functional skills rather than formal knowledge
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
En nuestro pas, y en Latinoamrica, probablemente tambin sea as. Y, a lo mejor, con los
INGENIEROS, en general, ocurra de la misma manera en todas partes! Solo cuando
pretendemos que los egresados funjan ms bien como Docentes o Investigadores, todo queda
medio al revs. O cuando ignoramos el patrn que para Ingenieros usan tan prestigiosas
instituciones como Stanford y el MIT.
En nuestra profesin NO se puede conocer un poco de todo; hay que saber USAR ese todo.
En 40 aos de ejercicio profesional, y en mi transicin desde profesor hasta el rea de proyectos:
ingeniero, gerente, vicepresidente de R&D, y en el perfil de empleado y de empresario (! y, de nuevo,
a profesor !), en las compaas en las que me desenvolv, contrat o trabaj con ellos a ms de 100
ingenieros, casi todos electrnicos, la mayora de la USB (NB: Cuando la profesora Trina Adrin de Prez hizo
la ltima encuesta externa para cambio de currculum, en mi empresa yo empleaba, simultneamente, 44 ingenieros electrnicos, 40
de la USB) Algo conozco del tema, y mi reales que me ha costado. OBSERVACIN: Yo podra
Como integrador de sistemas, nunca reinvent la rueda, y me fue bastante bien... en Venezuela!
Con lo anterior como premisa, yo abogo por un estudio de la Arquitectura (y los Sistemas
Operativos, y TODO lo que enseamos) orientado hacia la APLICACIN de la tecnologa a
la solucin de problemas. Si alguien quiere disear (micro)procesadores en Intel, se encontrar
con que las plazas ya estn copadas, que ese desarrollo lo hacen cientficos rara vez Ingenieros y
que son como 1,000 especialistas en todo el mundo.
Enfoque
Este libro no estudia cmo disear una computadora, y hace nfasis en cmo estn diseadas, no
en por qu estn diseadas as.
Observaciones sobre algunos trminos empleados
Siendo el Ingls la lingua mater de la investigacin electrnica, resulta en ocasiones difcil elaborar en
esa materia un texto en Castellano que no incurra en anglicismos, y aquellos que lo hacen pueden
terminar en un galimatas. Recuerdo algn impreso que traduca Master Clear como Limpieza
Maestra o, peor, buffer como Memorias Tampn, y flip-flops por bsculas.
Adems, he empleado la primera forma verbal en vez de la tercera, clsica y neutra, porque esto no es
una tesis ni un reporte de investigacin, y puedo darme el lujo de acercarme al lector hablando en
primera persona. El estudiante se abstendr de imitarme hasta que tenga tantos aos como yo.
Ing. Luis G. Uribe C.
Caracas, marzo de 2014.
Captulo
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
INTRODUCCIN
A las computadoras hay que programarlas, o instruirlas para que realicen sus actividades. Entienden,
para ese fin, un idioma propio de cada una de ellas, o Lenguaje de Mquina (Machine Language). El
programador emplea INSTRUCCIONES, compuestas de: a) una Voz Imperativa o COMANDO,
que le indica a la computadora qu operacin hacer en un instante determinado y b) la identificacin de
los operandos que deben participar en la accin.
Desde que estudibamos aritmtica aprendimos que un clculo largo, que inclua una cierta cantidad de
valores (operandos) y distintas operaciones aritmticas sobre ellos, poda descomponerse en una secuencia
ms simple de operaciones que incluyeran, como mximo, dos (2) operandos; as, por ejemplo:
F=A*BC/Dserealizacomo:
T1=A*B;T2=C/DyF=T1T2.
o:F=A*B;T=C/DyF=FT(seempleaunavariabletemporalmenos)
A las operaciones aritmticas elementales se las conoce como binarias, o didicas, porque
emplean dos operandos sobre los cuales actan para producir un (1) resultado. Lo mismo ocurre con
los operadores booleanos. Y aquellos que requieren un solo operando, como -5, o ~B (unarias o
mondicas) son un subconjunto y pueden recomponerse como binarios o didicos as: 0-5 o ~(0|B).
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Una computadora tiene una unidad Lgico Aritmtica (ALU: Arithmetic-Logic Unit) cuyos circuitos
realizan operaciones de suma y resta; otras incluyen multiplicacin y divisin y, las menos, soportan
-adems de nmeros Enteros representacin en punto flotante para nmeros Reales.
Para identificar los Comandos hay que codificarlos. Eso significa que si hubiera, por ejemplo, solo dos
operaciones (dos Comandos), podran representarse con un bit que, estando en 0 designara al primero
de ellos, y si valiera 1 sealara al otro. Si la Unidad de Control debe identificar 250 comandos dentro de
instrucciones (esa es la cantidad que tena el antecesor del HCS08) se necesitaran 8 bits, lo cual resulta
muy conveniente pues 8 son los bits que definen UN Byte, que es la cantidad mnima de bits que se
manipulan de una sola vez en las computadoras modernas.
Cuando tenemos procesadores con una cantidad superior a 256 Comandos (tal es el caso del nuevo
HCS08) podran codificarse con dos (2) bytes pero, como con 16 bits pueden individualizarse 65,536
entidades diferentes, se ve que habra una holgura innecesaria (dado que los computadores actuales no
tienen ms de alrededor de 1,000 y pico de cdigos de operacin, como orden de magnitud).
Entonces se usa un truco que codifica los Comandos ms empleados con un (1) byte, y para el resto usa
dos (2): uno llamado Escape, que advierte al procesador que, a continuacin, viene otro byte que es
el cdigo que en realidad identifica ese comando que por tanto requiere 2 bytes. Esta es la aproximacin
que se usa en el HCS08, y desde luego tambin en Intel.
As que para ver cuntos bits conforman una Instruccin tenemos que, para el Cdigo de Operacin, o
Comando (OpCode), se necesita un (1) byte.
Veamos ahora qu se requiere para codificar los operandos, que residen en la Memoria. La Unidad de
Control debe instruir a la memoria para que le suministre a la ALU cada operando, y para que reciba y
almacene el resultado. La Memoria o unidad de almacenamiento puede caracterizarse como un
dispositivo con dos dimensiones: qu se va a guardar (el Valor de la variable, consideradas ellas en el
sentido que se les atribuye al estudiar algn lenguaje de programacin), y dnde se va a almacenar ese
valor: Valor y Direccin. Sobre el Valor ya nos hacemos una idea de a qu corresponde. En cuanto a
la Direccin, las celdas o posiciones de memoria se numeran normalmente comenzando desde 0, en
incrementos comnmente de a uno, y cada una resulta as identificada mediante ese nmero, que se
conoce como la Direccin de la celda. Cuando decimos que debemos leer una variable (para hacer un
clculo), en lenguajes de programacin solemos identificarla mediante un Nombre, pero a la
computadora hay que sealrsela mediante un nmero, la Direccin sobre la cul la memoria debe
operar para entregarnos dicho Valor. As, una Variable identificada por el programador mediante un
Nombre, desde el punto de vista de la computadora equivale a una Direccin y un Valor.
Entonces, cuntos bits se requieren para identificar el Valor, y la Direccin? Ese nmero no tiene por
qu ser el mismo para ambos casos. Para el Valor, la mayora de los MCUs usan un (1) byte. Mquinas
ms nuevas emplean dos (2) bytes (16 bits), cuatro (4) bytes (32 bits); ahora se van imponiendo ocho
(8) bytes (64 bits) y ya llegarn hasta 16 bytes (128 bits). Ya eso me parece muy improbable.
Ahora, con una mquina comn de 32 bits, si cada dato es un nmero, ste puede representar enteros
hasta2^32=4,294,967,296 o, si llevan signo: de +2,147,483,647a2,147,483,648.
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
En el caso de las Direcciones se necesitan 4 bytes. Si tenemos dos (2) operandos que suministran
valores, y uno (1) para el resultado, y cada uno de ellos precisa cuatro (4) bytes para su identificacin, el
nmero de bytes de una instruccin sera de: 1 (OpCode) + 3 * 4 (Addresses) = trece (13) bytes.
Note que como son tres (3) operandos, a este tipo de computadoras se las conoce como Mquinas de
Tres Direcciones. Hay Instrucciones que tienen menos direcciones, como BORRE (Clear; V=0),
que tiene UNA sola direccin; y HALT, que no tiene ninguna.
MQUINAS DE 3, 2, 1 Y 0 DIRECCIONES
RECE (13) bytes son demasiados. Cada vez que se ejecuta una Instruccin, el CPU necesita
leer todos los bytes que la componen. Para obtener un alto rendimiento se requiere que se lea
la Instruccin con la menor cantidad de pasos posible; ojal UNA sola operacin. Para esto, el
Bus en el que se transfiere la informacin tendra un ancho exagerado, lo que resultara
costoso, adems de oponerse a los espacios pequeos que requieren los dispositivos modernos. Por
tanto, es importante ver cmo pueden eliminarse campos o elementos de la Instruccin. Recuerden
que con la codificacin del Comando hay poco que hacer, segn acabamos de describir.
El primer paso en este sentido se dio haciendo que uno de los 3 operandos de la Instruccin fuera, al
mismo tiempo, fuente de informacin y resultado; algo as como: A=A*B.
Eso, en realidad, elimina un operando (cuatro [4] bytes). Para que el sistema funcione hay que agregar
una instruccin que permita inicializar una variable con el contenido de otra; esta es un MOVE.
F=A*BC/Dserealizaahoracomo:
T=C(MOVETC;unasolaDireccin);T=T/D;F=A(MOVEFA);F=F*B;F=FT
10
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ste ltimo result ser el sistema ms eficiente en relacin a los parmetros referidos al principio, y es el
que ms se usa en la actualidad: Instrucciones de Una Direccin; Mquinas de Acumulador.
Finalmente, se forz la barra y existen Mquinas de Cero Direcciones. Los computadores HP fueron
sus exponentes ms sobresalientes. Una aplicacin muy generalizada de esta aproximacin de Cero
Direcciones la encontramos en la evaluacin automtica de expresiones, principalmente como parte
de los Compiladores. La notacin ms divulgada se conoce como RPN, Reverse Polish Notation.
Los tipos generales de Direcciones: inmediata, directa, indirecta, modo registro, indireccin con
registros, desplazamiento, stack, basadas, segmentadas, deben consultarse en las referencias genricas.
Existe un registro ndice (H:X) de 16 bits, que fundamentalmente sirve como apuntador (pointer,
como en C); es decir, alberga: no el valor de una variable, sino la direccin de esa variable (exactamente
como en C). Se pueden realizar operaciones que mimeticen las equivalentes de alto nivel, tales como:
(*p se refiere al H:X):
*p=Acc;Acc=*p;*p++=Acc;Acc=*p++;p=*p;jump*p;...ysimilares.
Est tambin el Stack Pointer SP de 16 bits, que permite realizar el protocolo para la ejecucin de
Subrutinas o Funciones, as como el de las Interrupciones, y sirve para establecer la existencia de
variables dinmicas, como en el C, que se materializan con la llamada de una funcin y desaparecen a
su finalizacin.
Finalmente se encuentran otros 2 registros de uso ms especfico que los 3 anteriores: el PC o Program
Counter, de 16 bits, que en principio identifica la instruccin que habr de ejecutarse a continuacin,
y el Processor Status Word, cuyo nombre fue cambiado a CCR: Condition Code Register; es de 16
bits y almacena banderas (flags) individuales que identifican el estado del procesador en un instante
dado, y facilitan el control del flujo del programa (saltos condicionales, habilitacin de interrupciones).
El uso en detalle de todos estos elementos del MCU lo veremos ms adelante como parte del anlisis y
desarrollo de la secuencia de programas, objetivo principal de este texto.
El microprocesador HCS08 que se escogi en la USB para incluirlo como elemento de trabajo en sus
laboratorios de electrnica es casi perfecto para estudiar la Arquitectura de las Computadoras, por sus
11
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
enriquecidas caractersticas, casi todas tomadas de las minicomputadoras DEC de los 70s y siguientes.
(Motorola no fue la nica en adoptar tan bella tecnologa de las PDP-11; Intel incluye ms conceptos
an en sus microcomputadores). Ya vimos que, a diferencia de muchos dispositivos similares de sus
competidores, tienen un repertorio de instrucciones poderoso, variado y numeroso (no como las 35
instrucciones de los 16F8Xx). En cuanto a los modos en que emplea las direcciones, hay 17 distintos.
Aqu solo se enumeran; enfquese para su estudio en el Manual de Referencia del CPU: CPU08RM.
El uso en detalle de todos los modos de direccionamiento lo veremos ms adelante como parte del
anlisis y desarrollo de la secuencia de programas que presentaremos.
1) Inherent(noaddresses)
2) Immediate,8bitconstants
3) Immediate,16bitsconstants
4) Direct8bits(ZEROpage)
5) Extended16bits;"NATURAL"addressingmode:ABSOLUTE
6) Indexednooffset
7) Indexed,8bitoffset
8) Indexed,16bitoffset
9) Indexednooffsetwith(Indexregister)postincrement
10) Indexed,8bitoffsetwith(Indexregister)postincrement
11) SP,8bitoffset
12) SP,16bitoffset(noexisteSINoffset)
13) Relative(notforDATA!OnlyforCODEBranches)
MemorytoMemory,MM(Onlyadvanced++):
14) MM:ImmediatetoDirect
15) MM:DirecttoDirect
16) MM:IndexedtoDirect,with(Indexregister)postincrement
17) MM:DirecttoIndexed,with(Indexregister)postincrement
VARIACIONES Y OPTIMIZACIONES
Para optimizar el rendimiento del HCS08, maximizando velocidad y minimizando uso de memoria, se
incluyeron varias excepciones a la arquitectura convencional; primero, en el manejo de la memoria.
Normalmente la memoria de una computadora tipo Von Neumann consiste, como ya indicamos, en
una coleccin de celdas o elementos almacenadores, de informacin y programas, colocados en
Secuencia Lineal. (La unidad de almacenamiento de las mquinas tipo Harvard tiene la particularidad
de que la seccin que podemos usar para guardar datos emplea su propio conjunto de direcciones,
separado del grupo de direcciones de la memoria en la que se guardar el programa. Cada una de ellas
puede verse como un arreglo lineal, pero no estn contiguos el uno junto al otro. Es decir, que si por
ejemplo, se recorre la RAM o memoria de almacenamiento para variables, y se llega hasta el final, la
prxima posicin NO es la del cdigo del programa. En las mquinas tipo von Neumann hay UN solo
12
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
campo de direcciones. Al recorrerse todas las posiciones en secuencia, se habrn visitado tanto las
variables como el programa).
13
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Consola de operador, con teletipo o tlex (Olivetti, Siemens), para el suministro de datos y
programa mediante el teclado, e impresin de resultados en papel. Automatizacin va lector
adjunto de cinta de papel. Tablero para despliegue de informacin interna: registros, direcciones,
instrucciones, botonera para encendido y dems funciones no realizables desde el teletipo.
LAS INSTRUCCIONES
Un modificador cambia las operaciones, de simples a Repetitivas. Una sola instruccin de mquina, como
IM: IMprima, arroja un nico valor, o un Rango de resultados (IR: Imprima Repetitivamente).
EL SUBSISTEMA DE ENTRADA Y SALIDA
Forma parte esencial de la Arquitectura del CPU, con instrucciones especficas, ms poderosas que
el INPUT o PRINT del Basic y superiores al IN y al OUT de los microprocesadores.
CDIGOS DE OPERACIN
Como el aspecto didctico es preeminente, los cdigos tienen una base mnemnica de fcil
comprensin y recordacin: Cuando dos palabras designan un comando, se toma la primera letra
de cada una para conformar dicho cdigo. Por ejemplo, "Acepte Informacin" se codifica como
"AI", y las letras 'A' e 'I' se almacenan en la memoria, en cdigo baudot de 5 bits.
14
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Si el comando tiene una sola voz imperativa, como "SUME", el cdigo se conforma como "SU",
utilizando sus 2 primeras letras.
Si se requiere el modificador de iteracin, se reemplaza la segunda letra por una R: AR es Acepte
informacin de manera Repetitiva (desde, hasta), SR totaliza un rea completa de memoria, etc.
EL EDITOR
Para cargar el programa hay un editor de texto compuesto por circuitos (no es software). Para invocarlo
existe el interruptor "Funcin Programa", y el "Botn de Correccin" para corregir errores tipogrficos.
EL FORMATO DE LOS NMEROS
La mquina es del tipo serial, con lgica secuencial convencional, no microprogramada. Posee
selectores que permiten trabajar a mxima velocidad (600 KHz!) o en animacin lenta para
permitir el seguimiento del flujo de informacin. Tiene un interruptor de paso a paso; uno para
Detener la operacin del programa en cualquier instante, otro para Continuarla, y el Master Reset.
DATOS ESTADSTICOS
Est compuesto por ms de 4.000 circuitos integrados TTL, 300 transistores, 200 tarjetas de
circuito impreso; 160.000 puntos de soldadura, 155.000 agujeros perforados con taladro de mano;
16.000 cablecitos de alambre telefnico (2.500 metros) y ms de 5 kilos de soldadura de estao.
Diez fuentes de alimentacin, de 5 Voltios a 10 amperios, ms fuentecitas variadas para manejar las
luces de nen, el teleimpresor, etc., alojadas en un gabinete independiente. Dos disipadores principales
tienen como 1,70 metros de altura c/u. El consumo est por encima de los 3 kilovatios y para controlar
la generacin de calor hay una pequea turbina elctrica que fuerza la circulacin de aire en el gabinete
principal, as como un poderoso ventilador situado en la base del gabinete de alimentacin.
CIRCUITOS IMPRESOS
En los primeros dibujos para obtener los negativos fotogrficos se emplearon "rapidgrafos"; luego se
usaron cintas adhesivas, como pistas, y ojetes para las perforaciones.
15
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
FOTOS
1) VISTA GENERAL
A la izquierda se ve la consola formada por la mesa, el teclado y el impresor (tlex o teletipo) al
que se le alcanza a ver el rollo de papel de impresin y el perforador de cinta de papel, adosado al
lado izquierdo. Adems, el lector de papel. A la derecha se observa el panel de control (botonera)
y despliegue de informacin (luces).
El gabinete principal es el que est a la derecha, con 4 racks (se ven dos, uno arriba del otro). En el
de abajo alcanza a verse la memoria de ncleos magnticos de ferrita.
El tercer gabinete, pequeo, situado entre los otros dos, alberga las fuentes de alimentacin.
16
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
17
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
3) ACERCAMIENTO
En esta foto no aparece el lector de cinta de papel.
18
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
19
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
5) PRESENTACIN
Le enseo el proyecto a mi padre, y a mi hermano que es el fotgrafo.
20
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
21
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
22
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
23
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Resaltan los sensores remotos (cinco y cinco, en acrlico blanco) que leen a distancia el valor de las
10 alimentaciones y los llevan hasta los reguladores. As se garantizan el valor de los voltajes en el
destino, a pesar de la considerable separacin entre el gabinete de las fuentes y el de la electrnica.
24
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
25
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
26
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
27
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
28
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
29
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
30
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
31
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
32
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
33
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
34
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
35
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
36
Captulo
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ASSEMBLER HCS08
"Perfection is finally attained, not when there is no longer
ARA comprender los aspectos ms importantes de una computadora es imprescindible dar una
mirada a la manera como el programador le transmite lo que ella debe hacer, cmo se la
programa en forma nativa: su Conjunto de Instrucciones, cmo direcciona la memoria, cmo
usa el Stack, qu recursos tiene, tales como registros ndice, Stack. En nuestro empeo por
apoyarnos en el MC9S08QE128 de Freescale instalado en la tarjeta de desarrollo DEMOQE128,
hemos elaborado una serie de programas ilustrativos que presentamos a continuacin.
Estos ejercicios se dividen en 4: Introductorios; referentes a Timers, en donde explico la librera que
suministro siempre con mis cursos, para estudiarla y usarla; Comunicaciones con el PC, usando el SCI
(RS-232); aqu tambin analizamos una librera que desarroll para mis cursos, la estudiamos con detalle
y tambin debemos poder usarla en nuestros ejercicios y proyectos. Finalmente, ejercicios varios.
1) Primer Programa para el HCS08: MINIMUM Program for HCS08
Este es el programa ms pequeo que puede escribirse en el ambiente de desarrollo
CodeWarrior(laversinqueusoenlaactualidades:CodeWarrior10.5.TienesusBugs,
algunos reportados por m [enero de 2014], sin corregir, pero es lo que hay... NB:
MUCHOSambientesdedesarrollo,enelreadeMCUs,sondeJUGUETE)
Elobjetivodeesteprogramaesverificarquesuinstalacindelambientededesarrollo
funciona,ylosmnimosaspectosquedebeincluirensusprogramas.
["Laboratorios\Lab1\00a_L1.asm"]
01;********************************************************************
02;00a_L1.asm,MINIMUMProgramforHCS08,Rev.F,V08J2012M29E2013
03;LuisG.UribeC.,D27Y2007J09A2009.ForCodeWarrior10.2
04;===================================================================
05;BeginofCodeSection
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
07
08ORG$2080;ORG?Origin.Nextcode(bra)islocated
09;..atthisaddress!
37
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
10;$2080isHCS08ROMStart(Flash)
11;Main:symbolicforaddress$2080(bra)
12Main:bra*;Branchtohimself(BRA:BranchAlways;*:here!)
13
14;
15nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
16;This'nop'MAYberemovedforCW6.3...
17;********************************************************************
18;InterruptVectors
19
20ORG$FFFE;VECTORholdingaddressforHCS08startup
21DC.W$2080;...(RESET)DC.W:DefineCONSTANTWord
22END;ENDandnextlines,removedbyAssembler
23
24Note:NothingisreadafterEND...(cfr.'main.dbg')
COMENTARIOS a ["Laboratorios\Lab1\00a_L1.asm"]:
LaFORMAylaPRESENTACINdelCdigoennuestrareadetrabajooencualquierotra,
esFUNDAMENTALparalavidadelosproyectos.Losprogramasdebenpoderentenderse,por
quien los hace, cuando vuelva a mirarlos, y por las personas que vengan despus a
modificarlosorepararlos.
Paraesoserequierencomentariostiles,resaltantesyclaros.
Lo primero que hay que incluir siempre, en un programa, es el nombre del mismo, la
fecha o fechas en los que se hizo, o modific el programa. En este libro empleo
abreviaturasycomolasvariacioneshansidocosmticascasinuncalasrelaciono:
01;********************************************************************
02;00a_L1.asm,MINIMUMProgramforHCS08,Rev.F,V08J2012M29E2013
03;LuisG.UribeC.,D27Y2007J09A2009.ForCodeWarrior10.2
Enlaprimeralnea:
;00a_L1.asm,MINIMUMProgramforHCS08,Rev.F,
EsteprogramasecomenzelDomingo27demaYode2007;eljueves09deAbrilde2009
se lo adapt al CodeWarrior 10.2 (ahora se sabe que funciona bien bajo la versin
10.5).Luego,elviernes08deJuniode2012selehizoalgunamodificacincosmtica
(porquenohaymayorreporte),ylaltimaedicinfueelmartes29deEnerode2013,
haceyaunao.
Ntese tambin la columna casi perfecta donde comienzan los comentarios. En Assembly
Languageserecomiendaqueel";"quemarcaelcomienzodeloscomentariossecoloque
EN la columna 32. A veces esto no es factible y hay que moverla, hacia atrs o
38
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
adelante,peroengeneraldebeutilizarseesaregla.SUSPROGRAMASTIENENQUEHACERSE
SIGUIENDOESTEYTODOSLOSLINEAMIENTOS.
Cuandounprogramasevaaejecutar(o,comotodoelmundodice,sevaaCORRER),hay
que indicarle al CPU dnde comienza el cdigo. Cada procesador tiene su propio
protocolo para esto. Por ejemplo, cuando se energizan los procesadores Intel, el PC
(ProgramCounter)asumeelvalor0xFFFF,paralosmicrosde16bits,y0xFFFFFFFFpara
losde32bits,comopartedeladefinicindesuEstadoInicial(unvalorde0x0000,
puros ceros, o 0xFFFF, puros unos, son cmodos de lograr, mediante las lneas
apropiadasdelosregistroscorrespondientes:ClearoPreset,respectivamente).Deesa
direccintomaelCPULAPRIMERAINSTRUCCINquehadeejecutarse.Comoesaubicacin
corresponde a la ltima posicin de la memoria, seguramente que all tiene el
programadorquecolocarunJUMPhaciasuverdaderaprimerainstruccin.
(Cmopuedecolocarseunainstruccinenlamemoria,sirecinseestenergizandola
mquina,yelestadoinicialdelaRAMesnormalmenteindeterminado,formapartedela
solucin al problema denominado IPL: Initial Program Loader. Revise en la literatura
delcursoenquconsisteconexactitudeseproblema,yculessonlassoluciones.Una
de ella consiste en que en la parte superior de la memoria de trabajo, voltil, se
coloca una ROM, o memoria de slo lectura, que contiene su programa, o un cdigo
destinadoabuscarsuprogramaylocalizarloenunsitioadecuado)
EnelHCS08,ustedtienequedecidirdndevaacolocarlaprimerainstruccindesu
programa.Esosehaceas:
SeleindicaalCodeWarriorquelaprimeradireccindesuprogramaes'Main'(tiene
queestarsegurodequeesasealaetiquetaapropiadadentrodesucdigo)
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
08ORG$2080;ORG?Origin.Nextcode(bra)islocated
ORG,porOrigin,leindicaalprogramaAssemblerqueelcdigoqueacontinuacinusted
vaaescribir,debecolocarlodemanerasecuencialapartirdeladireccinindicada;
$2080ennuestrocaso(queparaelHC9S08QE128queempleamos,eslaPRIMERAdireccin
de la memoria FLASH, que es su almacenamiento no voltil. Para una identificacin
precisadelasreasocupadasporlaRAMylaFlash,remtasealmanualMC9S08QE128RM
(ReferenceManual)
Luego,elprogramadortienequecolocarsu'Main'(ustedescogeasugustoelnombre;
notienequeserMain,siemprequeuseelmismoentodasaquellaspartesenlasqueyo
loincluenesteejemplo...)
11;Main:symbolicforaddress$2080(bra)
12Main:bra*;Branchtohimself(BRA:BranchAlways;*:here!)
Note que se enfatiza en que el smbolo mnemnico, alfabtico, 'Main', tiene una
equivalencia con el nmero $2080. Usted emplea 'Main'; el CPU usa $2080 (16 BITS EN
BINARIO,QUEESLONICOQUELASCOMPUTADORASENTIENDEN!)
Ahoraobservelalnea15;sehacolocadoeseNOPporqueserequiereenlasversiones
10.x(almenoshastala10.5;NOeranecesarioenlaversin6.xynorecuerdohaberlo
usadoenversionesanteriores,lasquecomencausarporallporla3.x,haceeones)
15nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
16;This'nop'MAYberemovedforCW6.3...
39
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Siestalneaseomite,elDebuggerproduceunerroraltratardeejecutarel'bra*'
(saltoinfinitoasmismo)delalnea12.EstoesunerrordelCodeWarrioractual.
Finalmentevienen losInterrupt Vectors de la lnea 20. Resulta que, a diferencia de
Intelque,comoyadijimos,inicializasusPCparaleerLAPRIMERAINSTRUCCINdesu
programaSIEMPREdesdelaltimadireccindememoria,elMotorola/Freescaleinicializa
tambinsuPChacialaltimadireccinWORD(16bits)delaFlash(16bitsqueocupan
$FFFE y $FFFF), PERO ALL LO QUE ESPERA encontrar es LA "DIRECCIN" DE LA PRIMERA
INSTRUCCINDESUPROGRAMA.Elmecanismoqueseempleaparaestablecerestevnculose
formadelasiguientemanera:
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
08ORG$2080;ORG?Origin.Nextcode(bra)islocated
...
12Main:bra*;Branchtohimself(BRA:BranchAlways;*:here!)
...
20ORG$FFFE;VECTORholdingaddressforHCS08startup
21DC.W$2080;...(RESET)DC.W:DefineCONSTANTWord
En06usteddefinelaEtiqueta(Main)enlaquevaacomenzarsuprograma,eindicaen
qu posicin (vlida) de Flash la va a colocar (el resto de su cdigo va a
continuacin!);luegoenla12estsu'Main'y,enla20ysiguientesseculminael
vnculo: cuando el PC asume su valor inicial, $FFFF, el CPU, que est en la fase de
inicializacin, usa ese PC para cargar un valor de 16 bits, que corresponde a la
direccindesuprimerainstruccin.Reemplazasu$FFFFporloqueestalmacenadoall
(elnmero$2080enelejemplo)ydeesaposicintomalaprimerainstruccinquevaa
ejecutar,deSUprograma.
Al espacio en donde se colocan los valores de arranque (o RESET), y otros que luego
estudiaremos, se loconoce comoel rea de Vectores de Interrupcin. Comienzan en la
LTIMA posicin de memoria, y va creciendo HACIA ABAJO, de a dos posiciones, porque
cadaelementodeinformacinallalmacenadocorrespondeadirecciones(dearranque,o
derutinasdeinterrupcin:ISR),ylasdireccionessiempretienen16bits.
TodoprogramafinalizaconunEND:
22END;ENDandnextlines,removedbyAssembler
24Note:NothingisreadafterEND...(cfr.'main.dbg')
Se ha incluido ex professo la lnea 24, con texto comn y corriente, para enfatizar
que,despusdelENDdelprogramaprincipal,elEnsambladorNOleeabsolutamentenada
ms.Puedeusarse,portanto,esareaparaincluirtextocualquiera,comocomentarios.
TengaCUIDADO:AlgunosensambladoressuspendenelanlisiscuandoencuentranCUALQUIER
END. A veces, si a un INCLUDE FILE, similar al que ya conoce del C, se le coloca
inadvertidamente un END, el programa queda procesado hasta all, y con mucha
probabilidadesonoesloqueelprogramadordesea...
2) Segundo Programa para el HCS08: Init COP & STACK
Hay un cdigo mnimo que SIEMPRE debe incluir en sus programas, y se indica a
continuacin:
40
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
["Laboratorios\Lab1\00c_L1.asm"]
01;********************************************************************
02;00c_L1.asm,MINIMUMProgramforHCS08,V08J2012
03;LuisG.UribeC.,J09A2009.ForCodeWarrior10.2
04;===================================================================
05;BeginofCodeSection
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
07
08ORG$2080;HCS08ROMStart(Flash)
09;
10;***ALWAYS***includethefollowing4instructions
11
12Main:lda#$42;$42(%0100_0010)?COPE(SOPT1b7)=0($1802)
13sta$1802;(SOPT1Pupinitto$C2=%1100_0010)
14ldhx#$1800;InitStackPointerSP(HCS08)
15txs;$1800?RAMEnd+1.SP=RAMEnd:$17FF
17;
18bra*;Branchtohimself(BRA:BranchAlways;*:here!)
19
20;
21nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
22;This'nop'MAYberemovedforCW6.3...
23;********************************************************************
24;InterruptVectors
25
26ORG$FFFE;"Vector"holdingstartingaddress,
27DC.W$2080;...(RESET)DC.W:DefineCONSTANTWord
28END
COMENTARIOS a ["Laboratorios\Lab1\00c_L1.asm"]:
Cuatrolneassehanaadidoporlassiguientesdosrazones:
PRIMERA: Casi todos los microcontroladores (MCU) incluyen un dispositivo que por
hardwareloinicializan(resetean)sinosehacumplidociertoprotocoloconl;selo
conocecomoel"WatchDog".Supropsitoeselderestaurarlamquina,talcomosise
hubieraactivadolasealdeRESET(osehubieraencendidoelMCUenesemomento).Bien
instrumentado, puede evitar costossimos desplazamientos a reinicializar nuestros
equipos,encasodequeporalgunafluctuacinenlaenergaelctrica,oimpactocon
unrayogammaopartculasalpha,elflujodelprogramatomeunderroteronoprevisto.
EnelMC9S08QE128alWatchDogseloconocecomoCOP:CpuOperatingProperly.Enlos
programas que se cubren en esta publicacin NO se utiliza el COP, pero hay que
DESACTIVARLO porque el MCU lo tiene activo al aplicrsele la energa. Ese es el
propsitodelcdigodelaslneas:
12Main:lda#$42;$42(%0100_0010)?COPE(SOPT1b7)=0($1802)
13sta$1802;(SOPT1Pupinitto$C2=%1100_0010)
SehanincluidovaloresenHexadecimal,peroluegoveremosquehayunmecanismoquenos
permitehacerreferenciasSIMBLICAS,queofrecenmayorclaridadaquiencodificaya
quienluegoquiereentenderelprograma.
41
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
EnelregistroSOPT1(SYSTEMOPTION1,ubicadoenlaposicin$1802)sedeshabilitael
COP: COPE=0: COP Enable=0. Como esta es una mquina de Acumulador, se necesitan dos
instruccionesparahacerelMOVEdeundatoaunavariable:LOADAccumulatorcon#$42y
STOREAccumulatoralaposicin$1802(lneas12y13).
Nteselasangradeunespacioqueheincluidoenlalnea13conrespectoala12.
Sirve para enfatizar que las dos instrucciones fsicas realizan una sola operacin
lgica.Usteddebetratardehacerlomismo.Luegoaprenderemosunmecanismo:MACROs,
que le permiten definir sus propias instrucciones, como MOVE, que reemplazan a la
secuenciadeLDAySTAsealadas.
SEGUNDA razn: Al encender el MCU el Stack Pointer (SP), al igual que el PC, se
inicializaenunvalortilparatodoslosmodelosdeMCUdelasfamiliasHC05yHC08,
algunosdeloscualesquepuedentenermuypequeaRAM.Ennuestrocasonoesas;en
el HC9S08QE128 hay mucha RAM (8064 bytes reporta el Reference Manual), as que el
manufacturanterecomiendainicializarelstack(vaelSP)as:
14ldhx#$1800;InitStackPointerSP(HCS08)
15txs;$1800?RAMEnd+1.SP=RAMEnd:$17FF
Observendenuevolasangra.
Main:DC.B$3F;DefineConstantByte.$3F$80?CLR$80
DC.B$80;$80?DirectAddress
PorsuerteelprogramaAssemblerpermitereferirnosalosOpCodemediantelosSMBOLOS
queelmanufacturantedefiniparaellos(CLRparaBORRARmemoria,etc.),ynotenemos
niqumemorizarsuscdigoshexadecimalesnibuscarentablaslasequivalencias.
Setratadeemplear,alMXIMO,smbolosalfanumricos,losdelasinstrucciones,ya
las variables y ciertas posiciones de cdigo tambin les damos NOMBRES, ojal con
significadoclaroypreciso,talcomosehaceenC.Elobjetivoeseldehacernosms
fcil la composicin, lectura e interpretacin del cdigo, y ese mecanismo pretende
ELEVARELVALORSEMNTICODELLENGUAJE,queyadepors,esbastamteBAJO
Puedeversecompletoestetercerejemploacontinuacin:
42
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
["Laboratorios\Lab1\01a_L1.asm"]
01;********************************************************************
02;01a_L1.asm,MINIMUMHCS08ProgramRev.E,V08J2012>>HEXADECIMAL<<
03;LuisG.UribeC.,D27Y2007J09A2009.ForCodeWarrior10.2L21N2013
04;Minimumaspectsneededtowriteaprogram:
05;1.DefineprogramORG($2080andup)
06;2.Writetheprogram(lookupforeachinstructioncodeinHex)
07;3.DefineRESETAddress(vector$FFFE)
08;NOTE:Lookup"SortedHCS08_ISet2013U.pdf"forOp.Codes
09;===================================================================
10;BeginofCodeSection
11ABSENTRYMain;Exportsymbol(DEBUGGERentry)
12
13ORG$2080;HCS08ROMStart(Flash)
14Main:DC.B$3F;DefineConstantByte.$3F$80?CLR$80
15DC.B$80;$80?DirectAddress
16DC.B$3C;LOOP:$3C,$80?INC$80(directvariable)
17DC.B$80;$80?DirectAddress
18DC.B$20;BRALOOP
19DC.B$FC;$FC?Relativeoffset.BRA*:$202($FE)
20;$FC?4.PCpointstoNOP.PC4is'LOOP'
21;
22nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
23;This'nop'MAYberemovedforCW6.3...
24;********************************************************************
25;InterruptVectors
26ORG$FFFE
27DC.B$20;ResetVectorHIGH
28DC.B$80;ResetVectorLOW(HCS08isBIGENDIAN)
29
30END
31;
32Byteaddressableprocessorsmaybecategorizedasbigendian,
33littleendian,orbiendian.
35AmultibytenumericalvaluestoredwiththeMOSTsignificant
36byteintheLOWESTnumericaladdressisstoredinbigendian
37fashion.
39ThelittleendianstylestorestheMOSTsignificantbyteinthe
40HIGHESTnumericaladdress.IntelmicroprocessorareLITTLEENDIAN.
41
42Abiendianprocessorcanhandlebothstyles(Motorola'sPowerPC).
COMENTARIOS a ["Laboratorios\Lab1\01a_L1.asm"]:
Hay varios documentos en los que pueden encontrar la asociacin entre Comandos y
OpCodes.Porejemplo:
08;NOTE:Lookup"SortedHCS08_ISet2013U.pdf"forOp.Codes
43
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Primerosedefine,comosiempre,laasociacinparaelvectordeRESET:
11ABSENTRYMain;Exportsymbol(DEBUGGERentry)
13ORG$2080;HCS08ROMStart(Flash)
14Main...
14Main:DC.B$3F;DefineConstantByte.$3F$80?CLR$80
15DC.B$80;$80?DirectAddress
16DC.B$3C;LOOP:$3C,$80?INC$80(directvariable)
17DC.B$80;$80?DirectAddress
18DC.B$20;BRALOOP
19DC.B$FC;$FC?Relativeoffset.BRA*:$202($FE)
20;$FC?4.PCpointstoNOP.PC4is'LOOP'
En cuanto a las lneas 18 y 19, que codifican un salto incondicional (BRA: Branch
Always)al"Loop"deIncremento,esinteresantenotarlosiguiente,queesdeusocomn
entrecasitodolosprocesadores:
Pararealizarunsaltoaalgunaposicindecdigodentrodelamemoria,elOpCodees
elquecorresponda,ennuestrocasounBRA,yluegohayqueidentificarlaposicina
lacualsaltar.ComoelprogramaenunamquinadeVonNeumannpuedeestarencualquier
parte de la memoria, se necesita identificar una direccin de 16 bits, en nuestro
micro,quedireccionaenformanatural,64KBytes.Deesamanera,lasinstruccionesde
ramificacin,quemodificanelflujodelprograma,yqueformanunodelosgruposms
usados,tendran3bytes:unoparaelOpCodeydosparaladireccin.
Unaformadeoptimizacinenestamateriaselogramediantelasiguienteobservacin:
la gran mayora de saltos se realizan en la "LOCALIDAD", que es un concepto que
identifica de manera genrica, las posiciones cercanas a la direccin del salto; sus
VECINAS. Y esa localidad es muy numerosa en un rango de 127 posiciones adelante, y
hasta 128 atrs. Lo cual es muy conveniente, ya que esa informacin es la que se
codificamediantebytesconsigno(signedchars).As,selograquelasinstrucciones
de ramificacin que ms se emplean tengan solo DOS bytes: uno para el OpCode, y uno
para el DESPLAZAMIENTO (no se indica a dnde, sino que se sealan cuntas posiciones
adelanteoatrs,medianteunOffset).Desdeluego,hayungrupodeinstruccionesque
permiten saltar a cualquier lado. En esta mquina, los BRANCHES son RELATIVOS, es
decir, emplean Desplazamientos que indican el offset en RELACIN a la instruccin. Y
losJUMPSsonabsolutos,empleandireccionesde16bits.
Lointeresanteeselmecanismoparacalcularladireccinefectiva,destinodelsalto:
Alaposicinactual(registradasiempremedianteelPC),seledebesumarelOffset
consignoparaobtenerasladireccindelaprximainstruccin.
Sedicebienperohaydoscosassutilesqueaclarar.Laprimeraesenrelacinaluso
delPC.Losegundo,vercmolasdirecciones,quesonnmerosSINsigno,sumanbiencon
losOffset,quesonnmerosCONsigno.
44
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
LaoperacindelPC,entodoslosmicrosqueconozco,escomosigue:secomienzaconel
PC apuntando a la prxima instruccin que se va a ejecutar. Cuando se trata de
instruccionesdevariosbytes,comoeselcasodelBRANCH,apuntaalOpCode.Cuandose
comienza a ejecutar la instruccin, en el ciclo de Fetch, el CPU lee, usando la
direccinalmacenadaenelPC,elOpCode,yapuntahaciaelsiguienteelemento.Estolo
hace incrementando el PC. Es decir, para cada lectura se produce la siguiente
secuencia:
InstructionRegister=*PC++;//secargaelOpCodeyseapunta
//..alsiguientebyte:elOffset
*DataBuf=*PC++;//secargaelOffsetyelPC,enestecaso,
//..apuntaalprximobyte:NextOpCode.
Ahora,siladireccindelcomienzodelainstruccinesN,alfinalizarlasecuencia
anteriorelPCalbergaN+2.Asqueunainstruccincomo:BR*,enlaquesedesea
haceruncicloinfinitodesaltosasmismo,elOffsetquehayquecolocares...2.
DeesamaneraelprximoPCserPC=N+22=N,queeraladireccinoriginal.
ESTA ES LA FUENTE DEL ERROR EN EL CODEWARRIOR, para solucionar el cual tuve que
agregarelNOPdelqueyahemoshablado.CuandoseejecutaelBRANCH,elPCapunta
MSALLDELAMEMORIAQUELEHASIDOASIGNADAALPROGRAMA.AllNOhaycdigo,y
el Assembler cree que se ha cometido un error, cuando en realidad no es as. De
hecho,laversin6.3funcionamuybiensineseNOP.
Enrelacinalsegundopunto,unodelosproblemasdelcuestionariopidedemostrarque
aunnmerosinsigno(unadireccin)selepuedesumarunoCONsigno(elOffset),yel
resultado es perfecto: la direccin requerida, adelante o atrs, de la direccin
original.
ESTAPROPIEDADDELOSNMEROSCONSIGNO,CODIFICADOSENCOMPLEMENTOADOS,ESLARAZN
PRIMORDIAL POR LA CUAL SE USA ESTA REPRESENTACIN NUMRICA, y no se emplean el
complementoa1(nimuchomenosotrasmsengorrosas,comoSignoyMagnitud).
Enlapartefinaldelejercicioseejemplificaelordenenqueunainformacinde16
bits(2bytes)deberepresentarseenunamquinaBIGENDIAN,comoeselcasodelHC08:
Yendodesdelasdireccionesinferioreshastalassuperiores(de$FFFEa$FFFF),primero
se coloca el byte de Mayor valor y a continuacin, de ltimo, va el final: la parte
Menos significativa del nmero. La informacin termina (END) en la direccin mayor
(BIG);deaheltrminoBIGENDIAN.
25;InterruptVectors
26ORG$FFFE
27DC.B$20;ResetVectorHIGH
28DC.B$80;ResetVectorLOW(HCS08isBIGENDIAN)
45
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Ademshayalmenosunamaneramsavanzadadehacerloqueesteejercicionosmuestra,
abasedeMACROs,peroesovendrdespus.
["Laboratorios\Lab1\01b_L1.asm"]
01;********************************************************************
02;01b_L1.asmSymbolicProgram(Userdefined)Rev.FV08J2012M29E2013
03;LuisG.UribeC.,J09A2009
04;Aspectosmnimosnecesariosalescribirunprograma:
05;1.Definirposicininicialdelcdigo.$8000up
06;2.Escribirelprograma(buscarcdigoHEXdec/instruccin)
07;HacerSUpropioconjuntodeinstruccionesenSimblico.
08;3.DefinirDireccindeiniciodeejecucinluego
09;deReset(vector$FFFE)
11;
12;ParameterDefinitions(UserdefinedSYMBOLSvia'EQU')
13;Youmaydefinewhateversymbolsyoulike...YourownAssemblyLanguage!
14
15START:EQU$2080
16STARTh:EQU$20
17STARTl:EQU$80
18XCLR:EQU$3F;Instructionclr,tomadadelReferenceManual
19XOP1:EQU$80;Operand(1stvariable)forclrandinc
20XINC:EQU$3C;Instructioninc,delReferenceManual
21XBRA:EQU$20;Instructionbra,delReferenceManual
22XOFF:EQU4;Offsetforinstructionbra
23RESET:EQU$FFFE;VectordeInterrupciones
24
25;===================================================================
26;BeginofCodeSection
27ABSENTRYMain;Exportsymbol(DEBUGGERentry)
28
29ORG$2080;HCS08ROMStart(Flash)
30Main:DC.BXCLR;LaterTRAYTHIS:Stepsome,InsertBREAK
31DC.BXOP1;..POINTinMain.>>RUN<<CWwillstop..
32loop:DC.BXINC;..here.WHY?**BECAUSECOPisENABLED**!
33DC.BXOP1;loop
34DC.BXBRA
35DC.BXOFF
36;
37nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
38;This'nop'MAYberemovedforCW6.3...
39;********************************************************************
40;InterruptVectors
42ORGRESET
44DC.BSTARTh;ResetVectorHIGH
45DC.BSTARTl;ResetVectorLOW(HCS08isBIGENDIAN)
46
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
46
47;NOTE:IfyouremoveALLreferencestoRESET,STARThandSTARTl...
48;theprogramcontinuestobe"debugged"fine!
49;TheDEBUGGERusesthe'ABSENTRYMain'instead...
50;TheactualCPUNEEDstheRESETVector(Vreset)
COMENTARIOS a ["Laboratorios\Lab1\01b_L1.asm"]:
Lo primero es generar SUS propios OpCodes. Los hemos comenzado con una 'X' para
ayudarnosconladiferenciacinentresuscdigosylosdelmanufacturante.
18XCLR:EQU$3F;Instructionclr,tomadadelReferenceManual
19XOP1:EQU$80;Operand(1stvariable)forclrandinc
20XINC:EQU$3C;Instructioninc,delReferenceManual
21XBRA:EQU$20;Instructionbra,delReferenceManual
22XOFF:EQU4;Offsetforinstructionbra
23RESET:EQU$FFFE;VectordeInterrupciones
Lapartesiguienteesmuysimilaralejercicioanterior:01a_L1.asm:
29ORG$2080;HCS08ROMStart(Flash)
30Main:DC.BXCLR;LaterTRAYTHIS:Stepsome,InsertBREAK
31DC.BXOP1;..POINTinMain.>>RUN<<CWwillstop..
32loop:DC.BXINC;..here.WHY?**BECAUSECOPisENABLED**!
33DC.BXOP1;loop
34DC.BXBRA
35DC.BXOFF
40;InterruptVectors
42ORGRESET
44DC.BSTARTh;ResetVectorHIGH
45DC.BSTARTl;ResetVectorLOW(HCS08isBIGENDIAN)
Elmismoejercicioanterior,01a_L1.asm,todoescritoenlenguajeSIMBLICO.Yausted
nousaSUSpropiosOpCodes,sinolosdeMotorola.
Usted(casi)NUNCAdebeemplearnmeros;lossmbolosalfanumricos,comoenelC,son
ms o menos descriptivos, dependiendo de lo bien que usted se aplique a hacer las
definiciones. Pero, un nmero como $40, difcilmente ser recordado como la cantidad
numricaqueseusaparadeshabilitarelCOP,cuandoseloalmacenaenel$1802(SOPT1)
["Laboratorios\Lab1\01c_L1.asm"]
01;********************************************************************
02;01c_L1.asmSymbolicProgram(Userdefined),Rev.EV08J2012
03;LuisG.UribeC.,J09A2009
04;Aspectosmnimosnecesariosalescribirunprograma:
05;1.Definirposicininicialdelcdigo.$2080up
06;2.Escribirelprograma(buscarcdigoSIMBLICOdec/instruccin)
07;3.DefinirDireccindeiniciodeejecucinluego
47
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
08;deRESET(vector$FFFE)
09
10;
11;ParameterDefinitions
12
13START:EQU$2080;comienzodelaFlash
14RESET:EQU$FFFE;vectorparaindicarcomienzodelcdigo
15
16;
17;Definicindevariables
18
19Var:EQU$80;unaformadeidentificarvariables
20
21;====================================================================
22;BeginofCodeSection
23ABSENTRYMain;Exportsymbol(DEBUGGERentry)
24
25ORGSTART;HCS08ROMStart(Flash)
26Main:clrVar;Ensayar:clrVAR(maysculas.Daerror)
27loop:incVar
28braloop
29;
30nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
31;This'nop'MAYberemovedforCW6.3...
32;********************************************************************
33;InterruptVectors
34
35ORGRESET
36DC.WMain;RESET:HCS08PowerOn(PON)procedure.
37END
COMENTARIOS a ["Laboratorios\Lab1\01c_L1.asm"]:
Loselementosimportantesson:
11;ParameterDefinitions
13START:EQU$2080;comienzodelaFlash
14RESET:EQU$FFFE;vectorparaindicarcomienzodelcdigo
Asociannmerosasmbolosalfanumricos.DicemuchomsRESET,que$FFFE.
17;Definicindevariables
19Var:EQU$80;unaformadeidentificarvariables
Muchomejorelsmbolodealtonivel'Var',ynotenerquerecordarquesudireccines
la$80,queademspuedecambiarsiseagreganoeliminanvariables.
25ORGSTART;HCS08ROMStart(Flash)
26Main:clrVar;Ensayar:clrVAR(maysculas.Daerror)
27loop:incVar
28braloop
48
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
33;InterruptVectors
35ORGRESET
36DC.WMain;RESET:HCS08PowerOn(PON)procedure.
Todo en simblico. Tampoco usaremos 'RESET', pues hay una serie de smbolos para la
tabladeInterruptVectors,definidosporelmanufacturante.
FULLUseofMotorola'sSymbolicLanguage
Ahoras;estaesLAformadefinitivaqueusteddebeusarparaescribirsusprogramas.
["Laboratorios\Lab1\01d_L1.asm"]
01;********************************************************************
02;01d_L1.asmUseofMotorola'sSymbolicLanguage,Rev.EV08J2012
03;LuisG.UribeC.,J09A2009
04;Aspectosmnimosnecesariosalescribirunprograma:
05;1.Definirposicininicialdelcdigo.$8000up
06;2.Escribirelprograma(buscarcdigoSIMBLICOdec/instruccin)
07;3.DefinirDireccindeiniciodeejecucinluego
08;deRESET(vector$FFFE)
09
10;
11;Includefiles:Workexactlylikein"C";defineprocessorsymbols:
12;..Z_RAMStart,ROMStart,INT_RESET,registers,I/Oports...
13;..derivative.incispreparedbytheProjectWizzard,foreachCPU.
14
15INCLUDE'derivative.inc'
16;
17;Definicindevariables
18
19ORGZ_RAMStart;$80
20
21Var:DS.B1;DS.B?1bytevariablesName&DataStorage
22
23;===================================================================
24;BeginofCodeSection
25ABSENTRYMain;Exportsymbol(DEBUGGERentry)
26
27ORGROMStart;HCS08ROMStart(Flash)
28Main:clrVar;ensayar:clrVAR(maysculas.Daerror)
29loop:incVar
30braloop
31;
49
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
32nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
33;This'nop'MAYberemovedforCW6.3...
34;********************************************************************
35;InterruptVectors
36
37ORGVreset
38DC.WMain;RESET:HCS08PowerOn(PON)procedure.
39END
40
41SEE'MC9S08QE128.inc'forSymbolsDefinitionslike:
42Z_RAMStart;$80
43ROMStart;HCS08ROMStart(Flash)
44Vreset
45
46'MC9S08QE128U.inc'was***COMPLETLY***REARRANGEDandBEAUTIFIEDby
47LuisG.UribeC.,J07J2012,forDOCUMENTATIONPURPOSESONLY.DoNOT
48REPLACEtheoriginal...
COMENTARIOS a ["Laboratorios\Lab1\01d_L1.asm"]:
Estecdigononecesitaexplicacinadicional.
["Laboratorios\Lab1\01e_L1.asm"]
01;********************************************************************
02;01e_L1.asmSymbolicAssemblyLanguage,Rev.EV08J2012
03;LuisG.UribeC.,J09A2009
04;ADVANCEDwaytodefinevariables...
05;
06;Includefiles
08INCLUDE'derivative.inc'
09;
10;Parameterdefinitions
50
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
12ram:setZ_RAMStart;Set'ram'to$80
13;
14;VariablesDefinicin(ADVANCED)
15
16ORGram;Startin$80
17
18Var:DS.B1;DS.B?1bytevariablesName&DataStorage
19Varend:
20ram:SETVarend;$81
21
22ORGram;Restartin$81
23Var2:DS.B1
24Var2end:
25ram:SETVar2end;$82
26
27ORGram;Restartin$82
28Var3:DS.B1
29Var3end:
30ram:SETVar3end;$83...andSOON.
31
32;====================================================================
33;BeginofCodeSection
34ABSENTRYMain;Exportsymbol(DEBUGGERentry)
36ORGROMStart;HCS08ROMStart(Flash)
37Main:ldhx#Var
38ldhx#Var2
39ldhx#Var3
40bra*
41;
42nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
43;This'nop'MAYberemovedforCW6.3...
44;********************************************************************
45;InterruptVectors
46
47ORGVreset
48DC.WMain;RESET:HCS08PowerUp(Pup)procedure.
49END
COMENTARIOS a ["Laboratorios\Lab1\01e_L1.asm"]:
LaprimeranovedadeselusodeINCLUDEfiles:
06;Includefiles
08INCLUDE'derivative.inc'
Luego,ladefinicindevariables,empleandounORG,talcomoparaelcdigo,peroen
lasdireccionescorrespondientesalasvariables:laRandomAccesMemory,RAM:
51
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ORGram:
10;Parameterdefinitions
12ram:setZ_RAMStart;Set'ram'to$80
13;
14;VariablesDefinicin(NORMAL,LAQUEUD.DEBEEMPLEAR)
16ORGram;Startin$80
18Var:DS.B1;DS.B?1bytevariablesName&DataStorage
23Var2:DS.B1
28Var3:DS.B1
Hastaalllapartecomndeladefinicindevariables,queustedSIEMPREusarensus
programas.
Ahora,sisedesearadefinirunavariable,ymsadelanteotra,yluegootra,eltruco
consiste en REDEFINIR la posicin 'RAM' para que lleve la cuenta hasta adnde hemos
llegadodefiniendovariables.Poreso,enelprogramaqueestamosanalizandoelcdigo
NO va como las 8 lneas anteriores, sino que en realidad es como se ilustra a
continuacin.
ComencemosdiciendoqueenelHC9S08QE128,lasreasdeRAMson:
Z_RAMStart:equ$00000080
Z_RAMEnd:equ$000000FF
RAMStart:equ$00000100
RAMEnd:equ$000017FF
RAM1Start:equ$00001880
RAM1End:equ$0000207F
NOTEquehayunAGUJERO,unespacionodefinidodentrodeesecampodedirecciones;lo
emplean REGISTROS usados en perifricos. En la $1800, por ejemplo, se encuentra el
registro
SRSSystemResetStatusRegister;0x00001800
Entonces,elcdigobajoanlisises,enrealidad,comosigue:
10;Parameterdefinitions
12ram:setZ_RAMStart;Set'ram'to$80
13;
14;VariablesDefinicin(ADVANCED)
16ORGram;Startin$80
17
18Var:DS.B1;DS.B?1bytevariablesName&DataStorage
19Varend:
20ram:SETVarend;$81
21
22ORGram;Restartin$81
23Var2:DS.B1
24Var2end:
52
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
25ram:SETVar2end;$82
26
27ORGram;Restartin$81
28Var3:DS.B1
29Var3end:
30ram:SETVar3end;$83...andSOON.
En realidad, en esta secuencia contigua SOLO HACE FALTA lo que ya se ilustr en las
lneasinmediatamenteanteriores:10,12,14,16,18,23,28.
Peroustedpuedehaceralgocomoesto:
ORGram;Startin$80
Var:DS.B1;DS.B?1bytevariablesName&DataStorage
Varend:
ram:SETVarend;ram=$81
ORGrom;Startin$2080
;...CDIGO,CDIGO,CDIGO
ActualRom:
rom:SETActualRom;rom=$20XX(dondesuprogramavaya)
ORGram;Restartin$81,enesteejemplo
Var2:DS.B1
Var2end:
ram:SETVar2end;ram=$82
ORGrom;Startin$20XX(dondesuprogramaiba)
;...MS_CDIGO1,MS_CDIGO1,MS_CDIGO1
ActualRom1:
rom:SETActualRom1;rom=$20XX(dondesuprogramavayaahora)
ORGram;Restartin$82
Var3:DS.B1
Var3end:
ram:SETVar3end;$83...andSOON.
ORGrom;Startin$20XX(dondesuprogramaiba)
;...MS_CDIGO2,MS_CDIGO2,MS_CDIGO2
ActualRom2:
rom:SETActualRom2;$20XX(dondesuprogramavayaahora...)
yyasehacenunaidea."THEPOOR'SMANPROGRAMSECTIONaproach"...
Elrestodelprogramanotiene,enesteejemplo,mayoresdificultades:
36ORGROMStart;HCS08ROMStart(Flash)
37Main:ldhx#Var
38ldhx#Var2
39ldhx#Var3
40bra*
53
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Trate usted de cambiar el programa para incluir cdigo de verdad, entremezclado con
definicindevariables.
Auncuandoleparezcaarrevesadoestemododeprogramacin(y,enrealidad,ases),lo
que ocurre es que cuando estamos haciendo uso de MACROs, que son rutinas que se
escribenenotraspartes,olibreras,yendondepuedenecesitarseagregarvariables,
queustednohaprevistoenelprogramaprincipal,esasMACROspuedenhacerusodeeste
mecanismo, si se establece un protocolo (ojal de aplicacin automtica) que permita
marcar el sitio en donde el programa principal iba al momento de llamar a la MACRO,
definir las variables a las que hubiera lugar, y luego dejar el CODE SECTION en el
precisovalorendondeelprogramalonecesita.
Programayconceptosmuyimportantes,peroquealniveldeestecurso,endondeNOse
estestudiandoenrealidadelAssemblerLanguage,noestanrelevante.Peroparam,
quedeboescribirlesrutinasybibliotecasdeellas,esfundamental.
8) Serie de Fibonacci.
EsteprogramaloadaptdelmanualdelAssemblerEclipse(lanuevaversin10.xsebasa
enEclipse,unIDEgratuito,construidoporIBM,yregaladoalacomunidad.Esusado
por Microchip, y ahora por Freescale, y otros. Est siendo adaptado en muchas
plataformas.Porejemplo,eldesarrolloparacelularesANDROIDsebasaenlaplataforma
Eclipse...)
No hay mayores comentarios sobre este programa. Usted debe ser capaz de decir cmo
funcionay,encasodeduda,acudaalDebuggerdelCodeWarrior,sigaelprogramapasoa
paso,ypodrhacerseunaideadelfuncionamiento).
["Laboratorios\Lab1\02Fibonacci.asm"]
01;********************************************************************
02;02Fibonacci.asm,LuisG.UribeC.,V10A2009V08J2012
03;ADAPTEDfrom:HCS08RS08_Assembler_MCU_Eclipse.pdf,Listing4.1
04;
05;Includefiles
06NOLIST
07INCLUDE'derivative.inc'
08LIST
09;
10;Parameterdefinitions
11
12ram:SETZ_RAMStart;$80
13initStack:EQU$1800
14COP_Disable:EQU%01000010;$42
15;
16;Definicindevariables(ds:bytepordefecto)
54
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
17ORGram
18
19Counter:DS.B1
20FiboRes:DS.B1;Aquvalarespuesta
21;===================================================================
22;BeginofCodeSection
23ABSENTRYMain;Exportsymbol(DEBUGGERentry)
24
25ORGROMStart;HCS08ROMStart(Flash)
26;
27;***ALWAYS***includethefollowing4instructions
28
29Main:lda#COP_Disable
30staSOPT1;SystemOptions1
31ldhx#initStack;InitSP
32txs
33;
34mainLoop:
35clra;UseAccumulatorasacounter
36;
37cntLoop:
38inca
39cbeqa#14,mainLoop;Largervaluescauseoverflow
40staCounter;Updateglobalvariable
41bsrCalcFibo
42staFiboRes;Storeresult
43ldaCounter;..ActivateBREAKPOINTheretosee...
44;..123581321345589144233
45bracntLoop;Nextround
46;====================================================================
47;FunctiontocomputeFibonaccinumbers.ArgumentisinA
48
49CalcFibo:
50dbnzafiboDo;FibonacciDo
51inca
52rts
53;
54fiboDo:
55psha;Thecounter
56clrx;Secondlast=0
57lda#$01;Last=1
58;
59FiboLoop:
60psha;Pushlast
61txa
62add1,sp
63pulx
64dbnz1,sp,FiboLoop
65
66;
67FiboDone:
68pulh;Releasecounter
55
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
69rts;ResultinA
70;
71nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
72;This'nop'MAYberemovedforCW6.3...
73;********************************************************************
74;InterruptVectors
75
76ORGVreset
77DC.WMain;RESET:HCS08PowerUp(Pup)
78END
COMENTARIOS a ["Laboratorios\Lab1\02Fibonacci.asm"]:
Unaspectoaresaltar:
05;Includefiles
06NOLIST
07INCLUDE'derivative.inc'
08LIST
NOLIST es una Pseudo operacin que indica al Assembler que el contenido del include
file NO lo incluya en los listados que se producen como resultado del proceso de
ensamblaje. De esta manera, slo queda en esos listados, para su documentacin,
informacinqueustedconsidererelevante.
Debajo del include file es menester rehabilitar la generacin de los listados, con
LIST,yaquedelocontario,TAMBINSUCDIGOsereliminado.
Esteprogramaenfatizaenelusoelementaldellamadasafunciones,osubrutinas(BSR).
Adems, se identifican algunos modos de direccionamiento empleados. La tabla de
Vectores de Interrupcin se ha ampliado para incluir IRQ (Interrupt ReQuest, un pin
externo del MCU que al activarlo genera una interrupcin), SWI (una instruccin
diseada para servir de interfaz con el Sistema Operativo: SoftWare Interrupt, muy
valiosa)yelconsabidoRESET.SevuelveamencionareltemadesuspensindelPROGRAM
SECTIONparavolverdespus.
IRQySWIenrealidadNOjueganningnpapelenesteprograma;seescribisuentrada
enlatabladeInterruptVectorssimplementeparavercmoseincluiran.
["Laboratorios\Lab1\Lab1_M\03a_L1_M.asm"]
01;********************************************************************
02;Programa03a_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03;
04;NuevosAspectos:
05;
06;EmpleodeunaSUBRUTINAdentrodelprograma,mediante"bsr"parael
07;..llamadoy"rts"paraelretorno.Seusanlosdireccionamientos:
08;InherenteDirectoInmediatoRelativo
09;
56
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
10;Includefiles
11NOLIST
12INCLUDE'derivative.inc'
13LIST
14
15;
16;Parameterdefinitions
17ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
18rom:SETROMStart;$2080
19initStack:EQU$1800
20COP_Disable:EQU$42
21
22;
23;Definicindevariables(DS:DATASTORATE;Bytepordefecto)
24ORGram
25
26var:DS1;EquivalenttoDS.B
27
28;====================================================================
29;BeginofCodeSection
30ABSENTRYMain;Exportsymbol(DEBUGGERentry)
31
32ORGrom;$2080:HCS08ROMStart(Flash)
33
34;
35;***ALWAYS***includethefollowing4instructions
36Main:lda#COP_Disable
37staSOPT1;SystemOptions1
38ldhx#initStack;InitSP
39txs;..
40;
41loop:clrvar;DirectAddressingMode
42bsrrutina;RelativeAddressingMode
43braloop;..
44
45;====================================================================
46;Subrutinadeejemplo
47rutina:
48ldavar
49cbeqa#10,fin;Terminacuandovarllegaa10
50incvar
51brarutina
52fin:rts;COLOCARBREAKPOINTAQU(Debugger)
53
54
55;********************************************************************
56;*SpuriousInterruptServiceRoutine(UnwantedInterrupt)*
57;********************************************************************
58spurious:
59rti
60;
61;SivaacambiardeORG,yluegodebecontinuarconelCdigo:
57
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
63endrom1:
64rom:SETendrom1
66;********************************************************************
67;*InterruptVectors*
68;********************************************************************
69
70ORGVirq
71DC.Wspurious;IRQ
72DC.Wspurious;SWI
73DC.WMain;RESET
74
75;********************************************************************
76;IFyouneedtocontinuewiththeprogram...:
77
78ORGrom;rompointsto:endrom1.Notneededhere
79
80END
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03a_L1_M.asm"]:
Las pocas cosas nuevas seran, una rutina DUMMY (no hace nada), para efectos del
ejemplo:
58spurious:
59rti
LamarcaparacambiardeCODESECTION:
61;SivaacambiardeORG,yluegodebecontinuarconelCdigo:
63endrom1:
64rom:SETendrom1
LaasignacinparalatabladeVectoresdeInterrupcin:
67;*InterruptVectors*
70ORGVirq
71DC.Wspurious;IRQ
72DC.Wspurious;SWI
73DC.WMain;RESET
76;IFyouneedtocontinuewiththeprogram...:
78ORGrom;rompointsto:endrom1.Notneededhere
...(Contina...)
58
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
DECABEZAdeunprogramadordesistemasEmbebidos...AsqueHAYQUEANDARSECONMUCHO
CUIDADOcuandoincluyamosInterrupcionesennuestroscdigos.Tienequehacersedeuna
maneraMUYDISCIPLINADA.LosSistemasOperativosaslohacen.
["Laboratorios\Lab1\Lab1_M\03b_L1_M.asm"]
001;********************************************************************
002;Programa03b_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013V22N13
003;
004;NuevosAspectos:
005;
006;UsodeRutinasdeInterrupcin:
007;a)InclusindelcdigodelarutinadeInterrupcin(Interrupt
008;ServiceRoutine,ISR),usando"RTI"pararetornardesta.
009;b)DefinicindelosVectoresdeInterrupcindeacuerdoconla
010;fuentedelainterrupcin;enestecaso:"IRQ".Suvectorde
011;interrupcionesestenVirq($FFFA$FFFB).Sehausadola
012;etiqueta"IRQISR"paradesignarladireccindelarutina
013;c)HabilitacindelperifricoparaInterrumpir
014;d)HabilitacindelCPU(CLI)paraqueacepteInterrupciones
015;(apartedeladelRESET)
016
017;
018;Includefiles
019NOLIST
020INCLUDE'derivative.inc'
021LIST
022
023;
024;Parameterdefinitions
025ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
026rom:SETROMStart;$2080
027initStack:EQU$1800
028COP_Disable:EQU$42
029
030;
031;Definicindevariables(ds:bytepordefecto)
032ORGram
033
034var:DS.B1;EquivalenttoDS
035
036;===================================================================
037;BeginofCodeSection
038ABSENTRYMain;Exportsymbol(DEBUGGERentry)
039
040ORGrom;$2080:HCS08ROMStart(Flash)
041
042;
043;***ALWAYS***includethefollowing4instructions
044Main:lda#COP_Disable
045staSOPT1;SystemOptions1
046ldhx#initStack;InitSP
047txs;..
59
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
048
049;
050;EnableInterruptsforIRQ
051;
052BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
053;
054;..Clearanypossibleprevious,false,interruptsbySetting
055;..IRQACKbitinIRQSC(IRQStatusandControlregister)
056BSETIRQSC_IRQACK,IRQSC
057;
058BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
059;
060
061cli;CPUInterruptENABLE
062
063;
064loop:clrvar;DirectAddressingMode
065bsrrutina;RelativeAddressingMode
066braloop
067
068;====================================================================
069;Subrutinadeejemplo
070rutina:
071ldavar
072cbeqa#10,fin;Terminacuandollegaa10
073incvar
074brarutina
075fin:rts;COLOCARBREAKPOINTAQU(Debugger)
076
077
078;====================================================================
079;EJEMPLOdeRutinadeInterrupcin(ISRforIRQsignal)
080;NOTE:EsnecesariorealizarunACKNOWLEDGEparaquelainterrupcin
081;vuelvaasuceder(InterruptHandshaking...differentforeach
082;peripheralequipment.NeedtoreadManualforeachone...:(
083IRQISR:
084clrvar
085BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
086;..(rearmIRQInterrupts)
087rti
088
089;********************************************************************
090;*InterruptVectors*
091;********************************************************************
092;(Estaparteesmsomenosestndar,
093;..exceptoquenormalmenteseincluyenTODOSlosperifricos...)
094spurious:
095rti
097ORGVirq;ChangeORG
098DC.WIRQISR;<<<IRQDefined
099DC.Wspurious;SWI
100DC.WMain;RESET
60
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
101
102END
103
104NOTE:IfinCW10.2,IRQdoesNOThaveanyeffectifyouare
105debugginginFullChipSimulation(FCS)andyouareusingstepby
106step(F5).YouneedtomakeabreakpointintheISRandthenRUNat
107fullspeed:F8.Now,IRQworks...
108
109GURIBE,M29E2013
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03b_L1_M.asm"]:
Cuando se trata del MCU hay varios pasos que se deben seguir al trabajar con
perifricos;alomejorhaydispositivosalosquenoseaplicantodoslospasos...Lo
primeroes,aveces,definirciertosvaloresoescoger,porejemplo,lafuentedeCLOCK
(comoenelcasodelascomunicaciones,SCI:SerialCommunicationInterface;perifrico
al que hay que definirle primero las caractersticas del canal de comunicaciones:
velocidad,nmerodebits,paridad,nmerodestopbits...ANTESdehacernadams).
Luego,hayque"ENERGIZAR"elperifrico.Muchosdispositivosnoestnconectadosala
alimentacinelctrica,dentrodelMCU,mientrasnoselosnecesite,conelpropsito
de ahorrar en consumo de energa. Esto es lo que yo denomin "ACTIVATE" en el
tratamiento del SCI. Ntese que cuando operamos con perifricos de comunicaciones en
realidadcadaunodeellospuedeversecomoDOScomponentes:eldetransmisinyelde
recepcin.AlomejorhayqueACTIVARcadaunodeellosporseparado(Revisarvezpor
vez el manual). En el caso del SCI es as, y en nuestros ejemplos yo ACTIVO ambos
transmisoryreceptoralmismotiempo,mediantelaoperacin'XmtRcvActivate'.
Despus, hay que habilitar las interrupciones (Peripheral Interrupt Enable) de los
dispositivosnecesarios,queyahansidoapropiadamenteinicializadosyACTIVADOS.
Por ltimo se debe habilitar al CPU para que procese interrupciones. Esa es la
secuencia genrica de actividades para habilitar perifricos para que interrumpan el
procesamientolinealdedatosdelCPU.
Ademsdetodo,hayqueestablecerlaidentificacinde:QUrutinadebeatenderCUL
interrupcin. El mecanismo que se emplea es mediante un link en el Vector de
Interrupciones, que tiene una posicin reservada para cada perifrico, o parte del
dispositivosqueestencapacidaddeinterrumpir.Porejemplo,enelcasodelSCI,el
transmisor tiene su propio vector de interrupciones; tambin lo tiene el receptor, y
asimismo lo posee el Control de Errores de Recepcin. En otros equipos, como los PC
compatiblesIBM/AT,hayunvectoradicionalparaelmanejodelModem,odispositivode
comunicacinconelcanaltelefnicoconvencional.
Finalmente, hay que escribir por aparte la rutina ISR que atender cada dispositivo
habilitado para hacerlo. Cada ISR tiene que responder de la manera convencional; por
ejemplo,unarutinadeinterrupcindeRecepcinenelSCI,tienealmenosqueleerel
datoqueestllegando,yquehaocasionadolainterrupcin,colocarloenelreade
memoriadispuestoparaeso(normalmenteunaCOLA,oQUEUE),indicarlealperifricoque
yaseloatendi(InterruptAcknowledge;estafuncionalidadenequiposmenosprimitivos
la suministra el hardware, pero en la mayora de los microcontroladores, el software
tiene que participar en mayor o menor grado en el protocolo de Aceptacin de
Interrupciones).
61
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Losconceptosnovedososaquson:elEnabledelIRQ(queNOdesusInterrupts,sinodel
PINdeIRQ):
052BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
054;..Clearanypossibleprevious,false,interruptsbySetting
055;..IRQACKbitinIRQSC(IRQStatusandControlregister)
056BSETIRQSC_IRQACK,IRQSC
Esta es una de las partes MAS COMPLICADAS en los sistemas reales (no de
laboratorio). Por ejemplo, cuando conectamos una Estacin Maestra (un PC) a un
grupo de dispositivos remotos que estn operando (RTUs, Remote Terminal Units),
probablemente, al habilitar la interfaz de comunicaciones del PC, ya las RTUs
estn comunicndose! Comenzar una comunicacin desde el PC, a la mitad de una
transmisindelaRTU,puededarlugaralosmsespinososproblemas...
LuegovienelahabilitacindelasINTERRUPCIONES,propiamentedicha:
058BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
Y,finalmente,lahabilitacindelCPUparaqueaceptelasinterrupcionesexternas:
061cli;CPUInterruptENABLE
ESTOS SON LOS PASOS, EN ESE ORDEN, QUE DEBEN SEGUIRSE SIEMPRE PARA ACTIVAR LAS
INTERRUPCIONESDELOSPERIFRICOSQUENECESITEMOS.
Larutinaprincipalesmuysimpleenesteejercicio,conelnimodenooscurecerel
problemadelasinterrupciones;consisteenuncicloqueincrementalavariable'var'
de0a10,yrepite...
064loop:clrvar;DirectAddressingMode
065bsrrutina;RelativeAddressingMode
066braloop
068;====================================================================
069;Subrutinadeejemplo
070rutina:
071ldavar
072cbeqa#10,fin;Terminacuandollegaa10
073incvar
074brarutina
075fin:rts;COLOCARBREAKPOINTAQU(Debugger)
083IRQISR:
084clrvar
62
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
085BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
086;..(rearmIRQInterrupts)
087rti
Por ltimo se culmina con la parte estndar de las definiciones de los vectores de
interrupcin,yavistavariasvecesconanterioridad.
["Laboratorios\Lab1\Lab1_M\03c_L1_M.asm"]
001;********************************************************************
002;Programa03c_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
003;
004;NuevosAspectos:
005;
006;DefinicindeconstantesenlaROM(Flash,memoriadeprograma):
007;Unatabladevaloresconsecutivosenunazonadelamemoriade
008;programaDIFERENTEaladelcdigo(instrucciones).Paraestose
009;hautilizadoDC(defineConstant),Bytespordefault.Losvalores
010;correspondenalcdigoASCIIdeloscaracteres'Hola',seguidos
011;deun"nulbyte"(0)
012;
013;DireccionamientoIndexadoconPostincremento(X+)enKBI1para
014;leerconsecutivamentede'Table'.
015;
016;Includefiles
017NOLIST
018INCLUDE'derivative.inc'
019LIST
020
021;
022;Parameterdefinitions
023ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
024rom:SETROMStart;$2080
025initStack:EQU$1800
026COP_DisableEQU$42
027ROMTable:EQU$3000;Posicinarbitraria,encimadel
028;..programa;debajodelareaocupada
029;..(VERMapadeMemoria)
030
031;
032;Definicindevariables(ds:bytepordefecto)
033ORGram
63
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
034TPtr:DS.W1
035out:DS1;'DS'y'DS.B'sonsinnimos
036var:DS.B1;VerifiquecomparandoProject.abs.s19
037
038;===================================================================
039;BeginofCodeSection
040ABSENTRYMain;Exportsymbol(DEBUGGERentry)
041
042ORGrom;$2080:HCS08ROMStart(Flash)
043;
044;***ALWAYS***includethefollowing4instructions
045Main:lda#COP_Disable
046staSOPT1;SystemOptions1
047ldhx#initStack;InitSP
048txs;..
049
050;
051;EnableInterruptsforIRQ
052;
053BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
054;
055;..Clearanypossibleprevious,false,interruptsbySetting
056;..IRQACKbitinIRQSC(IRQStatusandControlregister)
057BSETIRQSC_IRQACK,IRQSC
058;
059BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
060;
061cli;CPUInterruptENABLE
062
063;
064loop:clrvar;DirectAddressingMode
065bsrrutina;RelativeAddressingMode
066braloop
067
068;====================================================================
069;Subrutinadeejemplo
070rutina:
071ldavar
072cbeqa#10,fin;Terminacuandollegaa10
073incvar
074brarutina
075fin:rts;COLOCARBREAKPOINTAQU(Debugger)
076
077;====================================================================
078;TransferALLtablecompleteto'out',witheachIRQactivation.
079;NOTE:Enunarutinadeinterrupciones**JAMS**useunregistrosin
080;..SALVARpreviamentesuvalorenelstack.Alfinalizar,debe
081;..RESTAURARsuvalordesdeelstack.
082IRQISR:
083pshh;SaveHreg;HardwaredoesNOTdothis
084ldhx#Table;Indexreg.pointsto'Table'start.
085;(Cuntovale'Table'?Y'#Table'?)
64
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
086loop2:movX+,out
087beqdone;ActivateBREAKPOINTheretosee...
088braloop2
089
090done:pulh
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti
094
095;====================================================================
096;Table
097ORGROMTable
098Table:DC.B'H'
099DC.B'O'
100DC.B'L'
101DC.B'A'
102DC.B0
104;********************************************************************
105;*InterruptVectors*
106;********************************************************************
107;(Estaparteesmsomenosestndar,
108;..exceptoquenormalmenteseincluyenTODOSlosperifricos...)
109spurious:
110rti
112ORGVirq;ChangeORG
113DC.WIRQISR;<<<IRQDefined
114DC.Wspurious;SWI
115DC.WMain;RESET
116
117END
118
119NOTE:IfinCW10.2,IRQdoesNOThaveanyeffectifyouare
120debugginginFullChipSimulation(FCS)andyouareusingstepby
121step(F5).YouneedtomakeabreakpointintheISRandthenRUNat
122fullspeed:F8.Now,IRQworks...
123
124GURIBE,M29E2013
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03c_L1_M.asm"]:
Elprogramacomienzadelamaneraordinaria.DefinalaROMTablearbitrariamenteenla
posicin$3000,quequedabienporencimadelreadeFlashutilizadaporelprograma:
027ROMTable:EQU$3000;Posicinarbitraria
DefineunAPUNTADORalatablaque,portanto,tienequetener16bits(DS.W:Define
StorageWORD):
032;Definicindevariables(ds:bytepordefecto)
033ORGram
034TPtr:DS.W1
65
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
HaceluegolahabilitacinqueyahemosrealizadoparaelIRQ,yelCLIparahabilitar
las interrupciones del CPU. La rutina de ejemplo es el mismo cdigo simple que
empleamosenelejercicioanterior.
LapartenovedosaconsisteentransferirTODAlatabla(queenelejemplocontienesolo
lasletrasHOLAyun'\0'queestamosusandocomoterminadordestrings,igualqueen
C),deunsologolpe,cadavezqueseinterrumpaelCPUmedianteelbotndeIRQ.
Laadvertenciamsimportantees:
079;NOTE:Enunarutinadeinterrupciones**JAMS**useunregistrosin
080;..SALVARpreviamentesuvalorenelstack.Alfinalizar,debe
081;..RESTAURARsuvalordesdeelstack.
AnalicemoslaIRQISR:
082IRQISR:
083pshh;SaveHreg;HardwaredoesNOTdothis
084ldhx#Table;Indexreg.pointsto'Table'start.
085;(Cuntovale'Table'?Y'#Table'?)
LuegosecolocaladireccindelatablaenelregistrondiceH:X
Acontinuacinvieneelcicloquemuevetodalatabla,letraporletra,alavariable
'out'(que,comoveremosluego,sinofueraunavariablesinoelregistrodesalidadel
perifricodecomunicaciones,enviaraelmensajealPC!)
086loop2:movX+,out
087beqdone;ActivateBREAKPOINTheretosee...
088braloop2
Parafinalizar,HAYQUERESTAURARPORPROGRAMALAPARTEALTADELREGISTRONDICEH:X(
o sea, H, que resguard en Stack al comienzo). Luego se culmina con el protocolo ya
conocido de Interrupt Acknowledge para este perifrico, y la rutina retorna de la
interrupcin.Sisevuelveaoprimirelbotn,vuelveatrasmitirselatabla:
090done:pulh
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti
Definicindelatabla:
096;Table
097ORGROMTable
098Table:DC.B'H'
099DC.B'O'
100DC.B'L'
101DC.B'A'
66
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
102DC.B0
...quetambinpuedeescribirsecomo:
Table:DC.B"HOLA",0
Lapartefinal,delosvectoresdeinterrupcin,eslamismaqueyahemosvisto.
Esteprogramaessimilaralanterior,peronoenvalatablacompletacadavezquese
oprimeelIRQ,sinoquemueveunaletraalavez,porcadainterrupcindeIRQ.
["Laboratorios\Lab1\Lab1_M\03d_L1_M.asm"]
001;********************************************************************
002;Programa03d_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
003;
004;NuevosAspectos:
005;
006;Usodeunavariable'pointer'(TPtr)paratransferirlatabla
008;
009;Includefiles
010NOLIST
011INCLUDE'derivative.inc'
012LIST
014;
015;Parameterdefinitions
016ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
017rom:SETROMStart;$2080
018initStack:EQU$1800
019COP_DisableEQU$42
020ROMTable:EQU$3000;Posicinarbitraria,encimadel
021;..programa;debajodelareaocupada
022;..(VERMapadeMemoria)
023
024;
025;Definicindevariables(ds:bytepordefecto)
026ORGram
027TPtr:DS.W1
028out:DS1;'DS'y'DS.B'sonsinnimos
029var:DS.B1;VerifiquecomparandoProject.abs.s19
030
031;===================================================================
032;BeginofCodeSection
033ABSENTRYMain;Exportsymbol(DEBUGGERentry)
034
035ORGrom;$2080:HCS08ROMStart(Flash)
036;
037;***ALWAYS***includethefollowing4instructions
038Main:lda#COP_Disable
039staSOPT1;SystemOptions1
67
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
040ldhx#initStack;InitSP
041txs;..
042;
043
044ldhx#Table;InitpointertoTable
045sthxTPtr;..
046
047;
048;EnableInterruptsforIRQ
049;
050BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
051;
052;..Clearanypossibleprevious,false,interruptsbySetting
053;..IRQACKbitinIRQSC(IRQStatusandControlregister)
054BSETIRQSC_IRQACK,IRQSC
055;
056BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
057;
058cli;CPUInterruptENABLE
059
060;
061loop:clrvar;DirectAddressingMode
062bsrrutina;RelativeAddressingMode
063braloop
064
065;====================================================================
066;Subrutinadeejemplo
067rutina:
068ldavar
069cbeqa#10,fin;Terminacuandollegaa10
070incvar
071brarutina
072fin:rts
073
074;====================================================================
075;TransferALLtableto'out',CHARBYCHARwitheachIRQactivation.
076;NOTE:Enunarutinadeinterrupciones**JAMS**useunregistrosin
077;..SALVARpreviamentesuvalorenelstack.Alfinalizar,debe
078;..RESTAURARsuvalordesdeelstack.
079IRQISR:
080pshh;SalvarH(elHardwarenolohace!)
081ldhxTPtr;CargarregistrondiceconPointer
082movX+,out;Mueveletra;apuntaalasiguiente
083beqresetPtr
084sthxTPtr;..Actualizaelpointerenmemoria
085bradone
086
087resetPtr:
088ldhx#Table;ReinicializaelpointerdeTable
089sthxTPtr;..
090done:pulh
68
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti;ActivateBREAKPOINTheretosee...
094
095;====================================================================
096;Table
097ORGROMTable
098Table:DC"HOLA",0;QUESEL'0'QUEAPARECEALFINAL?
099;(DCeslomismoqueDC.B)
100;********************************************************************
101;InterruptVectors
102;ALWAYSINCLUDEVERBATIMCOPY,EXCEPTOFORVECTORSYOUUSE...
103dummy_isr:;ThismustbeplacedinROMSpace
104rti
105
106orgVtpm3ovf;Increasingpriorityfrombottomup
107DC.Wdummy_isr;Vtpm3ovf:
108DC.Wdummy_isr;Vtpm3ch5:
109DC.Wdummy_isr;Vtpm3ch4:
110DC.Wdummy_isr;Vtpm3ch3:
111DC.Wdummy_isr;Vtpm3ch2:
112DC.Wdummy_isr;Vtpm3ch1:
113DC.Wdummy_isr;Vtpm3ch0:
114DC.Wdummy_isr;Vrtc:
115DC.Wdummy_isr;Vsci2tx:
116DC.Wdummy_isr;Vsci2rx:
117DC.Wdummy_isr;Vsci2err:
118DC.Wdummy_isr;Vacmpx:
119DC.Wdummy_isr;Vadc:
120DC.Wdummy_isr;Vkeyboard:
121DC.Wdummy_isr;Viicx:
122DC.Wdummy_isr;Vsci1tx:
123DC.Wdummy_isr;Vsci1rx:
124DC.Wdummy_isr;Vsci1err:
125DC.Wdummy_isr;Vspi1:
126DC.Wdummy_isr;Vspi2:
127DC.Wdummy_isr;Vtpm2ovf:
128DC.Wdummy_isr;Vtpm2ch2:
129DC.Wdummy_isr;Vtpm2ch1:
130DC.Wdummy_isr;Vtpm2ch0:
131DC.Wdummy_isr;Vtpm1ovf:
132DC.Wdummy_isr;Vtpm1ch2:
133DC.Wdummy_isr;Vtpm1ch1:
134DC.Wdummy_isr;Vtpm1ch0:
135DC.Wdummy_isr;Vlvd:
136DC.WIRQISR;Virq:
137DC.Wdummy_isr;Vswi:
138DC.WMain;Vreset:
139
140END
69
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03d_L1_M.asm"]:
Usa una variable 'pointer' (TPtr) para transferir la tabla, letra por letra. En el
ejercicio11)tambinseuslavariable,perosetransferaTODAlatablaporcadaIRQ
interrupt.
LainicializacindeTPtrsehaceahoraenelprogramaprincipal(Main):
044ldhx#Table;InitpointertoTable
045sthxTPtr;..
LahabilitacindelasinterrupcionesparaelIRQquedaigual.La'rutina'yel'loop'
siguensiendolosmismosqueantes.
LaIRQISRcambiaunpoco,paratransferirletraporletra,notablaportabla:
079IRQISR:
080pshh;SalvarH(elHardwarenolohace!)
081ldhxTPtr;CargarregistrondiceconPointer
semueveunaletra
082movX+,out;Mueveletra;apuntaalasiguiente
083beqresetPtr
Sinosehaterminado,seguardaelnuevovalordePointer,quehasidoincrementado
paraapuntaralaprximaletraquedebetransferirse:
084sthxTPtr;..Actualizaelpointerenmemoria
yseterminalainterrupcin
085bradone
087resetPtr:
088ldhx#Table;ReinicializaelpointerdeTable
089sthxTPtr;..
70
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Lapartefinaleslamismahyaseterminadolatransmisinono.Serestauraelvalor
delregistroH,nosalvadoporelmecanismodeinterrupcionesyseejecutaelprotocolo
deAckparalainterrupcinylarutinaretornaalprogramaprincipal:
090done:pulh
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti;ActivateBREAKPOINTheretosee...
Latablatienelamismaestructuradeantes:
097ORGROMTable
098Table:DC"HOLA",0;QUESEL'0'QUEAPARECEALFINAL?
099;(DCeslomismoqueDC.B)
Comoejemplo,seincluyenTODOSlosvectoresdeinterrupcin,conlosnombresdefinidos
porelmanufacturante.Nolarepitoaquparaconservarelespacio.
Latablacontodoslosvaloresdelosvectoresdeinterrupcin,queseincluyenel
ejercicio anterior, se acomoda dentro de un INCLUDE FILE que se invoca al final del
problema.Elejercicioesmuysimpleynodesarrollaningncdigoespecial.
["Laboratorios\Lab1\Lab1_M\04b_L1_M.asm"]
01;********************************************************************
02;Programa04b_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03;
04;NuevosAspectos:
06;SeempleaunIncludeFile:'InitU_M.inc'(ALLInterruptVectors)
07
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;Parameterdefinitions
15
16ram:SETZ_RAMStart;$80
17rom:SETROMStart;$2080
18initStack:EQU$1800
19COP_Disable:EQU$42
20ROMTable:EQU$3000;Posicinarbitraria,encimadel
21;..programa;debajodelareaocupada
22;..(VERMapadeMemoria)
23;
24;Definicindevariables(ds:bytepordefecto)
25
26ORGram
27
28TPtr:DS.W1
71
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
29out:DS.B1
30var:DS.B1
31
32;===================================================================
33;BeginofCodeSection
34ABSENTRYMain;Exportsymbol(DEBUGGERentry)
35
36ORGrom;$2080:HCS08ROMStart(Flash)
37
38;
39;***ALWAYS***includethefollowing4instructions
40Main:lda#COP_Disable
41staSOPT1;SystemOptions1
42ldhx#initStack;InitSP
43txs;..
44
45;
46;Branchforever
47
48bra*
49
50;
51;InitU
52NOLIST
53INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
54LIST
55
56END
["Laboratorios\Lab1\Lab1_M\05a_L1_M.asm"]
01;********************************************************************
02;Programa05a_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03;LuisG.UribeC.,D12A2009
04;
05;EJEMPLO:RutinadeMULTIPLICAR,porsumassucesivas
07;NOTE:ElHCS08TIENEunainstruccindemultiplicar...
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;Parameterdefinitions
15ram:SETZ_RAMStart;$80
16rom:SETROMStart;$2080
72
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
17initStack:EQU$1800
18COP_Disable:EQU$42
19;
20;Definicindevariables(DS:DefineStorageBYTE,pordefecto)
21ORGram
22m_ando:DS.B1;Multiplicando
23m_ador:DS1;Multiplicador
24prod:DS.B1;Producto(RESULTADO)
25cnt:DS1;Contador
26;===================================================================
27;BeginofCodeSection
28ABSENTRYMain;Exportsymbol(DEBUGGERentry)
29ORGrom;$2080:HCS08ROMStart(Flash)
31;
32;***ALWAYS***includethefollowing4instructions
33Main:lda#COP_Disable
34staSOPT1;SystemOptions1
35ldhx#initStack;InitSP
36txs;..
37;
38;Inicializacindeparmetros
39mov#5,m_ando;Main:Etiquetadelprogramappal.
40mov#3,m_ador;Pasarparmetrosalarutina
41;
42;RutinadeMultiplicacinporsumassucesivas
43clrprod
44clrcnt
45mply:ldam_ador
46cbeqcnt,fin
47ldaprod
48addm_ando
49staprod
50inccnt
51bramply
52
53fin:bra*;SimulaunHALT
54;
55nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
56;This'nop'MAYberemovedforCW6.3...
57
58;
59;InitU
60;NOLIST
61INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
62;LIST
63
64END
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05a_L1_M.asm"]:
LaspartesnuevascomienzanconlaInicializacindeparmetros.Semultiplicarn,como
ejemplo,5*3(constantes):
73
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
39mov#5,m_ando;Main:Etiquetadelprogramappal.
40mov#3,m_ador;Pasarparmetrosalarutina
LaRutina(queanNOSubrutina)deMultiplicacinporsumassucesivasescomosigue:
43clrprod
44clrcnt
45mply:ldam_ador
46cbeqcnt,fin
47ldaprod
48addm_ando
49staprod
50inccnt
51bramply
53fin:bra*;SimulaunHALT
54;
55nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
56;This'nop'MAYberemovedforCW6.3...
El ejercicio termina con en la lnea 53 fin: bra *, que simula un HALT, para
permitirnosmirarelresultadoconelDebugger.
["Laboratorios\Lab1\Lab1_M\05b_L1_M.asm"]
01;********************************************************************
02;Programa05b_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03
04;EJEMPLO:RutinadeMULTIPLICAR,porsumassucesivas
06;NuevosAspectos:
07;
08;IncluyeunaSubrutina
09;
10;Includefiles
11NOLIST
12INCLUDE'derivative.inc'
13LIST
14;
15;Parameterdefinitions
16ram:SETZ_RAMStart;$80
17rom:SETROMStart;$2080
18initStack:EQU$1800
19COP_Disable:EQU$42
20;
21;Definicindevariables(DS:DefineStorageBYTE,pordefecto)
22ORGram
24m_ando:DS.B1;Multiplicando
74
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
25m_ador:DS1;Multiplicador
26prod:DS.B1;Producto(RESULTADO)
27;===================================================================
28;BeginofCodeSection
29ABSENTRYMain;Exportsymbol(DEBUGGERentry)
30ORGrom;$2080:HCS08ROMStart(Flash)
31;
32;***ALWAYS***includethefollowing4instructions
33Main:lda#COP_Disable
34staSOPT1;SystemOptions1
35ldhx#initStack;InitSP
36txs;..
37;
38;Inicializacindeparmetros
39mov#5,m_ando;Main:Etiquetadelprogramappal.
40mov#3,m_ador;Pasarparmetrosalarutina
41
42bsrmply;BranchtoSubroutinemply
43final:brafinal;Halt
44
45;===================================================================
46;RutinadeMultiplicacinporsumassucesivas
47mply:clrprod
48ldam_ador;RICHInstructionSet:Loadandmake
49;..tacit&automaticCOMPAREwith'0'
50beqfin
51;
52;Loop
53mply2:ldaprod
54addm_ando
55staprod
56decm_ador
57beqfin
58bramply2
59fin:rts
60;
61nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
62;This'nop'MAYberemovedforCW6.3...
63
64;
65;InitU
66NOLIST
67INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
68LIST
70END
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05b_L1_M.asm"]:
Lasnovedadescomienzanaqu:
42bsrmply;BranchtoSubroutinemply
43final:brafinal;Halt
75
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
SetrasladelcdigodelprogramaprincipalalaSUBRUTINAMPLY:
47mply:clrprod
48ldam_ador;RICHInstructionSet:Loadandmake
49;..tacit&automaticCOMPAREwith'0'
50beqfin
52;Loop
53mply2:ldaprod
54addm_ando
55staprod
56decm_ador
57beqfin
58bramply2
59fin:rts
Estemecanismotienedosaspectosimportantes:
Primero, emplea de una manera muy eficienteel espacio, segn acabo de explicar. Las
variables estticas o globales, conservan el espacio desde su asignacin hasta la
terminacindelprograma.Nuncaloliberanhastaentonces.
Segundo, permiten la codificacin de FUNCIONES RECURSIVAS, al estilo de FACTORIAL, o
lasTORRESDEHANOIysimilares.
EsMUYimportanteentenderypoderaplicarlastcnicasqueaquexpongo.
El ejemplo que usaremos como vehculo para aplicar y demostrar la forma de definir
variables dinmicas ser otra vez el Ejemplo de EXPONENCIACIN, por multiplicaciones
sucesivasqueasuvezsehacenporsumassucesivas...PeroTODASlasvariablesestarn
enelStack.
Esimportante,parasucomprensin,quesehagapasoapasoundibujodelStackyel
valor del SP, a medida que se ejecuta el programa. Puede ayudarse con el Debugger,
siguiendoelprogramapasoapasoymonitoreandoelSPyelreaasignadaalStack.
["Laboratorios\Lab1\Lab1_M\05d_L1_M.asm"]
001;********************************************************************
002;Programa05d_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
003
004;EJEMPLO:EXPONENCIACIN,pormultiplicacionessucesivas;
005;..queasuvezsehacenporsumassucesivas...
006;
007;NuevosAspectos:
008;
009;**USASOLOELSTACK;NOVARIABLESLOCALES**
010;
76
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
011;Includefiles
012NOLIST
013INCLUDE'derivative.inc'
014LIST
016;
017;Parameterdefinitions
018mantisa:EQU2;Resultado:2^5=32(0x20enelACC)
019exponente:EQU5;Cambieaqusisedesamsvalores
020;
021ram:SETZ_RAMStart;$80
022rom:SETROMStart;$2080
023initStack:EQU$1800
024COP_Disable:EQU$42
025
026STD:EQU4;PosicinSTandarDdela1avariable
027
028;===================================================================
029;DEFINICIONDEVARIABLESLOCALES:
031;Enlugardelasvariables(globales),seespecificael"Offset"
032;..quecadaunatendrenelStack(Frame)almomentodellamara
033;..unasubrutina.Deestamanera,talcomohaceelIJVM,cada
034;..subrutinaofuncinpuededireccionar"simblicamente"sus
035;..variableslocales,ydeidnticaforma,susparmetros.Seemplea
036;..paraello,demaneraextensiva,eldireccionamientoindexado.
037;
038;ObservequeestedireccionamientopuedehacerseenrelacinalSP,
039;..peroresultapreferibleenfuncindelH:X,yaqueelSPva
040;..movindosecadavezquesehaceunPUSH,unllamadodesubrutina,
041;..yestocomplicaelseguimientodelaposicindecadavariable.
042;
043;Losnmeros,talescomo:"resultEQUSTD",indicanacuntosbytes
044;..seencuentralavariableequivalente.As,"result"estsituada
045;..4bytesporencimadeX,alllamarlasubrutina'exp'
046;
047;Hganseungrficoquesealelaposicindec/variableenelstack
048;..Esoayudabastantealacomprensindeestecdigo
049;
050;==========================
051;subrutina'exp'(exponenciar)
052;
053;
054;(1)VariablesLOCALES(EnelSTACK):
055
056result:EQUSTD;nicavariable"local"de'exp'
057;Otrasvariablessedefiniranaqu.Porejemplo:
058;var2:EQUresult+1;1eseltamaoenbytesde'result'
059;var3:EQUvar2+1;1eseltamaoenbytesde'var2',etc.
060
061EXP_Vars:EQUresultSTD+1;Cantidaddevariableslocalesen'exp'
062;Laexpresines:PRIMERA_variableSTD+1
063;(*)NOTA:
064;Sifuera'result'laquemidiera2bytes,var2sera:
77
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
065;var2:EQUresult+2;etc.
066
067;
068;(2)PARMETROS(ENELSTACK,enrdenINVERSOacomoseapilan.
069;..Sisehace*PushBASE*yluego*PushEXP*,elordeneselquese
070;..indicaacontinuacin;primeroEXPyluegoBASE):
071
072exp:EQUresult+1;segundoparmetro
073base:EQUexp+1;PRIMERparmetro.Aplica(*)NOTAarriba
074
075EXP_Stack:EQUbaseSTD+1;usodelstack(vars+param)
076;LaexpresinesLTIMO_parmetroSTD+1
077
078;==========================
079;subrutina'mply'
080;(1)VARIABLESLOCALES(EnelSTACK):
081
082prod:EQUSTD;nicavariable"local"de'mply'
083
084MUL_Vars:EQUprodSTD+1;Cantidaddevariableslocalesen'mply'
085
086;
087;(2)PARMETROS(ENELSTACK):
088
089m_ador:EQUprod+1;segundoparmetro
090m_ando:EQUm_ador+1;primerparmetro
091
092MUL_Stack:EQUm_andoSTD+1;usodelstack(vars+param)
093
094;===================================================================
095;BeginofCodeSection
096ABSENTRYMain;Exportsymbol(DEBUGGERentry)
097
098ORGrom;$2080:HCS08ROMStart(Flash)
099
100;
101;***ALWAYS***includethefollowing4instructions
102Main:lda#COP_Disable
103staSOPT1;SystemOptions1
104ldhx#initStack;InitSP
105txs;..
106
107;
108;InitU
109;NOLIST
110INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
111;LIST
112
113;============================================================
114;Pasaparmetrosalarutina"expo"
115lda#mantisa;base
116psha
78
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
118lda#exponente;exp(2^5=32:0x20)
119psha
120
121ais#EXP_Vars;reservaVARIABLESlocalesen"expo"
122bsrexpo;JSRexpo.ResuladoenACC
123ais#EXP_Stack;recuperastack***ResuladoenACC***
124
125;
126bra*;SimulaunHALT.2^5=32:$20(seeACC)
127
128;===================================================================
129;RutinadeExponenciacinpormultiplicacionessucesivas
130expo:pshx;guardastackframeanterior
131pshh
132;
133tsx;MarkVariableFrameinstackwithH:X
134
135lda#1
136staresult,x
137
138ldaexp,x
139beqex_fin
140;
141;Pasarparmetrosalarutina"mply"
142expo2:ldaresult,x;pasaparmetrosalarutina"mply":
143psha;..m_ando
144
145ldabase,x;m_ador
146psha
147;
148ais#MUL_Vars;reservaareaparaVARIABLESlocales
149bsrmply;***ResuladoenACC
150ais#MUL_Stack;recuperastack
151;
152staresult,x
153ldaexp,x
154deca
155staexp,x
156beqex_fin
157braexpo2
158ex_fin:
159ldaresult,x;ResultinACC
160pulh;recuperastackframeanterior
161pulx
162rts
163;
164;RutinadeMultiplicacinporsumassucesivas
165mply:pshx;guardastackframeanterior
166pshh
167;
168tsx;MarkVariableFrameinstackwithHX
169clra
79
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
170staprod,x
171ldam_ador,x
172beqs_fin
173;
174;Loop
175mply2:ldaprod,x
176addm_ando,x
177staprod,x
178ldam_ador,x
179deca
180stam_ador,x
181beqs_fin
182bramply2
183s_fin:ldaprod,x;ResultinACC
184pulh;recuperastackframeanterior
185pulx
186rts
187
188END
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05d_L1_M.asm"]:
La primera modificacin al ejercicio que ya hemos presentado con anterioridad, es la
definicin de los valores que van a multiplicarse. Hasta ahora se usaron como
constantesnumricas:#3y#5.Aquselesdaunaidentificacinsimblica:
017;Parameterdefinitions
018mantisa:EQU2;Resultado:2^5=32(0x20enelACC)
019exponente:EQU5;Cambieaqusisedesamsvalores
Yluegovieneladiferenciafundamental:DEFINICIONDEVARIABLESLOCALES:
En lugar de las variables (globales) con las que se trabaj en los ejercicios
anteriores,seespecificaaquel"Offset"quecadaunatendrenelStack(Frame)al
momento de llamar a una subrutina. De esta manera, cada subrutina o funcin puede
direccionar "simblicamente" sus variables locales, y de idntica forma, sus
parmetros.Seempleaparaello,demaneraextensiva,eldireccionamientoindexado.
Elhechodequevariablesyparmetrosdeunafuncin,puedanmanipularseDELAMISMA
MANERA (en este caso, ambos con NOMBRES), fue una de las cosas importantes de los
lenguajesdealtonivel,comoelC.Cuandohacemosalgoascomo:
intexample(inta,intb)
{inttmp;
tmp=a*b;//mirandoestalnenopuedediferenciarseentrelos
//..parmetrosaybylavariablelocaltmp.Esel
...//..mismotratamientoparavariablesyparmetros!
}
80
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
la posicin de cada variable. En cambio, una vez marcado el STACK FRAME, con el
registro ndice, el H:X queda esttico y los desplazamientos en consecuencia no se
mueven.
Enelejercicio,losnmeroscomoeldelalnea056:
056result:EQUSTD;nicavariable"local"de'exp'
indicanacuntosbytesseencuentralavariableequivalentedentrodelStack(odentro
delSTACKFRAME,queeselreamarcadaporelregistrondiceH:X).As,"result"est
situada4bytesporencimadeH:X,alllamaryejecutarlasubrutina'exp'.Recuerde
queSTDhasidodefinidocomo:
026STD:EQU4;PosicinSTandarDdela1avariable
Ladefinicindevariablesyparmetrosparalaprimerasubrutina,'exp'(exponenciar)
escomosigue:
051;subrutina'exp'(exponenciar)
054;(1)VariablesLOCALES(EnelSTACK):
056result:EQUSTD;nicavariable"local"de'exp'
Sihubieramsvariablessedefiniranaquas:
058;var2:EQUresult+1;1estamaode'result'
059;var3:EQUvar2+1;1estamaode'var2',etc.
Sehaasumidoquevar2yvar3tendranuntamaodeunbyte.Silasvariablesfueran
WORDS,de2bytes,lasdefinicionesseranas:
058;var2:EQUresult+1;1estamaode'result'
059;var3:EQUvar2+2;2estamaode'var2'
MedicindelespaciodeStackocupadoporlasubrutina'exp':
061EXP_Vars:EQUresultSTD+1;CantidaddeVARIABLESlocalesen'exp'
062;Laexpresines:PRIMERA_variableSTD+1
AcontinuacinsedefinenlosPARMETROS(escostumbreponerlosenelStack,enorden
INVERSO a como se apilan. As se hace en C, de tal manera que una expresin como
printf( "%d", i ); introduce 'i' en el Stack y luego el FORMAT: %d. De esta manera,
como el nmero de parmetros de printf es VARIABLE, se puede averiguar con cuntos
parmetrosselallam,inspeccionandoelStringdeFORMAT,queconvenientementeesel
queesteneltechodelStack(apuntadodirectamenteporelSP1.RecuerdequeelSP
en esta mquina se dise para que apuntara a la prxima posicin VACA dentro del
Stack,adiferenciadetodaslasdemsmquinasdelorbe...)
81
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
RecuerdequeSTDhasidodefinidocomo:
026STD:EQU4;PosicinSTandarDdela1avariable
Repitoporclaridadlalnea56:
056result:EQUSTD;nicavariable"local"de'exp'
060
061EXP_Vars:EQUresultSTD+1;Cantidaddevariableslocalesen'exp'
062;Laexpresines:PRIMERA_variableSTD+1
067;
068;(2)PARMETROS(ENELSTACK,enrdenINVERSOacomoseapilan.
069;..Sisehace*PushBASE*yluego*PushEXP*,elordeneselquese
070;..indicaacontinuacin;primeroEXPyluegoBASE):
072exp:EQUresult+1;segundoparmetro.
073base:EQUexp+1;PRIMERparmetro.Aplica(*)NOTAarriba
075EXP_Stack:EQUbaseSTD+1;usodelstack(vars+param)
Elsegundosmboloauxiliarparalaliberacindeespacioenestasubrutinaes:
075EXP_Stack:EQUbaseSTD+1;usodelstack(vars+param)
Enlaexpresindelalnea072:
072exp:EQUresult+1;
'result'eslaLTIMAVARIABLEdelmtodo,ANTESdelosparmetros.(Aqu,ademsde
serlaltima,tambineslanica...)
Paralasubrutina'mply'sesigueelmismoprocedimiento:
079;subrutina'mply'
080;(1)VARIABLESLOCALES(EnelSTACK):
082prod:EQUSTD;nicavariable"local"de'mply'
084MUL_Vars:EQUprodSTD+1;Cantidaddevariableslocalesen'mply'
Lalnea084mideelnmerodevariableslocalesenestasubrutina,
084MUL_Vars:EQUprodSTD+1
Luegosedefinenlosparmetros,similarmenteacomosehizoenlasubrutinaanterior:
087;(2)PARMETROS(ENELSTACK):
089m_ador:EQUprod+1;segundoparmetro
090m_ando:EQUm_ador+1;primerparmetro
092MUL_Stack:EQUm_andoSTD+1;usodelstack(vars+param)
Estevalordelalnea092mideelUSOdelstackparaestasubrutina:
092MUL_Stack:EQUm_andoSTD+1;usodelstack(vars+param)
Note:LosvectoresdeInterrupcinestndefinidosparaarrancarenMain,enelINCLUDE
file:'InitU_M.inc',en:
82
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
110INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
Observemos cmo se pasan los parmetros a 'expo', y cmo se reservan las variables
locales:
113;============================================================
114;Pasaparmetrosalarutina"expo"
115lda#mantisa;base
116psha
117
118lda#exponente;exp(2^5=32:0x20)
119psha
Aestasalturas,sehanacomodadolosdosparmetrosenelStack.Ahorasereservael
espacioparalasvariableslocales,decrementandoelSPporlacantidaddefinidaarriba
comolacantidaddebytesdelasvariableslocales:
121ais#EXP_Vars;reservaVARIABLESlocalesen"expo"
Luegosesaltaalasubrutina,locualalejanuestrareadealmacenamiento,DOS(2)
bytesdelSP(porqueelsaltoasubrutinaimplicaguardarelPCderetornoenelStack,
yelPCmide2bytes)
122bsrexpo;JSRexpo.ResuladoenACC
Alretornar,deunasolaoperacinserecuperatodoelStack,tantoelcorrespondiente
alosparmetroscomoelocupadoporlasvariables:
123ais#EXP_Stack;recuperastack***ResuladoenACC***
Ahoraanalicemoslaprimerasubrutina,'expo'.LoprimeroquehaceesguardarelStack
Frame Anterior, que se encuentramarcado por el registro ndice: H:X. La cantidad de
bytes que ocupa el registro ndice guardado en el Stack (2 bytes) nos aleja justo 2
posicionesmsdenuestrosdatos,PARAUNTOTALDECUATRO(4)queeselvalordefinido
arribaparaelsmbolo'STD'.
130expo:pshx;guardastackframeanterior
131pshh
AhoraprocedeagenerarunNUEVOSTACKFRAME:
132;
133tsx;MarkVariableFrameinstackwithH:X
Deahenadelantelasecuenciadeoperacionesesbastantelegible:
135lda#1
136staresult,x;definidoen056result:EQUSTD
138ldaexp,x;definidoen072exp:EQUresult+1
139beqex_fin
83
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Recuerdenqueelmododedireccionamientoindexadocondesplazamientode8bits,suma
elregistrondiceH:Xconeldesplazamientoparaobtenerlaposicindelavariable,
por encima de los 4 bytes (STD) que estn ocupando el PC y el antiguo H:X. Recuerde
tambin que cada push DECREMENTA el SP. Por eso para reservar el espacio de las
variables,selesumaSPunnmeronegativo(repitolalnea121):
121ais#EXP_Vars;reservaVARIABLESlocalesen"expo"
Elcomportamientodelasiguientesubrutina,"mply",estansimilaralanterior,queno
voyacomentarmssobrel.
EnprimerlugarmostrarelejemploenC,paraWindows(compilarconVisualStudio10+)
y luego en Assembly Language para el HCS08. Cuando veamos todos estos programas
reescritosenCparaelHC9S08QE128,volveremosaverlo.
El ejercicio de las Torres de Hanoi supone 3 torres, en las que se han colocado N
discos, comenzando por el ms grande abajo, y colocando encima discos cada vez ms
pequeos. El ejercicio requiere pasar todos los discos de la torre 1 a la torre 3,
empleandolatorre2comoauxiliar.Lanicareglaesquenosepuedecolocarnuncaun
discograndesobreunomspequeo.
["Temarios\Ex#1HanoiMin\HanoiMin.c"]
01#include"hanoimin_.h"//hanoimin.cLGUribeCL12D2011J12D2013
02voidmain(intargc,char**argv)/*HANOImin.C*//*()*/
03{uintN;
04get(NDisks);
84
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
05hanoi(N,1,3);//MOVENdisksfromtower1to3.
06}/*main()*///..That'sall!
07//==================================================================
08voidhanoi(uintN,uinta,uintb)/*()*/
09{
10if(N==1)//GOTONLY1DISK?IT'SEASY!JUSTMOVEITON
11PrintW("Paseeldiscodelatorre'%d'ala'%d'",a,b);
12hanoi(N1,a,TowerTmp);//SEVERALDISKS?CALLITSELFRECURSIVELY:
13hanoi(1,a,b);
14hanoi(N1,TowerTmp,b);
15}/*hanoi()*/
B)IncludeFilehanoiMin_.h:
["Temarios\Ex#1HanoiMin\hanoiMin_.h"]
//HANOImin_h.h,LuisG.UribeC.:Playwithpaperdisks!
//S12N2005J23M2006L29G2011J12D2013
16#include<assert.h>
17#include<stdio.h>
18#include<stdlib.h>
19enum{DEFAULT=3,MAX=10};
20typedefunsignedintuint;
21voidhanoi(uintn,uinta,uintb);
22#defineget(NDisks){if(argc<2)N=DEFAULT;\
23elseif((N=atoi(argv[1]))==0)N=DEFAULT;\
24if(N>MAX){\
25puts("#Discosdebeser<=10.Asume3\n");\
26N=DEFAULT;}}
27//Printfmessage,andWaittheusertohitENTER,tocontinue
28#definePrintW(s,a,b){printf(s,a,b);getchar();return;}
29//MagicNumber!ie:fora=1&b=3,=>TowerTmp=2ETC!Sleeponit...
30#defineTowerTmp(6ab)
COMENTARIOS a ["Temarios\Ex#1-HanoiMin\HanoiMin--.c"]:
Desdeluego,meesforcenpresentarunalgoritmoMNIMO.Difcilmentepuedencolocarse
menosinstrucciones.
De'main'podemosolvidarnos:NOformapartedelalgoritmo;sirveparaleerdelusuario
el nmero de discos, N, y llamar a la respectiva funcin 'hanoi()', que es la que
realmente materializael algoritmo: Mover N discos desde la torre 'a' hasta la torre
'b':
08voidhanoi(uintN,uinta,uintb)/*()*/
10if(N==1)//GOTONLY1DISK?IT'SEASY!JUSTMOVEITON
11PrintW("Paseeldiscodelatorre'%d'ala'%d'",a,b);
85
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Como ya dijimos, si en un momento dado hay que mover UN disco (N==1), se lo pasa
simplementedelatorreFUENTE(SRC)allatorreDESTINO(DST).Esaparteesfcil:'a'
y'b'SONlastorresSRCyDST.
Ahora, si hay ms de un disco para mover entre la torre 'a' y la torre 'b', pues
tambinesmuysencillo,comoseexpresaacontinuacin:
12hanoi(N1,a,TowerTmp);//SEVERALDISKS?CALLITSELFRECURSIVELY:
13hanoi(1,a,b);
14hanoi(N1,TowerTmp,b);
LISTO.ESOESTODO.Juguenlocon12cartas(4095movimientos)yvernqueinventarse
unalgoritmoNORECURSIVO,noesnadasencillo...
B)IncludeFile
En este archivo se han colocado las cosas accesorias, que no forman parte del
algoritmo.Lonicoresaltantees:
//HANOImin_h.h,LuisG.UribeC.:Playwithpaperdisks!J12D2013
29//MagicNumber!ie:fora=1&b=3,=>TowerTmp=2ETC!Sleeponit...
30#defineTowerTmp(6ab)
ElMagicNumber,segnseseala,seobtienedeunafrmulasencillaquenospermite
saber:
Sivamosdelatorre1ala3,latemporalserla2.
Parairdela1ala2,latemporalserla3.
Y,dela2ala3,latemporalserla1.
EsafrmulaproduceelnmerodelatorreTEMPORAL,dadoslosotrosdosnmeros:SRCy
DST.
Cuando veamos los Timers, las rutinas de comunicaciones, este ejercicio... siempre
resaltoladefinicindelasPOLTICASy,aparte,laimplementacindelosmismos:los
MECANISMOS.
Otrofactorimportantequedebetenerseencuentaeseldiseo:TOPDOWN,esdecir,las
funcionalidadesdebenincluirsedesdeelnivelmsaltodelSISTEMA,eirbajandohasta
llegar a definir lo ms elemental que se requiere. Y luego, probablemente la
86
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
A) Programa HanoiMin--.asm:
["Temarios\Ex#1HanoiMin\HanoiMin.asm"]
001;hanoimin.asm,LuisG.UribeC.HanoiMinimumV27D2013
002;
003;Includefiles;Parameterdefinitions
004NOLIST
005INCLUDE'derivative.inc'
006INCLUDE'hanoimin_.inc'
007LIST
008;;<<<<<<Changehere'ND',NumberofDisks
009NDEQU3;TODO:Get"ND"frompushbuttons,orfromPC,viaSCI
010;====================================================================
011;GLOBALVariables
012ORGram
013tmpAcc:DS1;helpertocalculateMagicNumber
014;********************************************************************
015;MAINPROGRAMHEADER:
016ABSENTRYMain;Export'Main'symbol
017ORGrom
018Main:InitSys
019HanoiM#ND,#1,#3;MOVENDdisksfromtower1>3THAT'SIT!
020BRA*;Simulate"C"EXITfromMain.
021;====================================================================
022;byteHanoi_(byteN,byteTa,byteTb)//NfromTower_atoTb/*()*/
023Hanoi_:;CalledfromHanoiM(Main),andHanoi(below)recursively
024CreateNewStackFrame
025;
026ldaN,X;Acc="N",numberofdiscs(NisND
027cmp#1;..pushedbyHanoiMabove)
028bneSeveral;..if(N!=1)gotoSeveral
029;
030OnlyOne:;Only1disktomovefroma>b?MOVEIT,showtheANSWER:
031MoveOneFromSrcToDst;Acc=00Ta_00Tb
032brafin;<<<BreakheretoseeRESULTSinAcc
033;ND=3Seq:1_31_23_21_32_12_31_3
034;TODO:DisplayACCinLEDsorshowitsomehowinthePC(SCI)
035;
036Several:;GotSeveraldisks?Callitselfrecursively!
037EvalTowerTmpSrc,Dst;Acc=Temp.Towernumber:6ab
038staTowerTmp,X;..TowerTmp=6ab
039ldaN,X;n_1=n1
040deca;..
87
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
041stan_1,X;..
042;
043Hanoin_1,Src,TowerTmp
044HanoiK#1,Src,Dst
045Hanoin_1,TowerTmp,Dst
046;
047fin:RestoreOldStackFrame
048RTS
049;
050nop;<<<NEEDEDbyCodeWarrior10.15(not6.3).INCREDIBLE<<<
051;This'nop'MAYberemovedforCW6.3...
052;
053;InterruptVectors
054ORGVreset
055DC.WMain;RESET.Maximumpriority.Asynch.
056END
["Temarios\Ex#1HanoiMin\HanoiMin_.inc"]
057;HANOImin_.inc,LuisG.UribeC.:V27D2013M27Y2014
058rom:SETROMStart;$2080
059ram:SETRAMStart;PutTHISinMainprogram
060initStack:EQU$1800
061COP_Disable:EQU%01000010;$42
062STDEQU4;1stvariablepositioninStack
063;
064;Macros
065InitSysMACRO
066lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
067staSOPT1;..SystemOptions1
068ldhx#initStack;SetupSP(andH:XforStacFrame)
069txs;...
070ENDM
071;
072CreateNewStackFrameMACRO
073pshx;SavepreviousStackFrame,orderX,H
074pshh
075tsx;useH:XtopointtoStackFrame
076ENDM
077;
078RestoreOldStackFrameMACRO;intoHX.Order:H,X
079pulh;*RECOVER*oldStackFrame
080pulx
081ENDM
082;
083EvalTowerTmpMACROA,B;"ACC=6AB":MAGICNUMBER,i.e,for
084lda\1,X;tmpAcc=A
085statmpAcc;..
086lda\2,X;Acc=B
087addtmpAcc;Acc=B+A
88
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
088sub#6;Acc=B+A6
089nega;Acc=6AB
090ENDM
091;
092PushMACROPushValue;i.e:Push#3(Acc<=#3;pushAcc)
093lda\1
094psha
095ENDM
096;
097PopMACROVar;i.e:Popvar:popAcc;var<=Acc
098pula
099sta\1
100ENDM
101;
102PushHMACROPushValue;i.e:Pushdst(Acc<=dst;pushAcc)
103lda\1,X
104psha
105ENDM
106;
107PopHMACROVar;i.e:Popvar:popAcc;var<=Acc
108pula
109sta\1,X
110ENDM
111;
112HanoiMMACROn,SrcTower,DstTower;UseinMain
113Push\3;DstTower
114Push\2;SrcTower
115Push\1;nDisks
116ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
117bsrHanoi_
118ais#HANOI_Stack;RestoreStack.***ResultinACC***
119ENDM
120;
121HanoiMACROn,SrcTower,DstTower;UseRecursively
122PushH\3;DstTower
123PushH\2;SrcTower
124PushH\1;nDisks
125ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
126bsrHanoi_
127ais#HANOI_Stack;RestoreStack.***ResultinACC***
128ENDM
129;
130HanoiKMACROn,SrcTower,DstTower;1stparameterisConstant#1
131PushH\3;DstTower
132PushH\2;SrcTower
133Push#1;ONEDisk
134ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
135bsrHanoi_
136ais#HANOI_Stack;RestoreStack.***ResultinACC***
137ENDM
138;
89
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
139MoveOneFromSrcToDstMACRO
140ldaSrc,X;..(Acc)andRETURN.Acc=0000_00Ta
141nsa;..NibbleSwapAcc.:Acc=00Ta_0000
142statmpAcc;Tmp=00Ta_0000
143ldaDst,X;Acc=0000_00Tb
144oratmpAcc;..Acc=00Ta_00Tb
145ENDM
146;==============================
147;Subroutine'hanoi_'
148;In"C"itwouldbe:BYTEhanoi_(BYTEN,BYTESrc,BYTEDst);
149;
150;(1)LOCALVariables(inSTACK):
151TowerTmpEQUSTD;remembernumberoftemporaltower
152n_1EQUTowerTmp+1;store"n1"
153HANOI_VarsEQUn_1STD+1;#deBYTESlocalesen'hanoi_'
154;(2)PARAMETERS(INSTACK,in>>REVERSE<<ordertostack.
155;..Ifyoumake*PushDST*,*PushSRC*andthen*PushN*,orderisas
156;..follows:firstN,thenSRCandlastDST
157NEQUn_1+1;tercerparmetro(1byte)
158SrcEQUN+1;segundoparmetro(1byte)
159DstEQUSrc+1;PRIMERparmetro.(1byte)
160HANOI_StackEQUDstSTD+1;UsodelStack(vars+param)
COMENTARIOS a ["Temarios\Ex#1-HanoiMin\HanoiMin--.asm"]:
Bueno, analicemos primero el programa principal. Esta es la parte donde se define
cuntosdiscosvanajugar(alambradodentrodelcdigo,parahacerlosimple...)
009NDEQU3;TODO:Get"ND"frompushbuttons,orfromPC,viaSCI
Yahemosdichoquelosmtodosrecursivossebasanfundamentalmenteenvariablestipo
dinmicas(comoenelC),quesonlasquesedefinenenelStack(yahicimosejercicios
de eso). Pero aqu se necesita una variable global, visible por todas las instancias
delprocedimientorecursivo,yquesirveparadefinirculeslatorretemporal,enun
instantedado:
013tmpAcc:DS1;helpertocalculateMagicNumber
ElprogramasedefineexpresandoalmximoSLOlaspolticas.VeamosMain,quecomoen
elejemplocodificadoenC,sirvesolocomoinicializacinyllamadoalarutinaque
realizademanerarecursiva,todoeltrabajo:
018Main:InitSys
019HanoiM#ND,#1,#3;MOVENDdisksfromtower1>3THAT'SIT!
Y,ahoras,veamoslarutinarecursiva:
021;====================================================================
022;byteHanoi_(byteN,byteTa,byteTb)//NfromTower_atoTower_Tb/*()*/
023Hanoi_:;CalledfromHanoiM(Main),andHanoi(below)RECURSIVELY
024CreateNewStackFrame
90
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Se requiere definir un nuevo Stack Frame cada vez que llamamos la rutina. Ese es el
propsitodelaMacro'CreateNewStackFrame'(versuimplementacinenelINCLUDEfile).
Ahora,mirasilacantidaddediscosquetienequetransferiresUNO.Recuerdequeese
casoeselsencillo;sihayunsolodiscoparasermovidodelatorre1ala3,LISTO:
Moverlo...con'MoveOneFromSrcToDst'
026ldaN,X;Acc="N",numberofdiscs(NisND
027cmp#1;..pushedbyHanoiMabove)
028bneSeveral;..if(N!=1)gotoSeveral
029;
030OnlyOne:;Only1disktomovefroma>b?MOVEIT,showtheANSWER:
031MoveOneFromSrcToDst;Acc=00Ta_00Tb
032brafin;<<<BreakheretoseeRESULTSinAcc
033;ND=3Seq:1_31_23_21_32_12_31_3
Delocontrario,aplicarelmismoprocedimientodemanerarecursiva.Primeroobtengala
identificacin de la torre temporal (EvalTowerTmp), dadas las actuales torres SRC y
DST:
036Several:;GotSeveraldisks?CallitselfRECURSIVELY!
037EvalTowerTmpSrc,Dst;Acc=Temp.Towernumber:6ab
038staTowerTmp,X;..TowerTmp=6ab
LuegoobtengaelactualN1,quesonlosdiscosquedebenmoversealatorretemporal
039ldaN,X;n_1=n1
040deca;..
041stan_1,X;..
Y,finalmente,apliqueelprocedimientorecursivo:
043Hanoin_1,Src,TowerTmp
044HanoiK#1,Src,Dst
045Hanoin_1,TowerTmp,Dst
Porltimo,reestablezcaelvalordelantiguoStackFrame,yRETORNE:
047fin:RestoreOldStackFrame
048RTS
B)IncludeFilehanoiMin_.inc:
COMENTARIOS a ["Temarios\Ex#1-HanoiMin\hanoiMin_.inc"]:
057;HANOImin_.inc,LuisG.UribeC.:V27D2013
Las primeras lneas no necesitan especial mencin. Push y Pop se entiende con
facilidad.
EstnlasequivalentesqueusanelregistrondiceH:Xparaapuntaralvaloralquese
requierehacerpushopop:
91
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
102PushHMACROPushValue;i.e:Push#3(Acc<=#3;pushAcc)
103lda\1,X
104psha
105ENDM
106;
107PopHMACROVar;i.e:Popvar:popAcc;var<=Acc
108pula
109sta\1,X
110ENDM
La prxima Macro guarda los parmetros: DST, SRC y N en es stack, reserva (AIS) el
espacio para las variables, llama a la subrutina y al regresar, libera el espacio
ocupado en el Stack (AIS). Esta se dise para su uso en MAIN (HanoiM): (hace
referenciaalosparmetrosenformadirecta:Push):
112HanoiMMACROn,SrcTower,DstTower;UseinMain
113Push\3;DstTower
114Push\2;SrcTower
115Push\1;nDisks
116ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
117bsrHanoi_
118ais#HANOI_Stack;RestoreStack.***ResultinACC***
Hanoieslaqueseusademanerarecursiva(hacereferenciaalosparmetrosempleando
elregistrondice:PushH):
121HanoiMACROn,SrcTower,DstTower;UseRecursively
122PushH\3;DstTower
123PushH\2;SrcTower
124PushH\1;nDisks
125ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
126bsrHanoi_
127ais#HANOI_Stack;RestoreStack.***ResultinACC***
128ENDM
Finalmente,cuandoserequierepasarelnmero1(#1)comodisco,unodelosPushHde
'Hanoi'tienequecambiarseporPushsimple:
130HanoiKMACROn,SrcTower,DstTower;1stparameterisConstant#1
131PushH\3;DstTower
132PushH\2;SrcTower
133Push#1;ONEDisk
134ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
135bsrHanoi_
136ais#HANOI_Stack;RestoreStack.***ResultinACC***
137ENDM
92
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
LaMacroMoveOneFromSrcToDsteslaquerealizaelmovimiento(que,ennuestroejemplo,
consiste simplemente en mostrar en el ACUMULADOR los nmeros de las torres que
participan en cada jugada. (Esta parte debera modificarse para presentar la
informacin en los LEDs de la tarjeta DEMOQE128, o enviarla por el canal de
comunicacinserialalPCdellaboratorio,parasupresentacinporpantalla.
139MoveOneFromSrcToDstMACRO
140ldaSrc,X;..(Acc)andRETURN.Acc=0000_00Ta
141nsa;..NibbleSwapAcc.:Acc=00Ta_0000
142statmpAcc;Tmp=00Ta_0000
143ldaDst,X;Acc=0000_00Tb
144oratmpAcc;..Acc=00Ta_00Tb
145ENDM
Adems de las Macros, est la subrutina, que es el VERDADERO MOTOR DEL PROCESO
RECURSIVO,graciasasumanejodevariablesdinmicasenStack:
147;Subroutine'hanoi_'
148;In"C"itwouldbe:BYTEhanoi_(BYTEN,BYTESrc,BYTEDst);
149;
150;(1)LOCALVariables(inSTACK):
151TowerTmpEQUSTD;remembernumberoftemporaltower
152n_1EQUTowerTmp+1;store"n1"
153HANOI_VarsEQUn_1STD+1;#deBYTESlocalesen'hanoi_'
154;(2)PARAMETERS(INSTACK,in>>REVERSE<<ordertostack.
155;..Ifyoumake*PushDST*,*PushSRC*andthen*PushN*,orderisas
156;..follows:firstN,thenSRCandlastDST
157NEQUn_1+1;tercerparmetro(1byte)
158SrcEQUN+1;segundoparmetro(1byte)
159DstEQUSrc+1;PRIMERparmetro.(1byte)
160HANOI_StackEQUDstSTD+1;UsodelStack(vars+param)
SiustedentiendelaimportanciadelejerciciodelasTorresdeHanoi,yescapazde
reescribirlo por su cuenta, habr logrado culminar la parte genrica del Curso de
ArquitecturadelComputador.
TIMERS
NMERO DE TIMERS:
PorqunohacerunarutinaqueactiveydesactiveelTimer:RTC,TPM(oTIMER0enlos
PIC)deacuerdoalacantidaddemilisegundosquesequieremedir?
93
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Puesporque,comonormalmenteslohay*UN*mdulotemporizadorbsico(RTC),ysiempre
serequierenVARIOS(oMUCHOS)contadores,senecesitaranmsrecursosdehardwarede
losqueexisten!Lasolucincomnofrecevarioscontadoresporsoftware,basadosenun
slodispositivodehardware.
Anexohayunconjuntoderutinasparamanejar8temporizadoresdiferentes(quesonun
nmero razonable pero, si no le alcanzan, usted puede aumentarlos con relativa
facilidadparaajustarlosasusnecesidades!)
Estas rutinas fueron publicadas en EDN, en la versin que realic para MICROCHIP
PIC16F84A,operandoa4MHz.
EnInternet:
http://edn.com/design/URIBE:UseeighttimerswithPIC16Fxxxmicrocontrollers
1.Seactivaelprocesodelos8temporizadoresempleandolaMacro:
Init8Timers
Lamaneracomooperaneslasiguiente:'Init8Timers'genera8variables,desde'Timer0'
hasta'Timer7',queocupanDOS(2)bytescadauna,(16bits,sinsigno).
Cada 'Timer' cronometrar una cierta cantidad de tiempo, en milisegundos. Por tanto,
podrnmedirseintervalosentre1msy65,536segundos(unpocomsdeunminuto;si
necesitaextenderlomsan,ustedtienequeprogramarcontadoresdeminutos...)
ExistetambinunbyteenelqueCADABITrepresentaelestadodeUNtimer,del0al7:
lavariablellamada'TimerFlags',y8SMBOLOSquefacilitanlalecturadelestadode
cadaunodeesosbits:'Timer0Ready'a'Timer7Ready'
2.Parainicializaruntemporizador(enMiliSegundos)seusalamacro
SetimerMS.Unopuededecir:
SetimerMS0,#2;activetemporizador0conlaconstante#2:2milisegundos,o:
Enelprogramadepruebatimer8HS.asm,incluidomsadelante,seempleanas:
SetimerMS0,#50;Timer0:50mSecondsthroughCONSTANT
SetimerMS1,var;Timer1:25mSecondsthroughVARIABLE(varholds#25)
94
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
3.LamacroSetimerMSinicializauntimer,peroelflujodeprogramaNOSEDETIENEA
ESPERAR a que pase el tiempo programado. La macro WaitMS_on hace ambas cosas:
Inicializauntimer_Y_esperahastaquetranscurraellapsoindicadoenMiliSegundos:
esunarutinaBLOQUEANTE.
brsetTimer0Ready,TimerFlags,labelYES
;SielbitestSET,esporqueYAsecumplieltiempo
brclrTimer1Ready,TimerFlags,labelNOT
;SielbitestCLR,esporqueNOse;cumplieltiempo
Sin embargo usted no tiene que hacer necesariamente eso, ya que he incluido esta
funcionalidad,perfectamenteencapsuladaenlasdosmacrosadicionales,quesemuestran
acontinuacin:
TimeOuttimer,gotoAddress
;(JUMPtogotoAddressiftimerexpired.Returnwithjump/br)
TimeOutStimer,bsrAddress
;(BRANCHTOSUBROUTINEbsrAddressiftimerexpired.Returnwithrts)
TambinseincluyenlasMacrosComplementarias,parasuconveniencia:
NTimeOuttimer,gotoAddress
;..gotoAddressIFtimerhas*NOT*expired
NTimeOutStimer,callAddress
;..branchtoSubroutinecallAddressIFtimerhasNOTexpired
Antes de mostrar los programas en Assembly Language, voy a ilustrar el tema en "C"
(Windows). Luego tendrn la oportunidad de ver que las funcionalidades definidas en
EnsambladorsonEXACTAMENTELASMISMAS.Enesencialonicoquecambiaesellenguaje
deprogramacin.
Comoyahemosvistolaaproximacinalainclusindefuncionalidades,enformadeTop
DownDesign,voyapresentarenprimerlugarelincludefiletimers_h.h,quedefinelos
MECANISMOS. Despus, el programa que materializa la librera, Timers.cpp, y que
implementa los MECANISMOS. Por ltimo, un ejemplo para que se pueda visualizar el
empleodelasdiferentesfuncionalidades.timtst2.cpp:
95
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
["Laboratorios\Lab2\_New\timers_h.h"]
001/*****************************************************************/
002//timers_h.h:Windows,timeusage;LuisG.UribeC.
003//L13M2006L16O06MSVCJ01Y08C31G11V09S11S05E2013L21O2013
004/**/
005//IncludeFiles
006#include<windows.h>
007#include<conio.h>
008#include<stdio.h>
009usingnamespaceSystem;
010usingnamespaceSystem::Threading;
011#defineNTIMERS8//ThisMUSTbeapowerof2:2,4,8,16...
012/**/
013//FunctionPrototypes
014#defineTimeoutTimeouT//AvoidSystem::Timeoutconflict
015voidIniTimers(intntimers);
016voidSetimerMS(inttimer,inttimeMS);
017intTimeout(inttimer);
018voidWTimer(inttimer);
019voidWaitMS_on(inttimer,inttimeMS);
["Laboratorios\Lab2\_New\timers.cpp"]:
020/*****************************************************************/
021//Timers.cpp,WindowsLuisG.UribeC.S21S2013
022//..L13M2006L16O6VCC31G2011J17E2013(_kbhit)V08F2013
023//MSVisualStudio:Changeconfig.properties,general,toinclude:
024//..CommonLanguageRuntimeSupport(/clr)
025//..ProgramFileExtensionsMUSTbeCPP
026/**/
027//IncludeFiles
028#include"timers_h.h"
029/**/
030//GlobalVariables
031staticvolatilelongtimersMS[NTIMERS];
032/*===============================================================*/
033voidIniTimers(intntimers)/*()*/
034{//'ntimers'mustbe8inthisimplementation.ItisNOTused...
035if(NTIMERS&(NTIMERS1)){
036fprintf(stderr,
037"NTIMERS(%d)*MUST*beaPowerof2",NTIMERS);
038abort();
039}
96
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
040//LINKinitALLtimers(timersMS[NTIMERS])toZERO
041}/*IniTimers()*/
042/**/
043voidSetimerMS(inttimer,inttimeMS)/*()*/
044{
045longtc=(long)Environment::TickCount;//ticks(milliSeconds)
046timersMS[timer&(NTIMERS1)]=
047tc+(long)timeMS;//ticks(milliSeconds)
048}/*SetimerMS()*/
049/**/
050intTimeout(inttimer)/*()*/
051{
052longtc=(long)Environment::TickCount;//ticks(milliSeconds)
053_kbhit();//EnableCtrlCtesting!
054if(timersMS[timer&(NTIMERS1)]>=(tc))
055return(0);
056return(1);
057}/*Timeout()*/
058/**/
059voidWTimer(inttimer)/*()*/
060{
061longtc=(long)Environment::TickCount;//ticks(milliSeconds)
062if(timersMS[timer&(NTIMERS1)]tc>0)
063Thread::Sleep(timersMS[timer&(NTIMERS1)]tc);
064}/*WTimer()*/
065/**/
066voidWaitMS_on(inttimer,inttimeMS)/*()*/
067{
068SetimerMS(timer,timeMS);
069WTimer(timer);
070}/*WaitMS_on()*/
["Laboratorios\Lab2\_New\timtst2.cpp"]:
071char*_id=
072"timtst2.cpptestingroutines(Lite,WINDOWS).LuisG.UribeC.,"
073"C07S2011L31O2013\n";
074//char*_usage="timtest2\n";
075//cctimtst2.ctimers.c
076/**/
077/*IncludeFiles*/
97
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
078#include<stdio.h>
079#include<stdlib.h>
080#include"timers_h.h"
081/**/
082/*GlobalVariables*/
083chartext[]="1234567890";
084/*===============================================================*/
085voidmain(void)/*()*/
086{char*p=text;
087puts(_id);
088IniTimers(8);//only8timersallowedatthistime
089fputs("\n0)Press'ENTER'toprintw/odelays________",stdout);
090_getch();
091for(p=text;*p;p++){//ImpresinSINretardos
092_putch(*p);//putcharmaybebuffered;use_putch
093}
094/**/
095//RTCTest:Show3waysforcallingTimerRoutines.See://<<<
096fputs("\n1)Press'ENTER'tocontinueat300ms/char_",stdout);
097_getch();
098for(p=text;*p;p++){//ImpresinconWait_ona300mS.
099_putch(*p);
100WaitMS_on(0,300);//<<<BLOCKCPUfor300ms
101}
102fputs("\n2)Press'ENTER'tocontinueat750ms/char_",stdout);
103_getch();
104for(p=text;*p;p++){//Impresinconwhilea750mS.
105_putch(*p);
106SetimerMS(7,750);//<<<Setuptimer
107//<<<Dohereanyprocessyouneed
108WTimer(7);//<<<..waitforremainingtime
109}
110fputs("\n3)Press'ENTER'tocontinueat200ms/char_",stdout);
111_getch();
112p=text;//Impresinconwhilea200mS.
113ploop:
114while(*p){
115_putch(*p++);
116SetimerMS(5,200);//<<<Setuptimer
98
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
117//<<<Dohereanyprocessyouneed
118while(1){
119if(Timeout(5)){//<<<Testconditionlater...
120gotoploop;//<<<..finish?printnextchar
121}//<<<Youwon'tneedGOTOs!
122}
123}
124fputs("\n4)Press'ENTER'tocontinueat500ms/char_",stdout);
125_getch();
126for(p=text;*p;p++){//Impresinconwhilea500mS.
127_putch(*p);
128WaitMS_on(0,500);//<<<
129}
130fputs("\n5)Press'ENTER'tocontinueat1000ms/char",stdout);
131_getch();
132for(p=text;*p;p++){//Impresinconwhilea500mS.
133_putch(*p);
134WaitMS_on(0,1000);//<<<
135}
136fputs("\n6)Press'ENTER'toReturntofullspeed____",stdout);
137_getch();
138puts(text);
139puts("\nEnd...(Press'ENTER'tofinish)");
140getchar();
141exit(0);
142}/*main()*/
COMENTARIOS a ["Laboratorios\Lab2\_New\timers_.h"]:
El include file no tiene nada extrao; bsicamente define las funciones que se
implementarnacontinuacin.
011#defineNTIMERS8//ThisMUSTbeapowerof2:2,4,8,16...
Las funcionalidades que se ofrecen son casi idnticas a las que mencionamos en la
introduccin,yalasqueimplementaremosenlenguajeensamblador:
015voidIniTimers(intntimers);
016voidSetimerMS(inttimer,inttimeMS);
017intTimeout(inttimer);
018voidWTimer(inttimer);
019voidWaitMS_on(inttimer,inttimeMS);
99
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Laboratorios\Lab2\_New\timers.cpp"]:
LavariabletimersMSesglobal,porconveniencia:
031staticvolatilelongtimersMS[NTIMERS];//GlobalVariable
IniTimers(8)(elparmetronointeresa;perosevalidaqueNTIMERSseapotenciade2)
033voidIniTimers(intntimers)/*()*/
034{//'ntimers'mustbe8inthisimplementation.ItisNOTused...
035if(NTIMERS&(NTIMERS1)){
036fprintf(stderr,
037"NTIMERS(%d)*MUST*beaPowerof2",NTIMERS);
038abort();
039}
040//LINKinitALLtimers(timersMS[NTIMERS])toZERO
041}/*IniTimers()*/
Paraactivaruntimer:
043voidSetimerMS(inttimer,inttimeMS)/*()*/
044{longtc=(long)Environment::TickCount;//ticks(milliSeconds)
046timersMS[timer&(NTIMERS1)]=
047tc+(long)timeMS;//ticks(milliSeconds)
048}/*SetimerMS()*/
SetomaunadelasrepresentacionesdelahoradeWindows:TickCount(enMilisegundos);
selesumaeltiemporequerido,timeMS,enmilisegundostambin,yseloalmacenaenla
variablecorrespondientealtemporizadordeseado,timer.
La funcionalidad para establecer si ya venci el plazo seleccionado para algn
temporizador,timer,es'Timeout':
050intTimeout(inttimer){
052longtc=(long)Environment::TickCount;//ticks(milliSeconds)
053_kbhit();//EnableCtrlCtesting!
054if(timersMS[timer&(NTIMERS1)]>=(tc))
055return(0);
056return(1);
057}/*Timeout()*/
Timeout()leeen'tc'larepresentacindelahora,TickCountenMS,vigenteparael
momento en que se lo ejecuta; y compara si el valor almacenado para el temporizador
'timer' es mayor o igual a 'tc'. En caso de ser as significa que el tiempo actual,
'tc',nohasobrepasadoanalmemorizadoparaeltemporizador'timer'.Enesecaso,se
retornaun'0',queindiquequeannoestListoesetemporizador.
100
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Si,porelcontrario,eltiempoalmacenadoNOessuperioraltiempoactual,'tc',es
porque el tiempo ya ha sobrepasado el valor esperado por el temporizador deseado,
'timer',ysedevuelveun'1'indicandoqueeselapsoYAEXPIR.
WTimer consiste en detener el flujo del programa (bloquearlo) y esperar hasta que el
tiempo del temporizador 'timer', que ha sido previamente activado mediante un
SetimerMS, expire. Emplea una funcionalidad adhoc del Windows: Sleep(). Esta
implementacin tiene la ventaja de que al programa lo suspende el sistema operativo
hastaquesecumplalacondicin,yWindowspuedeadjudicarelCPUyotrosrecursos,
comolamemoria,eldisco,etc.,aalgnprocesoqueseencuentreendisponibilidadde
trabajar(estReady).
059voidWTimer(inttimer)/*()*/
060{longtc=(long)Environment::TickCount;//ticks(milliSeconds)
062if(timersMS[timer&(NTIMERS1)]tc>0)
063Thread::Sleep(timersMS[timer&(NTIMERS1)]tc);
064}/*WTimer()*/
Cuando hay que activar un temporizador, y el flujo del programa no puede continuar
hasta que transcurra el intervalo seleccionado, la funcionalidad BLOQUEANTE que se
empleaesWaitMS_on:
066voidWaitMS_on(inttimer,inttimeMS)/*()*/
067{SetimerMS(timer,timeMS);
069WTimer(timer);
070}/*WaitMS_on()*/
COMENTARIOS a ["Laboratorios\Lab2\_New\timtst2.cpp"]:
Elprogramadeprueba,timtst2.cpp,seexplicaporsmismo.
["Laboratorios\Lab2\Timers8HS\timers8HS.inc"]
001;Timers8HS.inc:LuisG.UribeC.,Basic8TimersSupportL30D2013
002;====================================================================
003;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
004;
005;Init8Timers:Init8Timerslibrary
006;
007;SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
008;..Settimerandcontinuetowork
009;
010;WaitMS_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
011;..SettimerandBLOCKuntiltimerexpires
012;
013;TimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
014;..gotoAddressIFtimerhasexpired
101
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
015;NTimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
016;..gotoAddressIFtimerhas*NOT*expired
018;TimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
019;..branchtoSubroutinecallAddressIFtimerhasexpired
020;NTimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
021;..branchtoSubroutinecallAddressIFtimerhasNOTexpired
022;
023;WaitISR_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
024;..SettimerandBLOCKuntiltimerexpires,INSIDEsomeISR
025;
026;TIMERS8ISR:ISRroutinestoupdate8timers(userneedtoINCLUDE
027;..thisMacroinMAINbutitisofnofurtherconcern)
028;====================================================================
029;DATADEFINITION.
030;Define8timersGlobalVariables
031;Note:Macrodirectives(DW,$IF...)cannnotgointomacros...GOK!
033;NOTE:REQUIRES'ORGram'**BEFORE**INCLUDE'timers8HS.inc'
034;..inmainprogram,tomakethisdatadefinitionswork!
035;***ALLfollowingvariables>>>MUST<<<resideonZEROpage!***
036;..(Timerflagsusebsetandbclr...)
037;
038;TimerDef:MACROandVariablesDEFINITION
039TimerDef:MACROtimer
040Timer\1:DS.W1;16bitcounters:65536mS:morethan
041Timer\1.RdyEQU\1;..oneminuteeachtimer(1mSTick)
042ENDM
043TimerDef0
044TimerDef1
045TimerDef2
046TimerDef3
047TimerDef4
048TimerDef5
049TimerDef6
050TimerDef7
051TimerFlags:DS.B1;8bitflags:Timer0,Timer1..
052;
053;DEFINES
054;ram:SETZ_RAMStart;<<<TIMERS8:PutTHISintoMainprogram<<<
055rom:SETROMStart;$2080
056initStack:EQURAMEnd+1;$1800=$17FF+1.Stackbeginson$17FF
057COP_Disable:EQU$42
058;
059;DefinesBitsforRTCProgramming
060;..RTCSC($1830)bits.02MC9S08QE128RM(ReferenceManual)U.pdf,p.246
061RTCPS_BY_ONEEQUmRTCSC_RTCPS3;..Bit#8Divideby1,gives1mSTick
062RTCIE:EQURTCSC_RTIE;..Bit#4RealTimeInterruptEnable
063RTCIE.bitEQUmRTCSC_RTIE;..Bit#4RealTimeClockInt.Enable
064NOT_RTCIE.bitEQU(~RTCIE.bit&$00FF)
065RTCIF:EQURTCSC_RTIF;..Bit#7RealTimeInterruptEnable
066RTCIF.bitEQUmRTCSC_RTIF;..Bit#7RealTimeClockInt.Enable
067ONE_KHZEQU0;Useinternaldefault1Khzclocksrc.
068RTC_FLAGSEQU(RTCIF.bit|ONE_KHZ|RTCIE.bit|RTCPS_BY_ONE)
102
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
069;====================================================================
070;MoreMACRODEFINITIONS
071TimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
072brset\1,TimerFlags,\2
073ENDM
074;
075NTimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
076brclr\1,TimerFlags,\2
077ENDM
078;
079TimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
080brclr\1,TimerFlags,\@cont
081bsr\2
082\@cont:
083ENDM
084;
085NTimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
086brset\1,TimerFlags,\@cont
087bsr\2
088\@cont:
089ENDM
090;
091SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
092bset\1,TimerFlags;MaketimerXReady...Mutex!!!
093pshh;saveH:X
094pshx;..
095ldhx\2;timeinmilliseconds(50)<<<
096sthxTimer\1;..<<<
097pulx;restoreH:X
098pulh;..
099bclr\1,TimerFlags;MaketimerXNotReady...
100ENDM
101;
102WaitMS_on:MACROtimer,time;timeisConstantorVariable
103SetimerMS\1,\2
104brclr\1,TimerFlags,*;Wait'time'msecondson'timer'
105ENDM
106;
107WaitISR_on:MACROtimer,time;timeisConstantorVariable
108psha;saveACC
109tpa;pushCCRSavesIMaskstatus
110psha;..
111sei;DISABLEINTERRUPTS(IMask=1):Let
112SetimerMS\1,\2;..SetimerusedinsideInt.Routines
113cli;REENABLEINTERRUPTS:LetRTCCount
114brclr\1,TimerFlags,*;Wait'time'msecondson'timer'
115pula;RestoreInterruptFlagMask
116tap;..toitsSavedvalue
117pula;RestoreACC
118ENDM
119;
120;AncillaryMACRODEFINITIONS
103
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
121UpdateTmr:MACROtimer
122brsetTimer\1.Rdy,TimerFlags,\@Next;Mutex!!!
123ldhxTimer\1;loadH:X
124aix#1;decrementTimerXX
125sthxTimer\1;..
126bne\@Next
127bsetTimer\1.Rdy,TimerFlags;0?:MarkTimerXXREADY
128\@Next:
129ENDM
130;====================================================================
131;RTCINIT.ThisisthebaseforTimerSupport
132Init8Timers:MACRO
133clrx
134clrh
135sthxTimer0;InitTimer0to0
136sthxTimer1;InitTimer1to0
137sthxTimer2;InitTimer2to0
138sthxTimer3;InitTimer3to0
139sthxTimer4;InitTimer4to0
140sthxTimer5;InitTimer5to0
141sthxTimer6;InitTimer6to0
142sthxTimer7;InitTimer7to0
143mov#$FF,TimerFlags;SetALL8bittimersflags:Done!
144lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
145staRTCSC;..ClearRTCIF;IntEnableRTC
146ENDM
147;====================================================================
148;RTCInterruptServiceRoutine(ISR).90cycles...
149TIMERS8ISR:MACRO
150pshh;HNotsavedbyInterruptprocess
151UpdateTmr0;ProtectedfromSetimersbyMutex
152UpdateTmr1;...
153UpdateTmr2
154UpdateTmr3
155UpdateTmr4
156UpdateTmr5
157UpdateTmr6
158UpdateTmr7
159;
160RTCISRexit:
161lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
162staRTCSC;..ClearRTCIF;IntEnableRTC
163pulh;HnotrestoredbyRTIprocess
164rti;..ReturnfromInterrupt
165ENDM
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\timers8HS.inc"]:
Losaspectosmssobresalientesson:
003;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
005;Init8Timers:Init8Timerslibrary
104
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
007;SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
008;..Settimerandcontinuetowork
010;WaitMS_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
011;..SettimerandBLOCKuntiltimerexpires
013;TimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
014;..gotoAddressIFtimerhasexpired
015;NTimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
016;..gotoAddressIFtimerhas*NOT*expired
018;TimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
019;..branchtoSubroutinecallAddressIFtimerhasexpired
020;NTimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
021;..branchtoSubroutinecallAddressIFtimerhasNOTexpired
023;WaitISR_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
024;..SettimerandBLOCKuntiltimerexpires,INSIDEsomeISR
026;TIMERS8ISR:ISRroutinestoupdate8timers(userneedtoINCLUDE
027;..thisMacroinMAINbutitisofnofurtherconcern)
029;DATADEFINITION.
033;NOTE:REQUIRES'ORGram'**BEFORE**INCLUDE'timers8HS.inc'
034;..inmainprogram,tomakethisdatadefinitionswork!
Esta es el primer REQUISITO IMPORTANTE para emplear esta librera: en Main, ANTES de
INCLUIR 'timers8HS.inc', debe haberse hecho un: 'ORG ram' Esto se debe a que esta
libreradefinesuspropiasvariables,yrequiereencontrarseenelDATASEGMENTala
horadehacerlo.
039TimerDef:MACROtimer
040Timer\1:DS.W1;16bitcounters:65536mS:morethan
041Timer\1.RdyEQU\1;..oneminuteeachtimer(1mSTick)
043TimerDef0
...etc.,hasta7.
Observe algo con detenimiento. A veces algn usuario de la librera necesita emplear
nicamente un pequeo valor en sus temporizadores, y decide usar slo un byte para
representar sus retardos... Cuando van a cambiar el valor del WORD que representa el
contador,loalmacenansimplementeenlavariableTimerN(digamos,Timer0).YESTMAL.
TienenquerecordarqueestamquinaesBIGENDIAN,yqueelvalorTerminaldeunWORD
esten"Timer0+1"(enelsegundobytedelWORD).
UnaaproximacinmejorseracargarelvalorenelregistrondiceH:X(suvalorde8
bits quedara en la parte inferior de ndice) y mover sus 16 bits a Timer0; el
procesadorloalmacenacomocorresponde,dejandoelbytequerepresentasuinformacin,
enlaparteapropiadadelavariable.
059;DefinesBitsforRTCProgramming
105
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
LomejoresqueverifiqueTODOSlosbitsempleadosaqu,conelReferenceManualdel
MC9S08QE128, en donde estn claramente definidos todos y cada uno de los bits aqu
utilizados.
AlleerlasMacrosyfuncionesdefinidasenestalibrera,estpendientedecaeren
cuentadelaimplementacinDownUp,delomselementalhastalomssofisticado.
091SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
Loprimeroquehace,antesdecomenzarajugarconlasvariablesasociadas,esmarcar
ese timer como READY (tiempo expirado). Lo hace colocando un uno (1) en el
correspondientebitdeTimerFlags:
092bset\1,TimerFlags;MaketimerXReady...Mutex!!!
Luego resguarda el registro ndice, que va a usar para cargar el valor del tiempo
(time)yalmacenarloenlavariableasociada(TimerX).Observelasangraeneltexto,
queresaltavariasinstruccionesparaunasolaoperacin.Finalmente,recuperaelvalor
delregistrondice:
093pshh;saveH:X
094pshx;..
095ldhx\2;timeinmilliseconds(50)<<<
096sthxTimer\1;..<<<
097pulx;restoreH:X
098pulh;..
099bclr\1,TimerFlags;MaketimerXNotReady...
ParalaMacroWaitMS_onresultatambininnecesarioalgnotrocomentario.
TAMPOCOUSEELMISMONMERODETIMERDENTRODELASRUTINASDEINTERRUPCIONESYENEL
PROGRAMAPRINCIPAL.
106
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
107WaitISR_on:MACROtimer,time;timeisConstantorVariable
Resguarda en el Stack el valor del acumulador; salva tambin el valor del CCR en el
Stack,paraguardarelestadoactualdelCPUyFUNDAMENTALMENTESIESTHABILITADOPARA
INTERRUPCIONES,ODESHABILITADO(IFlag)
Esto es importante porque, al momento de usar esta Macro WaitISR_on, la rutina debe
deshabilitar las interrupciones para poder trabajar toqueteando las variables del
timerinvolucrado.LuegodeesohabralatendenciaaREHABILITARlasinterrupciones...
pero lo que corresponde es DEJARLAS COMO ESTABAN cuando WaitISR_on comenz a
trabajar...Delocontrario,segenerarunDESASTRE.
108psha;saveACC
109tpa;pushCCRSavesIMaskstatus
110psha;..
Ahorasedeshabilitanlasinterrupciones(SEI)pues,comoacabodedecir,nosepuede
manipularlaestructuradedatosdeuntimer,sihaylaposibilidaddequeotrarutina,
fuera de sta interrupcin, tambin trate de hacerle cambios. Lo apropiado es
DESHABILITARLAS...
111sei;DISABLEINTERRUPTS(IMask=1):Let
Luego,semodificalaestructuradedatosdeltemporizador(SetimerMS)yseREHABILITAN
LAS INTERRUPCIONES (CLI), pues de lo contrario el timer no funcionara, ya que opera
porinterrupciones.Sehaceunbucledeespera(quenonecesariamenteesBLOQUEANTE,ya
quelasinterrupcionesestnACTIVAS!).
112SetimerMS\1,\2;..SetimerusedinsideInt.Routines
113cli;REENABLEINTERRUPTS:LetRTCCount
114brclr\1,TimerFlags,*;Wait'time'msecondson'timer'
Alterminarel'brclr',habrexpiradoeltimer;yeshoraderecomponertodo.
115pula;RestoreInterruptFlagMask
116tap;..toitsSavedvalue
117pula;RestoreACC
EsimportantenotarenUdateTmr,queNOTOCANADA(dadoqueentraporinterrupciones)
sielbitasociadoaltimerestenuno:
122brsetTimer\1.Rdy,TimerFlags,\@Next;Mutex!!!
(y,notequeSetimerloprimeroquehace,antesdemanipularnadams,escolocarese
bit en uno. As, si Setimer ha comenzado a actualizar la estructura de datos de un
temporizador dado, la rutina de interrupciones NO LO ACTUALIZAR, gracias a ese bit
que, adems de servir de indicador de READY, sirve como Semforopara la apropiacin
MutuamenteExclusivadeeserecurso:MUTEX)
120;AncillaryMACRODEFINITIONS
121UpdateTmr:MACROtimer
122brsetTimer\1.Rdy,TimerFlags,\@Next;Mutex!!!
123ldhxTimer\1;loadH:X
124aix#1;decrementTimerXX
107
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
125sthxTimer\1;..
126bne\@Next
127bsetTimer\1.Rdy,TimerFlags;0?:MarkTimerXXREADY
128\@Next:
La rutina de inicializacin de las variables, Init8Timers, no necesita mayores
aclaratorias.Soloqueenlaslneas144,145seescogeunrelojparaelRTC,queesde
1KHz(1milisegundoportick),muyconvenienteparanuestrospropsitos.Haytodauna
gama diferente para escoger; a usted le toca estudiarla, en caso de que sus
temporizadoresrequieransermuchomsrpidos,omslentos.
132Init8Timers:MACRO
...
144lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
145staRTCSC;..ClearRTCIF;IntEnableRTC
La rutina de interrupcin del RTC (Real Time Clock: TIMERS8ISR), que atiende las
actualizacionesdelosdiversostemporizadores,sebasaenlaMacroUpdateTmrque,como
yavimos,respetaauntemporizadorsifueradeestarutinadeinterrupciones,alguien
loestmanipulando,vaSetimer:
148;RTCInterruptServiceRoutine(ISR).90cycles...
149TIMERS8ISR:MACRO
150pshh;HNotsavedbyInterruptprocess
151UpdateTmr0;ProtectedfromSetimersbyMutex
152UpdateTmr1;...
153UpdateTmr2
154UpdateTmr3
155UpdateTmr4
156UpdateTmr5
157UpdateTmr6
158UpdateTmr7
160RTCISRexit:
161lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
162staRTCSC;..ClearRTCIF;IntEnableRTC
163pulh;HnotrestoredbyRTIprocess
164rti;..ReturnfromInterrupt
Lascosasquehayquerecordarparaemplearcorrectamentelalibreradetimers,estn
todasmarcadasenlosejemplosconelsmbolo:<<<
Nodejedemiraresasmarcasenlosejemplos,yatenderalasrecomendaciones...
["Laboratorios\Lab2\Timers8HS\timer8HS.asm"]
01;********************************************************************
02;ProgramaTimer8HS.asm:TSTTimerSupport
03;LuisG.UribeC.,L24N2003L08N4M27F7D08L7(timeOut)J16M2009
04;V31Y9V08J2012C04D2013L09D2013
108
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
05;
06;Includefiles
07;
08;CHECKLIST:ConserveelordenYlaposicinrelativade:
09;..derivative.inc,timers8HS.inceInit8Timers
10;
11;SiusaInit8Timers,*TIENE*queinicializarelvector:INT_RTC
12;..conDC.WRTC_INTERRUPT
13NOLIST
14INCLUDE'derivative.inc'
15LIST
16;
17;2)DEFINES
18ram:SETZ_RAMStart;<<<TIMERS8:<<<
19;====================================================================
20;3)GlobalVariables
21ORGram;<<<TIMERS8:*BEFORE*'timers8HS.inc'<<<
22NOLIST
23include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
24LIST
25var:DS.W1
26var2:DS.W1
27;********************************************************************
28;BeginofCodeSection
29ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
30ORGrom
31;
32;Alwaysincludethefollowing4instructions
33Main:lda#COP_Disable
34staSOPT1;SystemOptions1
35ldhx#initStack;InitSP
36txs
37Init8Timers
38;====================================================================
39;MainLoop(YourCode)
40ldhx#300;Beginwith300mSdelay,via'Var'
41sthxvar;..
42ldhx#2;2mSdelay,viaVar2
43sthxvar2;..
44;
45cli;Enableinterruptsnow
46;
109
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
47again:
48Setimer2,#200;Begin200mSecondsviaConstant
49Setimer5,var;300mSecondsviaVARIABLE
50loop:TimeOut2,Two_on;IfTimeOut2gotoTwo_on
51TimeOutS5,Five_on;elseifTimeOut5,brstoFive_on
52braloop;else'loop'
53;
54Five_on:;FromBRS(TimeOutS);returnviaRTS
55lda#5;ACC=5:identifyTHISroutine
56Setimer5,var;Reinstalltimer5w/300mS
57WaitMS_on7,var2;2mSecondsfromVariable(var2)
58ldhxvar
59bneFive_cont
60rts
61Five_cont:
62aix#1
63sthxvar
64rts
65;
66Two_on:;FromBRA(TimeOut);returnviaBRA
67lda#2;ACC=2:identifyTHISroutine
68Setimer2,#200;Reinstalltimerw/200mS
69WaitMS_on0,#150;TestWaitMS_onconstant
70braloop
71;====================================================================
72;PROGRAMTRAILER:
73;
74;1)TIM8INTMacro
75;2)InterruptVectors
76;
77;
78;RTCInterruptServiceRoutine,siusaInit8Timers...
79RTC_INTERRUPT:
80TIMERS8ISR
81;
82;InterruptVectors
83dummy_isr:;<<<MustbeplacedinROMSpace
84rti
85ORGVrtc;Increasingpriorityfrombottomup
86DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
87ORGVirq;Virq,VswiandVreset
88DC.Wdummy_isr;IRQ
89DC.Wdummy_isr;SWI
90DC.WMain;RESET.Maximumpriority.Asynch.
91END
110
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\timer8HS.asm"]:
Aspectosnovedosos:
18ram:SETZ_RAMStart;<<<TIMERS8:<<<
20;3)GlobalVariables
21ORGram;<<<TIMERS8:*BEFORE*'timers8HS.inc'<<<
22NOLIST
23include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
24LIST
33Main:lda#COP_Disable
...
37Init8Timers
40ldhx#300;Beginwith300mSdelay,via'Var'
41sthxvar;..
42ldhx#2;2mSdelay,viaVar2
43sthxvar2;..
44;
45cli;Enableinterruptsnow
Sueleolvidarseesteltimopaso,ynadafunciona.Esttodoactivo,peroelprocesador
ignoratodaslasinterrupciones.
LomismosueleocurrirconlarutinadeinterrupcionesdelRTC.Hayqueincluirlade
acuerdoalsiguientecdigo:
79RTC_INTERRUPT:
80TIMERS8ISR
82;InterruptVectors
85ORGVrtc;Increasingpriorityfrombottomup
86DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
...
["Laboratorios\Lab2\Timers8HS\tim8_IRQHS.asm"]
001;********************************************************************
002;ProgramaTim8_IRQHS.asm:TimercallsinsideIRQISRJ01M2007D12A09
003;LuisG.UribeC.,J16A09V29Y09V08J2012C20F2013S21D2013
004;C20F2013:Use'WaitISR_on7,delay'onIRQISR,insteadofWaitMS_on
005;
006;ProgramshowSinteractionsbetweenRTC'timers8'interruptroutines
007;..and'IRQ'interrupts,whenitisneededtorequesttimerdelays
008;..fromIRQISR.Thisisatypicalcasewhenyouneedtorearmglobal
009;..interruptsDESPITETHEADVISEINCONTRARYFROMMOTOROLATECHNICAL
111
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
010;..DOCUMENTS...(cfr.01CPU08RM!ReferenceManualU.pdf,page30)
011;
012;
013;Includefiles
014NOLIST
015INCLUDE'derivative.inc'
016LIST
017;
018;Parameterdefinitions
019IRQACK:EQUIRQSC_IRQACK
020IRQIE:EQUIRQSC_IRQIE
021IRQPE:EQUIRQSC_IRQPE
022ram:SETZ_RAMStart;$80
023;====================================================================
024;GlobalVariables
025ORGram;Putthis*BEFORE*'timers8HS.inc'
026NOLIST
027include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
028LIST
029delay:DS.W1
030counter:DS.B1
031;********************************************************************
032;MAINPROGRAMHEADER:
033ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
034ORGrom
035Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
036staSOPT1;..SystemOptions1
037ldhx#initStack;InitSP
038txs
039;====================================================================
040;ExternalInterruptInitialization(>>>IRQ<<<)
041;1.MaskinterruptsbyclearingIRQIEinIRQSC.
042;(IRQIE=0onPoweronReset,byDefault)
043;2.SelectthepinpolaritybysettingtheappropriateIRQEDGbits
044;inIRQSC(IRQEDG=0isfallingedgetriggering)
045;(IRQEDG=0onPoweronReset,byDefault)
046;3.Ifusinginternalpullup/pulldowndevice,cleartheIRQPDDbit
047;inIRQSC(IRQPDD=0onPoweronReset,byDefault)
048;4.EnabletheIRQpinbysettingtheappropriateIRQPEbitinIRQSC
049;(IRQPE=0byDefaultonPoweronReset>>>WEMUSTsetIRQPE=1<<<)
050;NOTE:IRQSC:equ$000F?ZeroPageRegister.UseDirectaddressing!!
051;5.WritetoIRQACKinIRQSCtoclearanyfalseinterrupts.
052;6.SetIRQIEinIRQSCtoenableinterrupts
112
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
053bsetIRQPE,IRQSC;4.above
054bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
055bsetIRQIE,IRQSC;6.above
056;
057mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
058mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)
059ldhx#20;timeinmilliseconds(20)
060sthxdelay;..
061mov#$FF,counter;Decrement!!!insteadofincrement...
062mov#$FF,PTCD;Ledshavenegativelogic:0tolight
063mov#$FF,PTED;..
064Init8Timers
065;
066;MainLoop
067cli;GlobalEnableinterruptsNOW
068again:braagain
069;====================================================================
070;PROGRAMTRAILER:
071;
072;1)TIM8INTMacro
073;2)InterruptVectors
074;
075;
076;RTCInterruptServiceRoutine,siusaInit8Timers...
077RTC_INTERRUPT:
078TIMERS8ISR
079;
080;IRQINTERRUPTSERVICEROUTINE
081;IRQhasoneofthehighestprioritiesintheHCS08,andthehigher
082;..hardwarepriority,bellowResetandSWI.Thatisokfor
083;..responsiveness,butcaremustbetakentoassurethatno
084;..>>>PRIORITYINVERSION<<<ocurrsthroughlongISRtimes,for
085;...examplebyusingdebouncingdelays.Ifthisisthecase,you
086;..MUSTautodisabletheIRQinterruptsandreenableglobal
087;..interrupts,topermitotherlowerperipheralsaccess...
088IRQISR:
089bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**
090pshh;Notsavedbyinterruptproc
091;
092;20mSdelayprocessingforIRQISR:Helptoavoidmultiple
093;..interruptsduetocontactbouncingfromIRQpin...
094WaitISR_on7,delay;20MSecondsfordebouncing.Thisonly
095;..worksifRTCisenabledtointerrupt..
096;..YoucouldhaveincludedNOPloopsto
097;..delay:butyouCANNOTblockallother
098;..peripheralinterrupts!So,youmust
099;..followthissamestrategy...
113
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
100;
101;***NOTE***Timer7>>>MUSTNOT<<<BEUSEDANYWHEREELSE!
102;..ItbelongsEXCLUSIVELYtothis'IRQISR'
103;
104deccounter;DriveLEDsusingnegativelogic,is
105movcounter,PTCD;6bitstodriveLEDs
106movcounter,PTED;2bitsmoretodrivehigherLEDs
107IRQISRexit:
108bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
109bsetIRQIE,IRQSC;ReenableIRQinterrupts
110pulh;Notrestoredbyinterruptprocess
111rti;ReturnfromInterrupt
112;
113;InterruptVectors
114ORGVrtc;Increasingpriorityfrombottomup
115DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
116ORGVirq
117DC.WIRQISR;IRQ
118ORGVreset
119DC.WMain;RESET.Maximumpriority.Asynch.
120END
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\tim8_IRQ-HS.asm"]:
Aspectosnovedosos:
ProtocolocompletodeHabilitacindelIRQ:ExternalInterruptInitialization
(>>>IRQ<<<)
041;1.MaskinterruptsbyclearingIRQIEinIRQSC.
042;(IRQIE=0onPoweronReset,byDefault)
043;2.SelectthepinPOLARITYbysettingtheappropriateIRQEDGbits
044;inIRQSC(IRQEDG=0isfallingedgetriggering)
045;(IRQEDG=0onPoweronReset,byDefault)
046;3.Ifusinginternalpullup/pulldowndevice,cleartheIRQPDDbit
047;inIRQSC(IRQPDD=0onPoweronReset,byDefault)
048;4.EnabletheIRQpinbysettingtheappropriateIRQPEbitinIRQSC
049;(IRQPE=0byDefaultonPoweronReset>>>WEMUSTsetIRQPE=1<<<)
050;NOTE:IRQSC:equ$000F?ZeroPageRegister.UseDirectaddressing!!
051;5.WritetoIRQACKinIRQSCtoclearanyfalseinterrupts.
052;6.SetIRQIEinIRQSCtoenableinterrupts
114
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
053bsetIRQPE,IRQSC;4.above
054bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
055bsetIRQIE,IRQSC;6.above
ProgramacindelosLEDs:
057mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
058mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)
059ldhx#20;timeinmilliseconds(20)
060sthxdelay;..
LosLEDsestnalambradosparaENCENDERconunCERO:
061mov#$FF,counter;Decrement!!!insteadofincrement...
062mov#$FF,PTCD;Ledshavenegativelogic:0tolight
063mov#$FF,PTED;..
080;IRQINTERRUPTSERVICEROUTINE
081;IRQhasoneofthehighestprioritiesintheHCS08,andthehigher
082;..hardwarepriority,bellowResetandSWI.Thatisokfor
083;..responsiveness,butcaremustbetakentoassurethatno
084;..>>>PRIORITYINVERSION<<<ocurrsthroughlongISRtimes,for
085;...examplebyusingdebouncingdelays.Ifthisisthecase,you
086;..MUSTautodisabletheIRQinterruptsandreenableglobal
087;..interrupts,topermitotherlowerperipheralsaccess...
LaISRdelperifricoquevayaaemplearWaitISR_on,tieneparticularidadesnecesarias
para funcionar. En primer lugar, dado que va a rehabilitarse la atencin de
interrupciones, ANTES de terminar esa IRQ (en el ejemplo, ISRIRQ), es INDISPENSABLE
AUTODESHABILITARlasinterrupciones:
088IRQISR:
089bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**
Enesteejemplosencillo,sellamaacontinuacinaWaitISR_on(quesiyaleyeronsu
cdigo,hacevariascosas,entreellas,HABILITARLASINTERRUPCIONESDELCPU.(Deotra
forma,nooperaranlasinterrupcionesdeltimer,RTC)
094WaitISR_on7,delay;20MSecondsfordebouncing.
101;***NOTE***Timer7>>>MUSTNOT<<<BEUSEDANYWHEREELSE!
102;..ItbelongsEXCLUSIVELYtothis'IRQISR'
103;
Enelejemplo,cadavezqueseactivaelIRQ,seincrementallosLEDs.Comoencienden
alrevs,enlugardeincrementar,decrementamos...(truco)
104deccounter;DriveLEDsusingnegativelogic,is
105movcounter,PTCD;6bitstodriveLEDs
106movcounter,PTED;2bitsmoretodrivehigherLEDs
ParafinalizarIRQISR,sedaelAcknowledgecorrespondientealhardware,yseretorna
alprogramaprincipal:
115
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
107IRQISRexit:
108bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
109bsetIRQIE,IRQSC;ReenableIRQinterrupts
...
111rti;ReturnfromInterrupt
["Laboratorios\Lab2\Timers8HS\TimedFlash8.asm"]
001;********************************************************************
002;ProgramTimedFlash8.asm:LuisGUribeC.D10J2012C20F2013C04D2013
003;Flashesall8LEDsatdifferentintervalseachone.PushIRQto
004;..toggleprogramOFF/ON
005;C20F2013:DoNOTusetimer7insideIRQISRANDinMainprogram...
006;
007;Includefiles
008NOLIST
009INCLUDE'derivative.inc'
010LIST
011;
012;Parameterdefinitions
013IRQACK:EQUIRQSC_IRQACK
014IRQIE:EQUIRQSC_IRQIE
015IRQPE:EQUIRQSC_IRQPE
016ram:SETZ_RAMStart;$80
017;====================================================================
018;GlobalVariables
019ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<
020NOLIST
021include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
022LIST
023LEDsMask:DS.B1;Rambank#0(directaddressing)
024Toggle:DS.B1
025;********************************************************************
026;MAINPROGRAMHEADER:
027ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
028ORGrom
029Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
030staSOPT1;..SystemOptions1
031ldhx#initStack;InitSP
032txs
033;====================================================================
034;ExternalInterruptInitialization(>>>IRQ<<<)(seeTim8_IRQHS.asm)
116
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
035bsetIRQPE,IRQSC;4.above
036bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
037bsetIRQIE,IRQSC;6.above
038;
039;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
040mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
041mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)
042Init8Timers
043;
044;MainLoop
045cli;GlobalEnableinterruptsNOW
046Setimer0,#673>>1
047Setimer1,#150>>1
048Setimer2,#2755>>1
049Setimer3,#1398>>1
050Setimer4,#511>>1
051Setimer5,#1002>>1
052Setimer6,#3000>>1
053Setimer7,#355>>1
054mov#$01,Toggle;BegininRUNstate
055loop:
056brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
057clrLEDsMask
058NTimeOut0,ET0
059bset0,LEDsMask
060Setimer0,#673>>1
061ET0:
062NTimeOut1,ET1
063bset1,LEDsMask
064Setimer1,#150>>1
065ET1:
066NTimeOut2,ET2
067bset2,LEDsMask
068Setimer2,#2755>>1
069ET2:
070NTimeOut3,ET3
071bset3,LEDsMask
072Setimer3,#1398>>1
073ET3:
074NTimeOut4,ET4
075bset4,LEDsMask
076Setimer4,#511>>1
077ET4:
078NTimeOut5,ET5
079bset5,LEDsMask
080Setimer5,#1002>>1
081ET5:
082NTimeOut6,ET6
083bset6,LEDsMask
117
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
084Setimer6,#3000>>1
085ET6:
086NTimeOut7,ET7
087bset7,LEDsMask
088Setimer7,#355>>1
089ET7:
090ldaPTCD
091eorLEDsMask
092staPTCD
093staPTED
094jmploop
095;====================================================================
096;PROGRAMTRAILER:
097;1)TIM8INTMacro
098;2)InterruptVectors
099;
100;RTCInterruptServiceRoutine,siusaInit8Timers...
101RTC_INTERRUPT:
102TIMERS8ISR
103;
104;IRQINTERRUPTSERVICEROUTINE
105IRQISR:
106bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**
107pshh;Notsavedbyinterruptproc
108ldaToggle
109eor#%00000001
110staToggle
111;
112IRQISRexit:
113sei
114bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
115bsetIRQIE,IRQSC;ReenableIRQinterrupts
116pulh;Notrestoredbyinterruptprocess
117rti;ReturnfromInterrupt
118;
119;InterruptVectors
120dummy_isr:;<<<<MustbeplacedinROMSpace
121rti
122ORGVrtc;Increasingpriorityfrombottomup
123DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
124ORGVirq;Virq,VswiandVreset
125DC.WIRQISR;IRQ
126DC.Wdummy_isr;SWI
127DC.WMain;RESET.Maximumpriority.Asynch.
128END
118
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\TimedFlash8.asm"]:
EsteejercicioresultasimpticodeobservarenlatarjetaDEMOQE128:
044;MainLoop
045cli;GlobalEnableinterruptsNOW
Activalos8timers,cadaunoconunvalorqueobtuvedeunprogramaquegeneranmeros
al azar.El nmero es dividido por dos (>> 1) paraque dure la mitad encendido y la
mitadapagado(50%DuttyCycle)
046Setimer0,#673>>1
047Setimer1,#150>>1
048Setimer2,#2755>>1
049Setimer3,#1398>>1
050Setimer4,#511>>1
051Setimer5,#1002>>1
052Setimer6,#3000>>1
053Setimer7,#355>>1
054mov#$01,Toggle;BegininRUNstate
Toggleesunavariablequesirveparadetenerocontinuarelparpadeo,aloprimirel
botndeIRQ.
La rutina no afecta directamente los LEDs, sino que, a partir de una mscara
(LEDsMask), que comienza en ceros al principio del ciclo, se coloca en 1 el bit
correspondiente a cada LED que tenga que CAMBIAR. Al finalizar el ciclo, se hace un
EXORdelLEDsMaskconelvaloractualdelosLEDs(lnea091eor).As,secambiael
valor,deencendidoaapagado,oviceversa,paraaquellosaloscualesselesvenciel
tiempo. Desde luego, cada vez que para alguno expira el intervalo, se lo vuelve a
inicializar,conSetimer...
091eorLEDsMask
055loop:
056brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
057clrLEDsMask
058NTimeOut0,ET0
059bset0,LEDsMask
060Setimer0,#673>>1
061ET0:
062NTimeOut1,ET1
063bset1,LEDsMask
064Setimer1,#150>>1
...
089ET7:
090ldaPTCD
091eorLEDsMask
119
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
092staPTCD
093staPTED
094jmploop
La105IRQISRbsicamentealternalavariableToggle(subit#0),deestamanera,el
programaprincipalpuededetenertodoelproceso,oreanudarlo,deacuerdoalvalorde
lavariableToggle:
056brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
...
108ldaToggle
109eor#%00000001
110staToggle
LosLEDsmslentosestnaunladodelatarjeta;losmsrpidosalotroextremo.Es
unavariacinsencilladelejercicioanterior,ynonecesitamayorescomentarios:
["Laboratorios\Lab2\Timers8HS\TimedFlash8Ordered.asm"]
001;********************************************************************
002;TimedFlash8Ordered.asm:LuisG.UribeC.D10J2012C20F2013S22G13
003;C04D2013,J19D2013cosmetics
004;Flashesall8LEDsatdifferentintervalseachone.PushIRQto
005;..toggleprogramOFF/ON
006;C20F2013:DoNOTusetimer7insideIRQISRANDinMainprogram...
007;
008;Includefiles
009NOLIST
010INCLUDE'derivative.inc'
011LIST
012;
013;Parameterdefinitions
014IRQACK:EQUIRQSC_IRQACK
015IRQIE:EQUIRQSC_IRQIE
016IRQPE:EQUIRQSC_IRQPE
017ram:SETZ_RAMStart;$80
018;====================================================================
019;GlobalVariables
020ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<
021NOLIST
022include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
023LIST
024LEDsMask:DS.B1;Rambank#0(directaddressing)
025Toggle:DS.B1
026;********************************************************************
120
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
027;MAINPROGRAMHEADER:
028ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
029ORGrom
030Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
031staSOPT1;..SystemOptions1
032ldhx#initStack;InitSP
033txs
034;====================================================================
035;ExternalInterruptInitialization(>>>IRQ<<<)(seeTim8_IRQHS.asm)
036bsetIRQPE,IRQSC;4.above
037bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
038bsetIRQIE,IRQSC;6.above
039;
040;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
041mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
042mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)
043Init8Timers
044;
045;MainLoop
046cli;GlobalEnableinterruptsNOW
047SetimerMS0,#150>>1
048SetimerMS1,#355>>1
049SetimerMS2,#511>>1
050SetimerMS3,#673>>1
051SetimerMS4,#1002>>1
052SetimerMS5,#1398>>1
053SetimerMS6,#2755>>1
054SetimerMS7,#3000>>1
055mov#$01,Toggle;BegininRUNstate
056loop:
057brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
058clrLEDsMask
059NTimeOut0,ET0
060bset0,LEDsMask
061SetimerMS0,#150>>1
062ET0:
063NTimeOut1,ET1
064bset1,LEDsMask
065SetimerMS1,#355>>1
066ET1:
067NTimeOut2,ET2
068bset2,LEDsMask
069SetimerMS2,#511>>1
070ET2:
071NTimeOut3,ET3
072bset3,LEDsMask
073SetimerMS3,#673>>1
121
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
074ET3:
075NTimeOut4,ET4
076bset4,LEDsMask
077SetimerMS4,#1002>>1
078ET4:
079NTimeOut5,ET5
080bset5,LEDsMask
081SetimerMS5,#1398>>1
082ET5:
083NTimeOut6,ET6
084bset6,LEDsMask
085SetimerMS6,#2755>>1
086ET6:
087NTimeOut7,ET7
088bset7,LEDsMask
089SetimerMS7,#3000>>1
090ET7:
091ldaPTCD
092eorLEDsMask
093staPTCD
094staPTED
095jmploop
096;====================================================================
097;PROGRAMTRAILER:
098;1)TIM8INTMacro
099;2)InterruptVectors
100;
101;RTCInterruptServiceRoutine,siusaInit8Timers...
102RTC_INTERRUPT:
103TIMERS8ISR
104;
105;IRQINTERRUPTSERVICEROUTINE
106IRQISR:
107bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**
108pshh;Notsavedbyinterruptproc
109ldaToggle
110eor#%00000001
111staToggle
112;
113IRQISRexit:
114sei
115bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
116bsetIRQIE,IRQSC;ReenableIRQinterrupts
117pulh;Notrestoredbyinterruptprocess
118rti;ReturnfromInterrupt
119;
120;InterruptVectors
121dummy_isr:;<<<MustbeplacedinROMSpace
122rti
123ORGVrtc;Increasingpriorityfrombottomup
122
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
124DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
125ORGVirq;Virq,VswiandVreset
126DC.WIRQISR;IRQ
127DC.Wdummy_isr;SWI
128DC.WMain;RESET.Maximumpriority.Asynch.
129END
123
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Y...comenzamoslaparteavanzada,dondeaprendimosaprogramarunabateradeTimers,
queademsderesultarnosmuybeneficiososennuestroslaboratoriosyenelproyecto,
nossirviparavercondetenimientolaformacomosediseayconstruyeSOFTWARE:Una
definicindelproblema,descomponindoloenfuncionesdesdeelnivelmsalto,bajando
hasta llegar a definir las operaciones ms elementales (Top Down Design); y la
codificacin,quehicimosdesdestasfuncioneselementaleshaciaarriba,hastallegar
aimplementarelcdigodemsaltonivel(ButtomUpCoding).Hicimosmuchoesfuerzoen
mostrareldesarrollodeesalibrera,descomponindolaenPolticasyMecanismos,para
definireimplementarporunalado,cdigoqueslotienequeverconLOQUESEVAA
124
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
HACER, sin tener en cuenta cmo se lo va a hacer (si van a hacerse los timers con
retrasos, con temporizadores, empleando o no interrupciones...). Y por ltimo, la
codificacindelosMecanismos,quesdependendecmosevaahacercadaoperacin.
Pero an all, puede obligarse al programador a establecer una separacin entre las
rutinasqueTOCANelhardware,yaquellasqueno.Windows,porejemplo,tieneunacapa
de software que separa el hardware de otro software, y se la denomina HAL: Hardware
AbstractionLayer.Esmuyimportantelograralmximoesaseparacin,demaneraquesi
secambiaelhardwarenohayaquetiraralabasuratodoelsoftware.Recuerdanhaber
odocadaratoqueelmicroeraun486,unPentium,unPRO,unMMX,unQuadracore?Y
esoocurreconunavelocidadpasmosa.Ytambin,quesusdiscoserande560Mb,de1Gb,
de100Gb,de1Terabyte,deestadoslido...
As que: NO separar el hardware especfico, del resto del cdigo, es GARANTA DE
SUICIDIOENUNAEMPRESA.
Llegamosahoraalltimoaspectoquepuedecubrirseenlashorasreservadasparaeste
cursodeArquitecturadelComputador,quehahechonfasisprimordialenlaUTILIZACIN
delosmicrocontroladores,msqueensudiseo.
Elperifricodecomunicacinserial(SCIenelMC9S08QE128)tienevariasventajaspara
elaprendizaje,porlascualeslohemosincluidoaqu.
En PRIMER lugar, una de las principales funciones que realizan los MCUs en sistemas
embebidos consiste en intercambiar informacin con unos con otros, y con sistemas de
mayorjerarqua,comoservidores,etc.Estudiaresteperifricoseenmarcadentrodela
importanciadelafuncin.
SEGUNDO,cubrelagranmayoradeaspectosbsicosquesedebenconsiderarsiempreal
utilizar una funcin de stas: manejo de los perifricos propiamente dichos
(encenderlos, apagarlos), control de sus lneas de habilitacin para interrupcin, y
protocolodeintercambiodeinformacin:DataReady,Done,dondeelperifricoproduce
una seal de que hay datos listos para leerse, y el MCU le da un reconocimiento
(Acknowledge)alperifricoparaquelpuedaprocedercorrectamenteconotrodato.Lo
mismoocurreconlasinterrupciones:suhabilitacin,procesamiento,reconocimiento.Se
tocan otros aspectos como la habilitacin de interrupciones DENTRO de rutinas de
interrupciones, a pesar de todolo que los manuales de Freescale hablan en contra...
Hayqueaprendertodoelprotocolodeinterrupcin:quguardaelmicroenelStack,
quno(yqueporlotantotienequeguardarelprogramadoramano),enquordense
guardanyserecuperanlosvaloresalmacenados,cmosedesactivanautomticamentelas
interrupcionesanivelgeneraldelCPU,etc.
125
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ellos,quesonlosdatosentrantesdeunequipoousuarioexterno,independiente,yel
MCU.Seindicanvariantesdelmtodo,medianteTABLAS,quepuedenfuncionarcomoDouble
Buffers cuando se procesan datos que llegan en rfagas, como es el caso de la
manipulacindediscos,etc.
Todoloanteriorseintegra,pues,enlasiguienteseccin.
COLAS DE DATOS
Cuando dos sistemas de diferentes velocidades se comunican entre s, de manera
asncrona,esdecir,cuandonoexisterelacintemporaldefinida,clarayprecisaentre
ellos,esindispensablesincronizarlosodelocontrarioseperderndatosdurantela
transferenciadeinformacin.Unejemplocotidianoesunapersonaempleandoelteclado
paraenviarinformacinasuPC;nopodransermsdiferentessusvelocidades,yno
existesincronaniporasomoentreelusuarioyelPC.
La forma de sincronizarlos vara de acuerdo a la naturaleza de la informacin
transmitida.Sielsistemamsrpidopuededarseellujodeemplearbuenapartedesu
tiempoesperandoqueelusuarioletransmitaunaletra,quizsbastaconunelementode
memoriaenelquereposarlaletramientrasselaprocesa,antesdeveniraleerel
siguiente smbolo. El dispositivo elemental, unitario, de memoria, suele ser un
registro (Data Buffer) interpuesto entre el dispositivo Productor de la informacin
(canaldecomunicacinconelusuario),yelConsumidordelamisma,enestecaso,el
CPUdelPC(EstaunidaddeacoplerecibeelnombredeINTERFAZ;eninglsInterface.NO
SETRADUCEALCASTELLANOCOMOINTERFACE!
Para facilitar la vida del PC, se agrega a la Interfaz una bandera, el bit de Data
Ready,queseactivacuandohallegadounaletraporelcanaldeinformacin,producida
desdeafueradelPCporelusuarioaloprimirunatecla.Alleerlatecla,sereponea
ceroelvalordelabandera,detalmaneraquelaunidaddecomunicacinsepaqueya
leyeroneldatoqueellaaport.
Aesteprotocolo,realizadomanipulandoordenadamentelabanderadeDataReady,selo
conocecomoHandShaking(eningls:apretndemanos).
ElsaludooHandShakingverbalizadoseraalgoascomo:
"Hola,tengoundato"."Ah,unmomento,yalorecibo"."Listo,graciasyciao"."Ciao".
Las dificultades comienzan cuando el CPU no puede bloquearse esperando a que llegue
cada smbolo, porque eso lo pondra a trabajar ms o menos a la velocidad del
subsistemalento,enestecaso,elusuario.Unaalternativaeslograrqueelprograma
queelCPUvaaestarcorriendoentreletrayletra,secomportecomounaespeciede
CICLOdelongitudindefinidaque,entrelascosasquetienequerealizar,estlade
pasararevisarsillegonounaletra.
CuntotiempotieneelCPUparadarlavueltaypreguntarporunaletraalaentrada,
antesdequecomienceallegarOTRALETRA,porquesobrescribiraparcialototalmente
la letra anterior? Pues si el registro de entrada es un "Shift Register" que va
recibiendounoaunolosNbitsdecadaletra,elCPUtienequeatenderalperifrico
ANTESdequetranscurraUNTIEMPODEBITdecomunicaciones.As,llegaelltimobitde
126
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
unsmboloproducidoporelusuarioeneltecladoyseactivaelbitdeSTATUS,Data
Ready.ElCPUtienequeleerloyactuarANTESdequecomienceallegarelprimerbit
delsegundosmbolo.Siseestenunatransferenciacontinuadedatos,secalculael
tiemponecesariodereaccindelCPU,comoseloconoce,infiriendo,delavelocidadde
comunicacin, el tiempo de cada bit. Ese es la cota superior o lmite en tiempo que
puedepasarentreatencinyatencinalperifrico,paragarantizarquenosepierden
ningnsmbolorecibido.
Unamodificacinquehacemsllevaderalavidadelossistemasconsisteenagregarle
un Registro Adicional al Serializador de Entrada (el serializador que es el que va
recibiendounoaunolosbitsdelaletra,ycuandotieneNnormalmente8bitspara
nuestrosejemplos,siendo8elnmeromsempleadoenlaactualidadelcontroladorde
lainterfazlotransfiereaeseDataBuffer.AhoraelCPUtieneTODOUNTIEMPODEBYTE
TRANSMITIDO, entre atencin y atencin al perifrico. Como cada byte (8 bits) puede
durar 10 tiempos de bit en transmitirse, se ha disminuido en un orden de magnitud
(dividido por 10) el tiempo permitido al CPU para atender los smbolos. A esta
combinacin de serializador alimentando a otro registro, que es el registro que en
definitiva OPERA el CPU, se lo conoce como Double Buffer (porque hay 2 registros
involucrados,obuffers).
CuandolavelocidadconlaquelaunidaddecomunicacionesleentregalosdatosalCPU
enalgunasoportunidades,esmayordeltiempolibre,odeholgura,delprocesador,ste
seveenlanecesidaddeatenderlosdatosconmayoragilidad.Yparafacilitareste
intercambio, se invent el mecanismo conocido como INTERRUPCIONES, que consiste en
lograrqueelCPUrespondarpidamenteacadaletrapero,siporalgnmotivonotiene
tiempoparaprocesarlainformacindeentrada,tienequemoverladeldoublebuffera
lamemoria.
Cuandolamemoriadetrabajotieneunprincipioyunfin,comounatabla,selaconoce
comoBUFFERdeEntrada.DesdeluegopuedehaberBUFFERSdeSalidatambin(tablas).Si
lavelocidaddetransferenciadeinformacinesmuyelevada,porejemploenlaentrada,
seempleanDOSBUFFERS,yselosconmutadetalmaneradeestaradquiriendoinformacin
sobre un BUFFER, mientras se est procesando el otro. A esta tcnica se la conoce
tambin como DOUBLE BUFFERING, y se distingue de la anterior por la cantidad de
elementos de informacin que conforma cada buffer. En el caso mencionado antes, eran
solo dos elementos o registros: el serializador, y el registro buffer, propiamente
dicho. En este segundo caso (que desafortunadamente recibe el mismo nombre, Double
Buffer,oBuffering)eltamaodelbuffersuelesergrande,entre64bytesparacanales
decomunicacinmuyrpidos,hasta512bytesparaunidadesadaptadorasdediscos,que
cuandodicentransferirinformacinlohacendemaneramuyveloz.
Pero hay otra alternativa, frente al Double Buffering, que consiste en el empleo de
COLASoQUEUEs;algunasdeellasrealizadasaniveldecircuitosintegrados(FIFOs).
Unacolapuedeversecomounatabladetamaofijo,peroCIRCULAR,locualquieredecir
quesisevancolocandodatosenellaysellegaalfinal,elprximodatoSECOLOCAR
ALPRINCIPIOdelatablaotravez.Estoproducelailusindequeesareadememoria
es CIRCULAR, pues el final de la tabla est contiguo al principio, como si fuera un
anillo(ocrculo)quenotienefin.
El mayor uso de las Colas se consigue cuando el proceso Productor de datos puede
generar a veces, rfagas de informacin, como picos de transmisin, pero que
normalmenteestpordebajodeloquepodramosllamarComunicacinIninterrumpida,o
127
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
continua.Esasquelacomunicacinvaaunpasodado,perodeprontoseaceleraen
unarfagadeunaduracinacotada,inferioraXcaracteres.SiademselConsumidorva
extrayendoconciertaperiodicidadlosdatosdelacola,ycuandolohacelohacemuy
rpidamente(delamismacola),laColapresentalaimagenvirtualdequeesdemayor
capacidadoperativadesurealcapacidadfsica.
UnodelosaspectososcurosdelempleodeColaseselestablecimientodeltamaodelas
mismas,yaquesucapacidaddependedeladiferenciadevelocidadesentreProductory
Consumidor. Una alternativa consiste en simular la cola en el PC, alimentndola y
extrayendo informacin de ella al azar, e ir incrementando un contador que determine
cundo, al tratar de agregarse un elemento a la cola, sta estaba llena, lo cual
conformaunerror,ytambin,dependiendodelcaso,sisequisoretirarunelementode
informacindelacola,ynosepudodebidoaquestaseencontrabavaca.
UnaCola,pues,esunaEstructuradeDatosqueestmaterializadaenlamemoriacomo
unatabla,yempleavarioselementosaccesoriosparasucorrectaoperacin.
Se requiere una variable que determine el tamao definido para la cola, 'SIZE'(1) en
nuestradescripcin.(Nota:losnmerosentreparntesiscorrespondenacadaelemento
identificadodelamismamaneraenelprximodibujo)
Es cmodo tener un pointer que seale siempre a dnde comienza la tabla: BASE, que
apuntaa"BUF"(2).
Se necesita un apuntador que indique en cul posicin de la tabla se colocar la
prximaletraquellegueensecuencia,yhayaquealmacenarla.EsteeselPUTpointer,
osimplemente"PUT"(3).
Se necesita otro apuntador, al que le corresponde sealar cul es la letra que debe
salir en secuencia de la cola, cuando se haga una lectura de all. Este es el GET
pointer,osencillamente"GET"(4).
Es cmodo tener otro pointer que identifique el final de la tabla: LIMIT, y una
variable"N"(5),queindiquelacantidaddebytesquealmacenalaColaenuninstante
dado.Parallevarlapistadecuntosbytesestnalmacenadosenlacola,cadavezque
seincluyaunodebeincrementarseelcontador,yalmomentodeextraerundato,debe
decrementarse dicho valor. As, siempre "N"(5) contiene la cantidad de Smbolos
almacenadosenunmomentodeterminado.
En'C',unelementodeinformacincomoelqueacabamosdedescribirserepresentade
maneranaturalcomounaSTRUCT;lanuestrasera(tomadademisrutinasdeColaspara
elPC):
typedefstruct{
byte*put;/*n(5)*/
byte*get;/*(2)buf>++*/
wordn;/*|(1)|>(4)get*/
wordc;/*(3)put>|s|*/
byte*base;/*|i|*/
byte*limit;/*|z|*/
wordsize;/*|e|*/
}QUE;/*++*/
128
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
EnestadefinicindeQUEestnlosdosapuntadoresabyte:*puty*get;elcontadorde
elementosque,paraestaimplementacinesunwordn(16bits,conloquelacapacidad
mximadelascolasesde64Kbytes);losapuntadoresabyte,queindicanelcomienzoy
alfinaldelatabla:byte*baseybyte*limit;unaconstanteparacadacola,queessu
tamao:wordsize;yfinalmenteunavariableauxiliarparaalmacenarunsmbolodela
tablatemporalmente,wordc(esword,nobyte,porqueigualqueelsmboloEOFenla
libreraestndardeC,senecesitaunwordparaalmacenarlo).
Unailustracindelosrangosdevaloresquepuedenalcanzarlasdiferentesvariables,
yladefinicindecolallenayvacaeslasiguiente:
Sea 'size'(1) de 'buf'(2) igual a 5, como ejemplo. Los pointers 'put'(3) y 'get'(4)
slopuedentenerlosvalores:
buf,buf+1,buf+2,buf+3,buf+4;
esdecir,lospointersdebenpermanecerenelrango:
buf<=pointer<(buf+size),o,loqueeslomismo:
buf<=pointer<limit
'n'(5)puedevaler:
0(vaco),1,2,3,4and5(lleno).
Noteque'n'esUNSEMFOROqueimponelassiguientesreglasdetrfico:
NO'deQue'cuandonsea<=0
NO'enQue'cuandonsea>=size
["Laboratorios\Lab3\SciComm\Que.inc"]
001;********************************************************************
002;Que.inc:QueueSupport(forSCI)
003;LuisG.UribeC.,C14M2007C15A09L08J09J14J2012(HCS08)M05M2013
004;S30N2013(defineQue&initQuenowbeginwithLowerCase)C18D2013
005;====================================================================
006;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
007;
008;defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG*
009;initQue:MACROname1,size2;==>>Use'initQue'in*ROMstartORG*
010;enQue:MACROname1;enQAccumulatorintoQue:'name1'
011;deQue:MACROname1;deQAccumulatorfromQue:'name1'
012;====================================================================
013;EXAMPLESOFUSE
014;...
015;GlobalVariables
016;ORGram
129
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
017;inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
018;outQ:defineQue5
019;...
020;
021;ORGrom
022;...
023;initQueinpQ,6;Usemacro'initQue'in'ORGrom'
024;initQueoutQ,5
025;
026;enQueinpQ
027;bcsfull_inpQ
028;...
029;deQueinpQ
030;bcsempty_inpQ
031;enQueoutQ
032;bcsfull_outQ
033;...
034;====================================================================
035;DATADEFINITION.
036;
037;NOTE:ThisisONEwaytoworkwith>>>STRUCTURES<<<inAssembler...
038;ReferencestointernalRAMstructpositionsaredoneviasymbols:
039;ThefollowingEQUsaredefinedtohelpusinlocatingthedifferent
040;..variablesusedinQueue'sstruct;i.e:
041;_QN:BYTE:unsignnumberofcharsstoredanytimeinoneQueue
042;_QPUT:WORD:pointerusedtostorethenextchar,vaenQue;
043;_QGET:WORD:pointertodeQueonechar.
044;_QSIZE:BYTE:staticspacereservedforQueue;
045;_QBASE:WORD:addressofthefirstchartobestoredinthe
046;..reservedmemoryofeachQueue;
047;_QLIMIT:WORD:lastelement'saddressinaQueue;usedinwrap
048;..aroundprocess,whenapointercrossestheborder
049;_QBUF:BYTES:herebeginsRAMspaceforcharacterstobestored
050_QN:EQU0;BYTE:databytescounterN
051_QPUT:EQU1;WORD:pointerforstoringdataintoQueue
052_QGET:EQU3;WORD:pointerforgettingdatafromQueue
053_QSIZE:EQU5;BYTE:sizeof
054_QBASE:EQU6;WORD:baseaddressofQueuestruc
055_QLIMIT:EQU8;WORD:lastaddressofbuffer
056_QBUF:EQU10;BYTES:reserve'size'databytes
057;====================================================================
058;"defineQue"isusedwith1parameter:SIZEoftheQueue.
059;..defineQueRESERVESRAMspace,and*MUST*beusedinRAMspaceORG.
060;===>>^^^^<<<===
061;Touse"defineQue",you*MUST*beginitwithaLABEL:This*IS*
062;..theNAMEofyourQUEUE;i.e:
063;
064;**********************
065;inpQ:defineQue6*
066;**********************
067;NOTE:Itisclevertodefinedatabytesramspace,thelast...
130
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
068defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG**
069;===>>===>===>===>===>===>>^^^^^^^^<<<===
070DS_QPUT_QN;n:databytescounterN
071DS_QGET_QPUT;put:ptrforSTOREdataintoQueue
072DS_QSIZE_QGET;get:ptrforGETdatafromQueue
073DS_QBASE_QSIZE;size:sizeof
074DS_QLIMIT_QBASE;base:baseaddressofQueuestruc
075DS_QBUF_QLIMIT;limit:lastaddressofbuffer
076DS\1;buf:reserve'size'databytes
077ENDM
078;
079;"initQue"isusedwith2parameters:NAMEoftheQueue,ANDSIZE.
080;initQueSTORESinformationintheQueue'sRAMspace,and
081;..*MUST*beusedin**ROMspaceORG**
082;==>>^^^^<<<===
083;ForinitQueyoumustwriteSAMEparametersusedondefineQue;i.e:
084;
085;******************
086;initQueinpQ,6*'inpQ'wasQueue'sNAMEindefineQue;sizewas6
087;******************
088;
089;ALLreferencestointernalRAMpositionsaredoneviathesymbols
090;.._QN,_QPUT,_QGET,_QSIZE,_QBASE,_QLIMITand_QBUF
091;..NotethatthisisONEwaytoworkwithSTRUCTURESinassembler...
092initQue:MACROname1,size2;==>>Use'initQue'in*ROMstartORG*
093;==>>====>====>======>>^^^^^^^^<<==
094clra;markQueueasempty(n=0)
095sta(\1+_QN);'sta',not'clrOP'causeOPcould
096;..residein16bitaddressspace
097ldhx#(\1+_QBUF)
098sthx(\1+_QBASE)
099sthx(\1+_QPUT)
100sthx(\1+_QGET)
101lda#\2
102sta(\1+_QSIZE)
103aix#\2
104sthx(\1+_QLIMIT)
105ENDM
106;
107;"enQue"storesthecontentofACCumulatorinthedesignatedQUEUE
108;
109;********************************************************************
110;*Youmayprogramotherusefullmacrossuchas:enQueKfordealing*
111;*..withconstants,enQueVtoenQuevariables,etcIt'suptoyou*
112;********************************************************************
113;
114;IfthereisNOspaceforstoringsomecharacter,themacrosignals
115;..itbysettingtheCbitonCCR,sotheinvokingprogrammay
116;..knowthattheQueueisfull,andtakeactions...
117;
131
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
118;NOTE:enQueisNOTablockingaction...
119;
120;******************
121;enQueoutQ;*enQAccumulatorintoQueuenamedoutQ
122;******************
123enQue:MACROname1;enQAccumulatorINTOQueue:'name1'
124psha
125lda(\1+_QN);Verifythatthereisroom(n<SIZE)
126cmp(\1+_QSIZE)
127pula
128blo\@ok
129sec;c=1signalerror:Queuefull
130bra\@exitQ
131\@ok:ldhx(\1+_QPUT);*put++=accumulator
132sta,x;..
133aix#1;..
134sthx(\1+_QPUT);..
135cphx(\1+_QLIMIT);..
136blo\@incn;putpointerinsideque?ok
137ldhx(\1+_QBASE);else:rollover:reasignputtoBASE
138sthx(\1+_QPUT);..
139\@incn:
140clc;c=0:enQuewassuccesfull
141ldhx#(\1+_QN);n++.ThisistheLASTthingtobe
142inc,x;<<<<<<..done:'n'ISthesemaphore
143\@exitQ:
144ENDM
145;
146;"deQue"retreivesdatafromthedesignatedQueueandstoresitin
147;..theACCumulator.
148;
149;********************************************************************
150;*Youmayprogramothermacros,suchas:deQueVforretreive*
151;*..dataandstoreitonvariables,etc.Itisuptoyou*
152;********************************************************************
153;
154;IfthereisNOdataforretrieving,themacrosignalsitbySETting
155;..theCbitonCCR,sotheinvokingprogrammayknowthattheQueue
156;..isempty,andtakeactions...
157;
158;NOTE:deQueisNOTablockingaction...
159;
160;******************
161;deQueinpQ;*deQuefromQueuenamedinpQintoAccumulator
162;******************
163deQue:MACROname1;deQ:AccumulatorFROMQueue:'name1'
164lda(\1+_QN);Verifythatqueisnotempty(n>0)
165bne\@ok
166sec;c=1signalerror:Queuefull
167bra\@exitQ
168\@ok:ldhx(\1+_QGET);accumulator=*get++
132
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
169lda,x;..
170aix#1;..
171sthx(\1+_QGET);..
172cphx(\1+_QLIMIT);..
173blo\@decn;getpointerinsideque?ok
174ldhx(\1+_QBASE);else:rollover:reasigngettoBASE
175sthx(\1+_QGET);..
176\@decn:
177clc;c=0:enQuewassuccesfull
178ldhx#(\1+_QN);n.ThisistheLASTthingtobe
179dec,x;<<<<<<..done:'n'ISthesemaphore
180\@exitQ:
181ENDM
COMENTARIOS a ["Laboratorios\Lab3\SciComm\Que.inc"]:
Seleofrecenalusuario4funcionesprincipales:
ParacadaColaseprecisahacerunadefinicinANTESdeinvocarcualquierotrafuncin
relacionada:
008;defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG*
Ejemplo:
inpQ:defineQue6
SedefineunaColade6elementos(enestaimplementacintodosloselementossonBYTES
pero, desde luego, usted puede emplear otros valores, como enteros, Longs, y otros
TiposdeDatos.Peroestoespreferible(comocasitodo)programarloenC.
NOTAIMPORTANTE:
'defineQue'debeusarsehabiendopreviamenteabiertounDATASECTION:'ORGram',porque
'defineQue'reservaespacioenRAMparalosapuntadoresydemsvariablesrelacionadas,
ascomotambinparalatablacircularpropiamentedicha.
Ejemplo:
initQueinpQ,6
NOTAIMPORTANTE:
'InitQue' slo debe emplearse estando en CODE SECTION, es decir, habiendo hecho
previamenteun'ORGrom',yaqueeslapartequegeneracdigoajustadoacadacolaen
particular.
133
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Finalmenteestnlasfuncionesdeusorutinario,paraalmacenaryextraerdatosdeuna
cola,lasMacrosenQueydeQue:
010;enQue:MACROname1;enQAccumulatorintoQue:'name1'
011;deQue:MACROname1;deQAccumulatorfromQue:'name1'
Cada Macro hace uso del dato que est previamente guardado en el Acumulador. A
continuacin,unejemploquecubretodoloanterior:
ParadefinirlasColas,hayqueabrirunDATASECTION(orgRAM)yluegollamarlaMacro
defineQue,tantasvecescomoColasquierandefinirse:
015;GlobalVariables
016;ORGram
017;inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
018;outQ:defineQue5
NotequeelNOMBREdelascolas,inpQyoutQ,sonETIQUETASdelaMacrodefineQue.
Cuandovanainicializarselascolas,hayquedefinirunCODESECTION(orgROM):
019;...
021;ORGrom
022;...
023;initQueinpQ,6;Usemacro'initQue'in'ORGrom'
024;initQueoutQ,5
NotequeelnombredelasColasNOesunnuevo"Label",sinoquelasetiquetasquese
emplearonenlaDefinicindelasColas,seusanahoracomoPARMETROSdelasmacrosde
Inicializacin:inpQyoutQ.
Elejemploencolaunchar,almacenadoenelAcumulador,enlacoladeentrada,inpQ;
msadelante,otraseccindelcdigo(seguramenteunarutinaquetransmitelosdatos
que se han encolado), saca elementos almacenados, posiblemente los preprocesa y,
finalmente,losencolaenoutQparaque,probablemente,larutinadeinterrupcionesque
seencargadetransmitirinformacin,laenvealPC,porejemplo.
025;
026;enQueinpQ
027;bcsfull_inpQ
028;...
029;deQueinpQ
030;bcsempty_inpQ
031;enQueoutQ
032;bcsfull_outQ
033;...
134
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
041;_QN:BYTE:unsignnumberofcharsstoredanytimeinoneQueue
Fjensequeenestaimplementacin,unaColapuedeidentificarmximo256caracteres,
pues'N'midesolounbyte.
042 ; _QPUT: WORD: pointer used to store the next char, via enQue; 043 ; _QGET:
WORD:pointertodeQueonechar.
044;_QSIZE:BYTE:staticspacereservedforQueue;
Aqu,denuevo,eltamaonocorrespondealquepuededefinirseenunentero,sinoen
unbyte.
045 ; _QBASE: WORD: address of the first char to be stored in the 046 ;
..reserved memory of each Queue; 047 ; _QLIMIT: WORD: last element's address in a
Queue;usedinwrap048;..aroundprocess,whenapointercrossesthe
border049;_QBUF:BYTES:herebeginsRAMspaceforcharacterstobestored
Conestasdefinicionesconcretas,definimosahoraelvalordecadasmbolo,utilizando
lapseudoinstruccinEQU:
050_QN:EQU0;BYTE:databytescounterN
_QNrepresentaunOffset,odesplazamientode0,ennuestra'STRUCT'.
Como_QNmideunBYTE(es'N',elcontadordebytesquehayenunmomentodeterminado
enlaCola),ytodosemideenBytes,elsiguienteelementoestUN(1)BYTEdespusde
_QN;poresoelEQU1:
051_QPUT:EQU1;WORD:pointerforstoringdataintoQueue
_QPUT,comoesunapuntador,tienequemedir16bits(DOS[2]bytes),puesenelHC9S08
todas las direcciones deben ser capaces de discriminar entre 65536 posiciones de
memoria. Por eso, elsiguiente elemento est separadode _QPUT por DOS (2)unidades.
ComoyallevbamosUNO(1),elsiguientees1+2=3:
052_QGET:EQU3;WORD:pointerforgettingdatafromQueue
Igualocurreconelsiguiente,queseseparaporDOS(2)delanterior,y3+2=5:
053_QSIZE:EQU5;BYTE:sizeof
_QSIZE mide UN (1) byte, as que el prximo, _QBASE, se separa de ste por UNA (1)
posicin,loqueda:5+1=6:
054_QBASE:EQU6;WORD:baseaddressofQueuestruc
ElprximoseseparaporDOS(2),queesloquemide_QBASE,dando6+2=8:
055_QLIMIT:EQU8;WORD:lastaddressofbuffer
135
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
y, finalmente, el buffer COMIENZA separado por DOS (2), que es lo que mide _QLIMIT,
dando8+2=10:
056_QBUF:EQU10;BYTES:reserve'size'databytes
OBSERVACINNOTABLE:
Laposicinenquecoloquelcomienzodelatabla,_QBUF,ESLAMEJORPOSICINPARA
ALOJAR LA TABLA en esta definicin. Qu pasara si la hubiramos incluido entre los
smbolos_QGETy_QSIZE,oentreotroscualesquiera?PINSELO!"Itisclevertodefine
databytesramspace,thelast..."
HechastodasestasparametrizacionesselasempleaparafinalmenteDEFINIRLACOLAEN
RAM,mediantela:
MACRODEFINEQUE:
068defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG**
069;===>>===>===>===>===>===>>^^^^^^^^<<<===
070DS_QPUT_QN;n:databytescounterN
071DS_QGET_QPUT;put:ptrforSTOREdataintoQueue
072DS_QSIZE_QGET;get:ptrforGETdatafromQueue
073DS_QBASE_QSIZE;size:sizeof
074DS_QLIMIT_QBASE;base:baseaddressofQueuestruc
075DS_QBUF_QLIMIT;limit:lastaddressofbuffer
076DS\1;buf:reserve'size'databytes
Fjense cmo cada variable usa el nmero de bytes apropiado, empleando DS (Data
Storage)ylacantidadqueresultadecalcularelnmerodebytesqueresultahaciendo:
siguientesmbolomenosactual,comoen:
070DS_QPUT_QN;n:databytescounterN
Sehabranpodidocolocarestascantidadesamano,perometomlamolestiadehacerlo
medianteparmetrosquemepermiten,siquierocambiaralgocomoeltamaodelacola
(peroNOqueremos)paraquefueradehasta64Kbytes,conslomodificarunsmbolo(o
dos...)elrestosereacomodaautomticamente.
Es EVIDENTE que en una mquina tan pequea, NO vamos a usar colas de tamao mayor a
256,queademssonsuficientesenMUCHOScasos,inclusoparamquinasmsgrandes.As
queesteejemplosloestcodificadoas,paraqueustedesveanlamaneraprofesional
dehacerlo:PARAMETRIZADO.
As,esperoquehayanaprendidoLAMANERAdetrabajarestructurasenAssemblyLanguage.
MACROINITQUE:
092initQue:MACROname1,size2;==>>Use'initQue'in*ROMstartORG*
094clra;markQueueasempty(n=0)
095sta(\1+_QN);'sta',not'clrOP'causeOPcould
096;..residein16bitaddressspace
136
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
CuandosecomienzaatrabajarconunaCola,losapuntadoresalaBASEytambinlosde
PUTyGETdebensealartodosalPRINCIPIODELATABLACircular.Notequelaexpresin
#(\1 + _QBUF) representa: una CONSTANTE (#), igual a la base de la Estructura de la
Cola ("\1", el primer parmetro) MS el desplazamiento a dondese comienza la tabla:
_QBUF)
097ldhx#(\1+_QBUF)
098sthx(\1+_QBASE)
099sthx(\1+_QPUT)
100sthx(\1+_QGET)
101lda#\2
102sta(\1+_QSIZE)
.........
103aix#\2
104sthx(\1+_QLIMIT)
Finalmente,revisemoscmosecodificaronlasMacrosparaelmanejonormaldelaColas:
enQueydeQue(encolarydecolar...).
"enQue":AlmacenaelcontenidodelAcumuladorenlaColarequerida:
Elproblemacuandosevaaencolaralgo,esqueNOhayaespaciopararecibirunnuevo
valor.Sifueraas,laMacroloSEALAcolocandoenUNOelbitdecarry,C,enelCCR;
as, el programa que invoca la Macro puede saber si la cola estaba llena, y tomar
acciones. Ntese que la manera como codifiqu la Macro enQue NO ES DE MANERA
BLOQUEADORA,locualresultamuyconveniente...Ustedsimplementeencolaalgoyluego
preguntasisehizobien,mirandoelbitdeCarry,C.Ahustedtomaladecisinque
corresponda.
123enQue:MACROname1;enQAccumulatorINTOQueue:'name1'
GuardaelvalordelAcumulador,enelStack:
124psha
Verificaquehayaespacio(quensea<SIZE):
125lda(\1+_QN);Verifythatthereisroom(n<SIZE)
126cmp(\1+_QSIZE)
127pula
128blo\@ok
SiShayespacioenlaCola,continuaenlaetiquetamarcadacomo:\@ok;deNOhaber
espacio,seactivalabanderaC(Carry),ytermina:
129sec;c=1signalerror:Queuefull
130bra\@exitQ
137
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Habiendo verificado que S hay espacio, carga la direccin para ENCOLAR (segn el
pointerPUT),enelregistrondiceH:X,yusandoeldireccionamientoindexadoalmacena
elnuevodato,tomndolodelAcumulador:
131\@ok:ldhx(\1+_QPUT);*put++=accumulator
132sta,x;..
Una vez guardado el dato, se incrementa el apuntador (aix #1), para que seale a la
prximaposicinquerecibirundato,yseguardaesenuevovalor,incrementado,enla
posicindememoriaquereservadaparaalmacenareseapuntador:
133aix#1;..
134sthx(\1+_QPUT);..
ComparaeseNUEVOvalor,paraversiseapuntafueradelreaasignada:
135cphx(\1+_QLIMIT);..
136blo\@incn;putpointerinsideque?OK
Si el apuntador contiene una direccin que queda FUERA del rea asignada, hay que
reiniciarlo,paraqueapuntealaBASE(ROLLOVER;estemecanismoeselquelacolasea
CIRCULAR):
137ldhx(\1+_QBASE);else:rollover:reasignputtoBASE
138sthx(\1+_QPUT);..
Sielapuntadorsealacorrectamentedentrodelreaasignada,seborralabanderaC,
Carry,paraindicarasqueTODOESTBIEN:
139\@incn:
140clc;c=0:enQuewassuccesfull
LuegovienelapartequizsMSDIFCILDECOMPRENDER,CONCEPTUALMENTE:
Como"N"eselMUTEX(semforobinario),
===lo>>>LTIMO<<<quehayquehaceralalmacenaralgoenlaColaes>>>INCREMENTAR
"N"<<<;
hacerlo ANTES puede deshacer la magia del semforo, que probablemente ya no nos
resguardecontrainconsistencias.
Supongamos,porejemplo,quelaColaestVACAy"Main"estuvieraenelprocesodel
"enQue",tratandodeENCOLARunsmbolo.SialgunarutinairrumpetratandodeDECOLAR
algopara,porejemplo,transmitirlo,y"N"leindicaqueShayinformacinenlaCola
(porque se increment "N", por ejemplo, al principio de la Macro, ANTES de que en
realidadsehubieraalmacenadonada),puesel"deQue"delaISRLEERAesainformacin,
QUENOEXISTE!
138
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
CAOSgarantizado...
141ldhx#(\1+_QN);n++.ThisistheLASTthingtobe
142inc,x;<<<<<<..done:'n'ISthesemaphore
La explicacin sobre "deQue" resulta algo as como el DUAL de la que acabo de hacer
sobre "enQue", y por eso no voy a presentar aqu ms comentarios. Se sigue la misma
normaconrelacinalbitC:Carry,quesiestEN0representaquetodofueBIEN,yEN
1,indicaquehubounERROR(fueaextraersealgodelacola,ystaestabaVACA...).
Elproblemaenestaparteessimilaralanterior:Supongamos,porejemplo,quelaCola
est LLENA y "Main" estuviera en el proceso del "deQue", tratando de DECOLAR un
smbolo.SialgunarutinairrumpetratandodeENCOLARalgo,porejemploloqueacabade
leer del receptor, y "N" le indica que S hay espacio en la Cola (porque Main
increment "N", por ejemplo, al principio de la Macro deQue, ANTES de en realidad
haberloledo(cambielordenqueenrealidadhayqueseguir),puesel"enQue"dela
ISRPERMITIRAALMACENARSUinformacin,ENUNAPOSICINQUEANNOHASIDOLEDAPOR
MAIN!
CAOSgarantizadodenuevo...
Verifique con MUCHO detenimiento en el cdigo, que tampoco aqu existe JAMS un
comportamiento indebido, como que la rutina de interrupciones almacene algo sin que
hayaespaciodndecolocarlo...
NOTA:LacodificacindelbitdeCarry,C,seusaenellenguaje"C"desdeelcomienzo
de los tiempos, para retornar CERO si una funcin S oper bien, y UNO si N oper
normalmente.Assecomportan,porejemplo,lasfuncionesdebajoniveldelaseccin
correspondientea<io.h>.
EsascosasustedhadebidoaprenderlasensuscursosdeProgramacin.Sinofueas,lo
estafaron.
Cuandoterminedeponderarlanitidezdelcdigo,tratedehacernuevamenteunExamen
deConciencia,ydigasiustedhubierapodidopensarentodalacomplejidadsubyacente
en las interacciones que pueden ocurrir asincrnicamente, entre un Main tratando de
Encolar,yunarutinadeinterrupcionestratandodeDecolar...oviceversa,SINQUESE
PUEDAJAMSEXTRAERDELACOLAALGOQUENOHAY,OENCOLARALGOENUNAPOSICINDELA
QUEANNOSEHADESOCUPADO!
139
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
["Laboratorios\Lab3\SciComm\4quetst.asm"]
01;********************************************************************
02;Programa4QueTst.asm:TestQueSupport(forSCI)
03;LuisG.UribeC.,M13M2007C15A09L08J09S16J2012(HCS08)
04;
05;Seeinthisprogram:TheuseofQue.inc,defineQue,initQue,enQue
06;..anddeQue.TrayandcodetheprogramusingRCVinterrupts,using
07;..a'Queue'fortemporallystoringtheincomingdata.
08;YoumustbecarefullyandnotexceedthefreeRAMonthechip...
09;
10;
11;Includefilesthatdonotdefineram
12;
13;CHECKLIST:Conservethisorder,andtherelativepositionof:
14;..'derivative.inc'and'Que.inc'
15;
16;Includefilesthatdoesnotdefineram
17NOLIST
18INCLUDE'derivative.inc'
19INCLUDE'Que.inc';<<<===Que.incfiledoesNOTuseRAM
20LIST;..storage,andTHISisit'splace
21;
22;2)DEFINES
23rom:SETROMStart;$2080
24ram:SETZ_RAMStart;$80
25initStack:EQURAMEnd+1;$1800=$17FF+1.Stackbeginson$17FF
26COP_Disable:EQU$42
27;====================================================================
28;3)GlobalVariables
29ORGram
30inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
31outQ:defineQue5
32;********************************************************************
33;4)MAINPROGRAMHEADER:
34ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
35ORGrom
36Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
37staSOPT1;..SystemOptions1
38ldhx#initStack;SetupSP
39txs;...
40;====================================================================
41initQueinpQ,6;Usemacro'InitQue'in'ORGrom'
42initQueoutQ,5
43lda#'A'
44cont:enQueinpQ
140
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
45bcsfull
46inca
47bracont
48full:
49cont2:deQueinpQ
50bcsempty
51enQueoutQ
52bcsfull2
53bracont2
54empty:
55full2:bra*
56;
57nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
58;This'nop'MAYberemovedforCW6.3...
59;
60;InterruptVectors
61ORGVreset
62DC.WMain;RESET.Maximumpriority.Asynch.
63END
COMENTARIOS a ["Laboratorios\Lab3\SciComm\4quetst.asm"]
Elqueestudiaestetextoharbienenlarecomendacindecodificarelprogramausando
interrupcionesRCVyuna'Queue'paraalmacenartemporalmentelainformacinquellega.
Comosiempre,vienen:
11;Includefilesthatdonotdefineram
EstoesIMPORTANTE:
13;CHECKLIST:ConservethisORDER,andtherelativepositionof:
14;..'derivative.inc'and'Que.inc'
Esteejercicioslotienelassiguientes(Global)VariablesenRAM(defineQue).Usted
DEBE jugar y cambiar los tamaos de cada cola para ver cmo se modifica el
comportamientodelprograma.
29ORGram
30inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
31outQ:defineQue5
DespusdelaDEFINICIN,alcomienzosehacelainicializacin:
41initQueinpQ,6;Usemacro'InitQue'in'ORGrom'
42initQueoutQ,5
Elprogramaenviarletrasconsecutivas,comenzandoenla'A',hastaquelacola"inpQ"
sellene.
Inicializaelacumulador:
141
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
43lda#'A'
ElcicloqueencolahastaqueinpQsellene:
44cont:enQueinpQ
45bcsfull
Incrementarunaletraproducelasiguiente:La'A'+1,produce'B':
46inca
47bracont
Cuando la cola "inpQ"se llenese extraenotra vez de"inpQ" yse los traslada a la
cola "outQ", hasta que "inpQ" se vace o hasta que "outQ" se llene. Verificar el
comportamientodelprogramaconelDebugger,siguindolopasoapaso.
48full:
49cont2:deQueinpQ
50bcsempty
51enQueoutQ
52bcsfull2
53bracont2
SefinalizaconlaconsabidaimitacindelHALT:
55full2:bra*
La modificacin que se sugiere hacer al programa consiste en colocar una Cola para
recibirporinterrupcionesloquellegadelPC.Larutinadeinterrupciones(alacual
se llega luego de las habilitaciones respectivas, y porque un smbolo lleg por la
lnea de comunicaciones, y as gener una interrupcin de RCV), toma la letra, la
ENCOLAysedevuelve(RTI).
Elprogramaprincipal,Main,selapasaleyendodelacolamientrasstaseencuentra
vaca; y, cuando llega a encontrarla NO vaca, DECOLA una letra y la devuelve al PC
(INCREMENTADAcomoyavimos),usandolaMacroPUTCHAR;luegoregresaalcicloinfinito.
AGREGO:Cuandoesofuncione,tratedecolocardos(2)colas,unapararecibirloque
llegadelPC,comoacabamosdever,yotraparaalmacenarloquesevaatransmitir;es
decir, la parte de cdigo que antes haca PUTCHAR, ahora hace "enQ outQ" y, LUEGO,
HABILITALASINTERRUPCIONESdesalida.
Larutinadeinterrupcionesdesalida,alacualsellegacuandosepueda,siesqueel
perifricotransmisorestdisponible(previasTODASlashabilitacionesnecesarias)...
DESENCOLA ("deQ outQ") si ve que NO ESTABA VACA transmite va PUTCHAR. Si la cola
estabavaca,larutinadetransmisinseAUTODESHABILITAparainterrupciones.ESTOES
IMPORTANTE!
Yenesasselapasan.
Laideaesqueustedaprendaausarlosmecanismosderecepcinytransmisin,tantode
manera programada como por interrupciones, usando como vehculo para aprender, las
comunicacionesserialesconelPC.As,estarpreparadoparasusproyectos...hoy,y
luegocomograduado.
142
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMUNICACIONES SERIALES
ESTEESELCULMENDELAPRESENTACIN;AQUCONFLUYENTODASLASTCNICASAPRENDIDAS;el
perifricodecomunicacionesnoesTANsimpledeestudiarpero,desdeluego,esmucho
ms sencillo que los stacks TCP/IP y Bluethoot, o algunos otros perifricos de
comunicacionessincrnicas,oelI2CyelSPI(SerialPeripheralInterface,withfull
duplex or singlewire bidirectional; doublebuffered transmit and receive; master or
slavemode;MSBfirstorLSBfirstshifting...)
EsteNOESUNTRATADODECOMUNICACIONESSERIALES.Ellectorestavisadodequedebe
revisar documentos publicados en relacin al tema. Yo mismo inclu el PDF:
"SerialComm16F84A(UribeChap14RS232)"enlaPginademicursoenAsignaturasdelaUSB.
YenelInternethaymultituddedocumentosrelacionados.
Usted tiene que aprender por su cuenta, en otra parte, cules son los voltajes
empleadosenlastransaccionesRS232F;lasvelocidades;ladistanciadeloscablesy
el tipo, los conectores; el nombre y significado de las seales como DTR, DSR, RTS,
CLS, Carrier Detect, TX, RX, Modem, Null Modem, dnde van los conectores hembra, y
donde los conectores macho; Gender Exchanger; lo que es comunicacin Full y Half
Duplex; Simplex. Start bit, Stop bit, tcnicas de lectura sobre la seal de entrada
paragarantizar5%deholguraenelosciladorlocalderecepcin,etc.
Tienequeleeralgntextoparaesto,comoyadije.
["Laboratorios\Lab3\SciComm\SciComm.inc"]
001;********************************************************************
002;SciComm.inc:SCIComm.SupportM28E2014
003;LuisG.UribeC.,D11M2007L12M07J16A09L08J09
004;..S16J2012(HCS08)D24J2012M26F2013J12D2013(putcX)C18D2013
005;J12D2013:Modified'putcX'toenableanypossiblefollowing'BEQ'
006;M10D2013:Changed'XmtRcvEnable'to'XmtRcvActivate'
007;M26F2013:Fixed:IncludeCommasinListofALLMacros(comments!)
008;J03E2013:ListALLMacros,forreference,inthisheader...AddresS
009;
010;**REFERto>>>>>02MC9S08QE128RM(ReferenceManual)U.pdf<<<<<**
012;====================================================================
013;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
014;
015;SCI9600N8:MACRO;ProgramSCI@9600,8,N,1
016;
017;getchar:MACRO;MAYrearmRcvinterrupts,insideISR
018;getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++
019;
143
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
020;putchar:MACRO;MAYrearmXmtinterrupts,insideISR
021;putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
022;putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
023;
024;RcvChar:MACRO
025;XmtChar:MACRO
026;
027;XmtRcvActivate:MACRO
028;
029;AncillaryMacros
030;
031;IfRcvRdy:MACRObrAddressIfReady1
032;IfXmtRdy:MACRObrAddressIfReady1
033;
034;XmtIntEn:MACRO
035;XmtIntDsb:MACRO
036;
037;RcvIntEn:MACRO
038;RcvIntDsb:MACRO
039;
040;ComIntEn:MACRO;InterruptEnableforCommunications
041;
042;
043;*TODO*:DefineIfNotRcvRdy,IfNotXmtRdy,IfNotRcvRdyS,IfNotXmtRdyS
044;..(cfr.timers8)ifyoueverneedthem.
045;CREATEkbhit,Nkbhit&equivalentsforoutput.getcvar
046;====================================================================
047;DEFINEREGISTERS:(in'MC9S08QE128.inc'),ANDREQUIREDBITS
048;..(here),forSCISerialCommunicationsInterface
049;********************************************************************
050;SCI1BD:EQU$0020;BaudeRateregister
051;LOOPMODE!!!
052Bauds9600Value:EQU$001A;16bit:4000000/(16*9600)=26.04=0x1A
053;
054;SCI1D:EQU$27
055;>>>>>>ALIAS<<<<<<(Othernamesforsameaddress.BECAREFULL!)
056XMTBUF:EQUSCI1D;TransmiterBuffer
057RCVBUF:EQUSCI1D;ReceiverBuffer
058;
059;SCI1C2:EQU$23
060;>>>>>>ALIAS<<<<<<(Othernamesforsameaddress.BECAREFULL!)
061XMTCTRLREG:EQUSCI1C2
062RCVCTRLREG:EQUSCI1C2
063XMTEN:EQUmSCI1C2_TE;TE:TransmiterEnable%00001000
064XMTIEN:EQUmSCI1C2_TIE;TIE:XmtINTEnable%10000000
065XMTIEN.bit:EQUSCI1C2_TIE;7
144
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
066RCVEN:EQUmSCI1C2_RE;RE:ReceiverEnable%00000100
067RCVIEN:EQUmSCI1C2_RIE;RIE:RcvINTEnable%00100000
068RCVIEN.bit:EQUSCI1C2_RIE;5
069XmtRcvEnab:EQU(XMTEN|RCVEN);EnableBOTHdevices%00001100
070;====================================================================
071;SCI1S1:EQU$24
072;>>>>>>ALIAS<<<<<<(OthernamesfortheSAMEADDRESS.BECAREFULL!)
073XMTSTATREG:EQUSCI1S1
074RCVSTATREG:EQUSCI1S1
075;Relevantbits:
076XMTRDY:EQUmSCI1S1_TDRE;TransmiterDataRegisterEmpty
077XMTRDY.bit:EQUSCI1S1_TDRE;7(mSCI1S1_TDRE:%10000000)
078RCVRDY:EQUmSCI1S1_RDRF;ReceiveDataRegisterFull
079RCVRDY.bit:EQUSCI1S1_RDRF;5(mSCI1S1_RDRF:%00100000)
080XMTEMPTY:EQUmSCI1S1_TC;TransmissionCompleteFlag
081XMTEMPTY.bit:EQUSCI1S1_TC;6(mSCI1S1_TC:%01000000):last!
082;
083;Receiver:
084OVERRUNERR:EQUmSCI1S1_OR;OR:Overrun%00001000
085NOISERR:EQUmSCI1S1_NF;NF:NoiseFlag%00000100
086FRAMERR:EQUmSCI1S1_FE;FE:FramingError%00000010
087PARERR:EQUmSCI1S1_PF;PE:ParityError%00000001
088RCVErrs:EQU(OVERRUNERR|NOISERR|FRAMERR|PARERR)
089;********************************************************************
090;MACRODEFINITIONS
091;NOTE:Accumulator,H:X,CCRareNOTpreservedthroughComm.Macros
092;
093;NoneedforpreviousenabledSCIperipherals
094SCI9600N8:MACRO;ProgramSCI@9600,8,N
095ldhx#Bauds9600Value;program9600bpsvalue
096sthxSCI1BD;..
097ENDM
098;
099XmtRcvActivate:MACRO
100mov#XmtRcvEnab,SCI1C2;ACTIVATEBOTHunits:xmt&rcv
101ENDM
102;====================================================================
103IfRcvRdy:MACRObrAddressIfReady1
104brsetRCVRDY.bit,RCVSTATREG,\1
105ENDM
106;
107getchar:MACRO;MAYrearmRcvinterrupts,insideISR
108brclrRCVRDY.bit,RCVSTATREG,*;rearm..
109ldaRCVBUF;..rearm
110ENDM
145
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
111;
112getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++
113ldhx\1
114brclrRCVRDY.bit,RCVSTATREG,*;rearm..
115movRCVBUF,x+;..rearm
116tpa;saveCCRtoenableanyfollowingBEQ
117sthx\1
118tap;..restoreCCR:enablefollowingBEQ
119ENDM
120;
121RcvChar:MACRO
122ldaRCVBUF
123ENDM
124;====================================================================
125IfXmtRdy:MACRObrAddressIfReady1
126brsetXMTRDY.bit,XMTSTATREG,\1
127ENDM
128;
129putchar:MACRO;MAYrearmXmtinterrupts,insideISR
130brclrXMTRDY.bit,XMTSTATREG,*;rearm..
131staXMTBUF;..rearm
132ENDM
133;
134putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
135lda\1
136brclrXMTRDY.bit,XMTSTATREG,*;rearm..
137staXMTBUF;..rearm
138ENDM
139;
140putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
141ldhx\1
142brclrXMTRDY.bit,XMTSTATREG,*;rearm..
143movx+,XMTBUF;..rearm
144tpa;saveCCRtoenableanyfollowingBEQ
145sthx\1
146tap;..restoreCCR:enablefollowingBEQ
147ENDM
148;
149XmtChar:MACRO
150staXMTBUF
151ENDM
152;====================================================================
153XmtIntEn:MACRO
154bsetXMTIEN.bit,XMTCTRLREG
155ENDM
156;
157XmtIntDsb:MACRO
158bclrXMTIEN.bit,XMTCTRLREG
159ENDM
160;
161RcvIntEn:MACRO
162bsetRCVIEN.bit,RCVCTRLREG
146
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
163ENDM
164;
165RcvIntDsb:MACRO
166bclrRCVIEN.bit,RCVCTRLREG
167ENDM
168;
169ComIntEn:MACRO;InterruptEnableforCommunications
170bsetRCVIEN.bit,RCVCTRLREG;JustonlyRCV...
171;MustEnableXMT*ONLY*whenneeded
172ldaRCVSTATREG;Clearanypossiblypending
173ldaRCVBUF;..RCVReadyFlag
174ENDM
COMENTARIOS a ["Laboratorios\Lab3\SciComm\SciComm.inc"]:
Comencemos, pues, identificando las funcionalidades que requiere el usuario cuando
necesitamanipularunperifricodecomunicacionesseriales,RS232.Noolvidenrevisar
elManualdeReferenciaquepubliqu:02MC9S08QE128RM(ReferenceManual)U.pdf.
NuestraMacroparainicializarelcanaldecomunicacionesserialeses:
015;SCI9600N8:MACRO;ProgramSCI@9600,8,N,1
Esdecir:9600bps,NOparity,8bitsperchar,ONE(1)stopbit.
017;getchar:MACRO;MAYrearmRcvinterrupts,insideISR
018;getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++
"getchar"funcionaigualqueenC:tomaunsmbolodeentrada(EnCvienendelteclado;
aqu, del puerto serial) y nos lo retorna en el Acumulador. "getcX" lee datos y los
almacena, no en el Acumulador, sino empleando el registro ndice H:X; muy til para
almacenarenunatablaloscaracteresrecibidos.
020;putchar:MACRO;MAYrearmXmtinterrupts,insideISR
021;putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
022;putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
147
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
"putchar",transmiteloqueestenelAcumulador,empleandolalneadecomunicaciones
seriales. "putc" se usa cuando desean transmitirse CONSTANTES o VARIABLES; y "putcX"
para enviar informacin que est almacenada en TABLAS, "apuntadas" empleando el
registrondiceH:X.
Lasprximas2Macrossondemsbajonivel:
024;RcvChar:MACRO
025;XmtChar:MACRO
DijeconanterioridadquelosperifricosdelMC9S08QE128tienen,enprimerlugar,que
ENERGIZARSE:muchosdeesosperifricosNOestnconectadospermanentementealafuente
dealimentacin,paradisminuirelconsumodeenerga.Losdosperifricosquetienen
queverconlacomunicacinserial,RS232(SCI),quesoneldeTransmisin(XMT)yel
deRecepcin(RCV),seenergizacadaunoporaparte.Yoactivolosdosdeunasolavez,
porqueenmisejemplosestamosempleandoAMBOS:XMTandRCV"Activate":
027;XmtRcvActivate:MACRO
Lasfuncionalidadesdemsbajonivelan,son:
029;AncillaryMacros
031;IfRcvRdy:MACRObrAddressIfReady1
032;IfXmtRdy:MACRObrAddressIfReady1
que sirven para ver si el dispositivo de recepcin (RCV) o el de transmisin (XMT)
estndisponibles(READY),afindesabersiselospuedeemplear.
ParaelTransmisor(XMT),activarydesactivarlasinterrupciones:
034;XmtIntEn:MACRO
035;XmtIntDsb:MACRO
ParaelReceptor(RCV),activarydesactivarlasinterrupciones:
037;RcvIntEn:MACRO
038;RcvIntDsb:MACRO
Y,finalmente,unaformaconvenientedeactivarAMBOSperifricossimultneamentepara
trabajarconellos:
040;ComIntEn:MACRO;InterruptEnableforCommunications
050;SCI1BD:EQU$0020;BaudeRateregister
052Bauds9600Value:EQU$001A;16bit:4000000/(16*9600)=26.04=0x1A
148
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
NOTA: Para aumentar la compresin del cdigo, he utilizado varios ALIAS, que son
NOMBRES ALTERNATIVOS para unas mismas direcciones o variables. Hay que ser MUY
CUIDADOSOScuandoseempleanALIAS,paranocaerenolvidosquenosllevenacreerque
losAliasSONDIFERENTESVARIABLES,OREGISTROS,OPOSICIONESDEMEMORIA!(Recuerde:
Son DISTINTOS nombres para LAS MISMAS COSAS ENTIDADES: registros, posiciones de
memoria,ETC.)
056XMTBUF:EQUSCI1D;TransmiterBuffer
057RCVBUF:EQUSCI1D;ReceiverBuffer
INTERESANTEnotarqueAMBOSderegistros,elbufferdetransmisinyelderecepcin,
corresponden a la MISMA ENTIDAD FSICA: SCI1D. Esto es as porque el campo de
direcciones es un recurso MUY LIMITADO; y para optimizar, se definen AMBOS registros
conlamismadireccin.
CmosabeelCPUculdelosdosperifricos,eldeentradaoeldesalida,estamos
direccionando? Pues, si estamos LEYENDO de esa nica direccin, seguro estamos
intentando RECIBIR desde el perifrico RECEPTOR. Y si estamos ESCRIBIENDO sobre ese
MISMO recurso, con seguridad estamos tratando de TRANSMITIR por el perifrico
TRANSMISOR.
ConseguridadcoincidirconmigoenqueesMUCHOmsinteligibleunsmbolocomoRCVBUF
(ReceiverBuffer,oregistrodedatosdelreceptor),queSCI1D.Enelcdigohayotros
ejemplos en los que la inteligibilidad de los smbolos por m definidos resulta con
muchosuperioraladelasdefinicionesdeFreescale!
RegistrosdeControldelTransmisor:
061XMTCTRLREG:EQUSCI1C2
062RCVCTRLREG:EQUSCI1C2
RECUERDE: hay que HABILITAR el transmisor (ENABLE: XMTEN), para trabajar con l;
adems,sidebeinterrumpir,hayquehabilitarlotambinparainterrupcin(XMTIEN):
Bitsdeusofrecuente:
063XMTEN:EQUmSCI1C2_TE;TE:TransmiterEnable%00001000
064XMTIEN:EQUmSCI1C2_TIE;TIE:XmtINTEnable%10000000
065XMTIEN.bit:EQUSCI1C2_TIE;7
Vuelvoarecalcar:UnacosaeselXMTEN(TransmiterENABLE),queACTIVAalperifrico
transmisor(loENERGIZA),
..yotramuydistintaXMTIEN,queeselInterruptENableparaelXMT(Transmiter).Yel
XMTIENqueyointroduzco,esmuchomejornombrequemSCI1C2_TIE.
Elnmerobinarioaladerechademisdefiniciones,identificaCULbiteselreferido:
TIE:XmtINTEnable%10000000(bit7)delregistrodecontrolasociado,XMTCTRLREG.
Esimportantesaberculessonlosbits,parapoderlosverconelDebugger.
Estenmero(7)identificaendecimal,elcorrespondientebit:
065XMTIEN.bit:EQUSCI1C2_TIE;7
149
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
DefinicionesequivalentesparaelReceptor:
066RCVEN:EQUmSCI1C2_RE;RE:ReceiverEnable%00000100
067RCVIEN:EQUmSCI1C2_RIE;RIE:RcvINTEnable%00100000
Elbitparahabilitarlasinterrupcionesdetransmisinsedefineporaparte:
068RCVIEN.bit:EQUSCI1C2_RIE;5
Finalmente, tenemos una forma de activar AMBOS dispositivos (para que reciban
alimentacinelctrica);unsmboloquecubrelosdosperifricos:
069XmtRcvEnab:EQU(XMTEN|RCVEN);EnableBOTHdevices%00001100
Antes se definieron los bits de los registros de Control; ahora les corresponde el
turnoalosStatusRegisters:
073XMTSTATREG:EQUSCI1S1
074RCVSTATREG:EQUSCI1S1
Losbitsmsusadosenellos,queelusuarionuncaversiestempleandomisMacros:
076XMTRDY:EQUmSCI1S1_TDRE;TransmiterDataRegisterEmpty
077XMTRDY.bit:EQUSCI1S1_TDRE;7(mSCI1S1_TDRE:%10000000)
078RCVRDY:EQUmSCI1S1_RDRF;ReceiveDataRegisterFull
079RCVRDY.bit:EQUSCI1S1_RDRF;5(mSCI1S1_RDRF:%00100000)
080XMTEMPTY:EQUmSCI1S1_TC;TransmissionCompleteFlag
081XMTEMPTY.bit:EQUSCI1S1_TC;6(mSCI1S1_TC:%01000000):last!
PorqupararecepcinhayunsolobitdeREADY,yparatransmisinhaydos?Bueno,
losdosperifricossonCASIDUALESelunodelotro,peronoexactamente.
Alcomienzo,cuandohablamosdeColas,indicamosunamodificacinparaeldispositivo
de entrada, que TAMBIN se le hizo al perifrico DE SALIDA: Se le agreg un segundo
Registro Adicional al Serializador de Salida (el serializador que es el que va
transmitiendounoaunolosbitsdelaletra)ycuandostehatransmitido8bits,el
controlador de la interfaz toma otro smbolo del Data Buffer y lo lleva al
serializador, si es que hay algn dato ya en el Data Buffer. A esta combinacin de
Serializadoralimentadoporotroregistro,queesaqueldedondeendefinitivaelCPU
ESCRIBE los datos, se lo conoce, al igual que en el caso del receptor, como Double
Buffer(porquehay2registrosinvolucrados,obuffers).
Elprotocoloessimilaraldelcasodeentrada:cadavezquehayunBitdeReadyactivo
enlatransmisin,elCPUpuedemoverelsiguientedatoalTransmiterBuffer.Enalgn
momento ese dato pasa al serializador, y como el Buffer de Transmisin ha quedado
libre,sevuelveaactivarelBitdeReadydeTransmisin,loquepermitealprograma
principal colocar un nuevo valor en el Transmiter Buffer, mientras se est
transmitiendoeldatoanterior.
150
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Ahora, cuando ya no hay nada ms que transmitir, la ltima vez que el subsistema de
salidaactivaunTransmiterReady,elprogramaprincipalpodraCORTARlacomunicacin
enesemomento,peroPERDERAlatransmisindelltimobyteporque,aunqueelbuffer
de salida est disponible, el perifrico de salida NO ha terminado de serializar el
ltimodatoquetienequetransmitirporelcanaldecomunicaciones.Estasituacinse
trat en los primeros UARTS, mediante un retardo que el programa principal activaba
cuando transfera el ltimo dato al Transmiter Buffer. Y NO cerraba el canal de
comunicaciones (Modem? Radio?) hasta que no hubiera transcurrido ese tiempo,
calculadocomomayoralnecesarioparaenviarunbyte.
EnlosUARTsmodernossecolocunSEGUNDObitdeReadyparaeltransmisor;queslo
usamosantesdecerrarelcanaldecomunicacionesdespusdehabertransmitidonuestro
ltimobyte.Ennuestrosejercicios,stenoeselcaso,peroenlavidareal,s.
Un ltimo grupo de bits dentro del SCI, que tambin pueden INTERRUMPIR y tienen su
propio vector de interrupciones, es el de los ERRORES. Note que NO hay errores de
TRANSMISIN, porque no tenemos control ni conocimiento de lo que pasa, una vez que
hemosenviadounsmboloalcanaldecomunicaciones.SlohayerroresdeRECEPCIN:
084OVERRUNERR:EQUmSCI1S1_OR;OR:Overrun%00001000
085NOISERR:EQUmSCI1S1_NF;NF:NoiseFlag%00000100
086FRAMERR:EQUmSCI1S1_FE;FE:FramingError%00000010
UnFramingErrorseproducecuandoelreceptorcomienzaamuestrearnuevosbits,porque
hadetectadounbitdeARRANQUE(START)y,alllegaralfinNOENCUENTRAUNSTOPBIT.
Estopuededeberseaexcesivoruidoenlalnea,quehizocreeralainterfazquehaba
unSTARTbit,oaunaprdidadesincronismoporalgunaotracausa,yqueentodocaso
producequelainformacindeentradanotengaelMarcooFRAMEcorrecto.Notequesi,
habindosesalidodesincronismo,pormalasuerteelltimobit,queselee,errneo,
esunUNO,lainterfazNOpuededetectarningnFramingError...
087PARERR:EQUmSCI1S1_PF;PE:ParityError%00000001
151
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Finalmente,sehaceunacombinacinparaidentificarCUALQUIERcondicindetectablede
error:
088RCVErrs:EQU(OVERRUNERR|NOISERR|FRAMERR|PARERR)
Unidadesdecomunicacinserialmsavanzadas,comolasqueseempleanenelPCIBM/AT
compatible,tienenunCUARTOelementoquepuedetambingenerarinterrupciones,enun
vectorindependiente.SetratadelmanejadordeLnea(LINECONTROLER)encargadodever
sielModemseactivosedesactiv,siseperdilaportadoraoregres,sihayun
inconvenienteconelModem(DSRinvlido),osienalgnmomentonopuedeaceptarun
smbolonuevo(CTSinvlido).
094SCI9600N8:MACRO;ProgramSCI@9600,8,N
095ldhx#Bauds9600Value;program9600bpsvalue
096sthxSCI1BD;..
LaACTIVACINdeambosdispositivos,transmisoryreceptor(energizarlos):
099XmtRcvActivate:MACRO
100mov#XmtRcvEnab,SCI1C2;ACTIVATEBOTHunits:xmt&rcv
Macroauxiliarparadeterminarsielreceptorestlisto:
103IfRcvRdy:MACRObrAddressIfReady1
104brsetRCVRDY.bit,RCVSTATREG,\1
152
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Sillegaanecesitarlamacroopuesta(IfRcvNotRdy),esas:
If_NOT_RcvRdy:MACRObrAddressIfNotReady1
brclrRCVRDY.bit,RCVSTATREG,\1
>>>LA<<<Macroprincipal,queleecomosiseestuvierahaciendoenC:
107getchar:MACRO;MAYrearmRcvinterrupts,insideISR
108brclrRCVRDY.bit,RCVSTATREG,*;rearm..
109ldaRCVBUF;..rearm
Sencillo,no?ObservequeestaMacroesBLOQUEANTE,igualqueenelC...Adems,si
est leyendo Strings,que son elementos de informacinterminadosen un byte ZERO, a
continuacin de un "getchar" usted puede simplemente hacer un BEQ, o BNE, y estas
instrucciones hacen referencia al LTIMO byte transferido por getchar (LDA hace una
comparacintcitadelvalorquetransfiere,contraCero).
Ojo que ambas Macros de RECEPCIN, Y LAS SIMILARES PARA TRANSMISIN (putchar, putc,
putcX), HAN SIDO PROGRAMADAS de tal manera que adems, "REARMEN" las
interrupcionesdecadaperifricoy,as,PUEDENUSARSETAMBINdentrodelasrutinas
deinterrupcin!
EsomequedMUUUYBIEN.
"ToclearRCVRDY,readRCVSTATREGwithRCVRDY=1andTHENreadtheSCIdataregister
(RCVBUF)".Estoesexactamenteloquehacegetchar:
107getchar:MACRO;MAYrearmRcvinterrupts,insideISR
108brclrRCVRDY.bit,RCVSTATREG,*;EsperaaqueRCVRDY=1
109ldaRCVBUF;LuegoLEEdelRCVBUF
Unaobservacinparaellectoravispado:Enlasrutinasdeinterrupcinpuedesuponerse
queNOHABRAnecesidaddeincluir:
108brclrRCVRDY.bit,RCVSTATREG,*;EsperaaqueRCVRDY=1
puesnicamentesellegaalarutinadeinterrupcinporqueelperifricoESTREADY!
Parecerasuperfluo.Pero,esosdospasossonlosqueserequieren,segneltextoen
inglsqueacabodecopiardirectamentedelReferenceManual.
NOTA:ElmanualesINEXACTOeIMPRECISO,porquecuandodice:"readRCVSTATREGwith
RCVRDY=1andTHENreadRCVBUF",NODICESIENTREESASDOSINSTRUCCIONESPUEDEN,O
NO,HABEROTRASINSTRUCCIONES(queseraelcasoenqueunainterrupcinsecolara
en medio de ellas, y la cosa quedara como: a) "read RCVSTATREG with RCVRDY=1",
b)a continuacin un nmero indeterminado de instrucciones (las de la rutina de
interrupcin)yfinalmente,c)el"readRCVBUF".
153
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Lanicamaneradeesclarecerestoesmedianteinvestigacin,incluyendoinstrucciones
amanoyviendoque,enrealidad,sfuncionaconinstruccionesextrasincluidasentre
lasotrasdos..Peroespocoprofesionalqueparasaberloquehaceundispositivo,no
seasuficienteconleerladocumentacin.
"To clear XMTRDY, read XMTSTATREG with XMTRDY = 1 and then write to the SCI data
register(XMTBUF)".Estoesexactamenteloquehaceputchar:
129putchar:MACRO;MAYrearmXmtinterrupts,insideISR
130brclrXMTRDY.bit,XMTSTATREG,*;EsperaaqueXMTRDY=1
131staXMTBUF;LuegoESCRIBEenelXMTBUF
NOTA:Endispositivosmsavanzados,comolafamiliaIntelqueseusaenlosPCIBM/AT
compatibles,elprotocolodeAcnowledgedeentradaysalidalorealizaelhardware:la
mismainstruccinqueLEEeldatodelbufferdeentrada,BORRALABANDERAdeReady;la
mismainstruccinqueescribesobreelperifricodesalidaBORRALABANDERAdeReady.
Noeraalgotancomplicado,comoparaobligaralprogramadorahacerestaoperacinpor
software.
Maisc'estlavie...
Sienalgnmomentodecidequeustednodebebloquearse(unprogramaCASINUNCAdebe
bloquearse, porque se pierde casi todo el control sobre el sistema), usted puede
preguntarsihayletrasenelreceptorANTESdellamaragetcharparaleerlas.Estees
elequivalenteausarkbhit()enCpero,muyprobablementeustedesjamsoyeronhablar
dekbhit()antes.
NotKbhit(mstilaququekbhit)puedecodificarseas(esigualaIf_NOT_RcvRdy):
NotKbhitEQUIf_NOT_RcvRdy
Elcdigoquedaraas:
NotKbhitcont;Sinohaydatos,noloslee
getchar;..getcharnosebloquea,porqueshaydatos
cont:
Unaltimafuncionalidadmuytilenelreceptorconsisteennoleerlosdatossobreel
acumulador,sinosobreunatabla,quesesuponequevamosallenarconlosdiferentes
smbolosquelleguen.TambinesBLOQUEANTE:
112getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++
SecargaelregistrondiceconelApuntadorhaciaelprximoelementodisponibleenla
tabla:
113ldhx\1
154
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Seesperaaquellegueunaletra,aligualqueengetchar:
114brclrRCVRDY.bit,RCVSTATREG,*;rearm..
AlllegarunnuevodatoselollevaalatablaconelMOV,SEINCREMENTAelapuntador
en un solo golpe, gracias al lujo de instrucciones y modos de direccionamiento que
tieneesteexcepcionalmicrocontrolador:
115movRCVBUF,x+;..rearm
Ahora, una funcionalidad prometida en estas macros es que, una vez transferido el
elemento de informacin principal (el DATO que lleg), el programador pueda hacer un
saltocondicional,aprovechandoelvalordelabanderaZ,activadoporelconjuntode
instruccionesENRIQUECIDOdelMCU.
Pero,apesardequeYAtransferimoseldatoasusitio,yqueelMOVyacolocelbit
Z en su estado apropiado, todava no hemos llevado el nuevo valor del pointer
incrementadoasusitio.Alhacerlatransferenciadelapuntador,sevanaalterarlas
banderasdelCCR,enparticularlaZ.AsquehayquepreservarelvaloractualdelCCR
(tpa)ANTESdeguardarelapuntador(sthx),yrecobrarlodespus(tap):
116tpa;saveCCRtoenableanyfollowingBEQ
117sthx\1
118tap;..restoreCCR:enablefollowingBEQ
Observeque"tpa"y"tap"fueronpensadasdetalmaneraqueNOmodificanlasbanderas
delCCR!
NOTE:INCREBLEMENTE,esteeselcomentarioquefiguraenelManualdeReferencia,en
relacinalainstruccinTAP:
*NOTE:TheTAPinstructionwasaddedtoimprovetestabilityof*theCPU08,andsofew
practicalapplicationsofthe*instructionexist.
The author of this infamous paragraph HAS NO IDEA OF WHAT HE IS TALKING ABOUT. This
instructionwasNOTaddedtoimprovetestability;itisoneofthemostimportantOp
CodesintheentireHC08instructionset,andonethatdeservesafullexampleonusing
it!
Forexample,towritesomegenericroutine,onethatcouldbeusedinsideanISR,if
youneedtodisableinterrupts,lateryoucannotsimplyenablethem:Youmustrestore
interruptstothestatetheywhereatthebeginning,somethinglikethis:
...
;
TPA
;TransferCCRtoAcc(TPAisTAPstwinopcode)
PSHA
;..SaveAcc(CCR)intostack
;...Lateryoumayrecovertheinterruptstate,asfollows:
PULA
;Pop(er...Pull)Acc
TAP
;..TransferAcctoCCR
;..(savedflags,includingIFlag)
;...
155
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Bytheway,TAPstandsfor:TransferAccumulatortoPROCESSORSTATUSWORD.Youknow,
theybeguncallingtheflags:PSWand,then,changetheirmindandrenamedthePSWlike
Condition Code Register (CCR) but, the instruction codes remain using the old
nomenclature(TAP,TPA).
Usted tiene que pensar en todo; la programacin es una actividad MUY MINUCIOSA. Por
eso,hayquedividirenproblemaenzonasmuymuypequeas,quenospermitanVERtodas
lasinteracciones.Siustedhaceuncdigodemillneas,yluegocomienzaaverpor
qunofunciona,estperdido.
Las Macros para el transmisor son las DUALES del receptor; por eso los comentarios
sernmnimos:
129putchar:MACRO;MAYrearmXmtinterrupts,insideISR
130brclrXMTRDY.bit,XMTSTATREG,*;rearm..
131staXMTBUF;..rearm
"putchar"esbloqueante.
putc no tiene equivalente en el dispositivo receptor: Se usa putc cuando se van a
transmitirCONSTANTESOVARIABLES;nospermitenotenerquecargarexplcitamenteesas
constantesovariablesenelacumulador:
134putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
135lda\1
136brclrXMTRDY.bit,XMTSTATREG,*;rearm..
137staXMTBUF;..rearm
putcXesmuysimilaragetcX.Parapoderhacerusodelasinstruccionesenriquecidas,
tal como en getcX, antes de almacenar el apuntador incrementado, hay que guardar el
valordeZ(CCR),cargadoporeldatoquesehatransmitido,yrecuperarlodespusde
moverelapuntador:
140putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
141ldhx\1
142brclrXMTRDY.bit,XMTSTATREG,*;rearm..
143movx+,XMTBUF;..rearm
144tpa;saveCCRtoenableanyfollowingBEQ
145sthx\1
146tap;..restoreCCR:enablefollowingBEQ
LasmacrosXmtIntEn,XmtIntDsb,RcvIntEn,RcvIntDsbsonsimplementeencenderoapagar
elbitcorrespondiente.
ComIntEn hace "Interrupt Enable for Communications". Es decir, una vez colocados los
valores:SCI9600N8,yenergizadoslosdosperifricos:XmtRcvActivate,sedeseaActivar
elSubsistemaCompletoparatrabajarporinterrupciones:
169ComIntEn:MACRO;InterruptEnableforCommunications
170bsetRCVIEN.bit,RCVCTRLREG;JustonlyRCV...
171;MustEnableXMT*ONLY*whenneeded
172ldaRCVSTATREG;Clearanypossiblypending
173ldaRCVBUF;..RCVReadyFlag
156
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Ntese que SLO SE ACTIVA LA RECEPCIN para que interrumpa. Esto es as porque el
comportamientodelosperifricosdeentradaestalqueNUNCAellosestnREADY(nunca
interrumpen) hasta que llega una letra o algn otro elemento por la correspondiente
entrada.
Losperifricosdesalida(impresoras,transmisorRSR232,ycualquierotro),cuandose
los Activa es ms que seguro que no estn haciendo nada (nadie los ha mandado A
transmitirnada,onoleshandadonadaparaimprimir).
Asque,paracomenzar,ESTNREADY.
Si se los activa para que interrumpan, como estn Ready, van a interrumpir
INMEDIATAMENTE. Por eso hay que posponer la habilitacin para interrupciones de los
perifricos de salida, hasta cuando haya salidas disponibles, como una tabla para
transmitir por interrupciones, o una cola, o incluso una letra, si es que no se la
deseaenviardemaneraprogramada,sinoporinterrupciones.
NTESEque,ademsdelaactivacindelbitdeRCVIEN.bit,leyendoelRCVSTATREGyel
RCVBUF:
172ldaRCVSTATREG;Clearanypossiblypending
173ldaRCVBUF;..RCVReadyFlag
..se BORRA cualquier posible "RCV Ready Flag" pendiente, si es que hubiera llegado
algnsmboloANTESdequeactivramoselComIntEn.
Piense bien sobre las implicaciones que existen si queremos habilitar nuestra
recepcin, y no lo podemos hacer sin estar seguros de que NO NOS HAN COMENZADO A
TRANSMITIRTODAVA!
Elcomportamientodelosperifricosdesalidaesas:larutina,probablementeMain,
llenaunatablaousauna,pregrabadaenROM(Flash),yhabilitalasinterrupcionesde
salida. La ISR de transmisin: XMTISR, se activa cuando est disponible, si se
encuentrahabilitadaparainterrumpir.As,sacaunelementodelatabla,lotransmite
yretornaconRTI(ReturnfromInterrupt).CuandovuelvaaquedarenestadodeReady,
vuelveainterrumpir.
Dosmecanismossuelenemplearseparaidentificarqueyanohaynadaqueprocesar:ose
acaba de enviar EL sealizador de final, que suele ser un byte NULL, lleno de ceros
(ste esel mismo mtodo que usa el C para terminar sus Strings), o llegaa cero un
contador que identifica cuntos caracteres faltan para terminar, y que se lo ha ido
decrementandocadavezquesetransmiteunaletra.
Cualquiera que sea el mtodo, cuando XMTISR determina que ya no hay nada ms que
enviar,SEAUTODESHABILITAPARAINTERRUMPIR,yretornaconRTI.
157
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Mucho cuidado con comenzar una accin antesde terminar la otra.Puede hacerse, pero
garantizando que jams se trancar el juego. Por ejemplo, supongamos que se est
empleandounaCOLA:SiMainhace"enQue"dealgoyhabilitalasinterrupciones,yla
XMTISR hace "deQue" y lo transmite, y si en un momento Main est "enQueing" algo y
quiere volver a habilitar las interrupciones, tiene que asegurarse que no ocurra una
situacindeDEADLOCK,enlaqueMainacabadehabilitarlasinterrupcionesyXMTISR
las desactiva y se llegue a un estado en que a Main le aparece la cola llena, y no
puedehacerunulteriorenvo,yXMTISRNOinterrumpe,porqueestdesactivada,ypor
tantonosacacaracteresdelacola.Esoes:SUPROGRAMAESTMUERTO:DEADLOCK.Nada
haceningnproceso;cadaentidadesperaporlaotra,yningunadelasdostrabaja...
Yolesdijequelasinterrupcionessonunagranadicinalmodelodelcomputador,sin
lascualesseranimpensableslascomputadorasmodernas,yqueapesardeello,sonel
PEORDOLORDECABEZAdeunprogramadordesistemasEmbebidos...
Elanlisissecomplicamuchsimo,porquesetiendeacreerque2instruccionesquese
escribieronunaacontinuacindelaotra,seejecutarnunainmediatamentedespusde
la otra. Cuando hay interrupciones activas, esto no necesariamente es as. Por eso,
cuando est haciendo un anlisis de coherencia, que le permita garantizar que su
programajamsquedarenDEADLOCK,paracadainstruccintienequesuponerquetodas
las ISR lo interrumpen, hacen su trabajo, y que todo sigue bien cuando su programa
contineaejecutarlasiguienteinstruccindesulalistado.Esmuylaborioso.
NOTAFINAL:
Usted debe haber observado que se ha empleado la instruccin MOV en varias partes;
incluso aprovechando su modo auto incrementado para el registro ndice H:X. Pero la
instruccinMOVrequierequealmenosunadesusdireccionesseencuentrenenlapgina
0 (ZPage),es decir, dentro de las 256 primeras posiciones. Por tanto, estasrutinas
PRECISAN la definicin de sus tablas EN ZRam. Si eseno va a ser su caso, tiene que
reescribirlasparausarparejasdeLDAySTAquereemplacenlosMOV.
28) Transmisin.
SeenvanpermanentementealPClasletrasdela'A'maysculaala'z'minscula.En
el PC se ejecuta un programa de comunicaciones tal como "Hyperterminal" (antigua
utilidad nativa en Windows, y ya periclitada...), el "TeraTerm" (que es el que yo
siempreuso),el"Putty"("poty",comosepronunciaenInternet),el"RealTerm",quees
el programa instalado en los PCs del Laboratorio C, y cualquier otro que ustedes
conozcanpararealizarestaactividaddeinteractuarenWindowsconundispositivova
canaldecomunicacionesRS232,enloqueseconoceunaCONSOLAREMOTA.
158
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
["Laboratorios\Lab3\SciComm\1tstXmt.asm"]
01;********************************************************************
02;Programa1TstXmt.asm:TestSCIComm.Support
03;LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)M10D2013
04;
05;..Send'A'to'z'lettersforever,toHyperterminal
06;
07;
08;Includefilesthatnodefineram
09NOLIST
10INCLUDE'derivative.inc'
11INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
12LIST;..storageandTHISisit'splace
13;
14;2)DEFINES
15ram:SETZ_RAMStart;$80
16rom:SETROMStart;$2080
17initStack:EQURAMEnd+1;$1800=$17FF+1.Stackbeginson$17FF
18COP_Disable:EQU$42
19;====================================================================
20;MAINPROGRAMHEADER:
21ABSENTRYMain
22ORGrom
23Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
24staSOPT1;..SystemOptions1
25ldhx#initStack;SetupSP
26txs;...
27;
28SCI9600N8;SetupSerialCommunicationsInter
29XmtRcvActivate;..face:9600bps,Noparity,8bits
30;
31Forever:
32lda#'A';Ascii'A'
33XmitLoop:
34putchar
35inca;'A'+1is'B';'Z'+1is'a'
36cmp#'z'
37blsXmitLoop
38putc#$0D;CarriageReturn(CR:'\r'inC)
39putc#$0A;LineFeed(LF:'\n')
40braForever;Tocometothisendyou'lneed
41;..217,191cycles@4,194,304Hz
42;
43nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
44;This'nop'MAYberemovedforCW6.3...
45;
46;InterruptVectors
159
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
47ORGVreset
48DC.WMain;RESET.Maximumpriority.Asynch.
49END
COMENTARIOS a ["Laboratorios\Lab3\SciComm\1tstXmt.asm"]
As,nuestroprimerprograma"1TstXmt.asm"incluyelalibrera'SciComm.inc'enunrea
queNOempleaRAM,acontinuacinde'derivative.inc':
10INCLUDE'derivative.inc'
11INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
NoolvidequestaeslaposicindondeDEBEincluirmilibreradecomunicaciones.
Luego, se definen los parmetros de comunicacin (SCI9600N8) y se activan AMBOS
perifricos:XmtRcvActivate(ActivateXmt&Rcv):
28SCI9600N8;SetupSerialCommunicationsInter
29XmtRcvActivate;..face:9600bps,Noparity,8bits
Elprogramaensesmuysencillo;consistedeuncicloindefinidoquetransmitetodas
lasletrasentrela'A'maysculayla'z'minscula:
31Forever:
32lda#'A';Ascii'A'
33XmitLoop:
34putchar
35inca;'A'+1is'B';'Z'+1is'a'
36cmp#'z'
37blsXmitLoop
Cada vez que se termina una serie, se imprime el smbolo que representa, para la
pantalla,eldevolversehaciaelladoizquierdodelamisma:CarriageReturn('\r'in
C),yluegoelqueobligaalcursordelapantallaabajarunalnea:LineFeed(LF:
'\n'):
38putc#$0D;CarriageReturn(CR:'\r'inC)
39putc#$0A;LineFeed(LF:'\n')
29) ECHO.
Este programa implementa una funcionalidad muy empleada entre los profesionales que
tienenqueinteractuarconcomunicacionesseriales,deltipoRS232.Consisteenhacer
unECO(ECHO)aloscaracteresquelellegananuestroequipo,probablementedesdeuna
estacinMaestra,remota.
Ustedes simularn la estacin remota con el PC; su dispositivo local ser nuestra
tarjetaDEMOQE128.Ahora,resultaqueenocasiones,losprogramasdecomunicacinque
se ejecutan en la estacin maestra (o en el PC), tienen una funcin que a veces el
operadorolvida,yquesellamaLOCALECHO.Estosignificaquetodoloqueseenva,
porejemplodesdeeltecladodelPC,seveenlapantalladelmismo.Esclaroque,si
160
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
est activa esa caracterstica, es difcil saber si nos estamos comunicando con el
perifricoremoto,ono.
Poresoelsiguienteprogramacontestaconlaletraquerecibe,INCREMENTADAenuno.Se
sabeque,enlacodificacindeloscaracteres(clsicamente,ASCII:AmericanStandard
CodeforInformationInterchange),unaletradelalfabetoesigualalaanterior,MAS
UNO.Esdecir,quelaletra'B'esigualalaletra'A'MS1.Asquenuestroprograma
de ECHO, toma cada smbolo que recibe, y devuelve el siguiente: Smbolo Recibido MS
UNO. Ahora s es fcil en el PC verificar que la comunicacin se ha establecido. Si
escriboun'A',recibouna'B',yasparatodaslasletras.
SiustedescribeHAL,comosellamabalasupercomputadoradelapelcula"2001Odisea
delEspacio",apareceenlapantalla...IBM.Qutal?
["Laboratorios\Lab3\SciComm\2echo1.asm"]
01;********************************************************************
02;Programa2Echo1.asm:TestSCIComm.Support
03;LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04;M10D2013cosmetics(XmtRcvActivate)
05;Tobesurethatthereis"ECHO",returnback'letter+1',
06;..i.e:ifHyperterminalsends'A',HC908willreturn'B'...
07;..fortherange'A'<=c<'z'.
08;Anyothercharsarereturnedbackwithoutmodification.
09;
10;Includefilesthatnodefineram
11NOLIST
12INCLUDE'derivative.inc'
13INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
14LIST;..storageandTHISisit'splace
15;
16;2)DEFINES
17ram:SETZ_RAMStart;$80
18rom:SETROMStart;$2080
19initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
20COP_Disable:EQU$42
21;====================================================================
22;MAINPROGRAMHEADER:
23ABSENTRYMain
24ORGrom
25Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
26staSOPT1;..SystemOptions1
27ldhx#initStack;SetupSP
28txs;...
29;
30;SCI9600N8:NoneedforpreviousenabledSCIperipherals
31SCI9600N8;SetupSerialCommunicationsInter
32XmtRcvActivate;..face:9600bps,Noparity,8bits
33;
34Prompt:
161
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
35lda#'A';Ascii'A'
36XmitLoop:
37putchar
38inca
39cmp#'z'
40blsXmitLoop
41putc#$0D;CarriageReturn(CR:'\r'inC)
42putc#$0A;LineFeed(LF:'\n')
43;BEPATIENT!Tocomehereyou'lneed
44;..217,191cycles@4,194,304Hz
45;************NOTE:***************
46;ToSIMULATESCI*inputs*usePEMicroSCI1debuggercommand.
48;ItwillbeinstructivetodisplaySCI1S1(statusregister),andsee
49;..mostimportantflags,bits7,6&5:XMTRDY,XMTEMPTY&RCVRDY
50;Whiledebugging,seehowreadingStatusandwritingBUF,clears
51;..theRCVReadyflag;seealsohowXMTStatuswork(RDY&EMPTY)
52inpLoop:
53getchar;Lettersinrange'A'..'z'will
54cmp#'A';..beincrementedbeforereturning,
55bhsinRange;..tobesurethatwhatweseein
56;..thePCisn'taLOCALECHO!
57Xmit:putchar
58brainpLoop;Stayinthisloop,forever
59inRange:
60cmp#'z'
61bhsXmit;Don'tincrement'z'either
62incLetter:
63inca;Incrementthisreceivedchar
64braXmit;..andreturnbackittoPC
65;
66nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
67;This'nop'MAYberemovedforCW6.3...
68;
69;InterruptVectors
70ORGVreset
71DC.WMain;RESET.Maximumpriority.Asynch.
72END
COMENTARIOS a ["Laboratorios\Lab3\SciComm\2echo1.asm"]:
NoolvidelaposicindondeDEBEincluirmilibreradecomunicaciones:
12INCLUDE'derivative.inc'
13INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
Acontinuacin,comoenelejemploanterior,lasMacros:
31SCI9600N8;SetupSerialCommunicationsInter
32XmtRcvActivate;..face:9600bps,Noparity,8bits
162
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
PrimeroelprogramaenvaLAMISMATRAMAdelejercicioanterior.Sellama"PROMPT"aun
textodeadvertenciaqueelcomputadorleenvaalusuariopararecordarlequeesten
posicin de recibir los datos que se le enven. Por eso esta trama la llamamos aqu
Prompt:
34Prompt:
35lda#'A';Ascii'A'
36XmitLoop:
37putchar
38inca
39cmp#'z'
40blsXmitLoop
41putc#$0D;CarriageReturn(CR:'\r'inC)
42putc#$0A;LineFeed(LF:'\n')
LuegorecibeloqueleenvandesdeelPC,verificaquelossmbolosseencuentrenen
elrango'A'..'z';sino,retransmitelomismoquerecibi...
52inpLoop:
53getchar;Lettersinrange'A'..'z'will
54cmp#'A';..beincrementedbeforereturning,
55bhsinRange;..tobesurethatwhatweseein
56;..thePCisn'taLOCALECHO!
57Xmit:putchar
58brainpLoop;Stayinthisloop,forever
59inRange:
60cmp#'z'
61bhsXmit;Don'tincrement'z'either
["Laboratorios\Lab3\SciComm\3echoInt1.asm"]
01;********************************************************************
02;Programa3EchoInt1.asm:TestSCIComm.Support
03;LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)D24J2012
04;M10D2013cosmetics(XmtRcvActivate)
05;..Same2Echo1.asmprogrambutusingINTERRUPTSforXMT'Message'
06;
07;Includefilesthatnodefineram
08NOLIST
09INCLUDE'derivative.inc'
10INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
163
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
11LIST;..storageandTHISisit'splace
12;
13;2)DEFINES
14ram:SETZ_RAMStart;$80
15rom:SETROMStart;$2080
16initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
17COP_Disable:EQU$42
18;====================================================================
19;GLOBALVARIABLES
20ORGram
21XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
22XmtPtr:DS2;charpointerofnextdatatoXmt
23;********************************************************************
24;MAINPROGRAMHEADER:
25ABSENTRYMain
26ORGrom
27Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
28staSOPT1;..SystemOptions1
29ldhx#initStack;SetupSP
30txs;...
31;
32;SCI9600N8:NoneedforpreviousenabledSCIperipherals
33SCI9600N8;SetupSerialCommunicationsInter
34XmtRcvActivate;..face:9600bps,Noparity,8bits
35;====================================================================
36;Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
37Prompt:
38ldhx#Message;InitXmtPtrwithMessageaddress;
39sthxXmtPtr;..initcounterwith#ofchars
40mov#LOW(MessageSize),XmtNchars;...
41XmtIntEn;XmtISRwillsendthemessageand
42;..clear'XmtNchars'whenfinished
43cli;<<<DON'TFORGETTOGLOBALENABLEINTs
44;
45XmtLoop:
46tstXmtNchars;Waituntildone(tst:cmpwith0)
47bneXmtLoop;(Notneededhere.Just:GotoBRA*)
48bra*
49;
50Message:DC'12345',$0D,$0A;Shortmessage.DC?DefineConstant
51;;Message:DC"Esteeselmensajedeprueba,"
52;;DC"primeroentransmitirsealPCporinterrupciones"
53;;DC$0D,$0A;CarriageReturn,LineFeed(Newline)
55MessageSize:EQU*Message
56;====================================================================
57XmtISR:
58pshh;Notsavedbyinterruptproc
59tstXmtNchars;Seeifdone
60beqXmtDone;0chars?GotoDsbXmtInt
164
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
61Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
62decXmtNchars;Adjustcharcounter
63braXmtIsrExit
64XmtDone:
65XmtIntDsb
66XmtIsrExit:
67pulh;Notrestoredbyinterruptproc
68rti
69;
73;InterruptVectors(ELIMINADASLNEAS70,71,72porespacio.VerSRCORG)
74ORGVsci1tx
75DC.WXmtISR;SCITransmit
76ORGVreset
77DC.WMain;RESET.Maximumpriority.Asynch.
78END
COMENTARIOS a ["Laboratorios\Lab3\SciComm\3echoInt-1.asm"]:
Comodecostumbre,aquvanlosIncludeFilesquenodefinenram:
09INCLUDE'derivative.inc'
10INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
Se incluyen dos variables GLOBALES: un contador de los caracteres que faltan por
enviar,XmtNchars,yelapuntadoralaprximaletradelmensajequesetransmitir:
20ORGram
21XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
22XmtPtr:DS2;charpointerofnextdatatoXmt
33SCI9600N8;SetupSerialCommunicationsInter
34XmtRcvActivate;..face:9600bps,Noparity,8bits
38ldhx#Message;InitXmtPtrwithMessageaddress;
39sthxXmtPtr;..initcounterwith#ofchars
165
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ste no sepa con seguridad si ese smbolo representa 8 bits o 16. Para evitar toda
ambigedad se usa el operador LOW, que escoge los 8 bits inferiores del smbolo en
cuestin. Y el numeral (#) se le agrega porque estamos usando la parte baja de
(MessageSize)comounaconstante(elvalordeltamaoreservadoparaesatabla):
40mov#LOW(MessageSize),XmtNchars;...
De los dos procedimientos que suelen emplearse para verificar que la transmisin se
termin(ZStrings,terminadosenNULL,ounContadorindicandolacantidaddesmbolos
quefaltaportransmitir),hemosescogidoesteltimo,uncontadordeletras.
Despus de esto estamos listos para transmitir; para esto habilitamos las
interrupcionesdeltransmisory,PORLTIMO,TAMBINhabilitamoslabanderaGLOBALdel
CPU,paraquesteacepteyproceseinterrupts:
41XmtIntEn;XmtISRwillsendthemessageand
42;..clear'XmtNchars'whenfinished
43cli;<<<DON'TFORGETTOGLOBALENABLEINTs
45XmtLoop:
46tstXmtNchars;Waituntildone(tst:cmpwith0)
47bneXmtLoop;(Notneededhere.Just:GotoBRA*)
48bra*
Seveconclaridadquebastarareemplazaresas3instruccionesconel"bra*",porque
despus de transmitir los datos, no hay ningn proceso ulterior en este ejercicio.
Tambinsevequenosenecesitanlasinterrupciones,porqueelCPUnoesthaciendo
nada mientras la ISR transmite el texto... porque ste es un ejemplo muy sencillo.
Cuando usted haga su proyecto tendr oportunidad de introducir en Main, cdigo que
trabajeCONCOMITANTEMENTEconlaISR.
VieneladefinicindelaTabla:
50Message:DC'12345',$0D,$0A;Shortmessage.DC?DefineConstant
55MessageSize:EQU*Message
El texto, muy corto en este ejercicio, corresponde a los nmeros 12345 y luego, el
Carriage Return (\r: 0x0D: $0D) y el New Line (\n: 0x0A: $0A). El DC es por "Define
Constant";debeutilizarseenelCODESECTION,puesdefineespacioenRAM(Flash).
Y para que sea el Assembler el que calcule el tamao del texto, a fin de que si lo
cambiamosNOTENGAMOSQUEVOLVERACONTARLO,eltrucoesgenerarunsmbolo,definido
ahoraporlapseudoinstruccinEQU,as:
55MessageSize:EQU*Message
Recuerde que el LOCATION COUNTER (que usted debi aprender al hacer una de las
monografas de la parte terica del curso) se identifica en el CodeWarrior con el
smbolo '*'. Y deesa manera es claro que el nmero de byteses iguala la posicin
166
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
siguientealtexto,identificadaporel'*',menoslaetiquetaquesealaelcomienzo
delatabla,Message:
Siquiereensayarcontextosmslargos,aquhayunejemplo:
51Message:DC"Esteeselmensajedeprueba,"
52DC"primeroentransmitirsealPCporinterrupciones"
53DC$0D,$0A;CarriageReturn,LineFeed(Newline)
55MessageSize:EQU*Message
Larutinadeinterrupcionesparaeltransmisor,XmtISR,comienzaguardandoenelStack
elvalordelaparteHdelregistrondice:H:X,porqueelhardwareNOsalvaesebyte
automticamente. Y como putcX emplea el registro ndice, pues hay que resguardar su
valoraliniciodelaISR,yrestaurarloparafinalizar.
57XmtISR:
58pshh;Notsavedbyinterruptproc
Loprimeroquesehaceesverificarsianhayalgoportransmitir.Sino,terminamos
saltandoalaetiquetaXmtDone:
59tstXmtNchars;Seeifdone
60beqXmtDone;0chars?GotoDsbXmtInt
61Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
Selerestaunoalcontadordeletras,XmtNchars,yseretornadelainterrupcin.
62decXmtNchars;Adjustcharcounter
63braXmtIsrExit
Cuandoelcontadordeterminaqueyasetermintodalatransmisin,seAUTODESHABILITA
larutinadeinterrupcin:
64XmtDone:
65XmtIntDsb
66XmtIsrExit:
67pulh;Notrestoredbyinterruptproc
68rti
LosInterruptVectorssonsloelVsci1txyelVreset:
74ORGVsci1tx
75DC.WXmtISR;SCITransmit
76ORGVreset
167
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
77DC.WMain;RESET.Maximumpriority.Asynch.
["Laboratorios\Lab3\SciComm\3echoInt1Leds.asm"]
001;********************************************************************
002;Programa3EchoInt1Leds.asm:TestSCIComm.Support
003;LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)C27J2012
004;..J03E2013M10D2013cosmetics(XmtRcvActivate)
005;..Same3echoInt1.asm,butFlashLEDswitheachbytesent.
006;InDEMOQUE128,DO***NOT***USEPTC5'sASSOCIATEDLED,asitis
007;..alsothepinusedtoDISABLECOMM1!!!,viaJumperJ8,THANKS!
008;
009;Includefilesthatnodefineram
010NOLIST
011INCLUDE'derivative.inc'
012INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
013LIST;..storageandTHISisit'splace
014;
015;2)DEFINES
016ram:SETZ_RAMStart;$80
017rom:SETROMStart;$2080
018;;;initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
019;;;COP_Disable:EQU$42
020;====================================================================
021;GLOBALVARIABLES
022ORGram
023NOLIST
024include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
025LIST
026XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
027XmtPtr:DS2;charpointerofnextdatatoXmt
028;********************************************************************
029;MAINPROGRAMHEADER:
030ABSENTRYMain
031ORGrom
032Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
033staSOPT1;..SystemOptions1
034ldhx#initStack;SetupSP
035txs;...
036;
037;SCI9600N8:NoneedforpreviousenabledSCIperipherals
168
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
038SCI9600N8;SetupSerialCommunicationsInter
039XmtRcvActivate;..face:9600bps,Noparity,8bits
040;====================================================================
041;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
042mov#%11110000,PTCD;Turnon4leds,toshowprogram
043mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
044mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
045mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
046;NOTE:PTC5isprogrammedforINPUTsowrittingtoPTC5doesNOTHING
047;********************************************************************
048;NOTE:GeniusworkingatPEMicrousesamePTC5pintoboth,drivea
049;LED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,THANKS!
050;So,ifyouuseBOTHCOMM1andLeds,doNOTusePTC5associatedLED.
051;********************************************************************
052Init8Timers
053cli;<<<DON'TFORGETTOGLOBALENABLEINTs
054Loop:WaitMS_on7,#750;Showthelights...
055;
056;Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
057Prompt:
058ldhx#Message;InitXmtPtrwithMessageaddress;
059sthxXmtPtr;..initcounterwith#ofchars
060mov#LOW(MessageSize),XmtNchars;...
061XmtIntEn;XmtISRwillsendthemessageand
062;..clear'XmtNchars'whenfinished
063XmtLoop:
064tstXmtNchars;Waituntildone(tst:cmpwith0)
065bneXmtLoop;..
066WaitMS_on7,#750;Showthelights...
067ldhx#Message2;InitXmtPtrwithMessageaddress;
068sthxXmtPtr;..initcounterwith#ofchars
069mov#LOW(MessageSize),XmtNchars;...
070XmtIntEn;XmtISRwillsendthemessageand
071XmtLoop2:
072tstXmtNchars;Waituntildone(tst:cmpwith0)
073bneXmtLoop2;..
074braLoop
075;
076Message:DC'1234567890',$0D;Shortmessage.DC?DefineConstant
077MessageSize:EQU*Message
078Message2:DC'6789012345',$0D;Shortmessage.DC?DefineConstant
079;;Message:DC"Esteeselmensajedeprueba,"
080;;DC"primeroentransmitirsealPCporinterrupciones"
081;;DC$0D,$0A;CarriageReturn,LineFeed(Newline)
082;;MessageEnd:
083;====================================================================
169
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
084XmtISR:
085pshh;Notsavedbyinterruptproc
086tstXmtNchars;Seeifdone
087beqXmtDone;0chars?GotoDsbXmtInt
088lda#$FF;FlashLedstoshowprogramprogress
089eorPTCD;..
090eorPTED;..
091staPTCD;..
092staPTED;..
093Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
094decXmtNchars;Adjustcharcounter
095braXmtIsrExit
096XmtDone:
097XmtIntDsb
098XmtIsrExit:
099pulh;Notrestoredbyinterruptproc
100rti
101;
102nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
103;This'nop'MAYberemovedforCW6.3...
104;====================================================================
105;RTCInterruptServiceRoutine,siusaInit8Timers...
106RTC_INTERRUPT:
107TIMERS8ISR
108;
109;InterruptVectors
110ORGVrtc;Increasingpriorityfrombottomup
111DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
112ORGVsci1tx
113DC.WXmtISR;SCITransmit
114ORGVreset
115DC.WMain;RESET.Maximumpriority.Asynch.
116END
COMENTARIOS a ["Laboratorios\Lab3\SciComm\3echoInt-1Leds.asm"]:
LoprimeroescomentarqueenlatarjetaDEMOQUE128,NOsepuedeusarelLEDasociado
con PTC5's ASSOCIATED LED, porque ese mismo pin se emplea en esa tarjeta para
DESHABILITARLASCOMUNICACIONES!!!,vaJumperJ8.Eso...eraINNECESARIO.Graciasa
PEMICRO!
009;Includefilesthatnodefineram
012INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
Incluirlalibreratimers8HS.inc,queSdefinevariablesenRAM:
022ORGram
024include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
170
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Elcontadordecaracteresyelapuntadoralaprximaletraquesertransmitida:
026XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
027XmtPtr:DS2;charpointerofnextdatatoXmt
Parmetrosdecomunicacin,yActivacin(Activate)deXMTyRCV:
038SCI9600N8;SetupSerialCommunicationsInter
039XmtRcvActivate;..face:9600bps,Noparity,8bits
INICIALIZACINDELOSLEDs.LosLEDsenlatarjetaDEMOQE128son8,peroNOprovienen
de un MISMO registro de 8 bits (lo que no le hubiera costado nada a la gente de
PEMicro),sinoquevienen6ydos,as:dePTCD:bits05,ydePTED;bits67.Eso...
eraINNECESARIO.Gracias,PEMICRO!
LoprimeroquesehacecuandosevanaprogramarunoomsbitsparaSALIDAcomoes
elcasodelosLEDsenesteejercicio,esinicializarlosconelvalorqueparael
ejercicioseaelmsconveniente,ANTESDEDEFINIRLOSCOMOSALIDA(Recuerdeque,al
encenderelMCU,TODOSlospuertossondeENTRADA).
041;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
042mov#%11110000,PTCD;Turnon4leds,toshowprogram
043mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
Despusdequeyatienenunvalordesalidaasignado,puedenahorasprogramarsepara
SALIDA:
044mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
045mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
046;NOTE:PTC5is^programmedforINPUT:WrittingtoitdoesNOTHING
ADVERTENCIA:
A algunos GENIOS que trabajan en PEMicro, se les ocurri usar el MISMO pin PTC5
paramanejarsimultneamenteunLEDYTAMBINPARADESHABILITARLASCOMUNICACIONES,
vaelJumperJ8,Gracias,PEMicro!
AsquesisuproyectousasimultneamenteelpuertodecomunicacionesSCI1yLEDs,
NOuseelLED5,asociadoconPTC5.
Ahora,inicializalostimers,comosiempresehahecho,yhabilitalasinterrupciones
globalesdelCPU:
052Init8Timers
053cli;<<<DON'TFORGETTOGLOBALENABLEINTs
171
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
PrimeroesperaunpocomenosdeunsegundoparaqueseveanlosLEDs:
054Loop:WaitMS_on7,#750;Showthelights...
Transmitaelmensaje;estaparteesidnticaaladelejercicioanterior:
057Prompt:
058ldhx#Message;InitXmtPtrwithMessageaddress;
059sthxXmtPtr;..initcounterwith#ofchars
060mov#LOW(MessageSize),XmtNchars;...
Despusdecargartodoslosparmetrosparaelmensaje#1,habilitalasinterrupciones
detransmisin:
061XmtIntEn;XmtISRwillsendthemessageand
Yluegovieneelciclodeesperahastaqueseterminedetransmitir:
063XmtLoop:
064tstXmtNchars;Waituntildone(tst:cmpwith0)
065bneXmtLoop;..
Cuandohayaterminado(XmtNcharsvalecero),vuelvaaesperar,afindequeseveanlos
LEDs:
066WaitMS_on7,#750;Showthelights...
Ahora carga la direccin del nuevo mensaje, Message2. Note que como ambos mensajes
tienenlamismalongitud,solosehaempleadoUNAlongitudparaellosdos.Esonotiene
porquseras.Sisusmensajestienendiferentelongitud,repitaelmismoclculoque
seesthaciendoparaelmensajeuno,enelmensaje2,yelrestosigueigual:
067ldhx#Message2;InitXmtPtrwithMessageaddress;
068sthxXmtPtr;..initcounterwith#ofchars
069mov#LOW(MessageSize),XmtNchars;...
Vueltaahabilitarlasinterrupcionesdesalida,queseAUTODESHABILITARONalterminar
detransmitirelmensajeanterior:
070XmtIntEn;XmtISRwillsendthemessageand
071XmtLoop2:
072tstXmtNchars;Waituntildone(tst:cmpwith0)
073bneXmtLoop2;..
074braLoop
Yrepite...
Losmensajes:
076Message:DC'1234567890',$0D;Shortmessage.DC?DefineConstant
077MessageSize:EQU*Message
078Message2:DC'6789012345',$0D;Shortmessage.DC?DefineConstant
172
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
084XmtISR:
085pshh;Notsavedbyinterruptproc
086tstXmtNchars;Seeifdone
087beqXmtDone;0chars?GotoDsbXmtInt
LasprximaslneasnieganlosbitsdelosregistrosCyE,quealimentanalosLEDs:
088lda#$FF;FlashLedstoshowprogramprogress
089eorPTCD;..
090eorPTED;..
091staPTCD;..
092staPTED;..
Luegosetransmitelasiguienteletra;sedecrementaelcontadoryseterminalaISR:
093Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
094decXmtNchars;Adjustcharcounter
095braXmtIsrExit
096XmtDone:
097XmtIntDsb
098XmtIsrExit:
099pulh;Notrestoredbyinterruptproc
100rti
LaRTCInterruptServiceRoutine:
106RTC_INTERRUPT:
107TIMERS8ISR
YlosInterruptVectors,unoparamilibreradeTimers,Vrtc,otroparaeltransmisor
deinformacinserial,Vsci1tx,yelsiemprenecesario,Vreset.
DebepoderhacerunprogramaquesimuleunCHAT:EnusuarioescribedesdeelPC,elMCU
le hace ECHO normal (si recibe una A retransmite una A), y para simular que el otro
usuario escribe desde el MCU, donde no hay muchos recursos... podemos pegar varios
mensajes,unoacadapushbuttondeentrada;elMCUleeelbotnqueseoprimi,encola
elcorrespondientemensaje,yrealizalatransmisinporinterrupciones.
173
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Tienequetomarprevisionesparaquenohayaconflictoentreelmensajequeustedest
transmitiendodesdeelMCU,conelECOqueseleesthaciendoacadaletraquereciba
del PC. (Por ejemplo, si est transmitiendo su mensaje, puede ignorar por completo
hacerle Eco a la informacin que de pronto le puedan enviar simultneamente desde el
PC).
De los dems perifricos, el PWM se usar en los proyectos en los que haya sonidos
(tipoWalkman,opiano).ElADC(AnalogtoDigitalConverter)seemplearenproyectos
donde,porejemplo,quieracambiarseelvolumendelsonido,olafrecuenciadelpiano,
osisedeseahacerunVoltmetroDigital(elpotencimetroalimentadirectamenteuno
deloscanalesdelADCenlatarjetaDEMOQE128)
UnaaplicacindelPWMesladehacerquelatarjetaHABLE:Segrabalavozysela
reproducevaPWM,detalmaneraquelacorneticadelatarjetasuene,locualharcon
muy mala calidad, porque la respuesta del piezoelctrico, que hace de transductor de
sonido,esmuypobre.Perosiustedpuedereproducirunapalabra,serunbuenlogro.
YlosotrosdispositivosnopuedenusarseenelDEMOQE128sintocarlosconectores,lo
queestprohibidoenloscursosdeArquitecturaIennuestroslaboratorios.Yatendrn
oportunidaddeemplearlosafondoenloscursosmsavanzadosdeArquitectura,yenlos
deLaboratoriosdeProyectos.
Sisetieneunatramadeinformacinde4bits,llamadosI7I6I5I3,ysequieredetectar
la presencia o ausencia de UN error, se le agrega UN BIT DE PARIDAD, del cual ya
hablamos con antelacin al explicar los aspectos ms relevantes de la LIBRERA DE
COMUNICACIONESSERIALES:SciComm.inc.
RichardWesleyHamminghizoen1950unacodificacinsimple,pura,clara,eficientey
eficaz,quepermiteDETECTARlaaparicindeUNERRORyCORREGIRLO,ydetectar(peroNO
corregir)laexistenciadeDOSerrores.
Para nuestro caso de ejemplo, Hamming dispuso los bits en la siguiente TRAMA (Trama
Hamming):I7I6I5P4I3P2P1,endonde,ademsdelosbitsdeInformacin,I7I6I5I3,sehan
entrelazado 3 bits adicionales, de paridad: P4P2P1 (note que su identificacin
correspondeapotenciasde2)
Enesatrama,Hamminghizoelsiguienteplanteamiento:Los3bitsextras,deparidad,
puedenestablecer8combinacionesentreellos.Lacombinacin000indicarqueNOhay
error.Ylasrestantes7combinaciones,del001al111,indicarnlaposicinendonde
apareceelerror,delaposicin1ala7,endecimal.
174
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
P1 = I3 XOR I5 XOR I7, el XOR entre los bits situados en las posiciones
correspondientesalosnmerosimparesdelatabladeabajo:
P2=I3XORI6XORI7(observeelporquenlatabla)
P4=I5XORI6XORI7(observeelporquenlatabla)
TABLAHAMMING:
Error_Column#
PPP|IIII
421|7653
+
0000(NOERROR)
0011....
0102....
0113...1P1=I3XORI5XORI7
1004....P2=I3XORI6XORI7
1015..1.P4=I5XORI6XORI7
1106.1..
11171...
Donde haya un 1, para cada Pn, se toma la Im que tenga 1 (si es que hay) y se la
incluyeenlaecuacin.
VerlaexplicacinparauncasodeNbitsdeinformacinestenIngenieraDigital.
SupongamosquetenemoslaInformacinde4bitsdelejemployqueremoscalcularlas3
Paridades.Cmoharaustedlos6XORsdelas3ecuacionesbooleanas?
Una forma inmediata de hacer los XORs sera colocando los bits en dos variables del
CPU,H1yH2,enlassiguientesposiciones,yemplearlainstruccinEOR(XORparael
S08):
H1|I5I3I3
H2|I6I6I5XOR
+
H2|p4p2p1(RespuestaParcial)
H1|I7I7I7XOR
+
H2|P4P2P1(RESPUESTADEFINITIVA)
b7b6b5b4b3b2b1b0
..I7I6I5P4I3P2P1(Variablede7bits;alojalaTramaHamming)
b7b6b5b4b3b2b1b0
H1|I5I3I3
H2|I6I6I5
175
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
H1|I7I7I7
ydeaquotravezalatrama:
H2|P4P2P1(RESPUESTA)
YsilosbitsdeInformacincomienzanjuntos:I7I6I5I3,hayquemoverlos,alcomienzo,
paraformarlaTramaHamming.
Setransmitelatramaaselaboradayeneldestinoseaplicaunclculosimilar,que
ustedtienequerevisarenIngenieraDigital.Altransmitir,secomienzacon4bitsde
informacinyseformaunatramade7bits;alreceptorlelleganlos7bits,selos
procesayseproducenlos4bitsdeinformacin,libresdeerror,mientrasnoocurra
msdeunerrorencadatramade7.
Paraunexamenoevaluacin,losejerciciossuelentenermsde3bitsdeinformacin,
loqueproducetramasquenocabenenunBYTE.Sinembargoelprocedimientoessimilar
alanterior.
["Laboratorios\Proy\Buzzer\BitCopy.asm"]
01;********************************************************************
02;BitCopy.asm;LuisG.UribeC.,D01L2012
03;MACROBITCOPYandtestprogram.
04;Toimplement"C"statmentslikethis:
05;PTCD_PTCD0=PTBD_PTBD5;
06;//DisplayPWMoutput,pinPTB5,intoLEDwiredtoPTC0
07;********************************************************************
08NOLIST
09INCLUDE'derivative.inc'
10LIST
11;
12;2)DEFINES
13
14ram:SETZ_RAMStart;$80
15rom:SETROMStart;$2080
16initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
17COP_Disable:EQU$42
18
19;====================================================================
20BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit
176
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
21;Example:BITCOPYSrc,3,Dst,5;Useanyvariables:DIRorEXT
22lda\1
23bit#1<<(\2&$07);IfSrcAdd[SrcBit]==0
24beq\@Clr_DstAdd;..gotoClr_DstAdd[DstBit]
25;Set_DstAdd[DstBit]:;Else,Set_DstAdd[DstBit]
26lda\3
27ora#1<<(\4&$07)
28bra\@cont
29;Clr_DstAdd[DstBit]:
30\@Clr_DstAdd:
31lda\3
32and#~(1<<(\4&$07))
33\@cont:
34sta\3
35ENDM
36
37;********************************************************************
38;MAINPROGRAMHEADER:
39ORGram
40Src:DS1
41Dst:DS1
42
43ABSENTRYMain
44ORGrom
46Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
47staSOPT1;..SystemOptions1
48ldhx#initStack;SetupSP
49txs;...
50
51lda#0
52staSrc
53lda#$FF
54staDst
55BITCOPYSrc,3,Dst,5;copya0
56
57lda#$FF
58staSrc
59lda#$0
60staDst
61BITCOPYSrc,2,Dst,6;copya1
62
63bra*
64;
65nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
66;This'nop'MAYberemovedforCW6.3...
67;
68;InterruptVectors
70ORGVreset
71DC.WMain;RESET.Maximumpriority.Asynch.
73END
177
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Laboratorios\Proy\Buzzer\BitCopy.asm"]:
En C es relativamente fcil expresar estos movimientos de bits, de un lugar a otro,
talescomo:
05;PTCD_PTCD0=PTBD_PTBD5;
06;//DisplayPWMoutput,pinPTB5,intoLEDwiredtoPTC0
EnrealidadestnasignadosaunaStructdeBITS,enUnionconelByte(enestecaso,
delosregistrosCyB).
20BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit
21;Example:BITCOPYSrc,3,Dst,5;Useanyvariables:DIRorEXT
LaMacrotiene4parmetros:ladireccin(1)delavariableFUENTE(SRC),dedondese
vaatomarelbit(2)paratransportarloalavariable(3)DESTINO,DST,enlaposicin
debit(4)
OBSERVACIONES:
A)LasvariablespuedenestarcolocadasencualquierposicindelaRAM,porqueseusan
LDAySTAenlugardeMOV.
22lda\1
Secargaenelacumuladorelprimerparmetro:LavariableSRC.
23bit#1<<(\2&$07);IfSrcAdd[SrcBit]==0
SehaceunacomparacindelbitSRCdeseado,indicadoporelparmetro\2,paraversi
estencerooenuno.ParahacerlacomparacinseusalainstruccinBIT(BitTest),
quehaceunANDentreelAcumuladoryelOperando,ycomparaelresultadocontracero.
...un uno (#1) colocado en la posicin (<<) de bit indicada por el nmero \2
(<<(\2&$07). Al parmetro \2 se le ha hecho un AND (&) con el nmero $07 (binario
%111),afindequesiporerrorelusuariollamalaMacropasndoleunnmeroMAYORa
7,stequedaautomticamenteconfinadoalrangopermitidode0a7.
Claro?
24beq\@Clr_DstAdd;..gotoClr_DstAdd[DstBit]
SielbitesCerosesalta(BEQ)aBORRARelbitenladireccindestino:Clr_DstAdd.
ComostaesunadireccinqueserepetiracadavezqueseemplearalaMacro(locual
daraerror,porquenopuedehabermsdeunadefinicinparaunadireccin,nipara
178
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
unavariable),eltrucoconsisteenantecederladireccinqueseindicadentrodela
Macro,conun\@.EstoleindicaalAssemblerquegenereunadireccindiferente,cada
vezqueveaesesmbolo\@Clr_DstAdd.
AcontinuacinvieneelcdigoqueseejecutasielbiteraUNO,yportantohayque
colocar en uno (SET) el bit en el destino. Primero se carga el acumulador con la
variableDST:
26lda\3
y,paracolocarununoenelbitdeseadodeDST,selehaceunOR(ora)as:
27ora#1<<(\4&$07)
Aqu,denuevo,laposicines:un1(#1),desplazadoalaizquierda(<<)tantospasos
cuantosindiqueelltimoparmetro(\4),alqueselohaconfinadoautomticamente
alrangode0a7medianteelAND(\4&$07).
28bra\@cont
Si el bit estuvo en cero, hay que colocar en cero el bit correspondiente de DST,
haciendo un AND del valor (del Acumulador) con un nmero formado por TODOS UNOS,
ExceptounCEROenlaposicinquesequiereborrar:
29;Clr_DstAdd[DstBit]:
30\@Clr_DstAdd:
31lda\3
32and#~(1<<(\4&$07))
Laexpresin"and#~(1<<(\4&$07))"haceexactamenteeso:unAND(and)conunamscara
depurosUNOSqueseconsiguehaciendoelNEGADObooleanodeUNunoenlaposicinque
sequiereborrar:~:Negadobooleano;laposicinquesequiereborrar:(1<<(\4&$07)).
Claro?
Ejemplo:
SecargaunceroenSRC,ysellenadepurosunoselDST:
51lda#0
52staSrc
53lda#$FF
54staDst
Secopiaelbit3deSRC,albit5deDST:
55BITCOPYSrc,3,Dst,5;copya0
ConelDebuggerpuedeverseelvalorresultante.
179
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Secargaahoraalrevs,purosUNOSenSRC,ypurosCEROSenDST:
57lda#$FF
58staSrc
59lda#$0
60staDst
Ysecopiaelbit2deSRC,albit6deDST.VaseconelDebugger.
61BITCOPYSrc,2,Dst,6;copya1
01["Laboratorios\Proy\Buzzer\ADC.asm"]
02;********************************************************************
03;ADC.asm;LuisG.UribeC.,D01L2012L11M2013
04;L11M2013:ClarificationaboutADCpinsENABLE(APCTLx)
05;DESCRIPTION:TheADCmoduleisconfiguredincontinuousconversion
06;mode,everyobtainedvalueisdisplayinportC&E(8LEDs).
07;PTA0isthebluePOTENCIOMETERinDEMOQE128!!!
08;********************************************************************
09NOLIST
10INCLUDE'derivative.inc'
11LIST;..storageandTHISisit'splace
12;
13;2)DEFINES
14ram:SETZ_RAMStart;$80
15rom:SETROMStart;$2080
16initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
17COP_Disable:EQU$42
18;********************************************************************
19;MAINPROGRAMHEADER:
20ABSENTRYMain
21ORGrom
22Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
23staSOPT1;..SystemOptions1
24ldhx#initStack;SetupSP
25txs;...
26;
27;MCU_Init
28;;lda#$23;EnableBusClocktotheADCmodule
29;;staSCGC1
30;;clra;DisableunusedperipheralsBusclock
31;;staSCGC2
32;
180
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
33;GPIO_Init
34;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
35mov#%11110000,PTCD;Turnon4leds,toshowprogram
36mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
37mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
38mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
39;NOTE:PTC5isprogrammedforINPUTsowrittingtoPTC5doesNOTHING
40;********************************************************************
41;NOTE:GeniusworkingatPEMicrousesamePTC5pintoboth,drivea
42;LED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,THANKS!
43;So,ifyouuseBOTHCOMM1andLeds,doNOTusePTC5associatedLED.
44;********************************************************************
45;
46;ADC_configuration
47;Int.disable.Continuousconversion
48mov#$20,ADCSC1;..modeandchannel0active
49clrADCSC2;Softwaretriggerselected
50mov#$30,ADCCFG;Inputclock/2.LongSampletime
51;..config.8bitconversion
52;====================================================================
53;See"02MC9S08QE128RM(ReferenceManual)U.pdf",10.5.1ADCModule
54;..InitializationExample,10.5.1.2PseudoCodeExample:
55;APCTL1=0x02means:AD1pinI/Ocontroldisabled.
56;..AllotherADpinsremaingeneralpurposeI/Opins
57;Manualsays:A"1"inAPCTLx:PinI/OcontrolDISABLED.
58;..Itmeans:A"1"inAPCTLx:ADCpinENABLED!!!<<<<<<<<<<<<
59;
60;Thesepeoplecannotevenwriteadecentmanual...
61clrAPCTL1;ALLADCpinsDISABLE;theyworkasGPIO
62bsetAPCTL1_ADPC0,APCTL1;ENABLEchannel0forADCinput
63bsetADCSC1_AIEN,ADCSC1;EnableADCinterrupt
64cli
65bra*
66;********************************************************************
67;interruptVectorNumber_VadcADC_ISR
68ADC_ISR:
69;
70;NOTE:ReadingADCRLclearCOCOFlag,ASITSHOULDBEDONEONALL
71;..PERIPHERALSTHATHAVEDATABUFFERSTOREADORWRITE!!!
72ldaADCRL;Negatebeforedisplay
73coma;..(LEDsturnonwith0's)
74staPTCD;MoveADCvaluetoportC
75staPTED;..andtoportE
76rti
77;
78nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
79;This'nop'MAYberemovedforCW6.3...
80;
181
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
81;InterruptVectors
82ORGVadc
83DC.WADC_ISR
84ORGVreset
85DC.WMain;RESET.Maximumpriority.Asynch.
86END
COMENTARIOS a ["Laboratorios\Proy\Buzzer\ADC.asm"]
Importante notar que el Potencimetro Azul del DEMOQE128 se conecta al ADC por la
entradaPTA0:
07;PTA0isthebluePOTENCIOMETERinDEMOQE128!!!
PERO,sisecambiaraalgunodeestos"settings",laformadeVOLVERaconfigurarloses
ejecutandoestas 4 lneas de cdigo. Para mayor informacin hay que revisar,como de
costumbre,elReferenceManual.
26;
27;MCU_Init
28;;lda#$23;EnableBusClocktotheADCmodule
29;;staSCGC1
30;;clra;DisableunusedperipheralsBusclock
31;;staSCGC2
Laexplicacindelainicializacindelos8LEDsesexactamenteigualalaquesehizo
en:30)CUARTOPROGRAMADECOMUNICACIONES,ynolavamosarepetiraqu.
46;ADC_configuration
47;Int.disable.Continuousconversion
48mov#$20,ADCSC1;..modeandchannel0active
49clrADCSC2;Softwaretriggerselected
50mov#$30,ADCCFG;Inputclock/2.LongSampletime
51;..config.8bitconversion
Hayunejemplodeinicializacin,10.5.1.2,escritoenPseudoCdigoycomentado:
182
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Primero se deshabilita el control de I/O para el pin o terminal AD1; los dems
terminalespermanecencomopinesdeI/Odepropsitosgenerales:
55;APCTL1=0x02means:AD1pinI/Ocontroldisabled.
56;..AllotherADpinsremaingeneralpurposeI/Opins
El manual, bien oscurecido, dice que un UNO en un pin x del APCTL (bit APCTLx) le
DESHABILITAaesepinelCONTROLDEI/O.
POR TANTO, ESE pin x del APCTL, por haberlo programado a UNO, hace que el
correspondientepindelADCSEHABILITE(parafuncionesdeADC)
"ParaHABILITARunpinxdelconversorADC,paraquefuncionecomoENTRADAANALGICA,
secolocaunUNOenelcorrespondientebitxdelregistroAnalgicoparaelControlde
Pines:APCTL(bitAPCTLx).
"Para HABILITAR como I/O digital un pin x, de los que pueden actuar como entrada
analgicadelADC(24canalesanalgicosenelMC9S08QE128),secolocaunCEROenel
correspondientebitxdelAPCTL,APCTLx.
"DespusdePowerOnReset(POR),todoslospinesquepotencialmentepuedenservircomo
entradasanalgicasdelADC,sonI/ODIGITALESGENRICOSyas,puedenprogramarsepara
entrada o salida, colocndoseles, o no, resistencias de Pullup, y todas las dems
funcionalidades definidas para las entradas y salidas digitales genricas. Por eso
nuestrosejemplosnuncahabilitaronesospinesmedianteunCEROenlosbitsAPCTLx:es
elvalorestndar.
57;Manualsays:A"1"inAPCTLx:PinI/OcontrolDISABLED.
58;..Itmeans:A"1"inAPCTLx:ADCpinENABLED!!!<<<<<<<<<<<<
Se programa el canal cero del ADC para que manipule entradas analgicas; los otro 7
bitsdeESEespecficogrupode24,enelMC9S08QE128,quedanenCERO,yporlotanto
siguensiendoEntradasySalidasDigitalesGenricas,GPIO.
61clrAPCTL1;ALLADCpinsDISABLE;theyworkasGPIO
62bsetAPCTL1_ADPC0,APCTL1;ENABLEchannel0forADCinput
Ennuestrocaso,podramoshaberhechosolamenteelBSETyaque,comohemosexplicado,
los otros 7 bits del APCTL1 estn en CERO (no necesitan un CLR). Desde luego, este
cdigosedejaac,porsiustedtienenecesidadderevertirenalgnotroejercicio,
lasentradasdeAnalgicas,aGPIO.
FINALMENTEsehabilitaelADCparaqueInterrumpa,lomismoquealCPU,ysesimulaun
HALTmedianteelBRA*:
63bsetADCSC1_AIEN,ADCSC1;EnableADCinterrupt
64cli
65bra*
183
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
NOTA:ComonofuemiintencinestablecerenestedocumentounsubsistemaparaelADC,
programadocontodaslasreglasdeTopDownDesignyBottomUpCodingqueseemplearon
enlaslibrerasquedesarrollparaTEMPORIZADORESyCOMUNICACIONESSERIALES,nous
nombres de un valor semntico ms elevado, establecidos mediante ALIAS a las, para
nuestros propsitos, oscuras identificaciones que definieron los diseadoresdel MCU.
Hubieransidodefinicionesalgoascomo"AdcIntEn"(parangndel"XmtIntEn"empleado
enanterioresejercicios...)
Cadavezqueseproduceunaconversin,secolocaenUNOlabanderadeREADY,queenel
conversorADCsellamaCOCO:COnversionCOmplete.LointeresantedelperifricoADCde
este MCU es que BASTA CON LEER EL REGISTRO DE DATOS, ADCRL, para AUTOMTICAMENTE
generarelAcknowledgedelaInterrupcin(reposicionandoCOCOenCERO).
Esto, aunque opera como las minicomputadoras Digital (PDP, VAX) lo hacan, o como
funciona el PC/AT Compatible, arquitectura desarrollada por la IBM y an en uso
actualmente, es decir, que OPERA COMO TODOS LOS PERIFRICO DEBAN HACERLO, introduce
unanuevaIRREGULARIDAD:
PerifricosalosqueelINTACKselesdaporsoftware,leyendolabanderadeREADY
enUNOy,acontinuacin,leyendoelDATABUFFER,talocomoestdefinidoelperifrico
SCIdeComunicacionesSeriales.
ElADCslorequierequeseleaelDATABUFparaaceptarunACK(COCOretornaaCERO)
Enlarutinadeinterrupcin,ADC_ISR,seleeelvalordelBUFFER,ADCRL(RegisterLOW,
que proporciona los 8 bits requeridos). Esto produce, como ya dijimos, un ACK que
reseteaelCOCO.Invertimoselvalornegndolo(conCOMA,1'sComplementAccumulator),
porquecomoyasabemos,losLEDsenlatarjetadedesarrolloDEMOQE128seenciendencon
CEROS. El valor lo llevamos a los dos registros en que los genios de PE Micro
descompusieronlos8LEDs(6enPTCy2enPTE).Porltimo,larutinahaceunRTI.
68ADC_ISR:
72ldaADCRL;Negatebeforedisplay
73coma;..(LEDsturnonwith0's)
74staPTCD;MoveADCvaluetoportC
75staPTED;..andtoportE
76rti
NOTE:NosehasalvadoporprogramaelregistroHalcomienzo,porqueestarutinano
usaparanadaelregistrondice,H:X.
35) Uso Bsico del ADC, Reversar Datos Antes de ir a los LEDs.
Supongaquevaaalojardentrodeunacajasutarjetadedesarrollo,yquequieredejar
unaventanillapordondepuedanversedesdeelexterior.Simirabien,notarquelos
bitsquedanalrevs,conelbit0alaizquierda.Asquelasecuencia1,2,3,4,5,
6,7severcomo:1000..,0100..,0110..,0001..,1001..,0011..,0111
184
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
EsomedalabaseadecirquePEMicroALAMBRLOSLEDsALREVS.
Esteejercicioesparecidoalanterior,peroalosbitsdelresultadodelaconversin
deLADCselosreordenaparaquelainformacinenbinarioquesepresentamediantelos
LEDs,quedeALDERECHO.
["Laboratorios\Proy\Buzzer\ADC_Reverse.asm"]
001;********************************************************************
002;ADC_Reverse.asm;LuisG.UribeC.,D01L2012
003;DESCRIPTION:TheADCmoduleisconfiguredinContinuousConversion
004;..Mode,everyobtainedvalueisdisplayinportC&E(8LEDs).
005;PTA0isthebluePOTENCIOMETERinDEMOQE128!!!
006;
007;********************************************************************
008;NOTEfromLuisG.UribeC.Desktop:
009;
010;GeniusworkingatPEMicronotonlyusedsamePTC5pintobothdrive
011;anLED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,!THANKS!,
012;butREVERSEWIREDtheLEDswithBit0attheLEFT!!!THANKS!,
013;andREVERSEDRIVEtheLEDssotheylightwitha'0'!THANKS!,
014;andREVERSEWIREDthePOTENCIOMETER,toprovide0Voltswhenfully
015;..turnedCLOCKWISE,and3VoltswhenturnedBACKWARDS!THANKS!.
016;..DidtheyeveruseaKNOBtoraisethemusicvolumealoud???
017;********************************************************************
018NOLIST
019INCLUDE'derivative.inc'
020LIST;..storageandTHISisit'splace
021;
022;2)DEFINES
023ram:SETZ_RAMStart;$80
024rom:SETROMStart;$2080
025initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
026COP_Disable:EQU$42
027;====================================================================
028BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit
029;Example:BITCOPYSrc,3,Dst,5;Useanyvariables:DIRorEXT
030lda\1
031bit#1<<(\2&$07);IfSrcAdd[SrcBit]==0
032beq\@Clr_DstAdd;..gotoClr_DstAdd[DstBit]
033;Set_DstAdd[DstBit]:;Else,Set_DstAdd[DstBit]
034lda\3
035ora#1<<(\4&$07)
036bra\@cont
037;Clr_DstAdd[DstBit]:
038\@Clr_DstAdd:
039lda\3
040and#~(1<<(\4&$07))
041\@cont:
042sta\3
043ENDM
185
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
044;====================================================================
045;GlobalVariables
046ORGram
047ADC_tmp1DS.B1
048ADC_tmp2DS.B1
049;********************************************************************
050;MAINPROGRAMHEADER:
051ABSENTRYMain
052ORGrom
053Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
054staSOPT1;..SystemOptions1
055ldhx#initStack;SetupSP
056txs;...
057;
058;Thisisthe'MCU_Init'fromtheOriginalCprogram.However,Iam
059;..usingPOR(PowerOnReset)defaults:ClocktoEVERYperipheral.
060;
061;MCU_Init
062;;lda#$23;EnableBusClocktotheADCmodule
063;;staSCGC1
064;;clra;DisableunusedperipheralsBusclock
065;;staSCGC2
066;
067;GPIO_Init
068;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
069;
070;NOTE:ForOUTPUTPins,alwaysSetupfirsttheinitialvalueyou
071;desireforthem,andTHENprogramthepinforOutput.
072mov#%11110000,PTCD;Turnon4leds,toshowprogram
073mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
074mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
075mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
076;NOTE:PTC5isprogrammedforINPUTsowrittingtoPTC5doesNOTHING
077;********************************************************************
078;NOTE:GeniusworkingatPEMicrousesamePTC5pintoboth,drivea
079;LED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,THANKS!
080;So,ifyouuseBOTHCOMM1andLeds,doNOTusePTC5associatedLED.
081;
082;ADC_configuration
083;Int.disable.Continuousconversion
084mov#$20,ADCSC1;..modeandchannel0active
085clrADCSC2;Softwaretriggerselected
086mov#$30,ADCCFG;Inputclock/2;LongSampletime
087;..config;8bitconversion
088clrAPCTL1;ADC0pindisable;itworksasGPIO...
089;===================================================================
090bsetAPCTL1_ADPC0,APCTL1;SelectchannelforADC0input
186
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
091bsetADCSC1_AIEN,ADCSC1;EnableADCinterrupt
092cli;GlobalEnableCPUInterrupts.
093bra*
094;********************************************************************
095;interruptVectorNumber_VadcADC_ISR
096ADC_ISR:
097;*******************************
098;NOTE:ReadingADCRLclearCOCOFlag,ASITSHOULDBEDONEON
099;..ALLPERIPHERALSTHATHAVEDATABUFFERSTOREADORWRITE!!!
100;*******************************
101ldaADCRL;Negatebeforedisplay,THANKSPEMicro!
102coma;..(LEDsturnonwith0's)
103staADC_tmp1
104;Exchangebitpositions,THANKSPEMicro!
105BITCOPYADC_tmp1,0,ADC_tmp2,7
106BITCOPYADC_tmp1,1,ADC_tmp2,6
107BITCOPYADC_tmp1,2,ADC_tmp2,5
108BITCOPYADC_tmp1,3,ADC_tmp2,4
109BITCOPYADC_tmp1,4,ADC_tmp2,3
110BITCOPYADC_tmp1,5,ADC_tmp2,2
111BITCOPYADC_tmp1,6,ADC_tmp2,1
112BITCOPYADC_tmp1,7,ADC_tmp2,0
113movADC_tmp2,PTCD;MoveADCvaluetoportC
114movADC_tmp2,PTED;..andtoportE
115rti
116;
117nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
118;This'nop'MAYberemovedforCW6.3...
119;
120;InterruptVectors
121ORGVadc
122DC.WADC_ISR
123ORGVreset
124DC.WMain;RESET.Maximumpriority.Asynch.
125END
COMENTARIOS a ["Laboratorios\Proy\Buzzer\ADC_Reverse.asm"]:
SeincluyelaMacroBITCOPY,anteriormenteexplicadayusada:
028BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit
DosvariablesGlobalestemporales(Bytes)paramanipularelvalordelaconversin:
046ORGram
047ADC_tmp1DS.B1
048ADC_tmp2DS.B1
187
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Se programan los LEDs y el ADC como en el ejercicio anterior; y se culmina con una
esperaeterna,medianteelBRA*.
LaISRdelconversorcomienzacomoantes,leyendoelBUFFER:ADCRLynegndolo(COMA:
1'sCOMPLEMENTACCUMULATOR),yloalmacenaenADC_tmp1:
101ldaADCRL;Negatebeforedisplay,THANKSPEMicro!
102coma;..(LEDsturnonwith0's)
103staADC_tmp1
UsaADC_tmp1comovariableSRCparalaMacroBITCOPY,ycruzalosbitsalmacenndolos
enlasegundavariabletemporal,ADC_tmp2.Notecmocopiaelbit0al7,el1al6,2
al5,3al4,4al3,5al2,6al1yfinalmente,elbit7albit0.
104;Exchangebitpositions,THANKSPEMicro!
105BITCOPYADC_tmp1,0,ADC_tmp2,7
106BITCOPYADC_tmp1,1,ADC_tmp2,6
107BITCOPYADC_tmp1,2,ADC_tmp2,5
108BITCOPYADC_tmp1,3,ADC_tmp2,4
109BITCOPYADC_tmp1,4,ADC_tmp2,3
110BITCOPYADC_tmp1,5,ADC_tmp2,2
111BITCOPYADC_tmp1,6,ADC_tmp2,1
112BITCOPYADC_tmp1,7,ADC_tmp2,0
Terminadalareasignacindebits,lospresentamosenlos8LEDsyterminamosconRTI:
113movADC_tmp2,PTCD;MoveADCvaluetoportC
114movADC_tmp2,PTED;..andtoportE
115rti
DadoqueestaIRQnoresguardaporprogramaelregistroH,ustedtienequeasegurarse
dequelaMacoBITCOPYTAMPOCOUSEelregistrondiceH:X.
DETALLES,DETALLES...
UNPUNTOMS:
ComoelPOTENCIMETROTAMBINSECABLEALREVS:significaquealestarcompletamente
a la izquierda entrega el mayor voltaje (3V), y al rotarlo hacia la derecha baja el
voltaje linealmente hasta llegara CERO V,una truco para arreglar ese problema, por
software,esconvertirlasmedidasqueenhexadecimalvande$FFa$00(deizquierdaa
derecha),enmedidasquevayande$00a$FF.SevequebastaconNEGARlamedidadel
conversorparasolucionarelproblemadelalambradoilgicodelpotencimetro.
Pero,YAHAYUN'COMA'pararesolverelproblemadequelosLEDsenciendenalrevs,en
CERO:
102coma;..(LEDsturnonwith0's)
RecuerdequenegardosvecesequivaleaNONEGAR.
Por tanto, NO HAY NECESIDAD del 'COMA de la lnea 102; basta con eliminarla, o
comentarla,yahoratodoparecerfuncionarbien.
188
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
EnCdossonlassolucionesmspublicitadas;laprimeraconsisteentenerunavariable
auxiliarquevale...001ysevadesplazandoalaizquierda,Nveces(8paraunbyte):
...001 ...010 ...100. Cada vez se hace un AND con el operando y si el resultado es
diferentedeceroseincrementaelcontadordeunos.
Una,msinteresantean,consisteenaplicarlaexpresinx&=(x1);queELIMINAde
'x'elUNOqueestmsalaizquierda:
while(x){
cnt++;
x&=(x1);
}
Unaventajadeestaltimaaproximacinconsisteenqueslohayquerepetirelciclo
mientrashayaUNOS,nonecesariamente8veces(8,paraBytes)
Elejemploqueincluyoacontinuacin,haceusodelainstruccindeLEFTSHIFT,que
desplazalavariableencuestin,unaposicinalaizquierdayelbitqueSALEqueda
almacenadoenlabanderaC(Carry).SeincrementaelcontadorcadavezqueC==1.Si
serepiteelcdigo8veces(paraBytes),habremoscontadoelnmerodeunos.
Unatajoconsisteendisponerdeunasegundacondicin,paradetenerelprocedimiento
si la variable llega a cero (antes de terminar los 8 ciclos). Esto agrega la misma
ventajadelltimoejemploenC,ytambinpermiterepetirelcicloslomientrashaya
UNOS,nonecesariamente8veces(8,paraBytes)
Este ejercicio est pensado para ejecutarse con el DEBUGGER, paso a paso, a fin de
poder introducir las entradas a mano (simuladas), va PTAD. Usted puede emplear los
interruptores de la tarjeta DEMOQE128 que usan, por ejemplo, el PTC, o usar otra
variablepuestaenelprogramaparaesepropsito.
["Books\InterfacingHCS08\Examples\bitcount3.asm"]
01;********************************************************************
02;BitCount3.asm,HCS08_CPU,LuisG.UribeC.,M05F2013
03;
04;Includefiles
05NOLIST
06INCLUDE'derivative.inc'
07LIST
08;
09;Parameterdefinitions
10ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
11rom:SETROMStart;$2080
12initStack:EQURAMEnd+1;$17FF+1=$1800
13COP_Disable:EQU$42
14;===================================================================
189
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
15;BeginofCodeSection
16ABSENTRYMain;Exportsymbol(DEBUGGERentry)
17ORGrom;$2080:HCS08ROMStart(Flash)
18;
19;***ALWAYS***includethefollowing4instructions
20Main:lda#COP_Disable
21staSOPT1;SystemOptions1
22ldhx#initStack;InitSP.H:X<$1800
23txs;..SP<=$17FF
24;
25clra;InitializeAto0
26ldxPTAD;LoadoperandintoX
27Loop:lslx;Shiftoutabitofoperand
28beqZero
29adc#0;Accumulateit
30braLoop
31Zero:adc#0;Accumulateit
32bra*
33;
34nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
35;This'nop'MAYberemovedforCW6.3...
36;********************************************************************
37;InterruptVectors
38ORGVreset
39DC.WMain;RESET:HCS08PowerOn(PON)procedure.
40END
COMENTARIOS a ["Books\Interfacing-HCS08\Examples\bitcount3.asm"]:
ElcontadorserelAcumulador,yseloinicializaencero.Sloparaelejercicio,se
suponequelaentradaquefuncionacomoeloperandoalaqueselecontarnlosunosse
tomadelPuertoA(PTAD);comoyasedijo,ustedpuedecolocarotravariablesiaslo
desea. El operando se lee desde PTAD y se almacena en la parte BAJA del registro
ndice:X
25clra;InitializeAto0
26ldxPTAD;LoadoperandintoX
27Loop:lslx;Shiftoutabitofoperand
28beqZero
SianlavariablenovaleCero,sesumaelCarryalAcumulador;comocadabitquesale
del operando al hacerse un desplazamiento, se almacena en el bit de Carry, C, ste
quedar en Cero o en Uno segn corresponda. Si se suma el Carry a Acumulador, se
produce un Incremento si lo que se desplaz era un UNO; si era un CERO, la suma no
190
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
generaningnincremento.Deestamanerasevancontabilizandocuntosunoshabaenel
operando.Luegorepiteelciclo.
NotequenohayunainstruccinsimpleparasumarelCarryalAcumulador;loquehayes
uncompuesta,ADC,quesumaunoperandoalAcumulador,yalavezlesumaelvalordel
Carry. Como lo nico que queremos es sumar el Carry, y nada ms, usamos ADC con un
operandodeCERO:ADC#0
29adc#0;Accumulateit
30braLoop
SilavariablesllegaCero,seterminaelprocedimiento,sumandoanteselCarryal
Acumulador,loqueproduceunIncrementosiloquesedesplazeraunUNO.
31Zero:adc#0;Accumulateit
32bra*
Sinembargo,sillegaanecesitarprogramarelBuzzerquetraelatarjetadedesarrollo
DEMOQE128,estaesunaGUAELEMENTAL.
Sinembargo,ahoraquefuiaescribirlaexplicacinlneaporlnea,encuentroqueen
PWM.c,yportantoaqutambin,seprogramacomosalidalalneaPTC0,sinqueeneste
momentoyoencuentreunajustificacinapropiadaparaesto.
Ustedespuedeneliminaresalnea,yagradecermereportensitodofuncionabien,para
removerlasdelcdigoenfuturasediciones.
["Laboratorios\Proy\Buzzer\Buzzer.asm"]
01;********************************************************************
02;Buzzer.asm;LuisG.UribeC.,D01L2012
03;DESCRIPTION:ThisprojectusesthePWMfunctionalityoftheTPM1
04;module.APWMsignalisgeneratedandwhentheMCUisinterrupted.
05;PTB5isconnectedtoBUZZERinDEMOQE128!!
06;********************************************************************
07NOLIST
08INCLUDE'derivative.inc'
09LIST;..storageandTHISisit'splace
10;
11;2)DEFINES
12ram:SETZ_RAMStart;$80
191
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
13rom:SETROMStart;$2080
14initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
15COP_Disable:EQU$42
16;********************************************************************
17;MAINPROGRAMHEADER:
18ABSENTRYMain
19ORGrom
20Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
21staSOPT1;..SystemOptions1
22ldhx#initStack;SetupSP
23txs;...
24;
25;MCU_Init
26lda#$20;EnableBusClocktotheTPWM1module
27staSCGC1
28clra;DisableunusedperipheralsBusclock
29staSCGC2
30;
31;GPIO_Init
32clrPTCD;Put0'sinPTC0port
33mov#$01,PTCDD;ConfigurePTC0pinasoutput
34;
35;TPM_configuration
36mov#$68,TPM1C1SC;Chan.1IntEn;PWMEdgeAlign.Or$24
37;*******************************
38;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
39;C1D1E1F1G1A1B1C2
40;20941976176016611480131911751047
41FREQEQU2094
42FREQ_4EQUFREQ>>2;25%DuttyCycle
43ldhx#FREQ;Really...itisPERIOD...
44sthxTPM1MOD
45ldhx#FREQ_4;25%DuttyCycle
46sthxTPM1C1V
47mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
48;MoreDividers:Table164in02MC9S08QE128RM(ReferenceManual)U.pdf
49;mov#%1111,TPM1SC;Bus_rate_clock/128=TPMClockSource
50;mov#%1110,TPM1SC;Bus_rate_clock/64=TPMClockSource
51;mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
52;====================================================================
53cli
54bra*
55;********************************************************************
56;interruptVectorNumber_Vtpm1ch1TPM_ISR
57TPM_ISR:
58ldaTPM1C1SC;ClearTPWMflags
192
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
59bclr7,TPM1C1SC;Twostepflagacknowledgement
60rti
61;
62nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
63;This'nop'MAYberemovedforCW6.3...
64;
65;InterruptVectors
66ORGVtpm1ch1
67DC.WTPM_ISR
68ORGVreset
69DC.WMain;RESET.Maximumpriority.Asynch.
70END
COMENTARIOS a ["Laboratorios\Proy\Buzzer\Buzzer.asm"]:
LosgeneradoresdefrecuenciaqueempleamosenesteMCU,sonfundamentalmentelosPWM,
quegeneranseales"moduladas"poramplituddepulso,PulseWidthModulation.
Enparticular,seusalafuncionalidadPWMdelmduloTPM1.
04;APWMsignalisgeneratedandwhentheMCUisinterrupted.
05;PTB5isconnectedtoBUZZERinDEMOQE128!!
La inicializacin del MCU incluye habilitar el Bus Clock para el mdulo TPM1; a los
perifricos no utilizados se les deshabilita el BusClock. Usted debe revisar con el
ReferenceManual,silosvaloresaquprogramadosparahabilitarelTPMWM1sononolos
estndarcuandohayunPOR.Deseras,puedeeliminar(comoyasehizoenelcasodel
ADC)estecdigosinningnproblema
25;MCU_Init
26lda#$20;EnableBusClocktotheTPWM1module
27staSCGC1
28clra;DisableunusedperipheralsBusclock
29staSCGC2
LosiguienteesprogramarelterminalPTC0comosalida.
Comodijeanteriormente,NOencuentroahoraunaJUSTIFICACINapropiadaparaesto.
Luego de que usted logre que el programa funcione (TODOS funcionan!), eliminen esas
dos(2)lneasyreportesitodofuncionabien,paraprocederaremoverlasdelcdigo
enfuturasediciones.OsialguienencuentraalgnmotivoplausibleparahabilitarPTC0
comosalida...
YoimaginoqueesunaimprecisindelprogramaoriginalPWM.c
31;GPIO_Init
32clrPTCD;Put0'sinPTC0port
33mov#$01,PTCDD;ConfigurePTC0pinasoutput
193
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
35;TPM_configuration
36mov#$68,TPM1C1SC;Chan.1IntEn;PWMEdgeAlign.Or$24
LosvaloresquecolocoenTPM1MOD(cfr.ReferenceManual)yenTPM1C1VparagenerarUNA
escaladelpiano(8notasBLANCAS,nohayNEGRAS),SONEMPRICOS(lanocheanteriora
laprimeravezquebamosausarlaescalamusical,melapascambiandovaloreshasta
lograrestalista.EnnuestroDEMOQE128,noesslocuestindeconocerlasfrecuencias
de la escala; hay que ver la RESPUESTA del transductor de sonido, o BUZZER). Usted
puede ajustar estas cantidades a sus necesidades pero... todos los proyectos, hasta
ahora,loshanusadoconxitorelativo.
RecuerdenqueestosvaloressondePerodo,nodeFrecuencia.
38;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
39;C1D1E1F1G1A1B1C2
40;20941976176016611480131911751047
Esaeslaescalacompleta.EnesteejercicioseGENERARUNASLANOTA.
41freqequ2094
AlgenerarPWM,unvalorfundamentaleslaFrecuenciadelaonda;elotroeselllamado
Dutty Cycle, que es el porcentaje, de 0% a 100%, que la seal debe estar en UNO.
Despusdeprobardurantealgntiempo,encontrexperimentalmentequeelDuttyCycle,
para obtener la mayor intensidad sonora (volumen) sobre el Buzzer de la tarjeta de
demostracin, DEMOQE128, era del 25% (1/4). Por eso el clculo de FREQ / 4. Esto es
absolutamente arbitrario y, a lo mejor, lo que funciona bien en mi transductor
piezoelctrico,puedenoserlomsapropiadoparaeldesutarjetadedesarrollo.Hay
queexperimentar.
42FREQ_4EQUFREQ>>2;25%DuttyCycle
NOTA:Recuerdequeaquelloslosclculostalescomoeldefinidoenlalnea42(FREQ>>
2),serealizanenAssemblyTime,noenRunTime;esdecir,loejecutaelAssembler,y
noelMCU.
SeprogramaentonceselPerodoenelregistroTPM1MOD(cfr.elReferenceManualpara
todaestaexplicacin)
43ldhx#FREQ;Really...itisPERIOD...
44sthxTPM1MOD
YenelregistroTPM1C1V,endondesedefineelDuttyCycle,colocamos1/4delvalor
delPerodo.
45ldhx#FREQ_4;25%DuttyCycle
46sthxTPM1C1V
194
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
EscogemoslaFuentedeRelojparaelTMP:
47mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
Una lista adicional de posibles divisores es la siguiente, segn la Tabla 164 del
02MC9S08QE128RM(ReferenceManual)U.pdf
49;mov#%1111,TPM1SC;Bus_rate_clock/128=TPMClockSource
50;mov#%1110,TPM1SC;Bus_rate_clock/64=TPMClockSource
51;mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
FinalmenteseactivanlasinterrupcionesenelCPU,ysesimulaunHALTconelBRA*:
53cli
54bra*
56;interruptVectorNumber_Vtpm1ch1TPM_ISR
57TPM_ISR:
58ldaTPM1C1SC;ClearTPWMflags
59bclr7,TPM1C1SC;Twostepflagacknowledgement
60rti
Porsimplicidad,esteejerciciopretendeinterpretarunacancindeUnaSolaVoz,con
un solo instrumento musical (a diferencia de las obras en general, que emplean
mltiples voces e instrumentos). Se basa en el programa anterior, al que le han
agregado varias cosas: una tabla que represente precisamente cada nota, o punto de
sonido,mediantelosdosaspectosreferidos,frecuenciayduracin.
Enrealidad,comovimosenelejercicioanterior,enlugardelafrecuenciasecolocar
el perodo, y se incluyen slo algunas de las Duraciones estndar de la notacin
musical (Redonda, Blanca con Puntillo, Blanca, Negra), que se han definido en
milisegundos,medianteunaasignacinaproximadayarbitraria,yquepuedemodificarse.
195
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Alexpirarellapsoprogramado,seprocedeconlasiguienteentrada(dedosposiciones)
delatablayashastasuterminacin.
["Laboratorios\Proy\Buzzer\Walkman.asm"]
001;********************************************************************
002;Walkman.asm;LuisG.UribeC.,D01L2012L09D2013
003;DESCRIPTION:ThisprojectusesthePWMfunctionalityoftheTPM1
004;module.APWMsignalisgeneratedandwhentheMCUisinterrupted,
005;theDuttycycleisincrementedin1.PTB5isBUZZERinDEMOQE128!!
006;********************************************************************
007NOLIST
008INCLUDE'derivative.inc'
009LIST
010;
011;2)DEFINES
012ram:SETZ_RAMStart;$80
013rom:SETROMStart;$2080
014;;initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
015;;COP_Disable:EQU$42
016;====================================================================
017;GlobalVariables
018ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<
019NOLIST
020include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
021LIST
022SongPtr:DS.W1
023NNotes:DS.W1
024NoteTime:DS.W1
025DCycle:DS.W1
026;********************************************************************
027;MAINPROGRAMHEADER:
028ABSENTRYMain
029ORGrom
030;*******************************
031;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
032;C1D1E1F1G1A1B1C2
033;20941976176016611480131911751047
034C1:EQU2094
035D1:EQU1976
036E1:EQU1760
037F1:EQU1661
038G1:EQU1480
039A1:EQU1319
040B1:EQU1175
041C2:EQU1047
042Div:EQU0
043;StandardDurationsinMusic:
044;
045r:EQU2000>>Div;Redonda
046b_:EQU1500>>Div;BlancaconPuntillo
196
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
047b:EQU1000>>Div;Blanca
048n:EQU500>>Div;Negra
049;;;Song:DC.WC1,b_,D1,n
050;;;DC.WE1,b_,G1,b
051;;;DC.WC2,n,B1,n,A1,n,G1,n
052;;;DC.WA1,b,G1,b
053;;;DC.WF1,n,A1,n,E1,n,G1,n
054;;;DC.WF1,n,D1,n,C1,b
055;;;SongSizeEQU(*Song)/4
056;SongtableisformedbyNOTE&DURATIONpairof16bitvalues
057;
058Song:DC.WC1,b,D1,b
059DC.WE1,b,F1,b
060DC.WG1,b,A1,b,B1,b,C2,b
061DC.WC2,b,B1,b,A1,b,G1,b
062DC.WF1,b,E1,b
063DC.WD1,b,C1,r
064DC.W0,1
065SongSizeEQU(*Song)/4
066;*******************************
067Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
068staSOPT1;..SystemOptions1
069ldhx#initStack;SetupSP
070txs;...
071;
072;Thisisthe'MCU_Init'fromtheOriginalCprogram.However,Iam
073;..usingPOR(PowerOnReset)defaults:ClocktoEVERYperipheral.
074;
075;MCU_Init
076;;lda#$20;EnableBusClocktotheTPWM1module
077;;staSCGC1
078;;clra;DisableunusedperipheralsBusclock
079;;staSCGC2
080;
081;GPIO_Init
082clrPTCD;Put0'sinPTC0port
083mov#$01,PTCDD;ConfigurePTC0pinasoutput
084;
085;TPM_configuration
086mov#$68,TPM1C1SC;Chan.1IntEn;PWMEdgeAlign.Or$24
087mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
088;
089Init8Timers;InitTimers&GloabalEnableCPUinter
090cli;..rupts(TPM&RTCarealreadyenabled)
091;====================================================================
092ldhx#SongSize;GetSongSize,constantrepresenting#of
093sthxNNotes;..NOTES;storeitintovariable'NNotes'
094beqEndSong;IfNNotesis0,finishthesong...
095ldhx#Song;GetAddressoftheSong:'#Song'itis!
096Loop:sthxSongPtr;StoreSong'sAddressintoSongPointer&
197
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
097ldhx,X;..usingit,loadthenextNOTEintoH:X
098sthxTPM1MOD;StoreintoTPM1MODtofixTPM1'sPERIOD
099sthxDCycle;StoreintoDCycletoo
100ldhx#DCycle;GetDCycleADDRESSintoH:Xtobeused
101lsr,X;..asapointertoDCycle.DivideDCycle
102lsr,X;..by4toget25%DuttyCycle
103ldhx,X;UsingDCycleaddressinH:X,getDCycle
104sthxTPM1C1V;..valueintoH:X,andmoveittoTPM1C1V
105;..tosettheDuttyCycle...
106ldhxSongPtr;GettheSongPointer;
107aix#2;..add#2topointtonextDURATION
108sthxSongPtr;..andsavenewvalue.
109ldhx,X;Usingthisnewaddress,getthenext
110sthxNoteTime;..NoteTIMEfromSongTable
111WaitMS_on0,NoteTime;NowTPM1generatesPWMpulsestodrive
112;..buzzer;Waithereforthedesiredtime
113ldhxNNotes;AtendgetNNotes,decreaseby1andsee
114aix#1;..iftheSongisdone.
115sthxNNotes;..
116beqEndSong;..
117ldhxSongPtr;Ifnot,loadaddressofnextSongtable
118aix#2;..possition,pointittothenextNOTE
119braLoop;..andLoopagain
120;====================================================================
121EndSong:
122clrTPM1C1SC;Chan.1IntDisable
123bra*;..andWaitForever
124;********************************************************************
125;InterruptVectorNumber_Vtpm1ch1TPM_ISR
126TPM_ISR:
127ldaTPM1C1SC;ClearTPWMflagsinthisTwostepflag
128bclr7,TPM1C1SC;..acknowledgementtoreenableTPM1INTs.
129rti;ReturnfromInterrupt
130;
131;RTCInterruptServiceRoutine
132RTC_INTERRUPT:
133TIMERS8ISR
134;
135nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
136;This'nop'MAYberemovedforCW6.3...
137;
138;InterruptVectors
139ORGVtpm1ch1
140DC.WTPM_ISR
141ORGVrtc
142DC.WRTC_INTERRUPT
143ORGVreset
144DC.WMain;RESET.Maximumpriority.Asynch.
145END
198
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Laboratorios\Proy\Buzzer\Walkman.asm"]:
RecordarsiempreelsitioapropiadoparacadaINCLUDE:
017;GlobalVariables
018ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<
019NOLIST
020include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
021LIST
Haycuatro(4)variablesde16bits(WORDS):
NNotes,quellevalacantidaddenotas(deDOSvalores)faltantesparafinalizarla
cancin
NoteTime,dondesealmacenatemporalmenteladuracindecadanota,paraemplearcon
facilidadlafuncindelalibreradeTimers
DCycle, en donde se calcula el Dutty Cycle para cada nota (empleando la misma
aproximacindelejercicioanterior)
022SongPtr:DS.W1
023NNotes:DS.W1
024NoteTime:DS.W1
025DCycle:DS.W1
Las definiciones de las notas (sus ALTURAS, aqu: sus perodos) son las mismas
introducidosenelejercicioanterior:
031;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
032;C1D1E1F1G1A1B1C2
033;20941976176016611480131911751047
034C1:EQU2094
035D1:EQU1976
036E1:EQU1760
037F1:EQU1661
038G1:EQU1480
039A1:EQU1319
040B1:EQU1175
041C2:EQU1047
AcontinuacinsedefinenalgunasdelasDuracionesestndardelanotacinmusical(r:
Redonda,b_:BlancaconPuntillo,b:Blanca,n:Negra),enmilisegundos,comosedijo
antes,medianteasignacinaproximadayarbitraria.
Paramodificarconciertafacilidadestasduraciones,sehaincluidounparmetro,Div,
medianteelcualselaspuededividirpor2,4,etc.Asselograquelacancinvaya
msrpido,sieslodeseado:
199
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
042Div:EQU0
043;StandardDurationsinMusic:
044;
045r:EQU2000>>Div;Redonda
046b_:EQU1500>>Div;BlancaconPuntillo
047b:EQU1000>>Div;Blanca
048n:EQU500>>Div;Negra
Comoejemplo,nohemosincluidounaverdaderacancinsinounaESCALAquesubedesdela
notamsbaja,C1,hastalamsaltaC2,yluegoseregresahastaelprincipio.Para
finalizar,hemosagregamosalatabla,luegodelacancin(oescala),unaentradacon
un perodo de CERO y una duracin de un Milisegundos. Su propsito es que NO quede
sonandoindefinidamenteelBuzzer(CEROPerodolosilencia).
058Song:DC.WC1,b,D1,b
059DC.WE1,b,F1,b
060DC.WG1,b,A1,b,B1,b,C2,b
061DC.WC2,b,B1,b,A1,b,G1,b
062DC.WF1,b,E1,b
063DC.WD1,b,C1,r
064DC.W0,1
065SongSizeEQU(*Song)/4
Comosehasugerido,elNMERODENOTAS(enlatabla)localculaelAssemblerempleando
elsmboloSongSizequesecolocaLUEGOdelatablayqueenestecasotieneelvalor:
SongSize=(*Song)/4;
Lainicializacin:GPIO_InityTPM_configuration,yalashemosrepasadovariasveces.
SeinicializanlosTimers:
089Init8Timers;InitTimers&GlobalEnableCPUinter
090cli;..rupts(TPM&RTCarealreadyenabled)
Yahorascomienzaelcdigonuevo,parainterpretarunacancin:
Primero se inicializa la variable NNotes, que indica cuntas notas faltan para
finalizarlacancin:
092ldhx#SongSize;GetSongSize,constantrepresenting#of
093sthxNNotes;..NOTES;storeitintovariable'NNotes'
SiNNotesfueraCERO,seterminaralainterpretacindelacancin:
094beqEndSong;IfNNotesis0,finishthesong...
200
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
LuegosealmacenaelPRINCIPIOdelacancin,esdecir,laDIRECCINdelatablaSong,
enlavariableAPUNTADORAparaeseefecto:SongPtr
095ldhx#Song;GetAddressoftheSong:'#Song'itis!
096Loop:sthxSongPtr;StoreSong'sAddressintoSongPointer&
EmpleandoelAPUNTADOR,seleeel"siguiente"valordelaNOTA,ALMISMOregistroH:X.
097ldhx,X;..usingit,loadthenextNOTEintoH:X
NOTA:EsGENIALpodertenerenH:XladireccindeloquesequierecargarENEL
PROPIOH:X!!!
Sealmacena,despus,elvalordeH:X:enelregistroTPM1MOD,quedefineelPERODO,y
enlavariableDCycle,paracalcularelDuttyCycle:
098sthxTPM1MOD;StoreintoTPM1MODtofixTPM1'sPERIOD
099sthxDCycle;StoreintoDCycletoo
LuegosecopiaLADIRECCINdeDCycle(#DCycle:NOTEEL#!!)enH:X,ycondosLSR,
Logical Shift Right, se divide el valor inicial por CUATRO (4) (que es el valor
EXPERIMENTALconelcualconseguquesonaraMEJORelBuzzerenMItarjetaDEMOQE128):
100ldhx#DCycle;GetDCycleADDRESSintoH:Xtobeused
101lsr,X;..asapointertoDCycle.DivideDCycle
102lsr,X;..by4toget25%DuttyCycle
103ldhx,X;UsingDCycleaddressinH:X,getDCycle
104sthxTPM1C1V;..valueintoH:X,andmoveittoTPM1C1V
105;..tosettheDuttyCycle...
Luegocargamosenelregistrondice,ladireccindelaSIGUIENTEnotadelacancin
(que,alcomenzar,eslaPRIMERAnota):
106ldhxSongPtr;GettheSongPointer;
Como cada nota est compuesta dedos valores: Altura (representada por su perodo: 2
BYTES)yporsuDuracin,2BYTEStambin,unavezqueseApuntaalaprimeranota(su
Perodo),hayqueapuntaralaDuracin;poresoseincrementaelH:XenDOS(2),que
esloquemideelPERODO:
107aix#2;..add#2topointtonextDURATION
108sthxSongPtr;..andsavenewvalue.
201
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
SealmacenatemporalmenteesenuevovalorenSongPtry,usandoesanuevadireccin,que
corresponde a la DURACIN (TIME), se carga ese valor en H:X (Genial modo de
Direccionamiento)yseloalmacenadondecorresponde:enNoteTime:
109ldhx,X;Usingthisnewaddress,getthenext
110sthxNoteTime;..NoteTIMEfromSongTable
Y,usandoesevalorNoteTime,sellamamirutinaWaitMS_on(timer0);ashemoslogrado
activarelvalordePerodo,yactivarelTimer0paraqueespereduranteNoteTime:
111WaitMS_on0,NoteTime;NowTPM1generatesPWMpulsestodrive
112;..buzzer;Waithereforthedesiredtime
Alfinalizar,sedecrementaelvalordeNNotes;seloalmacena(enNNotes),ysiyase
llegaCEROsesaledel"Loop"(BEQ)yseterminalacancin:EndSong:
113ldhxNNotes;AtendgetNNotes,decreaseby1andsee
114aix#1;..iftheSongisdone.
115sthxNNotes;..
116beqEndSong;..
SiNNotesNOlleganaCero,yportantolacancinNOsehaterminado,sevuelvea
cargarenelregistrondiceladireccindelaPRXIMAnota,H:X;sehacerapuntaresa
direccinalaSIGUIENTEnotaysevuelveal"Loop":
117ldhxSongPtr;Ifnot,loadaddressofnextSongtable
118aix#2;..possition,pointittothenextNOTE
119braLoop;..andLoopagain
Paraterminar,sedeshabilitanlasinterrupcionesdeTMP1,ysesimulaunHALT:
121EndSong:
122clrTPM1C1SC;Chan.1IntDisable
123bra*;..andWaitForever
202
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Otras veces los CASEs pueden tener valores que no comienzan en Cero (0), o que sean
nmeroscualesquiera,nonecesariamenteconsecutivoscomoenelejerciciomssimple.
Estopuedesolucionarsedemuchasmaneras,porejemplo,medianteunaseriedeCBEQ.Lo
cualesmenoselegantequelasolucindelpresenteejercicio,peromsgeneral...
Este ejercicio est pensado para ejecutarse con el DEBUGGER, paso a paso, a fin de
poderintroducirlasentradasamano,vaelpuertoSIMULADOPTAD.Ustedpuedeemplear
losinterruptoresdelatarjetaDEMOQE128queusan,porejemplo,elPTC,ousarotra
variablepuestaenelprogramaparaesepropsito.
["Laboratorios\FSMFiniteStateMachines\ComputedGoTo.asm"]
01;*************************ComputedGoTo.asm*************************
02;LuisG.UribeC.,Implement"SWITCH";D17F2013J05D2013
03;1)UseCOMPUTEDGOTO(CasesAREsequential:0,1,2,...)
04;
05;ThisexampleisonlymeanttobeDebugged/Simulated.Forreal,you
06;..willneedtodebounceinputs,perhapsincludesome'InputReady'
07;..signal(debounced),useTimersandproducesomerequiredoutputs.
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;2)DEFINES
15ram:SETZ_RAMStart;<<<TIMERS8:<<<
16rom:SETROMStart;HCS08ROMStart(Flash)
17initStack:EQU$1800
18COP_Disable:EQU%01000010;$42
19;====================================================================
20;3)GlobalVariables
21ORGram
22STATE:DS.W1
23;********************************************************************
24;BeginofCodeSection
25ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
26ORGrom
27;
28;***ALWAYS***includethefollowing4instructions
29Main:lda#COP_Disable
30staSOPT1;SystemOptions1
31ldhx#initStack;InitSP
32txs
33;
34clrSTATE;HIGHendalwayswillbe0intheexample
203
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
35;
36Forever:
37ldaPTAD
38and#LOW(Table_Mask);Makeinput<8(0..7),nomaterwhat
39lsla;Multiplyby2(Tableis2bytes/entry)
40staSTATE+1;>>>BIGENDIAN...REMEMBER???<<<
41ldhxSTATE
42ldhxTable,X;o=Table[ix];
43jmp,X
44;
45;THISISTHEWAYTODECLARE*TABLESOFADDRESSES*(Constants):
46;1:TheywillgoinROMFlash(constants...)
47;2:TheyhaveaNAME('Table'inthisexample)
48;3:Youpopulatetableswithvalues,usingDC.Wassemblerdirective,
49;becauseaddressesare16bitslong.
50;4:NORMALLY,youneedtoknowtheLENGHTofthetable.Soyou
51;putamarkerattheend:'Table_End:'inthisexample,the
52;assemblercalculateslenghtas:(Table_EndTable_Begin)/2
53;(YoudoNOTshallcalculateanythingtheassemblerwill!)
54Table:
55DC.WSTART,S1,S2,S3;Anysequenceforthisexample
56DC.WS2,S3,S2,START
57Table_End:
58TSIZE:EQU(Table_EndTable)/2
59Table_Mask:EQUTSIZE1;TSIZE*IS*apowerof2
60START:nop;'nop':ReplaceitwithYOURcode!
61braForever;'bra':useJMPiftoofaraway
62S1:nop
63braForever
64S2:nop
65braForever
66S3:nop
67braForever
68;
69;InterruptVectors
70dummy_isr:;<<<MustbeplacedinROMSpace
71rti
72ORGVswi;VswiandVreset
73DC.Wdummy_isr;SWI
74DC.WMain;RESET.Maximumpriority.Asynch.
75END
COMENTARIOS a ["Laboratorios\FSM-FiniteStateMachines\ComputedGoTo.asm"]:
AlprincipioseINICIAlavariabledeControl:STATE,de16bits(2Bytes),delacual,
enesteejercicioqueslotiene8estadosoposicionesenlatabla,sloseutilizarn
los 3 bits MENOS significativos y, en general, slo se emplear el BYTE MENOS
significativodeSTATE.Poreso,seborra(CLR)SUBYTE**MS**SIGNIFICATIVO:
34clrSTATE;HIGHendalwayswillbe0intheexample
204
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Recuerden: Esta mquina es BIG ENDIAN. Para borrar EL BYTE MS SIGNIFICATIVO de una
variable de 16 bits,como nuestra variable'STATE, hay que borrar la posicin STATE;
poreso',el'CLRSTATE'delalnea34.
OJO:
34clrSTATE;HIGHendalwayswillbe0intheexample
NOBORRATODALAVARIABLE'STATE',solosuparteMSSIGNIFICATIVA.
ElcicloinfinitoparaesteejerciciocomienzaleyendolavariabledeControl,PTAD,en
elacumulador,yasegurndosequeestdentrodelrangovlido,queparaesteejercicio
esentre0y7,inclusive:
36Forever:
37ldaPTAD
38and#LOW(Table_Mask);Makeinput<8(0..7),nomaterwhat
Comoesunrequisitoparaesteejemplo,quelatablaseasiemprepotenciadeDOS,seha
calculadomsabajoelvalor'Table_Mask',queesigualalapotenciade2quedefine
eltamao(OCHOenesteejercicio),MENOS1:SIETE,queenbinarioes:00..111.As,el
38AND#LOW(Table_Mask)
toma (LOW) los 8 bits menos significativos de 'Table_Mask' (00000111) y hace un AND
entreesaConstante(elNUMERAL:#)yelAcumulador,conloque,noimportaculseael
valoralimentado,siemprequedarconfinadoanmerosentre0y7,ambosinclusive.
LuegoquetenemoslavariabledeentradaapropiadamenteVALIDADA,lamultiplicamospor
DOS (LSLA) porque la tabla es de DIRECCIONES (a dnde Saltar) y en esta mquina las
direccionessonde16bits(DOSbytes)
39lsla;Multiplyby2(Tableis2bytes/entry)
40staSTATE+1;>>>BIGENDIAN...REMEMBER???<<<
Ahora,setomaelvalordeSTATE(16bits,deloscualesyahemosgarantizadoqueel
MSBesCero),selocargaenelregistrondice,H:X:
41ldhxSTATE
Yempleandoesendicecargamos,enelmismoregistrondice,H:X,elvalor'Table+
STATE'.Esevalorquesecarga(observebien!),correspondealaDIRECCIN,sacadade
laTabla,delarutinaadondehayqueSaltarparaejecutarloquecorrespondeaese
NmerodeCase,identificadoporlavariabledeControl!Finalmente,sesaltaadicha
rutina. Se emplea a fondo el direccionamiento Indexado. Pocos MCUs de 8 bits tienen
tantaexuberanciadeArquitectura!
42ldhxTable,X;o=Table[ix];
43jmp,X
205
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
VeamosahoracmoseestructuralaTabladeDirecciones.Enprimerlugar,lasentradas
en la Tabla son Direcciones de las diferentes Rutinas que han de materializar la
funcionalidad de cada Case; as que la Tabla normalmente ir en ROM (Flash). Podra
pensarse en tablas dinmicas, que recibieran sus valores en RUN TIME, pero no es el
caso de este ejemplo.Esas Tablas iran enRAM, y habra que inicializarlasmediante
cdigo.LasTablasenROM(Flash)lasinicializaelAssembler,yelQUEMADORdelcdigo
enelMPUlascopiainicializadasalaFlashdePrograma.
Segundo, las Tablas tienen una identificacin, o nombre, que en nuestro ejemplo es
"Table".
Casisiempreestilconocereltamaoolongituddelatabla,loquehemoscalculado
siempre de una manera simple y automtica: se coloca una etiqueta en la posicin
siguientealaltimadelatabla,selerestaladireccindelaposicindearranque,
lo cual nos da el tamao en BYTES. Si se desea calcular el tamao en Cantidad de
ELEMENTOS (en nuestro ejemplo, el nmero de direcciones almacenadas en la tabla), se
divideporelnmerodebytesquemidelaentidadalmacenada,enestecaso,sedivide
por2,puesdosbytestienecadadireccin:(Table_EndTable_Begin)/2
UstedNUNCAtienequehacerclculos;paraesoesttrabajandoenunaCOMPUTADORA.
Latablaparanuestroejemplo,quecontieneunasecuenciainventada,eslasiguiente:
54Table:
55DC.WSTART,S1,S2,S3;Anysequenceforthisexample
56DC.WS2,S3,S2,START
57Table_End:
58TSIZE:EQU(Table_EndTable)/2
59Table_Mask:EQUTSIZE1;TSIZE*IS*apowerof2
En otra localidad se colocan las rutinas que materializarn cada CASE. Pueden estar
colocadasantesodespusdeestaposicin,puedenestarseparadasportodoelprograma
(locual,sibienesposible,NOparececonveniente)oirencualquierorden:
60START:nop;'nop':ReplaceitwithYOURcode!
61braForever;'bra':useJMPiftoofaraway
62S1:nop
63braForever
64S2:nop
65braForever
66S3:nop
67braForever
Hemos reemplazado todo lo que sera el cdigo necesario para implementar cada uno de
losCASEs,porNOPs,queustedpuedecambiaravoluntadporlasrutinasnecesariaspara
susprogramasparticulares,segnseaelcaso.
NOTAS:
Encasoquelaetiqueta'Forever'(enelejemplo)estmuyapartada,porlacantidadde
cdigonecesarioparalosCASEs,enlugardeBRAForeverustedpuedecolocarJMP.
206
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Peroobserve:aunquelaInformacindeEntradanodebesobrepasarciertorango;sise
EXTRALIMITA por error en su adquisicin, procesarla mediante un AND, o empleando
comparaciones,paraobligarlaapermanecerconfinadadentrodeeserango,PUEDENOSER
LASOLUCIN.
Esdecir,enlavidareal,ambascosassonerrores:a)ejecutarunarutinaquesesabe
que NO se corresponde con la entrada, y que seguramente NI EXISTE, y b) ejecutar la
rutinaqueresultadeconfinarobligadamentealavariableaquepermanezcadentrodel
rangoacordado.
Porejemplo,silatablatiene8valores,delasposiciones0ala7,ylavariablede
Controlindica,porerrordelecturaoporequivocacindeloperador,etc.,quesedebe
ejecutarlaRUTINA"10"(%1010),seraunERRORGRAVEtratardeejecutardichaRUTINA
"10"delatabla,PORQUENOEXISTE!perotambinpuedeestarMUYMALejecutarlarutina
'DOS',queesennuestroejemploloqueresultaalhacerunANDentre%1010y%0111:
%0010.
Asqueenunejercicioreal,ustedtienequedecidirquhacersiseproduceunerror;
porejemplo,avisaraloperadoryqueltomeladecisin,tomarunvalor"estimado"
porunalgoritmoapropiado,tomarunvalormnimosiesquelavariableestpordebajo
del,omximosiseubicaporencimadeltecho,etc.Cadacasoserdistinto.PeroNO
puededejarquesuvariabledeControlobligueasuCPUaejecutarunarutinaqueusted
nisiquieraescribi.
ObservequeMUCHOSejerciciosdeRedesCombinatorias,comolasolucinalproblemadel
EDPCENTER,quetambinseencuentraenellibro"IngenieraDigital",seresuelvende
unamaneraSimilaroIGUALalproblemadeLaFbricadeChocolates.
01["Laboratorios\Tables\FabricaDeChocolates.asm"]
02;********************************************************************
03;FabricaDeChocolates.asm,LuisG.UribeC.,V15F2013
04;SeehowtoreadaTable.UseHXregisterasindextotravel'Table'
05;inputcomesfromPTAD.YouneedtoMASKoutallnotusedbits.
06;UseANDwith0x07[%00000111;#LOW(Table_Mask)]toMask'input'.
07;MainloopreadsPTADvalues(youwillfakeinputsfromdebugger);
08;..readRESPONSESfromTable,andoutputthemto'output'variable
09;..(inreallife,youwilloutputthisvaluestotheoutputPORT)
207
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
10;
11;Includefiles
12NOLIST
13INCLUDE'derivative.inc'
14LIST
15;
16;2)DEFINES
17ram:SETZ_RAMStart;<<<TIMERS8:<<<
18rom:SETROMStart;HCS08ROMStart(Flash)
19initStack:EQU$1800
20COP_Disable:EQU%01000010;$42
21;====================================================================
22;3)GlobalVariables
23ORGram
24input:DS.W1;DS.W:HXregisterneeds16bitsvalues..
25output:DS.B1
26;********************************************************************
27;BeginofCodeSection
28ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
29ORGrom
30;
31;***ALWAYS***includethefollowing4instructions
32Main:lda#COP_Disable
33staSOPT1;SystemOptions1
34ldhx#initStack;InitSP
35txs
36;
37clrinput;HIGHendalwayswillbe0intheexample
38Forever:
39ldaPTAD;Besure:input<8(0..7)
40and#LOW(Table_Mask)
41stainput+1;>>>BIGENDIAN...REMEMBER???<<<
42ldhxinput
43ldaTable,X;o=Table[ix];
44staoutput;..
45braForever
46;
47;THEFOLLOWINGISTHEWAYTODECLARE*TABLESOFCONSTANTS*:
48;1:TheygoinROMFlash(constants...)
49;2:TheyhaveaNAME('Table'inthisexample)
50;3:Youpopulatetableswithvalues,usingDCassemblerdirective
51;4:NORMALLY,youneedtoknowtheLENGHTofthetable.Soyou
52;putamarkerattheend:'Table_End:'inthisexample,the
53;assemblercalculatesthelenghtas:'Table_EndTable_Begin'
54;(YoudoNOTliketocalculateanythingtheassemblercan!)
55Table:
56DC.B%100,%100,%100,%100;Stop,Half,Fullarebits
57DC.B%100,%010,%010,%001;..b2,b1,b0on'output'
58Table_End:
208
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
59TSIZE:EQUTable_EndTable
60Table_Mask:EQUTSIZE1;TSIZE*IS*apowerof2
61;
62;InterruptVectors
63dummy_isr:;<<<MustbeplacedinROMSpace
64rti
65ORGVswi;VswiandVreset
66DC.Wdummy_isr;SWI
67DC.WMain;RESET.Maximumpriority.Asynch.
68END
A estas alturas, ustedes deben poder comprender por completo la solucin que aqu
presento,sincomentariosadicionales.
Enmuchasaplicacioneslavariabledesalida("o",output)serunPuertodelMCU,o
unainterfazdecomunicacionesseriales.Ustedsabrcambiarelejercicioparaacomodar
susnecesidadesespecficas.
Aprovechparadefinirlavariable"o"enelStack,cosaqueyaaprendimosahacer.
Adems,lavariable'ix',ndicedentrode"Tabla",sehadefinidocomoUNSIGNED.Usted
puede designar en sus programas el calificativo SIGNED. Es importante resaltar que
usteddebesaberaplicarlasRamificaciones(Branches)APROPIADOSPARACADAOCASIN.De
locontrarioustedhabrcometidolamismaTORPEZAqueAndrewS.Tanenbaumaldisear
sufallidoMIC(1,2y3)parasulibrodearquitectura.
01["Laboratorios\Tables\Tables0.asm"]
02;********************************************************************
03;Tables0.asm,LuisG.UribeC.,V15F2013
04;SeehowtoreadaTable.UseHXregisterasindextotravel'Table'
05;"o"varhasspacereservedinStack
06;SeehowtoimplementaFORLOOP
07;Inthisexample,'ix'varisUNSIGNEDchar
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;2)DEFINES
15ram:SETZ_RAMStart;<<<TIMERS8:<<<
16rom:SETROMStart;HCS08ROMStart(Flash)
209
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
17initStack:EQU$1800
18COP_Disable:EQU%01000010;$42
19;====================================================================
20;BeginofCodeSection
21ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
22ORGrom
23;
24;***ALWAYS***includethefollowing4instructions
25Main:lda#COP_Disable
26staSOPT1;SystemOptions1
27ldhx#initStack;InitSP
28txs
29;
30pshh;Reservespacefor"o"varstoredin1,SP
31For01_Init:;for(ix=0;ix<TSIZE;ix++)
32For01:;IPREFERLABEL'For01:',notFor01_Init
33clrx;INITFOR:ix=0;
34clrh;..
35For01_Tst:;Intheexample,ixIS'unsigned'char;
36cphx#TSIZE;..if(!(ix<TSIZE)gotoFor01_End;
37;..NOTE:HERE(ix<8)youmayuse'cpx'...
38bhsFor01_Exit;..Dontuse'BGT';use'BHS':ixISuchar
39For01_Code:
40ldaTable,X;o=Table[ix];
41sta1,SP;..
42For01_End:
43aix#1;ix++.HERE(ix<8)youmayuse'incx'...
44braFor01_Tst
45For01_Exit:
46pulh;restoreStack}//endmain
47bra*
48;
49;THEFOLLOWINGISTHEWAYTODECLARE*TABLESOFCONSTANTS*:
50;1:TheygoinROMFlash(constants...)
51;2:TheyhaveaNAME('Table'inthisexample)
52;3:Youpopulatetableswithvalues,usingDCassemblerdirective
53;4:NORMALLY,youneedtoknowtheLENGHTofthetable.Soyou
54;putamarkerattheend:'Table_End:'inthisexample,the
55;assemblercalculatesthelenghtas:'Table_EndTable_Begin'
56;(YoudoNOTliketocalculateanythingtheassemblercan!)
57Table:
58DC.B7,6,5,4,3,2,1,0
59Table_End:
60TSIZE:EQUTable_EndTable
61;
62;InterruptVectors
63dummy_isr:;<<<MustbeplacedinROMSpace
64rti
65ORGVswi;VswiandVreset
210
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
66DC.Wdummy_isr;SWI
67DC.WMain;RESET.Maximumpriority.Asynch.
68END
COMENTARIOS a ["Laboratorios\Tables\Tables0.asm"]
Despusdelarutinariainicializacin,sepasaareservarespacioenelStackparala
variable"o";estosehacedecrementandoelSP,medianteunpushdeunbyte:
30pshh;Reservespacefor"o"varstoredin1,SP
AcontinuacinelcdigogenricoparalosFOR,quecomoserecordar,tienena)una
parte de Inicializacin de variables, b) un Cuerpo con las instrucciones que usted
quiererepetirdentrodelcicloyc)unapartedeFinalizacin,luegodelacualest
laSalidadelFOR.
LaInicializacinaqu[for(ix=0;ix<TSIZE;ix++)]consisteencolocarenCERO
lavariablendice,queestenelStack:
31For01_Init:;for(ix=0;ix<TSIZE;ix++)
32For01:;IPREFERLABEL'For01:',notFor01_Init
33clrx;INITFOR:ix=0;
34clrh;..
Acontinuacinseverifica(TST)quetodavahaytrabajoquehacer,[ix<TSIZE;];si
yaseterminsevaalaseccindesalida,Exit:
35For01_Tst:;Intheexample,ixIS'unsigned'char;
36cphx#TSIZE;..if(!(ix<TSIZE)gotoFor01_End;
37;..NOTE:HERE(ix<8)youmayuse'cpx'...
38bhsFor01_Exit;..Dontuse'BGT';use'BHS':ixISuchar
Observe dos cosas importantes: en este ejemplo usted puede emplear simplemente
comparacionesconX,elLSBdelregistrondiceH:X,porque'ix'soloasumirvalores
inferioresa8.
39For01_Code:
40ldaTable,X;o=Table[ix];
41sta1,SP;..
EnlapartedefinalizacindelFORseincrementaelndice,[ix++]ysecontinaen
lapartedeTSTdelFOR,yelciclocontina:
42For01_End:
211
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
43aix#1;ix++.HERE(ix<8)youmayuse'incx'...
44braFor01_Tst
Se suele usar AIX para incrementar (#1) el ndice H:X directamente, pero en este
ejemploenparticular,enqueelvalordelndicenosobrepasarde8,tambinpodra
haberseempleadoINCX,queincrementasloX,laparteLSBdeH:X
ParafinalizarelFOR,sedejabalanceadoelStack(COSAFUNDAMENTAL)medianteelPULH,
ysesimulaunHALT:
45For01_Exit:
46pulh;restoreStack}//endmain
47bra*
57Table:
58DC.B7,6,5,4,3,2,1,0
59Table_End:
60TSIZE:EQUTable_EndTable
PORLTIMO,sisuvariablenoestuvieraenStack,ustedtendraquedefinirlaenRAM
SpaceyelCdigocambiarasutilmentedeSTA1,SPenlalnea41,aSTAVAR:
Estocorrespondeaunextractodelprograma:
["Laboratorios\Tables\Tables1.asm"]
nolistado:
39For01_Code:
40ldaTable,X;o=Table[ix];
41STAVAR;..
Aplicaigualparaunpuertodesalida.Sifueraatransmitirlosvaloresdelatabla
poruncanaldecomunicacinserial,tendraquereemplazarlalnea41porelllamado
a una rutina de transmisin (lo que ya hicimos en los ejercicios dedicados a
COMUNICACIONES)
EsteejerciciomuestracmorealizarlamismainstruccinperodentrodeOCHO(8)bits.
CorrespondeaunRotateLEFT,perobastaconcambiarlasinstruccionesROLAyROLpor
las equivalentes hacia la derecha, RORA y ROR, para invertir el sentido del giro de
rotacin:
01["Evaluaciones\201301Ene\Evaluaciones\Ex#1\Rotate8.asm"]
02;********************************************************************
212
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
03;Rotate8.asm,LuisG.UribeC.,D17F2013
04;
05;Includefiles
06NOLIST
07INCLUDE'derivative.inc'
08LIST
09;
10;2)DEFINES
11ram:SETZ_RAMStart;<<<TIMERS8:<<<
12rom:SETROMStart;HCS08ROMStart(Flash)
13initStack:EQU$1800
14COP_Disable:EQU%01000010;$42
15;====================================================================
16;3)GlobalVariables
17ORGram
18var:DS.B1
19;********************************************************************
20;BeginofCodeSection
21ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
22ORGrom
23;
24;***ALWAYS***includethefollowing4instructions
25Main:lda#COP_Disable
26staSOPT1;SystemOptions1
27ldhx#initStack;InitSP
28txs
29;
30mov#%10101010,var
31;
32ldavar
33rola
34rolvar
35bra*
36;
37;InterruptVectors
38dummy_isr:;<<<MustbeplacedinROMSpace
39rti
40ORGVswi;VswiandVreset
41DC.Wdummy_isr;SWI
42DC.WMain;RESET.Maximumpriority.Asynch.
43END
COMENTARIOS a ["Evaluaciones\2013-01Ene\Evaluaciones\Ex#1\Rotate8.asm"]:
Variablequeestarsujetaalarotacinde8bits:
17ORGram
18var:DS.B1
Inicializacinconunvalorarbitrario:
bits76543210
30mov#%10101010,var
213
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
32ldavar
33rola
ResultandodespusdelROLAen:
Acc=%0101010x
C=1(originalbit7de'var')
La 'x' en el bit0 del Acc es porque el valor del carry C, es indeterminado para
comenzar.
Ahora se rota 'var' a la izquierda, con lo cual el C, que era el bit7 de 'var',
alimentasubit0:
34rolvar
35bra*
Resultandoen:
var=%01010101(ROTATELEFTenOCHOBITS)
C=1(peroyanoseusams)
214
Captulo
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
PROGRAMACIN EN "C"
Unix, Linux, iOS, Windows, QNX... hacen del lenguaje C el
ms usado desde 1970 (44 aos). Ningn otro ostenta esa marca.
NOTAS INICIALES
ugieroencarecidamentequecadavezqueencuentrealgnaspectodelLenguajeCen
losejerciciosqueacontinuacinpresento,queustedNOENTIENDA,loANOTEpor
aparte, Y ME HAGA LLEGAR LA LISTA COMPLETA AL FINALIZAR la lectura de esta
seccincorrespondientealLenguajeC.
Servir para QUEJARME NUEVAMENTE a ver si logramos que CAMBIEN DE UNA VEZ LOS DOS
CURSOSDEPROGRAMACIN.
YaustedledarunaideaDEMUCHASCOSASQUELEFALTANPORAPRENDERDELLENGUAJE.En
su profesin, ES MUY IMPORTANTE MANEJAR EL "C", y aqu YA NO LE ENSEARN MS
PROGRAMACIN. As que le corresponde a usted estar DESCONTENTO y... ESTUDIAR POR SU
CUENTA!
DNDE ESTAMOS
ConfiguracionesdelasmquinasdeVonNeummanvs.lasHarvard
ClasesyrelevanciadeconjuntosdeinstruccionesCISCyRISC
Poderoyabundanciadelosmodosdedireccionamiento
ImportanciadelosmtodosdeEntradaySalida
ElementosdeinformacincomoelStack
Definicindevariableslocales,enelStack
Usodemtodosrecursivos
Direccionamientosindexados,vaSPyvaregistrondiceH:X
Interrupciones
Interrupcionesanidadas
Inversindeprioridades
215
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
HabilitacindeinterrupcionesaciertaalturadelasISR
AplicacindeinstruccionestanimportantescomoelSWI
UsodeTPAyTAPparaguardarelProcessorStatusWord
EnelreadelaaplicacindeMicrocontroladoresalossistemasEMBEBIDOS,elusodel
lenguaje"C"estmuyextendido.OtrosqueseempleanenmenorescalasonJava,ciertos
BASICs,FORTH...
PoresointrodujelaprogramacindeMC9S08QE128empleandoel"C",queesellenguaje
usadoenloscursosmsavanzadosdeArquitecturayLaboratoriodeProyectos.
GENERALIDADES
ividiremoslosejerciciosdeCentrespartes:Introduccin,conlosprogramas
ms simples, comparados con los similares en Assembler; el manejo de
temporizadores,enlaquepresentomilibreradeTimers,confuncionalidades
casiexactasalasdeelcaptuloanterior;lalibreradedeComunicaciones
Seriales, iguales a su contraparte en ASM, y la librera para el manejo de Colas,
imprescindibleparaoperarapropiadamentelasComunicacionesconflexibilidad.
Lascarpetasendondeseencuentranlosejerciciosintroductoriosson:
LabsC\Fibonacciy
LabsC\Lab1
["LabsC\Fibonacci\060Fibonacci.c"]
01//Fibonacci.c(02Fibonacci.asm),LuisG.UribeC.,M10D2013
02//******************************************************************
03//02Fibonacci.asm,LuisG.UribeC.,V10A2009V08J2012
04//ADAPTEDfrom:HCS08RS08_Assembler_MCU_Eclipse.pdf,Listing4.1
05//
06//Includefiles
07#include"derivative.h"//Includeperipheraldeclarations
08#include"Fibonacci_.h"
09//
10//Definicindevariables(ds:bytepordefecto)
11byteCounter;
12byteFiboRes;//Aquvalarespuesta
13voidmain(void)/*()*/
14{
15mainLoop:
16clra;
216
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
17cntLoop:
18inca;
19cbeqa(14,mainLoop);//Largervaluescauseoverflow
20sta(Counter);//Updateglobalvariable
21bsr(CalcFibo);
22sta(FiboRes);//Storeresult
23lda(Counter);//..ActivateBREAKPOINTheretosee..
24//..123581321345589144233
25bra(cntLoop);//Nextround
26for(;;){/*EMPTYFOR*/}
27}//endmain
28//==================================================================
29//FunctiontocomputeFibonaccinumbers.ArgumentisinA
30voidCalcFibo()
31{
32dbnza(fiboDo);//FibonacciDo
33inca;
34rts;
35//
36fiboDo:
37psha;//Thecounter
38clrx;//Secondlast=0
39lda(0x01);//Last=1
40//
41FiboLoop:
42psha;//Pushlast
43txa;
44add(1,sp);
45pulx;
46dbnz(1,sp,FiboLoop);
47//
48FiboDone:
49pulh;//Releasecounter
50rts;//ResultinA
51}//endCalcFibo()
COMENTARIOS a ["Labs-C\Fibonacci\060Fibonacci.c"]:
LamagiaquenospermitehacerunprogramaenC,queseVcasiIGUALalequivalenteen
Assembler, y que CORRE "IGUAL" (puede simularlo...) se encuentra en el include file:
Fibonacci_.h, que tiene las definiciones que mimetizan el ASM en C. Lo analizaremos
posteriormente.
Ladefinicindevariables,queenASMeran:"ds",bytepordefecto:
217
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
11byteCounter;
12byteFiboRes;//Aquvalarespuesta
Sabeques"byte"?LASSUPOSICIONESNUNCAPUEDENCONVERTIRSEENINFORMACIN.
SIUSTEDAVANZASINESCLARECERLASCOSASQUENOSABE,NOLEVAAIRBIENENLAVIDA
La definicin de (casi) todo lo que tiene que ver con este MCU se encuentra en
"mc9s08qe128.h".YotengounaversinREDUCIDA:"mc9s08qe128U.h",fcildeconsultar.
Enparticular,allfiguran:
typedefunsignedcharbyte;
typedefunsignedintword;
ElcomienzoenASMeraen'Main';aqu:
13voidmain(void)/*()*/
ElcicloprincipalsellamaigualenASM,ylasinstruccionesaquloMIMETIZANdeuna
manera casi IGUAL. Inclusive, como los punto y comas se usan en ASM para comenzar
COMENTARIOS, y en C para terminar 'SENTENCES', podemos rearreglarlos (;) para que se
veancomoelcomienzodeloscomentariosenASM:
15mainLoop:
16clra;//comienzodecomentario
17cntLoop:
18inca;//..tantoenASMcomoen...C!
Aqu viene una DIFERENCIA: aunque no es imposible evitar los parntesis que se
necesitanenC,peronoenASM,paraelllamadodelassubrutinas,noesfcil,porlo
queloshemosdejado...:
19cbeqa(14,mainLoop);//Largervaluescauseoverflow
20sta(Counter);//Updateglobalvariable
21bsr(CalcFibo);
22sta(FiboRes);//Storeresult
23lda(Counter);//..ActivateBREAKPOINTheretosee..
25bra(cntLoop);//Nextround
PoresodecimosqueelresultadoesCASIidntico.
LafuncintambinestmimetizadademaneraCASIigual,as:
30voidCalcFibo(){
32dbnza(fiboDo);//FibonacciDo
33inca;
34rts;
36fiboDo:
218
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
37psha;//Thecounter
38clrx;//Secondlast=0
39lda(0x01);//Last=1
41FiboLoop:
42psha;//Pushlast
43txa;
44add(1,sp);
45pulx;
46dbnz(1,sp,FiboLoop);
48FiboDone:
49pulh;//Releasecounter
50rts;//ResultinA
["Labs-C\Fibonacci\Fibonacci_.h"]:
Analicemosahoraelincludefile:
["LabsC\Fibonacci\Fibonacci_.h"]
01//==================================================================
02//Fibonacci_.h(02Fibonacci.asm),LuisGUribeC,S09N2013M10D2013
03//MimicCPURegisters
04byteA;//UseAasacounter
05byteX;
06byteH;
07#defineclraA=0
08#defineincaA++
09#definecbeqa(v,l)if(A==v)gotol
10#definesta(v)v=A
11#definebsr(l)l()
12#definelda(v)A=v
13#definebra(l)gotol
14#definedbnza(l)if(A)gotol
15#definedbnz(c,v,l)if(stack[v+c]=1)gotol
16#definertsreturn
17#defineMAX_SP16
18#defineclrxX=0
19#definetxaA=X
20#defineadd(n,v)A=A+stack[v+n]
21#definepshastack[sp]=A
22#definepulxX=stack[++sp]
23#definepulhH=stack[++sp]
24wordstack[MAX_SP];
25wordsp=MAX_SP1;
26voidCalcFibo();
219
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Fibonacci\Fibonacci_.h"]:
["LabsC\Fibonacci\Fibonacci_.h"]:
Como en C no tenemos acceso a los registros internos del CPU, los definimos como
variables:
04byteA;//UseAasacounter
05byteX;
06byteH;
UnaseriedeMACROS(enC),definenlasinstruccionesdelHCS08,medianteoperaciones
enCquesimulenelcomportamientooriginal.Porejemplo,'clra'enCsera:A=0
07#defineclraA=0
11#definebsr(l)l()
Ademsescogunejercicioqueemplearecursin,asquevernquesimulelStackcon
un arreglo de Words. Para decrementar la variable que est en el Techo del Stack, y
saltaraun"Label":
15#definedbnz(c,v,l)if(stack[v+c]=1)gotol
EltamaodelStacklodefinoarbitrariamenteen16:
17#defineMAX_SP16
SumarlealacumuladorunavariabledinmicamentedefinidaenelStack:
20#defineadd(n,v)A=A+stack[v+n]
ManipularelStack(pushypop)paraelAcumuladoryelregistrondiceH:X
21#definepshastack[sp]=A
22#definepulxX=stack[++sp]
23#definepulhH=stack[++sp]
LadefinicindelStack,yladefinicineinicializacindelStackPointerSP:
24bytestack[MAX_SP];
25bytesp=MAX_SP1;
Elprototipodelafuncinrecursiva:
26voidCalcFibo();
NOENTIENDEALGUNODELOS#define?OTRASDECLARACIONES?
TIENEQUEESTUDIAR"C"
220
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Fibonacci\090FibonacciOK.c"]:
EsteprogramaesCestndarynoameritamscomentarios.
NOENTIENDEELOPERADORTERNARIO?NISABESEALARCULES?
TIENEQUEESTUDIAR"C"
221
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
08#include"several_U.h"//Def:CpuIntEn,CpuIntDsb,EOF,Wait
09//******************************************************************
10voidmain(void)/*()*/
11{bytebase=2,exponent=5;//EXAMPLE2^5=32.See3^5=243
12byteresultExp=1;
13bytemultiplicand,multiplier,resultMpy;
14while(exponent){//...byrepeatedmultiplications
15multiplier=base;
16multiplicand=resultExp;
17resultMpy=0;
18while(multiplier){//...byrepeatedadditions
19resultMpy+=multiplicand;
20}
21resultExp=resultMpy;
22}
23Wait(0);//WaitforEver
24}
COMENTARIOS a ["Labs-C\Lab1\010Lab0e-1.c"]:
EsteprogramaesCestndar,portantonoameritamscomentarios.
08//
09//FunctionsPrototypes
10byteexpo(bytebase,byteexponent);
11bytemply(bytemultiplicand,bytemultiplier);
222
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
12//******************************************************************
13voidmain(void)/*()*/
14{bytebase=2,exponent=5;//EXAMPLE2^5=32.See3^5=243
15volatilebyteresultExp;
16resultExp=expo(base,exponent);
17Wait(0);//WaitforEver
18}
19//
20byteexpo(bytebase,byteexponent)/*()*/
21{byteresultExp=1;
22while(exponent){//...byrepeatedmultiplications
23resultExp=mply(resultExp,base);
24}
25returnresultExp;
26}
27//
28bytemply(bytemultiplicand,bytemultiplier)/*()*/
29{byteresultMpy=0;
30while(multiplier){//...byrepeatedadditions
31resultMpy+=multiplicand;
32}
33returnresultMpy;
34}
COMENTARIOS a ["Labs-C\Lab1\020Lab0e-2Sub.c"]:
EsteprogramaesCestndarynoameritamscomentarios.
07//
08//FunctionsPrototypes
09byteexpo(bytebase,byteexponent);
10bytemply(bytemultiplicand,bytemultiplier);
11//******************************************************************
12voidmain(void)/*()*/
13{bytebase=3,exponent=5;//EXAMPLE2^5=32.See3^5=243
223
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
14volatilebyteresultExp;
15resultExp=expo(base,exponent);
16Wait(0);//WaitforEver
17}
18//
19byteexpo(bytebase,byteexponent)/*()*/
20{byteresultExp=1;
21while(exponent){//...byrepeatedmultiplications
22resultExp=mply(resultExp,base);
23}
24returnresultExp;
25}
26//
27bytemply(bytemultiplicand,bytemultiplier)/*()*/
28{byteresultMpy=0;
29while(multiplier){//...byrepeatedadditions
30resultMpy+=multiplicand;
31}
32returnresultMpy;
33}
COMENTARIOS a ["Labs-C\Lab1\030Lab0e-2SubVisualStudio.c"]:
Este programa es C estndar para ser procesado por Visual Studio, y no amerita ms
comentarios.
COMENTARIOS a ["Labs-C\lab1\00a_l1.c"]:
Como ya se indic, FORMA y PRESENTACIN deCdigo en nuestro trabajo, es FUNDAMENTAL
para la vida de los proyectos. Los programas deben poder entenderse, por quien los
hace,cuandovuelvaamirarlos,yporlaspersonasquevengandespusamodificarloso
repararlos.
224
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Paraesoserequieren,entreotrascosas,comentariostiles,resaltantesyclaros.
IgualqueenprogramasescritosparaotrosLenguajes,enlasprimeraslneassecoloca
el Nombre del programa, su propsito, para qu plataforma y qu revisin
(identificacinquepermitellevarlapistadelasmodificacionesqueselehanhecho);
hay que incluir siempre fechas que indiquen el comienzo del programa, cundo se lo
modificyladatacindelarevisinactual.Cuandoesimportante,hayqueagregaruna
lista de fechas e indicar explcitamente qu cosas se aadieron, se quitaron o se
modificaron. Tambin,las iniciales de lapersona quehizo cambios en el cdigo, que
permitaidentificarlasparasaberaquinpreguntarsifueranecesario.
02//00a_L1.c,MINIMUM'C'ProgramforHCS08,J21N2013
03//LuisG.UribeC.,ForCodeWarrior10.3
SIEMPRE hay que indicarle al CPU dnde comienza su cdigo pero, a diferencia del
trabajoqueyahicimosanteriormenteenAssembler,aqueselcompiladordeC,ylas
dems herramientas asociadas a l y a su entorno de desarrollo, como el Linker, el
AbsoluteLoader,etc.)losquedeterminanladireccindearranque(manejoautomtico
delosVectoresdeInterrupcin).GraciasaDios.
Nohaymuchomsquesepuedaagregarparaexplicaresteejerciciotansencillo.
06voidmain(void)/*()*/
07{
08for(;;){
09/*EMPTYFOR*/
10}
11}
NOCOMPRENDEALGUNODELOSELEMENTOSDEESTEPROGRAMA?DESISTA!
NOENTIENDEELFOR?TIENEQUEESTUDIAR"C"
["LabsC\Lab1\01c_L1.c"]
01//******************************************************************
02//01c_L1.c,SmallCprogramM10D2013
03//LuisG.UribeC.,ForCodeWarrior10.3
04
05//
06//IncludeFiles
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
09
225
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
10//******************************************************************
11voidmain(void)/*()*/
12{
13bytevar;//Dependingonoptimizationoptions,
14//..Ccompilermaylearnthatnothing
15var=0;//..isrealybeingdone,andreplace
16while(1){//..var,orallyourcodeforempty/
17var++;//..null,block.Ifvarisnotseen
18}//..inDebugremovesomeoptimization
19}//..declaring:volatilebytevar;
COMENTARIOS a ["Labs-C\Lab1\01c_L1.c"]:
Losdos"includefiles"listadosacontinuacin,casisiempreseincluyen.
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
Porejemplo,paranuestromicro,laseccinmsimportanteen"derivative.h"es:
#include<mc9s08qe128.h>
<hidef.h>(HardwareInterfaceDefinitions)seusamenos,yaquefundamentalmenteloque
incluyesondefinicindeMacrosparalahabilitacindeInterrupciones.Msadelante
veremoscmomanejamosnosotrosestasfuncionalidades.
Elejercicioloquetratadehacer,ensusimplicidad,esincrementarpermanentemente
unavariable'var',detipo'unsignedchar'(byte).
Laaclaratorioquehayquehacer,paraqueustedesrecuerdensusCONOCIMIENTODEC,es
queelCompiladorpuededarsecuenta,dependiendodelasopcionesdeoptimizacin,que
nosehaceNADAcon'var':apesardeincrementarla,nadielausa.Asque,comobuen
"optimizador", puede quitar la variable por completo, y si yo hubiera diseado el
Optimizador,eliminaraTODOELCDIGO.
Como ustedes deben saber, de sus cursos de C, pueden deshabilitarse las opciones de
OPTIMIZACIN para que el compilador NO elimine ni la variable intil, ni el cdigo
INTIL.
Otra forma que ustedes debieron aprender en sus cursos del lenguaje, es que si se
declaraesavariablecomo"volatilebytevar;",elcompiladorasumirque,sinquel
entiendacmo,esavariableserusadaenalgunaotrapartequeldesconoce(como,por
ejemplo,siassehacereferenciaaunPuertoDigitaldeSalida:Elentornoexterno
USAR los valores calculados DENTRO del programa, aunque no se haga evidente para el
compiladorqueestoseaas.
13bytevar;//Dependingonoptimizationoptions,
14//..Ccompilermaylearnthatnothing
226
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
15var=0;//..isrealybeingdone,andreplace
16while(1){//..var,orallyourcodeforempty/
17var++;//..null,block.Ifvarisnotseen
18}//..inDebugremovesomeoptimization
19}//..declaring:volatilebytevar;
NoteenlosprogramasenC,similarmentealoquehicimosenloscdigosenAssembler,
lamuyajustadalneaendondesecolocanloscomentarios.Enprincipio,//comienzaen
la columna 32. Y aqu tambin puede haber ocasiones en las que haya que mover los
comentarios,peromientrasmsestandarizadoestlaformadepresentacindelcdigo,
mejorparatodos.
En Intel hay 4 registros de Segmento, con una funcin similar, llamados CS, Code
Segment; DS, Data Segment, SS, Stack Segment y EX, Extra Segment. El CS confina el
cdigodelprograma,quehadesercapturadomedianteelCSyelPC(ProgramCounter).
EnAssembler,sielprogramaesmsgrandeque64KB,seprogramaelCSy,enelmomento
enquesedeseasaltaraunaposicinqueestfueradeeseSegmento,sereprogramael
CSparautilizarotros64KB.Lamanipulacinsuelenosermuysencilla,yaquesise
cambiaelCS,DESAPARECENlasinstruccionesqueestnhaciendolareprogramacin,pero
haytrucosqueseacostumbran.
LociertoesqueparatrabajarenC,sielprogramaesmsgrandequeunSegmento,una
maneradeindicarlealcompiladorquelsehagacargodeesetrabajodereprogramacin
delCSes,porejemplo,definiendoapuntadoresquepuedanbarrermuchomsdelos64KB
(porejemplo,TODAlamemoria).Laformaesmedianteelindicativo'far',as:
farchar*ptr;
As,elcompiladorseencargadeirhaciendoeltrabajoqueenAssemblercorrespondera
alprogramador,deverificarsicadadireccinest,ono,confinadaaunsegmento.En
caso de no estarlo, el compilador incluye cdigo para la reprogramacin del CS y la
transicin,invisibleparaelprogramador,aotroSegmento.
AlgoparecidoocurreconelDS,oSegmentodeDatos.EldeCdigoverificaquealgn
salto(JMP)ollamadoasubrutina(JSR),secomportebiennoimportaenqupartedela
227
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
memoriaseencuentreelcdigo.EldeDato,DS,operadelamismamanera,peroyano
para cdigo, sino para manipularaquellas reas de memoria que estn en unaposicin
msalldelasfronterasde64KBimpuestasporelDataSegment.
Este ejercicio muestra cmo manejar las Interrupciones, con la Extensin para ese
propsito definida por Motorola, Freescale, CodeWarrior, mediante un cdigo sencillo
quehaceunamanipulacincualquierasobreunavariable'var',ycadavezqueserecibe
una interrupcin del botn IRQ (external Interrupt Request), se niega una variable
global,GlobalVar.
["LabsC\Lab1\03b_L1_M.c"]
01//******************************************************************
02//Programa03b_L1_M.C,HCS08_CPU,LuisG.UribeC,M10D2013
03//
04//UsodeRutinasdeInterrupcin:
05//A)HabilitacindelperifricoparaInterrumpir
06//B)HabilitacindelCPU(cli)paraqueacepteInterrupciones
07//(apartedelRESET,que**NO**esenmascarable)
08//C)InclusindelcdigodelarutinadeInterrupcin(Interrupt
09//ServiceRoutine,ISR).
10//******************************************************************
11//IncludeFiles
12#include<hidef.h>//ForEnableInterruptsmacro
13#include"derivative.h"//Includeperipheraldeclarations
14#include"several_U.h"//Def:CpuIntEn,CpuIntDsb,EOF,Wait
15//
16//FunctionsPrototypes
17byterutina(bytevar);
18//
19//GlobalVariables
20volatilebyteGlobalVar;
21//******************************************************************
22voidmain(void)/*()*/
23{volatilebytevar=30;
24//
25//>>>ALWAYSincludethefollowing2lines
26//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
27#defineCOP_Disable0x42
28SOPT1=COP_Disable;//SystemOptions1
29//
30//EnableInterruptsforIRQ
31//
32//1a)
33IRQSC_IRQPE=1;//BSETIRQSC_IRQPE,IRQSC:EnableIRQPIN
228
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
34//1b)
35//..Clearanypossibleprevious,false,interruptsbySetting
36//..IRQACKbitinIRQSC(IRQStatusandControlregister)
37IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC
38//
39//>>>>>Try:IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK<<<<<<
40//2)
41//
42IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC//IRQpinIntEn
43//===============================================================
44cli;//CPUInterruptENABLE
45//
46loop:
47while(1){
48var=rutina(var10);
49var=var;//COLOCARBREAKPOINTAQU(Debugger)
50}
51Wait(0);//WaitforEver
52}
53//==================================================================
54byterutina(bytevar)//Subrutinadeejemplo/*()*/
55{
56while(var<30){
57var++;
58}
59returnvar;
60}
61//==================================================================
62//EJEMPLOdeRutinadeInterrupcin(ISRforIRQsignal)
63//NOTE:EsnecesariorealizarunACKNOWLEDGEparaquevuelvaasuce
64//derlainterrupcin(InterruptHandshaking...differentfor
65//eachperipheral:YouneedtoreadManualforeachone...:(
66interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
67{
68GlobalVar^=(byte)1;
69IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
70}//..(RearmIRQInterrupts)
COMENTARIOS a ["Labs-C\Lab1\03b_L1_M.c"]:
LosIncludeFilesnormalesyunoextra,"several_U.h"(LOSPRESENTOMSADELANTE):
12#include<hidef.h>//ForEnableInterruptsmacro
13#include"derivative.h"//Includeperipheraldeclarations
229
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
14#include"several_U.h"//Def:CpuIntEn,CpuIntDsb,EOF,Wait
Elprototipodelafuncin'rutina',queretornaun'byte'yalacualselepasaun
tambinbyte,(bytevar):
17byterutina(bytevar);
Variableglobal.Ntesequeselahadefinidocomo'volatile',paraqueelOPTIMIZADOR
delcompiladorNOLAOMITA,nialcdigoquetambinseradetectadocomointil(este
programaesbastanteinane):
20volatilebyteGlobalVar;
Comienzodelprogramaydefinicinde'var',tambincomo'volatile':
22voidmain(void)/*()*/
23{volatilebytevar=30;
PeroelCOPshayquedeshabilitarloporprograma.Unposibleequivalentea:
Main:lda#$42;$42(%0100_0010)?COPE(SOPT1b7)=0($1802)
sta$1802;(SOPT1Pupinitto$C2=%1100_0010)
eselsiguiente:
27#defineCOP_Disable0x42
28SOPT1=COP_Disable;//SystemOptions1
Ahora, para habilitarlas interrupciones del IRQ, ste es el cdigo en Assembler que
siemprehemosusado,
BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
BSETIRQSC_IRQACK,IRQSC
BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
cli;CPUInterruptENABLE
enCelquecorrespondeeselsiguiente:
33IRQSC_IRQPE=1;//BSETIRQSC_IRQPE,IRQSC:EnableIRQPIN
37IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC
42IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC//IRQpinIntEn
44cli;//CPUInterruptENABLE
Ustedpuedeensayartambin(muchoMEJOR):
39IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK
230
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Funcionaigual,peroesmssimple.
Elcicloprincipaldelprogramaesmuysencillo,yenrealidadcorrespondeaunaespera
artificialhastaqueocurralainterrupcin.Estecdigodebeserseguidoempleandoel
Debugger(colocandounBreakpointdondeseindica):
46loop:
47while(1){
48var=rutina(var10);
49var=var;//COLOCARBREAKPOINTAQU(Debugger)
50}
51Wait(0);//WaitforEver
La'rutina'llamada,tambinesartificial:
54byterutina(bytevar)//Subrutinadeejemplo/*()*/
55{
56while(var<30){
57var++;
58}
59returnvar;
La rutina de Interrupciones tiene varios ASPECTOS NOVEDOSOS. Como dijimos que las
funcionalidades no definidas por el estndar ANSI se manejan como Extensiones al
lenguaje, y al compilador, las define cada proveedor, y si bien es cierto que se
parecenbastanteentreunoyotro,nosoniguales!Portanto...NOSONPORTABLES.Y
hayqueaprenderlasparacadasuplidor.
LuegovieneelTIPOdeinformacinquelarutinaretorna;lasrutinasdeInterrupcin,
ISR,JAMSDEVUELVENNADAysutipoSIEMPREes'void'.SiunaISR,InterruptService
Routine,debecomunicarseconelprogramaprincipal,tienequehacerlointercambiando
valoresmediantevariablesglobales,como'GlobalVar'enelpresenteejemplo.
Las ISR JAMS RECIBEN PARMETROS, como las subrutinas convencionales; por eso el
'(void)';silaISRtienequeleervaloresque'main'oalguienmsproduce,tienenque
intercambiarseTAMBIN(leerse,escribirse)envariablesglobales:
66interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
67{
231
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
68GlobalVar^=(byte)1;
ENTIENDELAEXPRESIN?SINO,TIENEQUEESTUDIAR"C"
69IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
70}//..(RearmIRQInterrupts)
NOTA: En la familia anterior: HC08 (sin la 'S'), el IRQ tena dos diferencias
fundamentalesconlafamiliaactual,HCS08:
1) Las interrupciones de IRQ estaban HABILITADAS SOLO CON ENCENDER EL MCU! Esto es
**MUYPOCOORTODOXO**,yfueeliminadoenelHCS08...
2) Bastaba con que el PC cargara el contenido del Vector de Interrupciones del IRQ,
como parte del proceso de atender esa interrupcin, para que automticamente el
HardwaretuvieraunAcknowledge.
Estobienpodranhaberlodejado,perolocambiaron:ahorahayquedarleexplcitamente
unACK,segnlalnea69arriba.
COMENTARIOS a ["Labs-C\Lab1\several_U.h"]:
Primero se define un 'Wait', empleando un 'while'. Wait es muy conveniente expresado
cosas como: Wait( kbhit() ): espere hasta que llegue una tecla. Empleando un while
habraqueescribir
232
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
while(!(kbhit());
ComoestaesunaproposicinenNEGATIVO,sehacemsdifcilsucomprensin.
MuchomejorqueSALTESI*NO*SONIGUALES.
07#undefWait
08#defineWait(e)while(!(e))
Para habilitar las interrupciones del CPU se emplea una instruccin de lenguaje
ensamblador,queNOpuedeexpresarseenlenguajeC!
Pero una de las extensiones de CASI todos los compiladores modernos, permite incluir
instruccionesdeAssembler,ENLNEAconelcdigoenC.Estoesexactamenteloquese
haceacontinuacinconel'asm':
10#defineCpuIntEn__asmCLI
Lomismosehaceparaladeshabilitacindeinterrupciones:
12#defineCpuIntDsb__asmSEI
(Adems, que mis nombres, CpuIntEn y CpuIntDsb, con seguridad que son MUCHO ms
INTELIGENTES,DIGO:INTELIGIBLES,quelosoriginalesdeFreescale!)
14#defineEOF((word)1)
NOENTIENDEEL#defineDELALNEA14?
TIENEQUEESTUDIAR"C"
OBSERVACIN:
NihemoscomenzadolosejerciciosenC,ylespregunto:
Sabanalgode#undef?
233
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
QuvalorinicialtieneGlobalVar(lnea20)?
Porquenlalnea
48var=rutina(var10);
'rutina'estPEGADAalparntesisizquierdo,entantoqueen:
54byterutina(bytevar)//Subrutinadeejemplo/*()*/
'rutina'estSEPARADAdelparntesisizquierdo?
Paraqupuedeservirel'moito':/*()*/?
Imagino,peroestoydesconfiado,queshabanusado#define?
39IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK
As:
//EnableInterruptsforIRQ
IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC//IRQpinIntEn
cli;//CPUInterruptENABLE
MANEJO DE TIMERS
Refirasealosejerciciosqueestnenlacarpeta:CarpetasLabsC\Lab2\TimersJ
234
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Timer(TBM:TimerBasicModule)interrumpibleporotrosdispositivos,yNOreentrante.
Estopermitaestudiarelconcepto,yalavezhacerquemistimers,querealidadno
requieren una exactitud ajustada al microsegundo, no molestaran a los dems
perifricos, en caso de que aquellos necesitaran interrumpir. La no reentrancia se
requera para evitar que el mismo TBM auto interrumpiera su propia ISR, en caso de
haber terminado un conteo por Hardware antes de haber terminado su Interrupt Service
Routine(pormotivodelosdemsperifricos).Noesconcienteaceptarunainterrupcin
de un perifrico sin haber terminado su ISR para una interrupcin anterior. Esta
funcionalidadselograprincipalmente,haciendoquelaISRdelTBMautoinhabilitesu
InterruptEnableyrehabilite(CLI)lasinterrupcionesdelCPU.RecuerdequeMotorola
ensusManualesdeReferencia,advierteEQUIVOCADAMENTEencontrariodeestaprctica.
3)LarevisinTimers8CesdelJueves01Dic2005paramisiguientecurso;allinclula
capacidaddequeOTRASISRspudieranemplearlasMacrosdelalibreradeTimers;as,
porejemplo,elIRQolascomunicacionespodan,dentrodesusISRs,temporizarciertos
eventos que el programador necesitara (timeouts y similares; control de "throttle" o
reguladordevelocidad).
5)Timers8G:CuandofuiadictarelcursodeArquitecturaenAbrilde2009meencontr
queelLaboratoriohabaadoptadoelcompiladorCodeWarriorporvariasrazones:
a)manejabaCademsdeASM;
b)eraelqueMotorolapromocionaba;
c)WinIDEseestabaquebrando,imaginoquenoganabanmuchoregalandosucompilador,y
ahoraqueracobrarlo,loqueobligacompararloconCW.
Porejemplo,enWinIDEyenCWunbitseidentificabacomo:
Timer0ReadyEQU0;..Bit#0;forbrclr&brset
Timer0.RdyEQU0;..Bit#0;forbrclr&brset
EnWinIDEyenCWladefinicindelasmacrostenaelsiguiente
aspecto:
$MACROSetimerKtimer,time;timeisaCONSTANT(K)
Setimer:MACROtimer,time;timeisaCONSTANT(K)
Desapareceel$de$MACRO,ycambiadeposicin...ElnombredelaMacroahoraesLA
ETIQUETA.
EnWinIDE,porejemplo,alprimerparmetrodelaMacroselehacareferenciacomo%1,
entantoqueenCWes\1;el%enCWidentificanmerosbinarios.Losnmerosenbase
diezahorasonelestndar,noprecisanidentificadorespecial;enWinIDEseescriban
como:!10
235
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
6)Misclaseshastael2012noincluyeronlasdeArquitectura;cuandoregresdespus
de3aos,acababandecambiarahora...ELCHIP.ElsucesorfueeldelafamiliaHS:
HC9S08QE128 y se inclua la tarjeta de desarrollo DEMOQE128. TODO VOLVI A CAMBIAR:
habaperifricosnuevosquereemplazabanfuncionesantiguas.Porejemplo,elTMByano
existayloreemplazelRTC.LosADCsiguieronsiendolosmismos,peroCAMBIARONlos
NOMBRES de los puertos y bits, de los originales de Motorola a los de nomenclatura
Freescale. Algunos cambios sutiles, como los del IRQ que ya hemos mencionado; ya el
osciladormaestrodelCPUpermiteusarloSINprogramacin,porloqueeliminesaparte
delabibliotecadesoporte.
Paracolmo,laversinactualdelCodeWarrioresla10.5,aunqueenelLaboratorioslo
se le da soporte a la antigua 6.3, que difieren bastante las dos. Incluso, la nueva
10.xtienenuevosbugsquehacenqueprogramasquecorranbienenla6.3,ahoranolo
hagan.
AsquecorrespondalaversinTimersH,yaprovechandolanuevadenominacindelchip,
larebauticcomoTimersHS.
La librera que aqu presento para el lenguaje C est basada en TimersHS, pero con
diferenciasquemeobligaronaavanzarlaversin;poresoenClabibliotecadeTimers
quelesofrezcoeslaTimersJ.c(LasiguienteaHeslaI,perohayciertasletrasque
enloslistadosanseprestanparaconfusin,dependiendoavecesdeltipodeletra:
Laiconel1,laOconel0;laAconel4...poresonoestimersIsinoTimersJ)
SiustedentendialaperfeccinlaversinenAssembler,nodeberatenerproblemas
conelestudiodeTimesrJ.c
["LabsC\Lab2\TimersJ\timersJ.c"]
001//******************************************************************
002//TimersJ.c,LuisG.UribeC.C19D2013
003//
004//******************************************************************
005//IncludeFiles
006#include"timersJ_.h"
007
008//
009//GlobalVariables
010volatilewordtimersMS[NTIMERS];
011
012//==================================================================
013voidIniTimers(bytentimers)/*()*/
014{//BydefaultLINKinitALLtimers(timersMS[NTIMERS])toZERO
015//'ntimers'NOTusedhere.CustomizeNTIMERS,intimersJ_.h
016
017//AssureuserdefinedNTIMERS(timersJ_.h)is2'spower!
018Sassert(!(NTIMERS&(NTIMERS1)));
019
020RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
021//..ClearRTCIF;IntEnableRTC
022}/*IniTimers()*/
236
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
023
024//
025wordSetimerMS(bytetimer,wordtimeMS)/*()*/
026{wordtmp=timersMS[timer&(NTIMERS1)];//Remindingtime
027
028timersMS[timer&(NTIMERS1)]=timeMS;//ticks(mSeconds)
029returntmp;
030
031}/*SetimerMS()*/
032
033//
034byteTimeout(bytetimer)/*()*/
035{
036if(timersMS[timer&(NTIMERS1)]){
037return0;
038}
039return1;//else...
040
041}/*Timeout()*/
042
043//
044voidWTimer(bytetimer)/*>>>WARNING<<<:BLOCKSCPU*//*()*/
045{
046while(!Timeout(timer)){
047/*EmptyWhile*/
048}
049
050}/*WTimer()*/
051
052//
053voidWaitMS_on(bytetimer,wordtimeMS)/*()*/
054{/*>>>WARNING<<<:BLOCKSCPU*/
055
056SetimerMS(timer,timeMS);
057WTimer(timer);
058
059}/*WaitMS_on()*/
060
061//
062voidWaitISR_on(bytetimer,wordtimeMS)/*()*/
063{//Save/RestoreCCRisNOTpossiblefrom'C'.WeneedtheASSEMBLER
064
065//
066//SAVEACTUALINTERRUPTMASKVALUE
067asm{
068tpa//PushCCRsavesIMaskstatus
069psha//..
070}
071
072//
073//CCode
074CpuIntDsb;//DISABLEINTERRUPTS(IMask=1):Let
237
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
075SetimerMS(timer,timeMS);//..SetimerusedinsideInt.Routines
076CpuIntEn;//REENABLEINTERRUPTS:LetRTCCount
077WTimer(timer);
078
079//
080//RESTORESAVEDINTERRUPTMASKVALUE.
081asm{//PopCCSrestoressavedIMaskstatus
082pula//..>>>URGENT<<<:Seepage183of
083tap//01CPU08RM!ReferenceManual2013U.pdf
084}//THISWAS***EXACTLY***MYEXAMPLEINTHERE!
085//(Stupidguy)
086}/*WaitISR_on()*/
087
088//==================================================================
089interruptVectorNumber_VrtcvoidTIMERS8ISR(void)/*()*/
090{bytei;
091
092for(i=0;i<NTIMERS;i++){
093if(timersMS[i]){
094timersMS[i];
095}
096}
097RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
098//..>>ClearRTCIF<<//IntEnableRTC
099}/*TIMERS8ISR*/
100
101//******************************************************************
102//NOTE:Thefollowingcode***DOESNOTWORK***(Seeabove...);WHY?
103//if(timersMS[i]<0){
104//timersMS[i]=0;
105//}
106
107//WHATis'Sassert'?HOWitworks?TryusingNTIMERS=6
COMENTARIOS a ["Labs-C\Lab2\TimersJ\timersJ.c"]:
HechaelMircoles19Dic2013
Adelantesepresentael"timersJ_.h",peroslosonlosPrototiposdelas6Funciones,
definicinde3parmetrosdelRTC,ylaMacroSassert(e)(StaticAssert.Assertesde
C.SABAUSTED?SINO,TIENEQUEESTUDIARC)
LarepresentacindecadatimeresunWORD,talcomoenASM.Hayunarreglo(vector),
timersMS,compuestoporlacantidadNTIMERS(8enestapresentacin,peroustedpuede
ajustarlaen"timersJ_.h"segnsuspreferencias)
El arreglo es Global para facilitar su visibilidad en los programas que usan esta
librera.Adems,sehadeclarado'volatile'paraevitaroptimizacionesindeseadasen
estasvariables.
010volatilewordtimersMS[NTIMERS];
238
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Laprimerafuncionalidadpermitelainicializacindelabiblioteca,IniTimers.Seusa
comoIniTimers(8)(olapotenciadedosqueusteddefina),paramantenerlaSEMNTICA
delafuncin,peroese#8NOseempleaenlabiblioteca:lavalidacinsehacecontra
laconstanteNTIMERS,definibleporusteden"timersJ_.h"
Como parte de la inicializacin habra que colocar en CERO las variables que
representan los timers; esto NO se hace explcitamente porque, SABA USTED que el
LINKER inicializa en CERO TODAS LAS VARIABLES "GLOBALES" QUE NO TIENEN ASIGNADO UN
VALOREXPLCITO?NO?SABELOQUEESLINKER?NO?TIENEQUEESTUDIARC
013voidIniTimers(bytentimers)/*()*/
AsegresedeentendercmoSassertvalidaenCOMPILETIME(nohaceNADAenRUNTIME)que
elnmerodetimersporusteddefinidoseapotenciadedos.
018Sassert(!(NTIMERS&(NTIMERS1)));
020RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
La funcin retorna la cantidad de MS que an faltaban para que ese timer terminara
(guardadaalcomienzoen'tmp');estopuedeservirdeverificacinpuessinoescero,
seestabortandountimerparavolverloainicializar.
Finalmente,seinicializalavariablecorrespondienteal'timer'conelvalordeseado
enmilisegundos:timeMS,talcomosucontraparteenASM.
025wordSetimerMS(bytetimer,wordtimeMS)/*()*/
026{wordtmp=timersMS[timer&(NTIMERS1)];//Remindingtime
028timersMS[timer&(NTIMERS1)]=timeMS;//ticks(mSeconds)
029returntmp;
Lafuncionalidadqueseusaparaaveriguarsiexpir(llegaCero)ono,algunodelos
timers es Timeout, que recibe como parmetro un 'byte timer' (de 0 a 7 en esta
implementacin)ydevuelvesono,sihuboTimeout(retorna0siNOhaytimeout;1si
sexpiresetimer)
034byteTimeout(bytetimer)/*()*/
036if(timersMS[timer&(NTIMERS1)]){
037return0;
038}
039return1;//else...
239
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Esperarbloqueandoelflujodelprograma,hastaquetermineunciertotemporizador,que
fue PREVIAMENTE inicializado por SetimerMS, es la funcin de WTimer, que recibe como
parmetro el ID del timer (byte timer), y no retorna ningn valor; solo bloquea el
programa.
044voidWTimer(bytetimer)/*>>>WARNING<<<:BLOCKSCPU*//*()*/
046while(!Timeout(timer)){
047/*EmptyWhile*/
048}
Locambiarenalgunaotraoportunidad.
Paraaquellasocasionesquerequieranprogramaruntimeryesperarhastaquetermine,
todoenunasolaoperacin,estWaitMS_on,querecibedosparmetros,comoSetimerMS,
ynoregresaningnvalor,comoWTimer.
053voidWaitMS_on(bytetimer,wordtimeMS)/*()*/
056SetimerMS(timer,timeMS);
057WTimer(timer);
Para realizar una espera estando en INTERRUPT STATE (es decir, ha ocurrido una
interrupcin y se est ejecutando la ISRdel perifrico en cuestin, y sta requiere
hacer una espera, se emplea WaitISR_on, equivalente de WaitMS_on, para ejecutarse en
ISRs). WaitISR_on recibe 2 parmetros, igual que WaitMS_on: byte timer (nmero del
temporizadorquehadeusarse,del0al7)yelnmerodeMilisegundos,wordtimeMS.
062voidWaitISR_on(bytetimer,wordtimeMS)/*()*/
EstafuncinsalvaguardaelCCRenelStack,ycomoelCnopuededirectamenterealizar
estaoperacin,selaimplementavaInlineASM:
ElobjetodeguardarelvalordelCCResparapreservarelInterruptStatedelCPU(I,
Interrupt Mask), pues SetimerMS no se puede ejecutar si las interrupciones estn
activas(CLI),asqueestafuncinlasdeshabilita,ejecutaelSetimerMSy...comoya
explicamos en la seccin de ASM, NO PUEDE SIMPLEMENTE HABILITAR LAS INTERRUPCIONES.
Tiene que dejar el Interrupt State TAL COMO ESTABA ANTES de DESHABILITAR las
interrupciones.Poreso,envezdeCLI,serecuperadesdeelStackelvalorpreviode
I,queestabaenelCCR.
066//SAVEACTUALINTERRUPTMASKVALUE
067asm{
068tpa//PushCCRsavesIMaskstatus
069psha//..
070}
073//CCode
074CpuIntDsb;//DISABLEINTERRUPTS(IMask=1):Let
075SetimerMS(timer,timeMS);//..SetimerusedinsideInt.Routines
076CpuIntEn;//REENABLEINTERRUPTS:LetRTCCount
077WTimer(timer);
240
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
080//RESTORESAVEDINTERRUPTMASKVALUE.
081asm{//PopCCSrestoressavedIMaskstatus
082pula//..>>>URGENT<<<:Seepage183of
083tap//01CPU08RM!ReferenceManual2013U.pdf
084}//THISWAS***EXACTLY***MYEXAMPLEINTHERE!
Desdeluego,seempleanlasinstruccionesTPAyTAPqueelReferenceManualindica
QUENOSIRVENPARANADA!
SABEUSTEDLOQUEESELLOADER?NO?TIENEQUEESTUDIARC
Elcdigoesmuysencillo:incrementarcadatemporizadorQUENOHAYAEXPIRADO(locual
sedeterminaenel'if'porquesuvalorESdiferentedeCERO),yseguirelprotocolode
AcknowledgedeInterrupcionesparaelperifrico:
089interruptVectorNumber_VrtcvoidTIMERS8ISR(void)/*()*/
090{bytei;
092for(i=0;i<NTIMERS;i++){
093if(timersMS[i]){
094timersMS[i];
095}
096}
097RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
098//..>>ClearRTCIF<<//IntEnableRTC
SeasignaRTCSC=RTC_FLAGS,comolarutinadeinicializacin,loqueBorralaInterrupt
Flag,IF,delRTC,rearmando(permitiendootrasposteriores)susinterrupciones.
TambinhubiramospodidoborrarexclusivamenteesebitRTCIF,peroelresultadoesel
mismo.
OBSERVACIN:PorqureescribiendoelIFcomosigue,elcdigoNOTRABAJA?
CdigoORIGINAL:
093if(timersMS[i]){
094timersMS[i];
Cambiadoa:
103//if(timersMS[i]<0){
104//timersMS[i]=0;
105//}
NOSABEPORQUNOTRABAJA?TIENEQUEESTUDIARCURGENTEMENTE!
241
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab2\TimersJ\timersJ_.h"]:
["LabsC\Lab2\TimersJ\timersJ_.h"]
01#ifndefTIMERSJ_H_INCLUDED
02#defineTIMERSJ_H_INCLUDED
03//******************************************************************
04//timersJ_.h,LuisG.UribeC.C11D2013
05//
06#defineNTIMERS8//2'sPower:2,4,8,16...128(max)
07
08//******************************************************************
09//IncludesFiles
10//<<<INCREDIBLE:CW10.3**NEEDS**toREIncludethisfiles**AGAIN**
11
12#include<hidef.h>//ForEnableInterruptsmacro
13#include"derivative.h"//Includeperipheraldeclarations
14
15//
16//FunctionPrototypes
17
18voidIniTimers(bytentimers);//UsedNTIMERS,notntimershere
19wordSetimerMS(bytetimer,wordtimeMS);
20byteTimeout(bytetimer);
21voidWTimer(bytetimer);
22voidWaitMS_on(bytetimer,wordtimeMS);
23voidWaitISR_on(bytetimer,wordtimeMS);
24
25//
26//ParameterDefinitions
27
28#defineRTCPS_BY_ONE8U//Dividedby1,gives1mSTick
29#defineONE_KHZ0//Usesinternal1Khzclock
30
31#defineRTC_FLAGS(RTCSC_RTIF_MASK|ONE_KHZ|RTCSC_RTIE_MASK|\
32RTCPS_BY_ONE)
33//RTCSC_RTCPS0_MASK1U<<<2,ONE_KHZ(bits2,1,0)
34//RTCSC_RTCPS3_MASK8U...
35//RTCPS_BY_ONE8U<<<4,Divideby1;gives1mSTick
36//RTCSC_RTIE_MASK16U<<<3
37//RTCSC_RTIF_MASK128U<<<1
38
39//
40//DefineSassert,incaseyouneedaStaticassert
41#defineSassert(e)do{enum{assert_static__=1/(e)};}while(0)
42
43//
44//SeveralDefines
45#undefWait
46#defineWait(e)while(!(e))
47#undefCpuIntEn
48#defineCpuIntEn__asmCLI
49#undefCpuIntDsb
242
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
50#defineCpuIntDsb__asmSEI
51#undefEOF
52#defineEOF((word)1)
53
54#endif//TIMERSJ_H_INCLUDED
Nohaymuchoquecomentar.Ustedtienequepoderdecirquhaceycmo,elSassert.
Este ejercicio enciende los 8 leds a diferentes TIEMPOS, que han sido definidos
mediante la tabla "const word Delays[]". Una activacin del botn de IRQ detiene el
programa;lasiguienteactivacinhacequeelprogramacontine.Paraexperimentar,se
usTAMBINlalibreradeTimersenlaISRdelIRQ,afindesepararlaspulsaciones
delbotn,almenos1segundo(1000MS)
["LabsC\Lab2\TimersJ\100TimedFlash8.c"]
01//******************************************************************
02//Program100TimedFlash8.c:LuisG.UribeC.D24N2013C11D2013
03//8LEDsflashingatdifferentrates.IRQtoggle'sprogramOFF/ON
04//
05//******************************************************************
06//IncludeFiles
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
09
10#include"timersJ_.h"//Definescli,sti
11
12constwordDelays[]={150,355,511,673,1002,1398,2755,3000};
13//constwordDelays[]={673,150,2755,1398,511,1002,3000,355};
14
15byteToggle=1;//BegininRUNstate(1)
16
17//******************************************************************
18voidmain(void)/*()*/
19{bytei,LEDsMask;
20
21//
22//>>>ALWAYSincludethefollowing2lines
23//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
24
25#defineCOP_Disable0x42
26SOPT1=COP_Disable;//SystemOptions1
27
28//
29//EnableInterruptsforIRQ
30
243
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
31IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
32IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
34//
35//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
36PTCDD=0xFF;//..(theydriveLEDsonDEMOQE128)
37PTEDD=0xFF;
38
39//
40//EnableTimers
41IniTimers(8);
42
43//
44//Start8timers
45for(i=0;i<8;i++){
46SetimerMS(i,Delays[i]>>1);
47}
48
49//===============================================================
50CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!
51
52//
53//Loopforever...IRQtogglesRUN/~STOP
54
55while(1){
56Wait(Toggle);//IRQ:RUN/~STOP
57for(LEDsMask=0,i=0;i<8;i++){
58if(Timeout(i)){
59LEDsMask|=1<<i;
60SetimerMS(i,Delays[i]>>1);
61}
62}
63PTED=(PTCD^=LEDsMask);
64}
65}
66
67//==================================================================
68//IRQINTERRUPTSERVICEROUTINE
69//NOTE:EsnecesariohacerUNACKNOWLEDGEparaquelainterrupcin
70//vuelvaasuceder(InterruptHandshaking,differentforeach
71//peripheral!NeedtoreadManualforeachequipment...:(
72
73interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
74{
75IRQSC_IRQIE=0;//AutodisableIRQInterrupt
76Toggle^=(byte)1;
77WaitISR_on(7,1000);
78
79IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
80//..Interrupt(ReArmIRQInterrupts)
81IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:ReEnable
82//..IRQpinIntEn
83}
244
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab2\TimersJ\100TimedFlash8.c"]
TodocomienzacomoSIEMPRE.
Luego viene la tabla de Delays, acompaada de una Alternativa, para que usted
experimente. Ambas tablas han sido escogidos empleando una funcin random (en Perl)
paranmerosentre150y3000:
12constwordDelays[]={150,355,511,673,1002,1398,2755,3000};
13//constwordDelays[]={673,150,2755,1398,511,1002,3000,355};
LavariableGLOBALToggle,quecomienzaen1(RUNstate),serNEGADA(vaExor)porla
ISRdelIRQ,cadavezqueseoprimaelbotndeIRQ.
15byteToggle=1;//BegininRUNstate(1)
Dosvariableslocales:
18voidmain(void)/*()*/
19{bytei,LEDsMask;
Las2instruccionesqueSIEMPREhayqueincluir:
25#defineCOP_Disable0x42
26SOPT1=COP_Disable;//SystemOptions1
HabilitacindeInterrupcionesparaelIRQ:
31IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
32IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
36PTCDD=0xFF;//..(theydriveLEDsonDEMOQE128)
37PTEDD=0xFF;
InicializamoslosTimers:
41IniTimers(8);
Arrancamosinicialmentetodoslos8timersleyendodelatablaDelays:
45for(i=0;i<8;i++){
46SetimerMS(i,Delays[i]>>1);
47}
HabilitamoslasinterrupcionesdelCPU:
50CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!
245
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
55while(1){
56Wait(Toggle);//IRQ:RUN/~STOP
Sicorrespondeejecutarelcicloinfinito,seinicializalavariableauxiliarLEDsMask
en0,yluegosevanrecorriendotodoslostimers,buscandoaquellosqueyaExpiraron
(Timeout),yselossealaconun1enLEDsMask,enlaposicincorrespondienteasu
ID, de 0 a 7; adems, como ya les expir el tiempo se los vuelve a activar con un
SetimerMS:
57for(LEDsMask=0,i=0;i<8;i++){
58if(Timeout(i)){
59LEDsMask|=1<<i;
60SetimerMS(i,Delays[i]>>1);
61}
62}
Alfinalizarelanlisisdetodoslostimers,secambia(NIEGA)elestadodelosLEDs
correspondientes a aquellos que ya expiraron (usando un Exor: PTCD ^= LEDsMask). El
resultadodeesenuevovalorseloreplicaenPTED:
63PTED=(PTCD^=LEDsMask);
LaIRQINTERRUPTSERVICEROUTINE:
Alcomienzoseautodeshabilitaparainterrupciones,afindequelaspulsacionesdel
botnIRQnotenganrepercusionesmientrasnoseterminelaIRQISR:
73interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
74{
75IRQSC_IRQIE=0;//AutodisableIRQInterrupt
LuegoseinvierteelestadodelavariableToggleempleandounExor:
76Toggle^=(byte)1;
77WaitISR_on(7,1000);
IMPORTANTSIMO:
NOPUEDEUSARSEELMISMOTIMER(7enelejemplo)ENNINGUNAOTRAPARTE.Bastaconque
seandistintosparaquenohayaconflictos
Terminadalaespera,quebloqueacualquierentradadelusuarioduranteunsegundo,se
procede al Protocolo de Acknowledge de interrupciones para este perifrico IRQ en
246
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
particular, que es diferente de los dems y que, como ya dijimos tantas veces, hace
necesarioestudiarcadaperifricoporseparado:
79IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
80//..Interrupt(ReArmIRQInterrupts)
81IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:ReEnable
82//..IRQpinIntEn
["LabsC\Lab2\TimersJ\110TimedFlash8X4.c"]:
01//******************************************************************
02//ProgramTimedFlash8X4.c:LuisG.UribeC.L25N2013C11D2013
03//8LEDsflashingatdifferentrates.IRQstepsthroughDelayTables
04
05//******************************************************************
06//IncludeFiles
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
09
10#include"timersJ_.h"//Definescli,sti
11
12constwordDelays[4][8]=
13{{673,150,2755,1398,511,1002,3000,355},
14{355,511,2755,1398,1002,673,150,3000},
15{1002,3000,1398,511,673,355,2755,150},
16{355,1002,2755,1398,150,511,3000,673},
17};
18byteIndex=0;
19
20//******************************************************************
21voidmain(void)/*()*/
22{bytei,LEDsMask;//BegininRUNstate(1)
23
24//
25//>>>ALWAYSincludethefollowing2lines
26//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
27
28#defineCOP_Disable0x42
29SOPT1=COP_Disable;//SystemOptions1
30
31//
32//EnableInterruptsforIRQ
247
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
34IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
35IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
36
37//
38//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
39PTCDD=0xFF;//..(theydriveLEDsonDEMOQE128)
40PTEDD=0xFF;
41
42//
43//EnableTimers
44IniTimers(8);
45
46//
47//Start8timers
48for(i=0;i<8;i++){
49SetimerMS(i,Delays[Index][i]>>1);
50}
52//===============================================================
53CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!
54
55//
56//Loopforever..PressingIRQstepsthroughDelayTables(Index)
57
58while(1){
59for(LEDsMask=0,i=0;i<8;i++){
60if(Timeout(i)){
61LEDsMask|=1<<i;
62SetimerMS(i,Delays[Index][i]>>1);
63}
64}
65PTED=(PTCD^=LEDsMask);
66}
67}
68
69//==================================================================
70//IRQINTERRUPTSERVICEROUTINE
71//NOTE:ItisneccesarytoACKNOWLEDGEtheInterrupt,inorderto
72//reArmit.'InterruptHandshaking'...isdifferentforeach
73//peripheral!soyouwillneedto...readtheManual&program
74//adifferentroutine...forEACHperipheraldevice.<;~(
75
76interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
77{
78IRQSC_IRQIE=0;//AUTODisableIRQInterrupt
79Index=(Index+1)&0x03;//0,1,2,3,0,1,2..
80WaitISR_on(7,1000);
81
82IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
83//..Interrupt(RearmIRQInterrupts)
84IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:ReEnable
85//..IRQpinIntEn
86}
248
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab2\TimersJ\110TimedFlash8X4.c"]:
Matrizde4vectores,c/ude8valores:
12constwordDelays[4][8]=
13{{673,150,2755,1398,511,1002,3000,355},
14{355,511,2755,1398,1002,673,150,3000},
15{1002,3000,1398,511,673,355,2755,150},
16{355,1002,2755,1398,150,511,3000,673},
17};
ndiceparaseleccionarentrelos4vectores,del0al3:
18byteIndex=0;
21voidmain(void)/*()*/
22{bytei,LEDsMask;//BegininRUNstate(1)
23
LamismahabilitacindeIRQparainterrumpir,ylainicializacindelosLEDs:
32//EnableInterruptsforIRQ
38//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
LainicializacindesiempreparalosTimersyhabilitacindeinterrupcionesdelCPU:
44IniTimers(8);
48for(i=0;i<8;i++){
49SetimerMS(i,Delays[Index][i]>>1);
50}
53CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!
Cicloinfinito,comoenelejercicioanterior,peroahoraelIRQNOdetieneyrearranca
elcdigo,sinoquecambiael'Index'entre0y3:
58while(1){
59for(LEDsMask=0,i=0;i<8;i++){
60if(Timeout(i)){
61LEDsMask|=1<<i;
62SetimerMS(i,Delays[Index][i]>>1);
63}
64}
65PTED=(PTCD^=LEDsMask);
Rutina de interrupciones para el botn de IRQ; todas las lneas de programa son
idnticasalejercicioanterior,exceptoporelcicladodeIndex:
79Index=(Index+1)&0x03;//0,1,2,3,0,1,2..
ENTIENDECMOESQUEINDEXCICLAENTRE0Y3?SINO,TIENEQUEESTUDIARC.
249
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
omoenelcasodelosejerciciosenLenguajeensamblador,laparteculminante
por el momento, de los programas en C, son las rutinas de Comunicaciones
Serialesysuscompaeros,losprocesadoresdeColasdeDatos.Lespresentomi
segunda librera en C, el manejador de Comunicaciones Seriales y, a
continuacin, mi librera para el manejo de Colas de Datos, auxiliar imprescindible
paraelmanejodeComunicacionesconflexibilidad.
Refirasealosejerciciosqueestnenlacarpeta:CarpetasLabsC\ Lab3\SciComm.
["LabsC\Lab3\SciComm\SciComm.h"]
001#ifndefSCICOMM_H_INCLUDED
002#defineSCICOMM_H_INCLUDED
003
004//******************************************************************
005//SciComm.h:SCIComm.Support
006//LuisG.UribeC.,D11M2007L12M07J16A09L08J09
007//..S16J2012(HCS08)D24J2012M26F2013J28N2013
008//S30N2013:Migratedbackto'C'S21D2013cosmetics:XmtRcvActivate
009
010//
011//**REFERto02MC9S08QE128RM(ReferenceManual)U.pdf**
012#undefWait
013#defineWait(e)while(!(e))
014#undefCpuIntEn
015#defineCpuIntEn__asmCLI
016#undefCpuIntDsb
017#defineCpuIntDsb__asmSEI
018#undefEOF
019#defineEOF((word)1)
020
021//==================================================================
022//THEFOLLOWINGMAIN**FUNCTIONALITIES**AREDEFINEDINTHISLIBRARY
023//>>MAIN<<:getchar(),putchar(),RcvIntEn,RcvIntDsb,XmtIntEn,
024//XmtIntDsb,XmtRcvActivate
025//
026//>>ANCILLARY<<:Bauds9600Value,CommIntEn,RcvChar,RcvRdy,
027//XmtChar,XmtRdy
028
029//==================================================================
030//***REDEFINE***MC9S08QE128REGISTERSANDREQUIREDBITS
031//..forSCISerialCommunicationsInterface
032//>>>ALIAS<<<areothernamesforsameaddresses.BECAREFUL!
033
034//******************************************************************
035//SCI1BD:EQU$0020;BaudeRateregister
036//LOOPMODE!!!
250
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
037
038#defineBauds9600Value0x001A//16BITS:4e6/(16*9600)=26.04=0x1A
039
040//
041//SCI1D:EQU$27
042
043#defineXMTBUFSCI1D//TransmiterBuffer
044#defineRCVBUFSCI1D//ReceiverBuffer
045
046//
047//SCI1C2:EQU$23
048
049#defineXMTCTRLREGSCI1C2
050#defineRCVCTRLREGSCI1C2
051
052#defineXMTENSCI1C2_TE_MASK//TE:TransmiterEnabl%00001000
053#defineXMTIENSCI1C2_TIE_MASK//TIE:XmtINTEnabl%10000000
054#defineXMTIEN_bitSCI1C2_TIE//7
055
056#defineRCVENSCI1C2_RE_MASK//RE:ReceiverEnable%00000100
057#defineRCVIENSCI1C2_RIE_MASK//RIE:RcvINTEnable%00100000
058#defineRCVIEN_bitSCI1C2_RIE//5
059
060#defineXmtRcvEnab(XMTEN|RCVEN)//EnableBOTHdevices%00001100
061
062//==================================================================
063//SCI1S1:EQU$24
064
065#defineXMTSTATREGSCI1S1
066#defineRCVSTATREGSCI1S1
067
068//Relevantbits:
069
070#defineXMTRDYSCI1S1_TDRE_MASK//TransmiterDataRegisterEmpty
071#defineXMTRDY_bitSCI1S1_TDRE//7(mSCI1S1_TDRE:%10000000)
072
073#defineRCVRDYSCI1S1_RDRF_MASK//ReceiveDataRegisterFull
074#defineRCVRDY_bitSCI1S1_RDRF//5(mSCI1S1_RDRF:%00100000)
075
076#defineXMTEMPTYSCI1S1_TC_MASK//TransmissionCompleteFlag
077#defineXMTEMPTY_bitSCI1S1_TC//6(mSCI1S1_TC:%01000000):LAST
078
079//
080//Receiver:
081
082#defineOVERRUNERRSCI1S1_OR//OR:Overrun%00001000
083#defineNOISERRSCI1S1_NF//NF:NoiseFlag%00000100
084#defineFRAMERRSCI1S1_FE//FE:FramingError%00000010
085#definePARERRSCI1S1_PF//PE:ParityError%00000001
086
087#defineRCVErrs(OVERRUNERR|NOISERR|FRAMERR|PARERR)
088
251
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
089//******************************************************************
090//MACRODEFINITIONS
091
092#defineSCI9600N8(SCI1BD=Bauds9600Value)//Prog.SCI@9600,8,N
093
094//
095#defineXmtRcvActivate(SCI1C2=XmtRcvEnab);/*ACTIVATEXmt&Rcv*/\
096SCI9600N8/*SerialCommunicationsInterface*/\
097/*..9600bps,Noparity,8bits*/
098
099//==================================================================
100#defineRcvRdyRCVRDY_bit
101
102//
103#defineRcvCharRCVBUF
104
105//
106//getchar()MAYRearmRcvInterruptsifinsideISR
107bytegetchar(){
108Wait(RcvRdy);
109returnRcvChar;
110}
111
112//==================================================================
113#defineXmtRdyXMTRDY_bit
114
115//
116#defineXmtChar(c)(XMTBUF=(byte)(c))
117
118//
119#defineputchar(c)_putchar((byte)(c))
120//putchar(c)MAYrearmXmtinterruptsifinsideISR
121byte_putchar(bytec)
122{
123Wait(XmtRdy);
124XmtChar(c);
125returnc;
126}
127
128//==================================================================
129#defineXmtIntEn(XMTIEN_bit=1)
130//
131#defineXmtIntDsb(XMTIEN_bit=0)
132//
133#defineRcvIntEn(RCVIEN_bit=1)
134//
135#defineRcvIntDsb(RCVIEN_bit=0)
136
137//
138//InterruptEnableforCommunications(Remember:Outputdevicesare
139//..enabled**ONLY**whentheyarereadyfortransmitting
140//ReadingRCVSTATREGandRCVBUF,clearanypossiblyRCVReadyFlag
252
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
141//..pendingatthemomentofinterruptenablingthedevice
142
143#defineCommIntEn{RCVSTATREG;RCVBUF;RcvIntEn;}
144
145//==================================================================
146//AnciliaryStuff
147
148#defineI//NULdefinition.Fromthispointon,'I'meansNOTHING!
149#defineForeverfor(;;){
150#defineEndforever}
151
152#endif//SCICOMM_H_INCLUDED
COMENTARIOS a ["Labs-C\Lab3\SciComm\SciComm.h"]:
001#ifndefSCICOMM_H_INCLUDED
002#defineSCICOMM_H_INCLUDED
LasprimerasdoslneassonmuycomunesentodoslosincludefilesdeC;suobjetivoes
que el cdigo del archivo NO se agregue mltiples veces, aun cuando el programador,
concienteoinconcientemente,lohayaincluidomsdeunavez.Sielsmbolo,eneste
caso:SCICOMM_H_INCLUDED,quenormalmenteseextraedelmismonombredelincludefile,
noexiste,entoncesseloDEFINEyseincluyeeltexto;siYAestdefinido,sesalta
todalainclusindecdigo(hastael#endif//SCICOMM_H_INCLUDEDfinal)
Refirasealmanual:02MC9S08QE128RM(ReferenceManual)U.pdf
Wait,CpuIntEn,CpuIntDsb,yEOFyalosvimosconanterioridad.
LasfuncionalidadesPRINCIPALESdefinidasaquson:
XmtRcvActivate:Energizayactivalosdosperifricos:XMTYRCV
getchar():Leeorecibeunsmbolodelpuertodecomunicaciones
putchar():Envaunsmboloporelpuertodecomunicaciones
RcvIntEn:HabilitalasinterrupcionesdelReceptor
RcvIntDsb:DeshabilitalasinterrupcionesdelReceptor
XmtIntEn:HabilitalasinterrupcionesdelTransmisor
XmtIntDsb:DeshabilitalasinterrupcionesdelTransmisor
Otrasfuncionalidadesauxiliaresson:
Bauds9600Value:ProgramaelpuertoSCIparatrabajara:9600,8N1:9600bps,8bitspor
smbolo,Noparity,1stopbit
035//SCI1BD:EQU$0020;BaudeRateregister
038#defineBauds9600Value0x001A//16BITS:4e6/(16*9600)=26.04=0x1A
253
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
041//SCI1D:EQU$27
043#defineXMTBUFSCI1D//TransmiterBuffer
044#defineRCVBUFSCI1D//ReceiverBuffer
HayunsoloRegistrodeControldeintersenestalibrera:SCI1C2(SCI1,Control2);
de all, algunos bits son para XMT y otros para RCV. Otros fabricantes diferencian
mucho ms abruptamente los dos perifricos, el de transmisin y el de recepcin, e
incluyen DOS registros de Control; por eso yo he incluido DOS nombres, XMTCTRLREG y
RCVCTRLREG,perosonALIASdelnicoregistrofsico:
047//SCI1C2:EQU$23
049#defineXMTCTRLREGSCI1C2
050#defineRCVCTRLREGSCI1C2
LosbitsdeControlquenosinteresan,tantoparaXMTcomoparaRCV,son:
052#defineXMTENSCI1C2_TE_MASK//TE:TransmiterEnabl%00001000
053#defineXMTIENSCI1C2_TIE_MASK//TIE:XmtINTEnabl%10000000
054#defineXMTIEN_bitSCI1C2_TIE//7
055
056#defineRCVENSCI1C2_RE_MASK//RE:ReceiverEnable%00000100
057#defineRCVIENSCI1C2_RIE_MASK//RIE:RcvINTEnable%00100000
058#defineRCVIEN_bitSCI1C2_RIE//5
Hay que recordar que existe la Habilitacin (ENABLE: XMTEN, RCVEN), que equivale a
energizarelperifrico,yqueesdiferentedelIEN:InterruptENable:XMTIEN,RCVIEN.
Nuestra librera siempre Habilita los dos perifricos simultneamente, por lo que
tenemosunsmboloparaeso:XmtRcvEnab
060#defineXmtRcvEnab(XMTEN|RCVEN)//EnableBOTHdevices%00001100
ConloselementosdeStatusocurrelomismoqueconlosdeControl,queseencuentran
reunidostantolosdeXMTcomolosdeRCV,enelregistrodeStatus1:SCI1S1
063//SCI1S1:EQU$24
065#defineXMTSTATREGSCI1S1
066#defineRCVSTATREGSCI1S1
Losbitsquenosinteresanson:
070#defineXMTRDYSCI1S1_TDRE_MASK//TransmiterDataRegisterEmpty
071#defineXMTRDY_bitSCI1S1_TDRE//7(mSCI1S1_TDRE:%10000000)
073#defineRCVRDYSCI1S1_RDRF_MASK//ReceiveDataRegisterFull
074#defineRCVRDY_bitSCI1S1_RDRF//5(mSCI1S1_RDRF:%00100000)
254
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
076#defineXMTEMPTYSCI1S1_TC_MASK//TransmissionCompleteFlag
077#defineXMTEMPTY_bitSCI1S1_TC//6(mSCI1S1_TC:%01000000):LAST
LosERRORES,comovimosalanalizarlasrutinasdeComunicacionesenASM,slopodemos
detectarlosenelRECEPTOR:
082#defineOVERRUNERRSCI1S1_OR//OR:Overrun%00001000
083#defineNOISERRSCI1S1_NF//NF:NoiseFlag%00000100
084#defineFRAMERRSCI1S1_FE//FE:FramingError%00000010
085#definePARERRSCI1S1_PF//PE:ParityError%00000001
087#defineRCVErrs(OVERRUNERR|NOISERR|FRAMERR|PARERR)
LadefinicinesexactamentelamismaqueenASM,pueseselMISMOperifrico:
OVERRUN ocurre cuando el serializador de entrada completa de leer los 10 bits del
smboloquellega,ylecorrespondeahoratrasladarloalBUFFERderecepcin,perose
encuentraconqueelprogramaanNOhaledoelcarcteranterior;asquedetodas
maneras lo almacena en el registro de recepcin, sobrescribiendo la informacin que
allseencontraba,ysealamedianteestabandera,queseestperdiendoinformacin
deentrada,porsobreescrituradelRCVBUF.Elprogramadortienequetomarnotadeesto,
probablemente solicitando la retransmisin de la informacin al otro extremo de la
lnea. Normalmente hay que calibrar la cantidad de informacin y la velocidad de
entrada, para evitar que esto suceda. Manejar la entrada por interrupciones, y hacer
usodeFIFOsoCOLASeslomsindicado.
NOISERRocurrecuandolalneatieneruido,quesereflejaporvariacionesenlaseal
queseestleyendo,yqueocurrenentreelcomienzoyelfinaldelosbits.Sesupone
quelalneanocambiadevaloreneseintervalo.
FRAMERRsepresentacuando,habiendoelreceptordetectadounbitdeSTART,alllegara
laposicinendondedeberaestarelbitdeSTOP,NOhayun1.Estopuedesignificar
que el receptor se est descincronizando, y que a lo mejor el bit que detect como
Startnoloera.
PARERRocurrecuando,estandohabilitadoelclculodeparidad,seencuentraqueenla
recepcin sta no coincide con el valor que tendra que haber. Nosotros NO estamos
usandoParidadennuestrabibliotecadeComunicacionesSeriales.
090//MACRODEFINITIONS
092#defineSCI9600N8(SCI1BD=Bauds9600Value)//Prog.SCI@9600,8,N
095#defineXmtRcvActivate(SCI1C2=XmtRcvEnab);/*ACTIVATEXmt&Rcv*/\
096SCI9600N8/*SerialCommunicationsInterface*/\
097/*..9600bps,Noparity,8bits*/
Mirebien,paraentenderlaMacro,losCONTINUADORESdelnea:"\"
Sialgoallnoentiende,TIENEQUEESTUDIARC
255
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
100#defineRcvRdyRCVRDY_bit
103#defineRcvCharRCVBUF
getchar() es una funcin BLOQUEANTE, que suspende el flujo del programa hasta que se
hayarecibidoundato,loquesereflejaalencenderelbitde'RcvRdy'.Devuelveel
valorrecibido:RcvChar(quetienedosalias:RCVBUF,queasuvezesaliasdeSCI1D)
Lasecuenciade:leerelbitRcvRdyyacontinuacinleerelRCVBUF(vaRcvChar),es
tambin la necesaria para el protocolo de Acknowledge de interrupciones del RCV; por
esoseusa'getchar'tambinDENTROdelaISRdeRecepcin.
106//getchar()MAYRearmRcvInterruptsifinsideISR
107bytegetchar(){
108Wait(RcvRdy);
109returnRcvChar;
110}
En una prxima revisin, cambiar RcvChar por RcvChar(), para mimetizar mejor el
comportamientodeunafuncinyasemejarlamsaXmtChar().Suusocambiaras:
109returnRcvChar();
113#defineXmtRdyXMTRDY_bit
116#defineXmtChar(c)(XMTBUF=(byte)(c))
putchar()tambinesunafuncinBLOQUEANTE,quesuspendeelflujodelprogramahasta
queelTransmisorestlistoparaenviarundato,loquesereflejaalencenderelbit
de'XmtRdy'.
119#defineputchar(c)_putchar((byte)(c))
EstadefinicinobligamedianteunCASTaqueelsmboloquesetransmiteseaunBYTE,
aunqueelusuariohayaempleadounWORD.
SABELOQUEESUNCAST?SUUSOEIMPORTANCIA?NO?TIENEQUEESTUDIARC.
121byte_putchar(bytec)
122{
123Wait(XmtRdy);
124XmtChar(c);
125returnc;
126}
Smbolosimportantes:
129#defineXmtIntEn(XMTIEN_bit=1)
131#defineXmtIntDsb(XMTIEN_bit=0)
133#defineRcvIntEn(RCVIEN_bit=1)
135#defineRcvIntDsb(RCVIEN_bit=0)
143#defineCommIntEn{RCVSTATREG;RCVBUF;RcvIntEn;}
256
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ElCommIntEn,ohabilitacindeinterrupcionesparaComunicaciones,hacelomismoque
mencionamosenelprogramaenASM:slohabilitalasinterrupcionesdeRCV;lasdeXMT
debe habilitarse caso a caso por el programador, cuando haya algo que enviar por
interrupciones.
Lafuncionalidad,queusteddebeCORROBORARconelReferenceManual,consisteenleer
elRCVSTATREG;luegoleerelRCVBUF;yporltimohabilitarlasInterrupcionesdeRCV,
mediante:RcvIntEn.
Cdigoauxiliar:
148#defineI//NULdefinition.Fromthispointon,'I'meansNOTHING!
149#defineForeverfor(;;){
150#defineEndforever}
152#endif//SCICOMM_H_INCLUDED
Paraqupuedeutilizarseel'#defineI'quehacequelaletraInovalgaNADA?
257
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab3\SciComm\1tstXmt.c"]:
El comienzo es ya conocido. Se definen luego dos smbolos, ambos definidos por el
estndar ASCII (American Standard Code for Information Interchange) el CR, que es el
smbolo que hace que el cursor se vaya a la izquierda (Carriage Return, cuando se
tratabademquinasdeescribir,oTeletipos),yelNL(NewLine,quesaltaalalnea
siguiente)
14#defineCR0x0D
15#defineLF0x0A
18voidmain(void)/*()*/
19{byteLetter;
Luegodelapartemsconvencional,vienelainicializacindelSCI:
28SCI9600N8;//SetupSerialCommunicationsInter
29XmtRcvActivate;//..face:9600bps,Noparity,8bits
YQUPASCONELCLI?EstaaplicacinNOusainterrupciones.
Elcicloinfinitoparaesteprogramageneralasletrasdesdela'A'hastala'z'ylas
transmite con putchar( Letter ); al finalizar cada secuencia agrega un Retorno de
Cursor,CR('\r'enC)yunSaltodeLnea,LF('\n'enC),yrecomienzaconlasletras
enlasiguientelnea,parasiempre:
32while(1){
33for(Letter='A';Letter<='z';Letter++){
34putchar(Letter);
35}
36putchar(CR);//CarriageReturn(CR:'\r'inC)
37putchar(LF);//LineFeed(LF:'\n')
38}
39}
57) SEND STEP BY STEP (IRQ) 'A' TO 'Z' LETTERS TO PC & SHOW IN LEDS
["LabsC\Lab3\SciComm\1tstXmtLeds.c"]
01//******************************************************************
02//Programa1TstXmtLeds.C:TestSCIComm.Support
03//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04//C11D2013(C)
05//
06//..Send'A'to'z'lettersforevertoHyperterminal.LEDsdisplay
07//..StepbystepusingIRQ
08//******************************************************************
09//IncludeFiles
10#include<hidef.h>/*forEnableInterruptsmacro*/
11#include"derivative.h"/*includeperipheraldeclarations*/
12
13#include"SciComm.h"//SCIComm.Support
14
258
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
15//
16//GlobalVariables
17
18volatilebyteGlobalVar;
19
20//******************************************************************
21voidmain(void)
22{byteLetter;
23
24//
25//>>>ALWAYSincludethefollowing2lines
26//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
27#defineCOP_Disable0x42
28SOPT1=COP_Disable;//SystemOptions1
29
30//
31//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
32//InDEMOQUE128,DO***NOT***USEPTC5'sASSOCIATEDLED,asitis
33//..alsothepinusedtoDISABLECOMM1!!!viaJumperJ8,THANKS!
34//
35//NOTE1:ForOutputPins/Ports,FirstloadaSAFEvalue(youwill
36//..decideit),then,programthemforOutputs.Thisway,itwill
37//..NOTappearFALSEoutput,values/glitches.
38//
39//NOTE2:Supposeyourprogramhas,forexample,twooutputsthat
40//..willcontroltheaccessfor2devicestoacommonbus.The
41//..logicis:00:Noperipheralhasaccess.01:Ahasaccess.
42//..10:Bhasaccess.11:Neverhappens!Ifitwill,peripherals
43//..willburnout.
44//Now,atPowerUp,ALLdigitalpinsdefaulttoINPUTS.Without
45//..Pullupresistors:TheyFLOAT!!Forhowlong?Italldepends
46//..onoscilatorsetup,andthetimeyouexpendbeforeprogram
47//..mingthepinsforoutput.Itmeans:maybeBOTHA&Bdevices
48//..willreachthebus...andBURN!Shortcircuittheiroutputs!!
49//Sleeponthis,andcomeupwithasolution...
50
51PTCD=0xFF;
52PTED=0xFF;
53PTCDD=0x1F;//..(theydriveLEDsonDEMOQE128)
54PTEDD=0xC0;
55
56//
57//EnableIRQpin
58IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
59IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
60
61//
62SCI9600N8;//SetupSerialCommunicationsInter
63XmtRcvActivate;//..face:9600bps,Noparity,8bits
64
65CpuIntEn;
66
259
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
67//
68while(1){
69for(Letter='A';Letter<='z';Letter++){
70putchar(Letter);
71Wait(GlobalVar);
72GlobalVar=0;
73PTCD=~Letter;
74PTED=~Letter;
75}
76putchar('\r');//CarriageReturn(CR)
77putchar('\n');//LineFeed(LF)
78}
79}
80
81//==================================================================
82interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
83{
84GlobalVar=1;
85IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
86//..(RearmIRQInterrupts)
87}
COMENTARIOS a ["Labs-C\Lab3\SciComm\1tstXmt-Leds.c"]:
Laparteinicialeslaconvencional.Leanotravez(yahabamosdicholomismocuando
hicimos los ejercicios en ASM) y con detenimiento los requisitos para programar los
terminalesdigitalescomoSALIDAS:
31//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
32//InDEMOQUE128,DO***NOT***USEPTC5'sASSOCIATEDLED,asitis
33//..alsothepinusedtoDISABLECOMM1!!!viaJumperJ8,THANKS!
34//
35//NOTE1:ForOutputPins/Ports,FirstloadaSAFEvalue(youwill
36//..decideit),then,programthemforOutputs.Thisway,itwill
37//..NOTappearFALSEoutput,values/glitches.
38//
39//NOTE2:Supposeyourprogramhas,forexample,twooutputsthat
40//..willcontroltheaccessfor2devicestoacommonbus.The
41//..logicis:00:Noperipheralhasaccess.01:Ahasaccess.
42//..10:Bhasaccess.11:Neverhappens!Ifitwill,peripherals
43//..willburnout.
44//Now,atPowerUp,ALLdigitalpinsdefaulttoINPUTS.Without
45//..Pullupresistors:TheyFLOAT!!Forhowlong?Italldepends
46//..onoscilatorsetup,andthetimeyouexpendbeforeprogram
47//..mingthepinsforoutput.ITMEANS:maybeBOTHA&Bdevices
48//..willreachthebus...andBURN!Shortcircuittheiroutputs!!
49//Sleeponthis,ANDCOMEUPWITHASOLUTION...
Se determina que queremos que al iniciar las salidas, todas tengan unos en sus
terminales:
51PTCD=0xFF;
52PTED=0xFF;
260
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
LuegoseprogramaloscorrespondientesbitsenlosDirectionRegisters,5vanelPTCy
2enPTE(total7LEDs).
SeexcluyeelterminalPTC5,quequedacomoENTRADA,porquecomoyadijimosarriba,en
el DEMOQUE128 el PTC5, si est como salida (para manejar el LED asociado), tambin
INHABILITARelpuertodeComunicacionesSeriales,vaelJumperJ8.GRACIASPEMicro!
53PTCDD=0x1F;//..(theydriveLEDsonDEMOQE128)
54PTEDD=0xC0;
LahabilitacindelIRQysuautorizacinparaInterrumpir,eslaconvencional:
58IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
59IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
Despusseinicializa,comodecostumbre,elpuertodecomunicacionesSCI,seActivan
losdosperifricos,elderecepcinyeldetransmisin,yAQUS,sehabilitanlas
interrupcionesdelCPU:
62SCI9600N8;//SetupSerialCommunicationsInter
63XmtRcvActivate;//..face:9600bps,Noparity,8bits
65CpuIntEn;
El ciclo indefinido es tan sencillo como el del anterior ejercicio, pero despus de
transmitircada letra, incluye una espera a que 'GlobalVar' valga uno (por qu est
inicializadaenCERO?Siannolosabe,DESISTA)
CuandolaIRQISRcolocaen1aGlobalVar,elprogramacontina,reponiendoacerola
variable,paraelprximoturno,ypresentandolaletraporlosLEDs.Semueve~Letter
(NEGADA booleanamente) porque, como ya sabemos, los genios de PE Micro encienden los
LEDsconCEROS:
68while(1){
69for(Letter='A';Letter<='z';Letter++){
70putchar(Letter);
71Wait(GlobalVar);
72GlobalVar=0;
73PTCD=~Letter;
74PTED=~Letter;
75}
76putchar('\r');//CarriageReturn(CR)
77putchar('\n');//LineFeed(LF)
78}
79}
LarutinaIRQISReslaconvencional,msGlobalVar=1;
82interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
83{
84GlobalVar=1;
85IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
86//..(RearmIRQInterrupts)
87}
261
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
58) ECHO
HaceECHOaloscaracteresquelelleganalequipodesdeotraestacin.
Recuerdeprobarloenvindole"HAL"(lasupercomputadorade"2001OdiseadelEspacio"):
apareceenlapantalla...IBM.
["LabsC\Lab3\SciComm\2echo1.c"]
01//******************************************************************
02//Program2Echo1.c:TestSCIComm.Support
03//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04//C11DN2013(C)
05//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)L25N2013
06//Tobesurethatthereis"ECHO",returnback'letter+1',
07//..i.e:ifHyperterminalsends'A',HC9S08willreturn'B'...
08//..fortherange:'A'<=char<'z'.
09//Anyothercharsarereturnedbackwithoutmodification.
10//******************************************************************
11//IncludeFiles
12#include<hidef.h>//forEnableInterruptsmacro
13#include"derivative.h"//includeperipheraldeclarations
14#include"SciComm.h"//SCIComm.Support
15//******************************************************************
16voidmain(void)
17{byteLetter;
18//
19//>>>ALWAYSincludethefollowing2lines
20//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
21#defineCOP_Disable0x42
22SOPT1=COP_Disable;//SystemOptions1
23//
24SCI9600N8;//SetupSerialCommunicationsInter
25XmtRcvActivate;//..face:9600bps,Noparity,8bits
26//Prompt:
27for(Letter='A';Letter<='z';Letter++){
28putchar(Letter);
29}
30putchar('\r');//CarriageReturn(CR)
31putchar('\n');//LineFeed(LF)
32//************NOTE:************
33//ToSIMULATESCI*inputs*usePEMicroSCI1debuggercommand.
34//
262
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
35//ItwillbeinstructivetodisplaySCI1S1(statusregister),and
36//..seemostimportantflags,bits7,6,5:XMTRDY,XMTEMPTY,RCVRDY.
37//Whiledebugging,seehowreadingStatusANDwritingBUF,clears
38//..theRCVReadyflag.SeealsohowXMTStatuswork:RDY&EMPTY
39while(1){//OnlycharsinrangeA..zwillbe
40if((Letter=getchar())>='A'&&Letter<='z'){
41Letter++;//..returnedasNEXTchar:Letter++
42}
43putchar(Letter);//..Thosenotinrangewillecho
44}//Endwhile(1)//..WITHOUTanymodification:Letter
45}
COMENTARIOS a ["Labs-C\Lab3\SciComm\2echo1.c"]:
Esteprogramatampocoemplealasinterrupciones:estodoentradaysalidaprogramada;
poresonoapareceunCpuIntEn.
26//Prompt:
27for(Letter='A';Letter<='z';Letter++){
28putchar(Letter);
29}
30putchar('\r');//CarriageReturn(CR)
31putchar('\n');//LineFeed(LF)
39while(1){//OnlycharsinrangeA..zwillbe
40if((Letter=getchar())>='A'&&Letter<='z'){
41Letter++;//..returnedasNEXTchar:Letter++
42}
43putchar(Letter);//..Thosenotinrangewillecho
44}//Endwhile(1)//..WITHOUTanymodification:Letter
263
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations
10#include"SciComm.h"//SCIComm.Support
11//==================================================================
12//GLOBALVARIABLES
13byteXmtNchars;//SoftFlagforMain:0NothingtoXmt
14byte*XmtPtr;//charpointerofnextdatatoXmt
15byteMessage[]="12345\n\r";//Shortmessage
16//byteMessage[]="Esteeselmensajedeprueba,"
17//"primeroentransmitirsealPCporinterrupciones\n\r"
18//******************************************************************
19voidmain(void)
20{byteLetter;
21//
22//>>>ALWAYSincludethefollowing2lines
23//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
24#defineCOP_Disable0x42
25SOPT1=COP_Disable;//SystemOptions1
26//
27SCI9600N8;//SetupSerialCommunicationsInter
28XmtRcvActivate;//..face:9600bps,Noparity,8bits
29//==================================================================
30//Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
31//Prompt:
32XmtPtr=Message;//InitXmtPtrwith'Message'address;
33XmtNchars=sizeof(Message);
34XmtIntEn;//XmtISRwillsendthemessageand
35//..clear'XmtNchars'whenfinished
36CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs
37//
38//XmtLoop:
39Wait(XmtNchars==0);//WaituntildoneORjustWaitForEver
40Wait(0);//..WaitForEver
41}
42//==================================================================
43interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
44{
45if(XmtNchars){//Seeifdone;ifnot:
46putchar(*XmtPtr++);//(NOTE:putcharclearsXMTRDY.bit)
47XmtNchars;//Adjustcharcounter
48}else{//IfXmtDone:
49XmtIntDsb;//..
50}
51}
264
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab3\SciComm\3echoInt-1.c"]:
VariablesGlobales,paraservisiblestantoenelprogramaprincipal:
XmtNchars,quemantieneelnmeroactualdecaracteresquefaltanportransmitirse;es
de tipo byte, por lo cual no pueden manejarse mensajes de ms de 255 letras; 0
significavaco.
*XmtPtr apuntador a caracteres, seala el siguiente dato que ser transmitido. byte
*XmtPtr
13byteXmtNchars;//SoftFlagforMain:0NothingtoXmt
14byte*XmtPtr;//charpointerofnextdatatoXmt
Siendoquelosapuntadorestienen16bits,porqunosehizoladefinicincomo:word
*XmtPtr
SIDUDATIENEQUEESTUDIARMUCHSIMOC(SINDUDA)
Luegovieneelmensajequesequieretransmitir;elsegundo,comentado,esunpocoms
largo,paraensayar:
15byteMessage[]="12345\n\r";//Shortmessage
16//byteMessage[]="Esteeselmensajedeprueba,"
17//"primeroentransmitirsealPCporinterrupciones\n\r"
27SCI9600N8;//SetupSerialCommunicationsInter
28XmtRcvActivate;//..face:9600bps,Noparity,8bits
32XmtPtr=Message;//InitXmtPtrwith'Message'address;
33XmtNchars=sizeof(Message);
34XmtIntEn;//XmtISRwillsendthemessageand
35//..clear'XmtNchars'whenfinished
yNOOLVIDARhabilitarlasinterrupcionesGlobales,delCPU:
36CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs
Elciclodetransmisinesmuysimple:elprogramaespera(Wait)hastaqueelnmerode
caracteresseacero,loqueleindicalafinalizacindelatransmisindelmensaje,y
contina;comoesteejerciciollegahastaall,hacemosunasimulacindeunHALT:
38//XmtLoop:
39Wait(XmtNchars==0);//WaituntildoneORjustWaitForEver
40Wait(0);//..WaitForEver
265
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
43interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
Si an hay caracteres para transmitir, los enva con putchar (que realiza el ACK),
incrementaelapuntadordecaracteres,decrementaelnmerodesmbolosquefaltanpor
transmitirse,yRTI(AUNQUEXmtNcharshayaproducidoCERO)
45if(XmtNchars){//Seeifdone;ifnot:
46putchar(*XmtPtr++);//(NOTE:putcharclearsXMTRDY.bit)
47XmtNchars;//Adjustcharcounter
Sialmomentodeinterrumpirparatransmitir,seencuentraqueXmtNcharsvalecero,se
AUTOdeshabilitanlasinterrupcionesdetransmisinyseretornaconRTI:
48}else{//IfXmtDone:
49XmtIntDsb;//..
50}
51}
Estemecanismoenelcualel'Cliente'(main)haceunapeticinalarutinadeServicio
(XmtISR),activndolelasInterrupciones,ydondelaISRseAUTODESACTIVAalterminar
lo que le solicitaron, ES LA FORMA en que usted debe trabajar: MECANISMO Cliente
Servidor.
Ocurrequeconfrecuencia,porhacerundiseonomuypulcro,aparecenvariosClientes
(o lugares en su cdigo en donde se habilitan las interrupciones), O SE MEZCLAN
putcharsdesdeMAINylaISR:ESORARAVEZFUNCIONA.YelprogramadorNOVAASABER
PORQU!
NOLOHAGA
UnaaproximacinparecidacambiaelContadordeSmbolosporunTERMINADOR,queesun
smboloespecialqueindicaelfinaldelmensaje.EnC,los"strings"sedefinenas,y
el terminador es un byte NULO, con todos sus bits en CERO. Un nombre, anterior a la
existencia del lenguaje C, que designa esto mismo, es el de un texto de tipo ASCIZ
(cdigoASCIIterminadoenZERO)
Esteejemploessimilaralanterior,peromuestraelmanejodemensajesdeltipoASCIZ:
["LabsC\Lab3\SciComm\3EchoInt2Z.c"]
01//******************************************************************
02//Program3EchoInt2Z.c:TestSCIComm.Support
03//LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)D24J2012
04//M10D2013(C)
05//..Similarto2Echoint1.C,butusesASCIZ
266
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//ForEnableInterruptsmacro
09#include"derivative.h"//Includeperipheraldeclarations
10#include"SciComm.h"//SCIComm.Support
11//==================================================================
12//GLOBALVARIABLES
13byte*XmtPtr;//charpointerofnextdatatoXmt
14byte*Message="12345\n\r";//Shortmessage
15//byte*Message="Esteeselmensajedeprueba,"
16//"primeroentransmitirsealPCporinterrupciones\n\r"
17//******************************************************************
18voidmain(void)/*()*/
19{
20//
21//>>>ALWAYSincludethefollowing2lines
22//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
23#defineCOP_Disable0x42
24SOPT1=COP_Disable;//SystemOptions1
25//
26SCI9600N8;//SetupSerialCommunicationsInter
27XmtRcvActivate;//..face:9600bps,Noparity,8bits
28//==================================================================
29//Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
30//Prompt:
31XmtPtr=Message;//InitXmtPtrwith'Message'address;
32XmtIntEn;//XmtISRwillsendthemessageand
33//..autodesable
34CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs
35//
36//XmtLoop:
37Wait(0);//..WaitForEver
38}
39//==================================================================
40interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
41{//NOTE:putcharclearsXMTRDY.bit.Veryclever...
42if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
43XmtIntDsb;
44}
45}
267
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab3\SciComm\3EchoInt-2Z.c"]:
ElMessagees"12345\n\r",ycomoesunStringdeC(porlascomillas),aunquenolo
vemos sabemos que est terminado por un ltimo smbolo, el '\0' o NUL byte. La
diferenciaconladefinicinanterioressutil,perofundamental.
14byte*Message="12345\n\r";//Shortmessage
31XmtPtr=Message;//InitXmtPtrwith'Message'address;
32XmtIntEn;//XmtISRwillsendthemessageand
33//..autodesable
34CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs
37Wait(0);//..WaitForEver
La rutina XmtISR es BIEN SIMPLE: Cada vez que hay una interrupcin, TRANSMITE la
prximaletraysistacoincideconelNULchar,seautodeshabilitaparainterrumpir:
40interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
41{//NOTE:putcharclearsXMTRDY.bit.Veryclever...
42if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
43XmtIntDsb;
44}
45}
Ahora, USTED TIENE QUE SABER C PARA ENTENDER ESTE CDIGO. Hasta las COMAS son
FUNDAMENTALESenelsiguientetexto:
["LabsC\Lab3\SciComm\Que.h"]
01#ifndefQUE_H_INCLUDED
02#defineQUE_H_INCLUDED
03//******************************************************************
04//QUE.HLuisG.UribeC,V20J2014:.gt.pt
05//18S1990D04S2011V29N21013
06//
07//SeveralDefinies
08
09#undefWait
10#defineWait(e)while(!(e))
11#undefCpuIntEn
12#defineCpuIntEn__asmCLI
13#undefCpuIntDsb
14#defineCpuIntDsb__asmSEI
15#undefEOF
16#defineEOF((word)1)
268
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
18//REMEMBER!!!:'byte'isUNSIGNEDchar;'word'isUNSIGNEDint
20/**/
21typedefstruct{
22byte*put;/*n(5)*/
23byte*get;/*(2)buf>++*/
24wordn;/*|(1)|>(4)get*/
25wordgt;/*(3)put>|s|*/
26wordpt;/*|i|*/
27byte*base;/*|z|*/
28byte*limit;/*|e|*/
29wordsize;/*++*/
30}QUE;
31
32/*Ejemplo:Sea'size'(1)de'buf'(2)iguala5.*
33*Lospointers'put'(3)y'get'(4)puedentenerlosvalores*
34*buf,buf+1,buf+2,buf+3,buf+4;*
35*esdecir,lospointersdebenpermanecerenelrango*
36*buf<=pointer<(buf+size),o,loqueeslomismo*
37*buf<=pointer<limit*
38**
39*'n'(5)puedevaler:*
40*0(vaco),1,2,3,4y5(lleno).Noteque'n'ES*
41*el>>>SEMAFORO<<<,eimponelassiguientesreglasdetrfico:*
42**
43*NO'deQue'cuandonsea<=0*
44*NO'enQue'cuandonsea>=size*
45**
46*Lassiguientesoperacionesestndefinidas:*
47*/
49#definedefineQue(in,n)byte_Q##in[n];QUEin
50
51#defineinitQue(in)in.base=in.put=in.get=_Q##in;\
52in.n=0;in.size=sizeof(_Q##in);\
53in.limit=in.base+in.size
54
55#defineenQue(in,c)(in.n>=in.size?EOF:\
56(in.pt=c,*in.put++=(byte)c,\
57in.put=in.put>=in.limit?\
58in.base:in.put,\
59in.n++,in.pt\
60)\
61)
62
63#definedeQue(in)(in.n<=0?EOF:\
64(in.gt=*in.get++,\
65in.get=in.get>=in.limit?\
66in.base:in.get,\
67in.n,in.gt\
68)\
69)
70
71#endif//QUE_H_INCLUDED
269
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab3\SciComm\Que.h"]:
Las primeras definiciones estn duplicadas en varios otros sitios pero NO arrojan
erroresporqueestntodasantecedidaspor#UNDEFs.
EnprimerlugarlaEstructuraquetienenmisQUEs,plasmadaenun'typedef':QUE.Enel
esquemaseindicanloselementosquelacomponen,ordenadosdel1al5.
Unacolatiene:
1. Untamaofsico,'size'
2. Unadireccindecomienzo,'buf'
3. Un apuntador al sitio EN el que almacenar (enQue) el prximo smbolo, 'put'; se
inicializaen'buf'.
4. UnapuntadoralsitioDESDEelqueextraer(deQue)lasiguienteletra,'get';se
inicializaen'buf'.
5. Y'n',MUYIMPORTANTE:indicacuntoscaractereshayenlacolaenunmomentodado.
EsteeselSEMFOROquerigeyordenalastransacciones;as:
'n'puedevaler0(vaco),1,2,...'size'(lleno)Lasreglassonlassiguientes:
NO'deQue'cuandonsea<=0NO'enQue'cuandonsea>=size
HaydosvariablestemporalesdetipoWord:'gt'y'pt';luegoveremossuuso,yporqu
sonWORDenvezdeBYTE.UnapuntadoralFINALdelatabla,'limit',noesencialpero
parafacilitarelcdigo,yunaposicinqueindicaeltamaodelacola(aqulahemos
definidocomoWORD,quepermitecolashastade64K,loqueesmucho...)
20/**/
21typedefstruct{
22byte*put;/*n(5)*/
23byte*get;/*(2)buf>++*/
24wordn;/*|(1)|>(4)get*/
25wordgt;/*(3)put>|s|*/
26wordpt;/*|i|*/
27byte*base;/*|z|*/
28byte*limit;/*|e|*/
29wordsize;/*++*/
30}QUE;
Lassiguientesoperacionesestndefinidas,igualqueensucontraparteenASM:
defineQue,initQue,enQueydeQue:
49#definedefineQue(in,n)byte_Q##in[n];QUEin
Primerosedefineunarreglo(vector);byte_Q##in[n];
Aquenovieronalgoas...ESTUDIENC.##eseloperadorcatenate:unedossmbolos.
270
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Elnombredelvectores:_Qseguido(CONCATENADO:##)conelnombrequeelusuariole
da a su cola, representada por el parmetro 'in', y ocupando un espacio en BYTES de
'n',parmetroquereemplazaaltamaoqueelusuariodeseadarlealaCola.
Acontinuacin,separadaporunpuntoycomadelaanterior,paraquequedeenlamisma
lnea(habanvistovariasinstruccionesdeC,enlamismalnea?)viene:QUEin,que
defineunavariableconelnombrequeelusuarioquiere,simbolizadoenlaMacroporel
parmetro'in',ydetypeQUE,segnladefinicin'typedef'anterior.
Ejemplo:Sielusuarioquieredefinirunacolallamada'ColaRead',de
'16'bytes,loexpresardelasiguienteforma:
defineQue(colaRead,16)
Elresultadoser,unarreglo:
byte_QcolaRead[16];
yunaestructurallamada'colaRead',detipoQUE.
MireelNOMBREdelarreglo:elsmbolo'_Q'concatenadoconelnombrequeseleest
dandoalacola:'colaRead'.
IMPORTANTE:
'defineQue'*TIENE*QUEEMPLEARSECOMOVARIABLE'GLOBAL',FUERADECUALQUIER{}:Fuera
demain(),ydecualquierfuncin.ComoenASM.
Despusdedefinirlacola,hayqueinicializarla.EstossehaceDENTRODEMAIN.Para
lacola'colaRead',lainvocacines:
initQue(colaRead);
51#defineinitQue(in)in.base=in.put=in.get=_Q##in;\
52in.n=0;in.size=sizeof(_Q##in);\
53in.limit=in.base+in.size
ImaginoquesabenCMOcontinuarelcdigodeunaMacroenvariaslneas:paraesose
empleael'\'.NotequelaLTIMAnololleva...
Talcomosedijoantes,seinicializanlosapuntadoresbase,putygetdelacolaen
consideracin(enelejemplo:colaRead.base,colaRead.putycolaRead.get).Elvalorque
toma es el del comienzo de VECTOR que ya se DEFINI: _Q##in, que en el ejemplo
correspondea:_QcolaRead.
Sinosabecmoseusa'sizeof',ustedNOSABE"C"yTIENEQUEESTUDIARC,URGENTE.
271
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
53in.limit=in.base+in.size
Esdecir:colaRead.limit=colaRead.base+colaRead.size
Laoperacinpara'encolar'unbyte...tomenALIENTO.MenosmalqueYOhagolalibrera
yusted,fundamentalmente,LAUSA(aunquesinolaENTIENDE,andabastanteMAL)
55#defineenQue(in,c)(in.n>=in.size?EOF:\
56(in.pt=c,*in.put++=(byte)c,\
57in.put=in.put>=in.limit?\
58in.base:in.put,\
59in.n++,in.pt\
60)\
61)
Primero,porqutienetantosparntesis?RecuerdenqueelusodeestaMacroes:
c=enQue(colaWrite,letra);
Entonces,QUESLOQUEDEVUELVELAMACRO?Normalmentedevuelve'c',elMISMOparmetro
queselepasparaencolar('letra'enelejemplo),pero,silacolaestLLENA,ypor
tantonosepuedeejecutarlafuncindeEncolar,sedevuelveelsmboloEOF(espero
quessepanloqueesEOF).Asqueelvalordeesaexpresin,es'c',sihayespacio
enlacola,oEOF,silacolaestllena.Cmoocurreeso?
VoyareescribirlaMacroparamejorarsulegilibilidad,alineandolosparntesisque
abren,conlosquecierran,yvoyaELIMINARloscontinuadores'\'delaMacro:
(in.n>=in.size?EOF:
(in.pt=c,*in.put++=(byte)c,
in.put=in.put>=in.limit?
in.base:in.put,
in.n++,in.pt
)
)
Ahora voy a dejar slo lo que tiene que ver con devolver 'c' o EOF. ELIMINO
temporalmente 4 lneas Internas de la Macro), y lo coloco en una lnea: ( in.n >=
in.size?EOF:(eliminado),in.n++,in.pt)
Primero,eloperadorTERNARIO:expC?expT:expF
SINOSABEQUESELOPERADORTERNARIO,USTEDNOSABEC.ESTUDIE!!!
'expC'esCUALQUIERexpresin;implicaasignaciones,Comparaciones,funciones...El'?'
PREGUNTAsi'expC'esVerdaderaoFalsa.Siesverdadera,eloperadorternarioasumeel
valor 'expT', si es falsa el valor es 'expF', siendo expT y expF, a su vez,
expresiones.Parasepararlasestelsmbolo':'Ennuestrocaso:
expC:in.n>=in.size
expT:EOF
expF:(eliminado),in.n++,in.pt
272
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
Esdecir,sielnmerodecaracteresalmacenadosenlacola,esMAYOROIGUALaltamao
DEFINIDO,sedevuelveEOF.Hastaah,ok.
Pero,qudevuelve'expF'?Ques"in.n++,in.pt"?
EselCOMMAOPERATOR.NOSABEQUEES?TIENEQUEESTUDIARMUCHSIMOC.
El Comma Operator evala, de IZQUIERDA a DERECHA, todas las expresiones que estn
separadas por COMAS... Y RETORNA UN VALOR: EL DE LA *LTIMA* EXPRESIN, LA DE LA
*DERECHA*.
Enestecaso,expFejecuta(eliminado)primero,'in.n++'luegoy'in.pt'despus.
Imaginoquenolosaben,perounavariableESunaexpresin.Asque:
in.pt;
UnexpressionyunstatementTIENENunvalor.Elvalorde:
in.pt;
esloqueestalmacenadoen'in.pt':eselVALORdelparmetro'c',quesealmacenen
in.ptenlalnea56:
56(in.pt=c,...
Entonces,'expF':"(eliminado),in.n++,in.pt",DEVUELVE'c'.
Asfuncionalaprimeraparte:Sinohayespacio,devuelveEOF,delocontrario,encola
laletraydevuelvesuvalor.
LaparteinternadelaMacro,queseejecutaslosihayespacio,seencargadeEncolar
elsmbolo:
...*in.put++=(byte)c,
in.put=in.put>=in.limit?
in.base:in.put,
Sealmacena'c',empleandoelpointer'put',queseautoincrementa.A'c'selehace
unCASTa(byte),porqueelusuariohapodidoenviaralgodemayorlongitud.
in.put=in.put>=in.limit?in.base:in.put
273
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
ltimopunto,ylomsIMPORTANTE:ElSEMFORO:in.n,NOPUEDEestarenNINGUNAOTRA
posicindelcdigo.Enelmomentoenqueselomodifica,ahmismopuedeocurriruna
interrupcin para efectuar la operacin contraria (si est haciendo enQue, se querr
hacer un deQue). El semforo TIENE que garantizar que no importa DNDE ocurra la
interrupcin,TODOFUNCIONAALAPERFECCIN.Enelsitioendondeest,slofaltapor
devolverelvalorqueestguardadoenlavariabledeusuario'in.pt',porloquedeQue
NOalteraparanadaelestadodelacola,desdeelpuntodevistadelenQue.Observe
ms adelante lo mismo, en relacin a la Macro deQue. Para eso sirve la variable
temporalin.gtqueseusaall.
CLARO?
CtieneunasintaxisMUYcomprimida.Lossiguientessmbolos
simples:+*/%&|^!~#()_=[]{};:'",.<>?\
dobles:++**&&||##==<<>>
poseenunsignificado.(Algunostienenvarios,dependiendodelcontexto.Porejemplo,
las COMAS en las llamadas a Funciones, NO SON COMMA OPERATORS y, de hecho, su
EVALUACINesdeDERECHAAIZQUIERDA,alrevsdelOperadorComa)
SINOCONOCEELUSODEALGUNODEESOSSMBOLOS,USTEDNOSABEC,YTIENEQUEESTUDIAR
MUCHSIMO.
LamacrodeQueesparaserusadaas:c=deQue(colaRead);ydebeserahorafcilde
entender.
63#definedeQue(in)(in.n<=0?EOF:\
64(in.gt=*in.get++,\
65in.get=in.get>=in.limit?\
66in.base:in.get,\
67in.n,in.gt\
68)\
69)
Una librera GENRICA para el manejo de Colas de Datos, tendra que poder manipular
cualquiertipodevariables,incluyendolasdefinidasvaTypedefs.Peroesoestms
alldeloquepretendoensearenestetextodeARQUITECTURADELCOMPUTADOR.
274
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
["LabsC\Lab3\SciComm\4quetst.c"]
01//******************************************************************
02//Program4QueTst.c:Test"Queue"Support(forSCI)
03//LuisGUribeCM13M2007C15A09L08J09S16J2012(HCS08)S30N2013"C"
04//See:4QueTstB.c(COMPACT)
05//Seeinthisprogram:TheuseofQue.H,defineQue,initQue,enQue
06//..anddeQue.YoumustNOTexceedthefreeRAMontheMCU...
07//
08//******************************************************************
09//IncludeFiles
10#include<hidef.h>//ForEnableInterruptsmacro
11#include"derivative.h"//Includeperipheraldeclarations
12#include"Que.h"//QUEUESupport
13//==================================================================
14//GLOBALVARIABLES.See'defQ'use...
15//defQ>>>"ALWAYS"mustbeGLOBAL<<<:Outofany'{}'
16defineQue(inQ,6);/*DEFINEQueues'inQ',6bytes&'outQ',*/
17defineQue(outQ,5);/*..5bytes.Choosethenamesyouwant...*/
18//******************************************************************
19voidmain(void)
20{bytec;
21wordcw;
22//
23//>>>ALWAYSincludethefollowing2lines
24//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
25#defineCOP_Disable0x42
26SOPT1=COP_Disable;//SystemOptions1
27//
28initQue(inQ);
29initQue(outQ);
30//
31cont:
32for(c='A';;c++){
33if(enQue(inQ,c)==EOF)//PutDebugger'sbreakpointhere
34break;//..toseecharsgoinginto'inQ'
35}
36full:
37while(1){
38cw=deQue(inQ);
39if(cw==EOF)
40break;
41if(enQue(outQ,cw)==EOF)//Willbreakherebecause...
42break;//..outQissmallerthaninQ
43}
44Wait(0);
45}
275
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
COMENTARIOS a ["Labs-C\Lab3\SciComm\4quetst.c"]:
El#include"Que.h"comocorresponde:
12#include"Que.h"//QUEUESupport
VARIABLESGLOBALES:ELdefQue,SIEMPREGLOBAL(comoenlalibreraenASM)
Paraelejemplosedefinandoscolas,inQde6bytes,youtQde5:
16defineQue(inQ,6);/*DEFINEQueues'inQ',6bytes&'outQ',*/
17defineQue(outQ,5);/*..5bytes.Choosethenamesyouwant...*/
Alcomienzodemain,ladefinicinde'c'.Enrealidadseusaunbytecyunwordcw,
comoveremosadelante.
19voidmain(void)
20{bytec;
21wordcw;
LaINICIALIZACINdelascolas:
28initQue(inQ);
29initQue(outQ);
Sehaceuncicloindefinido(forsinlmite:;;),quealmacenaletrascomenzandodesde
la'A'.Cuandolacolasellena,seterminaelfor(nosehacelacomparacinconel
tamao de la cola, para evidenciar el mecanismo que opera cuando la cola se llena).
Para la simulacin, est pendiente de colocar BREAKPOINTS en donde se indica en el
cdigo,paravisualizarloqueseestmanipulandoenlascolas:
32for(c='A';;c++){
33if(enQue(inQ,c)==EOF)//PutDebugger'sbreakpointhere
34break;//..toseecharsgoinginto'inQ'
35}
SinosabequeunbreakterminaunFOR,estMUYMALENC:ABANDONE!
AhoraqueselleninQ,sehaceuncicloindefinido,extrayendounoaunosuselementos
ytransfirindolosalaotracola.
EsexactamenteloqueharaunaRutinadeComunicaciones:EnlaISRdelRCV,seleeel
datorecibidoyseloalmacenaenlaColadeEntrada;mainencuentraquehaydatosen
esaCola,lossaca,losprocesasiesnecesarioylosalmacenaenlaColadesalida.A
lo mejor habilita las interrupciones de salida EN ALGN MOMENTO APROPIADO. Cuando la
ISRdeRCVtomaelcontrol,sacaelprximovalordelacoladesalidaylotransmite.
Enesteejemplo,elcicloterminarenlalnea42,porquelacoladesalidasellena
antesdequesevaceladeentrada,porlostamaosquedecidcolocarles.
37while(1){
38cw=deQue(inQ);
39if(cw==EOF)
40break;
276
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
41if(enQue(outQ,cw)==EOF)//Willbreakherebecause...
42break;//..outQissmallerthaninQ
43}
44Wait(0);
Para asignar el 'deQue' sobre una variable, SE NECESITA QUE LA VARIABLE SEA DE TIPO
WORD.Porqu?
Si usted estudi el getchar del 'C', tiene que poder saberlo. Si no, USTED SABE MUY
POCODEC.ESTUDIE!!!
EstaeslaraznporlacuallaMacroenQuehaceunCASTaBYTEdelvalorquesele
pasaparaencolar...
Revisesielcuerpodelwhilepuedeescribirseas:
if(enQue(outQ,deQue(inQ))==EOF)
break;
CMOFUNCIONARA?OPORQUNO?
TienequeanalizarcuandodeQuedevuelveEOF,cuandolohaceenQue,cuandonolohace
ningunoycuandolohacenlosdos.
63) CHAT POR INTERRUPCIONES, USANDO COLAS
El ltimo ejemplo es un CHAT por interrupciones, que muestra la interrelacin entre
todo: comunicaciones seriales, transmitiendo y recibiendo por interrupciones, con uso
decolas.Adems,seesquematizalaformadeprogramarseparandolomsquesepuedan,
PolticasyMecanismos,TALCOMOTIENEQUEHACERSESIEMPRE.
NooyhablarnuncadePoliticsandMechanisms?NoleensearonPROGRAMACINtampoco.
Enesteejercicioansepuedenocultarmsalgunasvariables,comokbhit;peronolo
hicepararesaltarlosparecidosconel'kbhit'queustedhadebidoestudiar.
["LabsC\Lab3\SciComm\6ChatInt.c"]
01//******************************************************************
02//Program6ChatInt.c:Send/Receivetextto/fromPC,FullInterrupt
03//LuisG.UribeC.,D15D2013
04#include"6ChatInt_.h"//includeperipheraldeclarations
05byte*Prompt="\a\r\n\n0_Envemeuntexto,porfavor<;)";
06defineQue(inQ,48);//DEFINEQue'inQ',48bytes
07//******************************************************************
08voidmain(void)/*()*/
09{/*ChatInt.c*/
277
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
10SysInit;//COP_Disable
11initQue(inQ);
12EnableIRQ;
13XmtRcvActivate;//EnableXmt&Rcv,onchipDEVICES;9600bps
14//==================================================================
15//TransmityourPrompt:Enqueatoncefull'Prompt'TableforXmt:
16SetupXmtBlk(Prompt);//TxtPtr;XmtControl=XMTMSG_S;XmtIntEn
17CpuIntEn;//<<<REMEMBER:GLOBALENABLEINTs
18RcvIntEn;//CommIntEn?{RCVSTATREG;RCVBUF;RcvIntEn;}
19Forever
20if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
21SetupXmtBlk(Prompt);
22kbhit=0;
23}
24Endforever
25Wait(0);
26}/*main()*/
27//==================================================================
28interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
29{
30kbhit=1;
31IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
32}//..Interrupt(RearmIRQInterrupts)
33//==================================================================
34interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
35{//NOTE:putcharclearsRCVRDY.bit.Veryclever...
36wordc;//MUSTbe'word'toholdbothCharsAndEOF(0xFFFF)
37switch(XmtControl){
38caseXMTMSG_S:
39if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
40XmtControl=XMTDEFAULT_S;//..(Zstrings:ASCIZ)
41}
42break;
43caseXMTDEFAULT_S:
44if((c=deQue(inQ))!=EOF){//Didsomethingarrive?
45putchar(c);//'C'Stringsendat'\0'
46}else{
47XmtIntDsb;
48}
49break;
50}
51}
52//==================================================================
53interruptVectorNumber_Vsci1rxvoidRcvISR(void)/*()*/
278
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
54{//NOTE:getcharclearsRCVRDY.bit.Veryclever...
55bytec;
56c=getchar();
57if(enQue(inQ,c)!=EOF){
58XmtIntEn;
59}
60}
["LabsC\Lab3\SciComm\6ChatInt_.h"]
01#ifndef_6CHATINT_H_INCLUDED
02#define_6CHATINT_H_INCLUDED
03//******************************************************************
04//6ChatInt_.h:Send/Receivetextto/fromPC,FullInterrupt
05//LuisG.UribeC.,D15D2013
06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations
10#include"SciComm.h"//SCIComm.Support
11#include"Que.h"//QueSupport
12#include"4InputPushButtons_.h"//Inputs4(0000b3b2b1b0)=PTA2,3;PTD2,3
13//==================================================================
14//GLOBALVARIABLES
15typedefenum{XMTDEFAULT_S,XMTMSG_S}XmtControls;
16XmtControlsXmtControl=XMTDEFAULT_S;//Maychangethistobits.
17byte*XmtPtr;//charpointerofnextdatatoXmt
18bytekbhit;
19//
20//>>>ALWAYSincludeSysInit
21//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
22#defineCOP_Disable0x42
23#defineSysInitSOPT1=COP_Disable/*SystemOptions1*/
24//
25//EnableIRQpin
26#defineEnableIRQIRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;\
27IRQSC_IRQIE=1/*IRQpin,IntEn*/
28//
29#defineSetupXmtBlk(p)XmtPtr=(p);/*PointtoPrompt*/\
30XmtControl=XMTMSG_S;\
31XmtIntEn/*XmtISRwillsendthePrompt*/
32#endif//_6CHATINT_H_INCLUDED
["LabsC\Lab3\SciComm\4InputPushButtons_.h"]
279
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
01#ifndef_4INPUTPUSHBUTTONS_H_INCLUDED
02#define_4INPUTPUSHBUTTONS_H_INCLUDED
03//******************************************************************
04//4InputPushButtons_.h:Inputs4(0000b3b2b1b0)=PTA2,3;PTD2,3
05//LuisG.UribeC.,D15D2013
06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations
10//==================================================================
11//DefinedFunctionality
12#defineSetup4PushBtnsPTAPE_PTAPE3=PTAPE_PTAPE2=PTDPE_PTDPE3\
13=PTDPE_PTDPE2=1/*Pullupsenable*/
14#defineget4Inputs()Inp3=PTAD_PTAD2;Inp2=PTAD_PTAD3;\
15Inp1=PTDD_PTDD2;Inp0=PTDD_PTDD3;\
16Inp4_7=~0;Inputs4=~Inputs4
17//==================================================================
18//GLOBALVARIABLES.IRQpinEnabledin"6ChatInt_.h"
19typedefunion{
20byteByte;
21struct{
22byteINPUTS40:1;//individualbitsMUSTbeUNSIGNED
23byteINPUTS41:1;
24byteINPUTS42:1;
25byteINPUTS43:1;
26bytespare:4;
27}Bits;
28}_INPUTS4;
29externvolatile_INPUTS4INPUTS4;
30#defineInputs4INPUTS4.Byte
31#defineInp0INPUTS4.Bits.INPUTS40
32#defineInp1INPUTS4.Bits.INPUTS41
33#defineInp2INPUTS4.Bits.INPUTS42
34#defineInp3INPUTS4.Bits.INPUTS43
35#defineInp4_7INPUTS4.Bits.spare
36#defineINP01U
37#defineINP12U
38#defineINP24U
39#defineINP38U
40#endif//_4INPUTPUSHBUTTONS_H_INCLUDED
COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt.c"]:
En el archivo "6ChatInt_.h" se definen cosas de bajo nivel, relacionadas con
perifricos,comoveremosabajo:
280
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
04#include"6ChatInt_.h"//includeperipheraldeclarations
ElmensajeconelquequeremosavisarlealusuariodelPCquenosenveuntexto:
05byte*Prompt="\a\r\n\n0_Envemeuntexto,porfavor<;)";
Sedefineunacola,inQ,de48posiciones:
06defineQue(inQ,48);//DEFINEQue'inQ',48bytes
08voidmain(void)/*()*/
09{/*ChatInt.c*/
Las lneas 10 a la 13 son auto explicativas con solo leerlas; dicen qu se har, NO
cmosehar(Politics;Mechanismsseenlater)
10SysInit;//COP_Disable
11initQue(inQ);
12EnableIRQ;
13XmtRcvActivate;//EnableXmt&Rcv,onchipDEVICES;9600bps
AhoraseTRANSMITEELPROMPT,queesdeltipoASCIZ,trasmitindolotododeunasola
vez,porinterrupciones:
15//TransmityourPrompt:Enqueatoncefull'Prompt'TableforXmt:
16SetupXmtBlk(Prompt);//TxtPtr;XmtControl=XMTMSG_S;XmtIntEn
17CpuIntEn;//<<<REMEMBER:GLOBALENABLEINTs
Sehabilitanlasinterrupcionesderecepcin,paraentraralcicloinfinito.kbhites
unavariablequeseactiva(1)porlaISRdelIRQ;esdecir,cadavezqueseoprimeel
botndeIRQ,setransmitedenuevoelPROMPT.ElECHOsemanejadirectamenteentrelas
ISRdeRCVyXMT:
18RcvIntEn;//CommIntEn?{RCVSTATREG;RCVBUF;RcvIntEn;}
19Forever
20if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
21SetupXmtBlk(Prompt);
22kbhit=0;
23}
24Endforever
26}/*main()*/
La IRQISR es muy simple: cargar el valor de ACTIVO para la variable kbhit, y el ACK
correspondientealIRQ:
28interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
29{
30kbhit=1;
31IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
32}//..Interrupt(RearmIRQInterrupts)
281
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
LaXmtISR:
34interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
35{//NOTE:putcharclearsRCVRDY.bit.Veryclever...
36wordc;//MUSTbe'word'toholdbothCharsAndEOF(0xFFFF)
ElcaseXMTMSG_S:esigualalltimoquevimos,cuandotransmitimosuntextodetipo
ASCIZ;alfinalsecambialavariabledeEstado,XmtControlasufuncindeECHO,que
eslaestndar:
37switch(XmtControl){
38caseXMTMSG_S:
39if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
40XmtControl=XMTDEFAULT_S;//..(Zstrings:ASCIZ)
41}
42break;
ElcaseXMTDEFAULT_Sestambincomoyahemosvisto:siloquesedesencola,cuandohay
una interrupcin paraTransmitir, no es EOF, quiere decir que s hay caracteres para
transmitirlealPC,yassehaceconputcharque,comoyalosabemos,haceeldebido
ACK al XMT. Si en la cola no hay nada para transmitir, se auto deshabilitan las
interrupcionesdelXMT:
43caseXMTDEFAULT_S:
44if((c=deQue(inQ))!=EOF){//Didsomethingarrive?
45putchar(c);//'C'Stringsendat'\0'
46}else{
47XmtIntDsb;
48}
49break;
50}
51}
LaRcvISResmuysencillatambin,empleandoestalibreradecomunicacionesseriales:
52//==================================================================
53interruptVectorNumber_Vsci1rxvoidRcvISR(void)/*()*/
54{//NOTE:getcharclearsRCVRDY.bit.Veryclever...
55bytec;
56c=getchar();
57if(enQue(inQ,c)!=EOF){
58XmtIntEn;
59}
60}
COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt_.h"]:
El6ChatInt_.hconstadeunapartedeinicializacin:
282
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations
10#include"SciComm.h"//SCIComm.Support
11#include"Que.h"//QueSupport
12#include"4InputPushButtons_.h"//Inputs4(0000b3b2b1b0)=PTA2,3;PTD2,3
LadefinicindelasVARIABLESGLOBALES:
15typedefenum{XMTDEFAULT_S,XMTMSG_S}XmtControls;
16XmtControlsXmtControl=XMTDEFAULT_S;//Maychangethistobits.
17byte*XmtPtr;//charpointerofnextdatatoXmt
18bytekbhit;
La definicin de la Macro que realiza la inicializacin del sistema Macro que usted
deberaUTILIZARSIEMPRE,deahoraenadelante)
20//>>>ALWAYSincludeSysInit
22#defineCOP_Disable0x42
23#defineSysInitSOPT1=COP_Disable/*SystemOptions1*/
SedefineunaMacroparahabilitarelIRQ;observequenecesitael'\'porquetienems
deunalnea
26#defineEnableIRQIRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;\
27IRQSC_IRQIE=1/*IRQpin,IntEn*/
SedefinelaMacroSetupXmtBlk,queinicializaytransmiteelPrompt.Recuerdequehay
una pequea mquina de estados, controlada por la variable XmtControl; aqu se
inicializaesaFSMconXMTMSG_S,quehacequelaXmtISRtransmitaelmensajeASCIZ:
29#defineSetupXmtBlk(p)XmtPtr=(p);/*PointtoPrompt*/\
30XmtControl=XMTMSG_S;\
31XmtIntEn/*XmtISRwillsendthePrompt*/
COMENTARIOS a ["Labs-C\Lab3\SciComm\4InputPushButtons_.h"]:
Definelassiguientesfuncionalidades:Setup4PushBtnsyget4Inputs().
Setup4PushBtns les activa todas las resistencias de Pull Up a los botones de entrada
(un1lasactivas).Nohayqueactivaresosterminalesparaentrada,porquedespusde
POR,todoslospinesdigitalesestnactivoscomoENTRADAS.
12#defineSetup4PushBtnsPTAPE_PTAPE3=PTAPE_PTAPE2=PTDPE_PTDPE3\
13=PTDPE_PTDPE2=1/*Pullupsenable*/
get4Inputs()LEElos4botones,unoencadabitdelavariabledefinidacomodetipo
_INPUTS4. Despus se colocan en valor inicial los 4 bits que no se usan (hay solo 4
botones)yporltimoSENIEGANLASENTRADA,tomndolasdelavariableyalmacenndolas
283
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
de nuevo all. Se niegan porque, en la forma como la gente de PE Micro conect los
botones,cadavezqueunodeellosseACTIVA,produceunCERO,locualpodraresultar
poconatural:
14#defineget4Inputs()Inp3=PTAD_PTAD2;Inp2=PTAD_PTAD3;\
15Inp1=PTDD_PTDD2;Inp0=PTDD_PTDD3;\
16Inp4_7=~0;Inputs4=~Inputs4
Seestableceunaestructuraconlos4bitsparalosbotones,yelrestosedefinecomo
'spare'.SecolocanenUNIONconunByte,parafacilitar,porejemplo,elnegarTODOS
losbitsdeungolpeInputs4=~Inputs4)
19typedefunion{
20byteByte;
21struct{
22byteINPUTS40:1;//individualbitsMUSTbeUNSIGNED
23byteINPUTS41:1;
24byteINPUTS42:1;
25byteINPUTS43:1;
26bytespare:4;
27}Bits;
28}_INPUTS4;
Se define la variable INPUTS4, de tipo _INPUTS4 (el typedef), volatile (para evitar
Optimizacin del compilador) y extern, para que sea visible desde el cdigo de los
demsarchivos:
29externvolatile_INPUTS4INPUTS4;
30#defineInputs4INPUTS4.Byte
NOSABENADADEEXTERN?UNION?NOSABEC.
Finalmente,parafacilitarelusodelosbitsdelavariableINPUTS4,detipo_INPUTS4
que,porejemplo,paradesignarelBit0requeriraescribir:INPUTS4.Bits.INPUTS40.
ConlasdefinicionescadabitesInp0,etc.Muchomssencillo
31#defineInp0INPUTS4.Bits.INPUTS40
32#defineInp1INPUTS4.Bits.INPUTS41
33#defineInp2INPUTS4.Bits.INPUTS42
34#defineInp3INPUTS4.Bits.INPUTS43
35#defineInp4_7INPUTS4.Bits.spare
Unverdaderochatenvamensajesdiferentesdeladoylado!Peroelsistemadebotones
del DEMOQE128 resulta algo inflexible para generar texto. Este ejercicio enva un
Prompt,igualqueelprogramaanterior,perolosmensajesnofluyensolamentedesdeel
PC,sinoquetocandocadaunodelos4botones,seenvanhastacuatromensajesalPC,
dndoleunaspectounpocomsrealistaalchat.
["LabsC\Lab3\SciComm\6ChatInt4.c"]
284
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
01//******************************************************************
02//Program6ChatInt4.c:Send/Receivetextto/fromPC,FullInterrupt
03//LuisG.UribeC.,L16D2013(4DEMOQE128textsources)
04#include"6ChatInt_.h"//includeperipheraldeclarations
05byte*Prompt="\a\r\n\n0_Envemeuntexto,porfavor<;)";
06byte*Prompts[4]={
07{"\a\r\n\n1_Meencantapoderhablarlehoy___"},
08{"\a\r\n\n2_Cmovatodo,finalizandoel13?"},
09{"\a\r\n\n3_Ledeseosuerteparaelao2014"},
10{"\a\r\n\n4_QuetengabuenanotaenArquiI!"},
11};
12defineQue(inQ,48);//DEFINEQue'inQ',48bytes
13//******************************************************************
14voidmain(void)/*()*/
15{/*ChatInt.c*/
16SysInit;//COP_Disable
17initQue(inQ);
18EnableIRQ;
19XmtRcvActivate;//EnableXmt&Rcv,onchipDEVICES;9600bps
20Setup4PushBtns;//Activate4DEMOQE128inputpushbuttons
21//==================================================================
22//TransmityourPrompt:Enqueatoncefull'Prompt'TableforXmt:
23SetupXmtBlk(Prompt);//TxtPtr;XmtControl=XMTMSG_S;XmtIntEn
24CpuIntEn;//<<<REMEMBER:GLOBALENABLEINTs
25RcvIntEn;//CommIntEn?{RCVSTATREG;RCVBUF;RcvIntEn;}
26Forever
27if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
28switch(Inputs4){//1:1;2:2;4:3;8:4
29case1:
30case2:
31break;
32case4:
33Inputs4=3;
34break;
35case8:
36Inputs4=4;
37break;
38default:
39Inputs4=15;
40break;
41}
42SetupXmtBlk(Inputs4==15?Prompt:Prompts[Inputs41]);
43kbhit=0;
44}
45Endforever
285
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
46Wait(0);
47}/*main()*/
48//==================================================================
49interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
50{
51get4Inputs();//LoadInputs4
52kbhit=1;
53IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
54}//..Interrupt(RearmIRQInterrupts)
55//==================================================================
56interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
57{//NOTE:putcharclearsRCVRDY.bit.Veryclever...
58wordc;//MUSTbe'word'toholdbothCharsAndEOF(0xFFFF)
59switch(XmtControl){
60caseXMTMSG_S:
61if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
62XmtControl=XMTDEFAULT_S;//..(Zstrings:ASCIZ)
63}
64break;
65caseXMTDEFAULT_S:
66if((c=deQue(inQ))!=EOF){//Didsomethingarrive?
67putchar(c);//'C'Stringsendat'\0'
68}else{
69XmtIntDsb;
70}
71break;
72}
73}
74//==================================================================
75interruptVectorNumber_Vsci1rxvoidRcvISR(void)/*()*/
76{//NOTE:getcharclearsRCVRDY.bit.Veryclever...
77bytec;
78c=getchar();
79if(enQue(inQ,c)!=EOF){
80XmtIntEn;
81}
82}
COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt-4.c"]:
Esteprogramaestanparecidoalanterior,yustedconocetantoaestasalturas,que
loscomentariossernmuybreves:
LadefinicindelPromptesidnticaalchatanterior;los4promptsestncolocadosen
unamatrizquecontiene4mensajes:
286
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
06byte*Prompts[4]={
07{"\a\r\n\n1_Meencantapoderhablarlehoy___"},
08{"\a\r\n\n2_Cmovatodo,finalizandoel13?"},
09{"\a\r\n\n3_Ledeseosuerteparaelao2014"},
10{"\a\r\n\n4_QuetengabuenanotaenArquiI!"},
11};
ImaginoqueconoceTODOSlossmbolos...Ques'\a'?
Contina todo igual, hasta enviar el Prompt. El ciclo infinito se diferencia del
anterior porque contiene un Switch con 4 Cases, uno para cada interruptor de la
tarjeta. kbhit funciona igual que antes, el programa principal lo coloca en 0, y la
IRQISRen1.
Observebienquealoprimircadainterruptorsegeneranlosnmeros1,2,4y8,pero
hemos codificado los Cases para que se generen los nmeros 0, 1, 2 y 3, que
correspondenalossubndicesqueidentificanlos4mensajesenelarreglo.Asquehay
que hay que relacionar los nmeros obtenidos con losdeseados, de la siguiente forma
(Obtenido:Generado)1:0;2:1;4:2;8:3
Pero ntese que el '0' NO CORRESPONDE a oprimir ningn botn; siempre se est
generando! As que la variable 'Inputs4', que representa los botones, tendr un Cero
SIEMPRE que no se est oprimiendo nada. Mala seleccin para el Switch, porque no
permitedistinguirentreNOseleccin,yseleccindelnmero0.
Por eso escog generar estos nmeros, en lugar de los indicados dos prrafos atrs"
(Obtenido:Generado) 1:1; 2:2; 4:3; 8:4; ahora s es fcil saber si se oprimi algn
interruptor; en caso contrario, la variable Inputs4 vale 0. Y, al usar Inputs4 como
ndice, se le resta un uno, para convertir estos valores intermedios, en los que en
realidaddeseamos.CualquiervalorNOdefinido(default)colocaun'15'enlavariable,
simulando que se oprimieron TODOS los interruptores. Si Inputs4 vale 15, seenva el
PROMPT;paralosotros4valoresposibles,selerestaununoaInputs4,yselousa
como ndice del Arreglo, para escoger uno de los mensajes, y transmitirlo empleando
'SetupXmtBlk', que como vimos antes, inicializa el sistema de transmisin y
efectivamentehacequesetransmitaelBloque,conelmensajedeseado.
26Forever
27if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
28switch(Inputs4){//1:1;2:2;4:3;8:4
29case1:
30case2:
31break;
32case4:
33Inputs4=3;
34break;
35case8:
36Inputs4=4;
37break;
38default:
39Inputs4=15;
40break;
287
I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08
41}
42SetupXmtBlk(Inputs4==15?Prompt:Prompts[Inputs41]);
43kbhit=0;
44}
45Endforever
LarutinaIRQISRescasiexactaaladelejercicioprevio;sediferenciaenqueseleen
yadecanlosinterruptores,usandolaMacroget4Inputs,yaanalizada.Elrestosigue
igual.
49interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
50{
51get4Inputs();//LoadInputs4
Las dos rutinas finales, XmtISR y RcvISR son exactamente iguales a las delejercicio
anterior.
FIN DE LA OBRA
mailto:LUribe@usb.ve
288