HC12tutorial Tasm
HC12tutorial Tasm
HC12tutorial Tasm
1 Entorno de desarrollo
El entorno de desarrollo que utilizaremos a lo largo de las sesiones de
prácticas es el CodeWarrior IDE.
Este software nos permitirá llevar a cabo los diversos pasos necesarios para
la creación y ejecución de nuestros programas. Dispondremos de las herramientas
típicas de desarrollo como un editor de código, un compilador, facilidades para la
descarga en el microcontrolador, etc. La interfaz gráfica es muy “amigable” e
“intuitiva” por lo que no tendréis mayores problemas al trabajar con ella.
2 Iniciando el CodeWarrior
El programa se encuentra en el escritorio o en
Inicio>Programas>Metrowerks CodeWarrior>CW12 v3.0>CodeWarrior IDE. La
figura siguiente enseña la ventana principal del programa.
3 Metodología de desarrollo
La metodología a seguir es la siguiente:
1
Tutorial PK-HCS12E128 Estructura de Computadores
2
Tutorial PK-HCS12E128 Estructura de Computadores
3
Tutorial PK-HCS12E128 Estructura de Computadores
ORG RAMStart
.
. segmento de variables
.
ORG ROMStart
.
. segmento de codigo
.
4
Tutorial PK-HCS12E128 Estructura de Computadores
Para que tenga efecto estas direcciones, utilizamos la directiva ORG (origin)
para definir cada una de nuestras regiones de memoria.
3.3.1.1 Sintaxis
Las directivas y las instrucciones no son “case sensitive” mientras que las
etiquetas y símbolos son.
Los comentarios son utilizados para explicar el significado de alguna parte del
código y se definen mediante la utilización del “;” (e.j., DEC Var01 ; decremento de
la variable var01).
Las etiquetas son símbolos que son seguidos de un “:” pegados a ellos. Son
utilizadas para marcar algun punto del código que sea necesario acceder
directamente (e.j., LOOP:).
Los “strings” son una cadena de caracteres delimitados por comillas simples o
bien comillas dobles. Por ejemplo:
5
Tutorial PK-HCS12E128 Estructura de Computadores
Pregunta:
Pregunta:
Pregunta:
Pregunta:
7) Sabiéndo que el botón derecho del ratón sirve para activar el menú de
contexto, experimente las posibilidades de este menú en la ventana
“Assembly” y escriba el código binario de las 3 primeras instrucciones del
programa
6
Tutorial PK-HCS12E128 Estructura de Computadores
Pregunta:
Para insertar un breakpoint pulsa el botón derecho del ratón y elige la opción
Set Breakpoint.
Pregunta:
12) ¿En qué punto se debe poner el breakpoint para que el programa
pare siempre que temp_byte sea 0?
7
Tutorial PK-HCS12E128 Estructura de Computadores
8
Tutorial PK-HCS12E128 Estructura de Computadores
9
Tutorial PK-HCS12E128 Estructura de Computadores
4.2.2 Subrutinas
Las subrutinas son muy útiles y ayudan a localiza fácilmente los
problemas. Para crear una subrutina, se hace igual que con las etiquetas pero
la forma de acceso es a través de llamadas a subrutinas. Por ejemplo: BSR y
RTS. En el manual del HSC12 podrán encontrar referencias detalladas.
10
Tutorial PK-HCS12E128 Estructura de Computadores
ABSENTRY Entry
PTM EQU $0250 ; Puerto M (controla el LED DA0)
DDRM EQU $0252 ;Define la configuración del puerto M (si es entrada ó salida)
ATDDIEN1 EQU $008D ; Habilita entrada en el puerto AD bits (7..0)
PTADLo EQU $0271 ; Byte menos significativo de AD (bits 7-0)
DDRADLo EQU $0275 ;Define la configuración del puerto AD (si es entrada ó salida)
PERADLo EQU $0279 ; Define alimentacion de entrada
; (0= desabilitada / 1= habilitada)
RAMStart EQU $0400 ; Inicio de la area de variables
ROMStart EQU $4000 ; Inicio del codigo
ORG RAMStart ; data section
ORG ROMStart ; code section
Entry:
LDS #$1FFF ; Carga la dirección de la pila
LDAB #$FF ; envia FF al registro B
STAB DDRM ; define el modo del PTM. PTM es salida
11
Tutorial PK-HCS12E128 Estructura de Computadores
00) ABSENTRY Entry ; for absolute assembly: mark this as application entry point
01) RAMStart EQU $0400 ; absolute address to place my variables
02) ROMStart EQU $4000 ; absolute address to place my code/constant data
03) PTT EQU $0240 ; Direccion del puerto T= LEDS
04) DDRT EQU $0242 ; Direccion que define se PT es entrada o salida
05) ; variable/data section
06) TMP EQU $FFFF ; Time to delay
07)
08)
09) ORG RAMStart; Insert here your data definition.
11) Entry:
12) CLI ; enable interrupts
13) LDAB #$FF ; PT es salida
14) STAB DDRT
15) LDAB #0
16) for1:
17) STAB PTT ; Encende los leds
18) INCB
19) LDX #TMP
20) for2:
21) DEX
22) BNE for2
23) BRA for1 ; bucle infinito
Pregunta:
12
Tutorial PK-HCS12E128 Estructura de Computadores
ORG RAMStart
time ds.b 1
var ds.b 1
res ds.b 1
ORG ROMStart
Entry:
lds STACKAdress
Main:
movb #$5,res
movb #$4,var
movb #01,time
for:
ldaa var
ldab res
MUL
STAB res
BSR SHOW
movb #01,time
SHOW:
ldab res
stab PTT
RTS
13
Tutorial PK-HCS12E128 Estructura de Computadores
14
Tutorial PK-HCS12E128 Estructura de Computadores
1 Entorno de desarrollo
El entorno de desarrollo que utilizaremos a lo largo de las sesiones de
prácticas es el CodeWarrior IDE.
Este software nos permitirá llevar a cabo los diversos pasos necesarios para
la creación y ejecución de nuestros programas. Dispondremos de las herramientas
típicas de desarrollo como un editor de código, un compilador, facilidades para la
descarga en el microcontrolador, etc. La interfaz gráfica es muy “amigable” e
“intuitiva” por lo que no tendréis mayores problemas al trabajar con ella.
2 Iniciando el CodeWarrior
El programa se encuentra en el escritorio o en
Inicio>Programas>Metrowerks CodeWarrior>CW12 v3.0>CodeWarrior IDE. La
figura siguiente enseña la ventana principal del programa.
3 Metodología de desarrollo
La metodología a seguir es la siguiente:
1º) Creación/Edición del código fuente utilizando CodeWarrior IDE;
2º) Compilación del programa utilizando CodeWarrior IDE;
3º) Descarga del programa a la placa de evaluación PK-HCS12E128;
4º) Verificación del correcto funcionamiento utilizando el monitor de la placa de
evaluación;
5º) Modificación de parámetros mediante el monitor.
1
Tutorial PK-HCS12E128 Estructura de Computadores
2
Tutorial PK-HCS12E128 Estructura de Computadores
Pregunta:
1) Indique la dirección de memoria en donde empieza el código.
2) ¿Qué cambio será necesario si queremos que el programa comience
en la dirección 4300?
En la ventana “Memory” se puede mirar la memoria del controlador. Pulsando
con el botón derecho del ratón en esta ventana aparecerá un menú de contexto. Elija
la opción “Address…” y ponga el valor 4000. Mire lo que pasa en la ventana
“Memory”.
Pregunta:
3) ¿Cuántos bytes tiene el programa ejecutable?
4) ¿Cuál es la dirección de memoria de la variable temp_byte?
3
Tutorial PK-HCS12E128 Estructura de Computadores
4
Tutorial PK-HCS12E128 Estructura de Computadores
5
Tutorial PK-HCS12E128 Estructura de Computadores
4 Ejercicios
Cree un nuevo proyecto e introduzca el siguiente código:
Entry:
CLI ; Habilita interrupciones
LDAB #$FF ; PT es salida
STAB DDRT ; Programa PT
LDAB #0
for1: ; Bucle de contaje
STAB PTT ; Enciende los leds
INCB ; Próximo valor
LDX #TIME
for2: ; Bucle de tempo
DEX
BNE for2
6
Tutorial PK-HCS12E128 Estructura de Computadores
Pregunta:
11) ¿Explique qué hace el programa?
12) Modifique el programa para que presente una secuencia inversa.
5 Trabajos Finales
13) Modifique el programa original para que presente los resultados de
manera más lenta.
7
Tutorial HC12Sim _____
1
Tutorial HC12Sim _____
La edición del programa ensamblador se puede realizar con cualquier editor de texto. En
Windows podremos utilizar el notepad y en DOS podemos utilizar el programa edit.
Los ficheros de código fuente debería tener la extensión asm para utilizar una nomenclatura
común (aunque el ensamblador que vamos a utilizar no requiere una extensión específica).
Tut1.asm
2
Tutorial HC12Sim _____
Para ensamblar nuestros ficheros fuentes vamos a utilizar el ensamblador AS12 desde una
ventana de DOS. Este programa recibe un fichero fuente, genera el código ensamblado en un
fichero con formato s19 y un listado por pantalla.
Si no se especifica lo contrario el fichero s19 tiene el mismo nombre que el fichero original
pero con la extensión s19 (Esto implica que nunca se puede utilizar la extensión s19 si no
queremos perder el código fuente cuando este se compile).
El ensamblador nos indica las líneas donde hay errores leves (warnings) o graves. Los errores
graves deben corregirse editando el fichero original y volviendo a ensamblar. Es conveniente
corregir también los errores leves si los hubiese.
Una vez se ha ensamblado el código correctamente este se tiene que que cargar en el
simulador para poder simular su ejecución. La carga de programas se realiza utilizando el
menú file del simulador y seleccionando el fichero de entrada S19 que queramos simular.
Cargar el fichero compilado anterior (Tut1.s19) en el simulador mediante el menú
File Load.
3.4.- Simulación
Una vez tenemos nuestro programa cargado en el simulador podemos realizar algunas de las
siguientes funciones:
• Ejecutar paso a paso cada una de sus instrucciones.
• Ejecutar el programa de forma continua hasta una determinada instrucción, utilizando
breakpoints.
• Visualizar el contenido de los registros y puertos del procesador.
• Comprobar el contenido de la memoria.
• Etc.
Esta funcionalidad nos permite verificar nuestro código y localizar errores de forma que
podamos comprobar que realiza correctamente la función para la cual ha sido diseñado.
En el siguiente apartado veremos cómo utilizar todas estas características del simulador de
forma que la depuración del código se pueda realizar de forma fácil y sin necesidad de
disponer del microprocesador para poder probar y depurar nuestro programas.
3
Tutorial HC12Sim _____
4.- Simulador.
En la parte superior de la ventana de la aplicación podemos ver tres menús: File, View y
Help.
El menú File nos permite cargar el fichero s19 del código a simular (como hemos visto en el
apartado anterior), inicializar el estado del microprocesador (Reset), generar un log de la
simulación en un fichero (Log) ó cerrar el simulador (Exit).
El menú View nos permite visualizar diversa información de la simulación que esta ubicada
en ventanas independientes como puede ser: el código del programa (Code view), un
emulador de un terminal (SCI Viewer), los puertos paralelos (Parallel Ports), el generador de
señales (Signal Generator), las entradas analógicas (ADC Analog to Digital Converter) y
capturar instantáneas de cierta información de la simulación (Snapshot).
Por último, el menú Help nos permite acceder a la ayuda del simulador.
El visor de código nos permite visualizar el código de nuestro programa, ya que a medida que
simulación avanza, en la ventana principal únicamente se nos muestra la siguiente instrucción
que se va a ejecutar.
4
Tutorial HC12Sim _____
Esta ventana se abre mediante la opción View Code View. Dispone de un campo (Address)
en donde se puede especificar a partir de que dirección de memoria se quiere realizar el
desensamblado (convertir código maquina en código ensamblador) del código.
La siguiente zona del simulador nos permite ver y modificar los valores del los registros y
los flags del microprocesador. Para modificar el valor de un registro hay que posicionarse
en el campo correspondiente e introducir el valor deseado en formato hexadecimal. Los
flags se pueden modificar mediante un clic en el campo del flag que queramos cambiar, si
esta activado (valor =1) se desactivará (valor =0) y viceversa.
5
Tutorial HC12Sim _____
Simular la ejecución del programa anterior paso a paso hasta ejecutar la instrucción
STAA 1,x.
P3: ¿Qué valores tenemos en los diferentes registros y que flags están activados?
6
Tutorial HC12Sim _____
Utilizando los breakpoints, simular la ejecución del programa Tut1 hasta el final de la
iteración 8.
P4: a) ¿En qué punto se debe situar el breakpoint?
b) ¿Qué valores tienen los registros A y X al final de cada iteración?
7
Tutorial HC12Sim _____
Para seleccionar la zona de memoria que se quiere visualizar se tiene que presionar el
botón de “Show” y a continuación insertar la dirección de inicio de la zona de memoria
que se quiere consultar.
Para modificar una posición de memoria hay que rellenar el campo de “Fill start” con la
dirección de inicio del bloque de memoria, el campo de “Fill end” con la dirección final y el
campo “Value” con el valor que se va escribir. A continuación apretando el botón “Fill” se
escribirá el valor en todas las posiciones del bloque de memoria seleccionado.
Inicializar todas las posiciones del bloque de memoria 5000-5020h a 11h y volver a
ejecutar el programa Tut1.asm hasta el final.
P7: ¿ Que resultado obtenemos en el registro A?
P9: Modificar el programa Tut1.asm, de forma que en vez utilizar un bloque de memoria
preestablecido para guardar los resultados se utilice una variable que ocupe 20 bytes.
¿Cuál es la dirección de la variable?
8
Tutorial HC12Sim _____
; Codigo Principal.
ORG DBasePrograma
LDS #DBasePila
LDA #$11
LDB #$22
LDX #$3333
LDY #$4444
;Guardar en la pila.
PSHA
PSHB
PSHX
PSHY
PSHD
EjercicioA:
NOP
;Restaurar de la pila.
PULB
PULA
PULX
PULY
PULD
; Fin programa.
SWI ; Esta instrucción solo funciona en el.
; microprocesador real.
Tut2.asm
9
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
Material:
Placa de desarrollo SofTec Microsystems PK-HCS12E128.
Computador Personal (MS-Windows) con un puerto USB disponible y cable USB
Metrowerks CodeWarrior HC(S)12 (http://www.codewarrior.com/MW/download)
SofTec Microsystems PK-HCS12E128 “System Software” (Campus Virtual)
Documentación técnica resumida y completa (Campus Virtual)
1.1 Sintaxis
Por regla general, cada línea de texto de un programa debe contener una única instrucción, o la
definición de una variable, o una directiva (o seudo-operación). En la siguiente sección se
describirán estos tres elementos que determinan la semántica de los programas. Una línea
puede contener una etiqueta y un comentario.
La sintaxis de una línea consiste en hasta cuatro campos separados por caracteres “whitespace”
(el carácter espacio o el carácter de tabulación): una etiqueta, seguida de una operación (que
puede ser una instrucción, una directiva, o una macro), seguida de operandos opcionales
separados por comas, y seguidos de un comentario opcional que comienza con el carácter ‘;’.
Ejemplos:
Etiqueta: instr1 op1, op2 ; comentario
instr2 ; comentario
Una etiqueta es una serie de caracteres alfanuméricos que comienza en la primera columna del
texto y que finaliza en un carácter espacio, en un carácter de tabulación, o en el carácter ‘:’. Si no
se quiere etiquetar una línea, se debe comenzar la línea con un espacio o un carácter de
tabulación. Una etiqueta representa la dirección de memoria en la que se coloca la instrucción o
la variable definidos en esa línea (→ver más adelante la definición). De este modo, el programa
no necesita hacer referencia explícita a direcciones de memoria, sino que puede utilizar etiquetas
simbólicas, para así facilitar la escritura del programa. Las etiquetas son case sensitive
(sensibles a mayúsculas o minúsculas). Por ejemplo, no es lo mismo “Start” que “START”.
-1-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
Una operación es un mnemotécnico que consiste en una serie de caracteres alfabéticos, donde
no se distingue entre mayúsculas y minúsculas. El mnemotécnico representa o bien una única
instrucción del repertorio de instrucciones (ver manual del HCS12 para conocer la lista completa
de todas las instrucciones, p.e. ADCA, ó bge), o bien una directiva (→ver más adelante la
definición).
Tras el mnemotécnico que indica la operación se pueden incluir cero, uno o varios operandos,
separados por comas (p. e., 0, #!17). Los operandos son una mezcla de constantes numéricas
(ver Tabla 1), nombres de registros (A, B, D, X, Y, SP), y signos ‘+’, ‘-‘, ‘[‘, ‘]’, ‘#’. Las cadenas de
caracteres (strings) son constantes que también se pueden utilizar como operandos al definir el
contenido de variables de texto. Se representan delimitadas por comillas simples ‘’ o bien por
comillas dobles ””.
Base Prefijo Sufijo
Binaria (2) % Q
Decimal (10) T
Hexadecimal (16) $ H
Tabla 1. Representación de constantes. Por defecto se supone que las constantes del programa están en
decimal, aunque las que se muestran en el depurador están en hexadecimal.
Un comentario se utiliza para documentar el código. Puede ocupar toda una línea si el primer
carácter de la línea es ‘*’ o ‘;’. Generalmente se ponen al final de la línea tras la operación y los
operandos y el carácter “;”.
Cuidado! En ocasiones se comete el error de escribir la operación en la primera columna,
de modo que el ensamblador la considera como una etiqueta y por tanto desaparece
misteriosamente de nuestro programa!
-2-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
sufijo “.w”, de word, o palabra). Al definir una variable se le puede asignar un valor inicial
predefinido, o no darle ningún valor, y por tanto al inicio de la ejecución del programa tendrá un
valor indefinido.
Para declarar una variable con un valor indefinido (sin inicializar) se utiliza la directiva DS
(declare storage). Esta directiva reserva posiciones consecutivas de memoria, pero no las
inicializa. Por ejemplo:
Variable1 ds.b 1
Vector2 ds.b 5
Vector3 ds.w 3
Las tres líneas anteriores declaran tres variables, la primera de un byte de tamaño, la segunda
de 5 bytes de tamaño, y la tercera de 3 palabras de 2 bytes cada una (es decir, 6 bytes en total).
Las tres etiquetas representan las direcciones de cada una de las variables. Tal como se indicó
previamente, los sufijos “.b” y “.w” indican el tamaño de cada elemento de la variable (un byte, o
una palabra de 2 bytes). Los números finales (1, 5 y 3) indican el número de elementos a
reservar para la variable. Una variable compuesta de más de un elemento (como en el caso de
Vector2 y Vector3), se denomina vector, y los elementos de él se almacenan continuos en
memoria. Más adelante se propondrá un ejercicio para manejar los elementos de un vector.
Para declarar una variable con un valor inicial predefinido se utiliza la directiva DC (define
constant). Esta directiva reserva una posición (o varias consecutivas) de memoria y la inicializa
con un valor constante. De todos modos, si la variable está definida en la dirección de memoria
que corresponde a la memoria RAM (→ver más adelante la definición), el contenido de la
variable podrá ser modificado dinámicamente por el programa, y por tanto la palabra “constante”
no se debe interpretar de forma estricta.
Las declaraciones anteriores que usaban DS se pueden sustituir por las siguientes declaraciones
de variables con valores iniciales:
Variable1 dc.b $FC
Vector2 dc.b ‘adios’
Vector3 dc.w %4,$18,!24
Fijarse en cómo se puede declarar una lista de constantes separadas por comas o una cadena
de caracteres (cada carácter codificado con un byte).
-3-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
XDEF Entry
ABSENTRY Entry
ORG RAMStart
temp_byte ds.b 1
ORG ROMStart
Entry:
CLI ; enable interrupts
MOVB #1,temp_byte ; just some demonstration code
NOP ; insert here you own code
BRA Entry ; endless loop
ORG $FFFE
fdb Entry ; Reset
-4-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
-5-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
El programa es el mismo que se presentó en la sección anterior (si no lo es, utilizar la nueva
versión, en la que es posible que los valores RAMStart y ROMStart sean diferentes), y se trata
de un esqueleto que servirá de base para que el alumno pueda escribir sus propios programas.
De momento se utilizará tal y como está, y más adelante se realizarán modificaciones sobre él.
-6-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
información visualizada, y que también permite poner y quitar puntos de parada (→ver
más adelante la definición).
Register: permite visualizar el contenido de los registros del microcontrolador y cambiar
el formato de visualización de los valores (p.e., Hexadecimal, Binario, Decimal, etc…).
Las modificaciones también se hacen invocando el menú de contexto con el botón
derecho del ratón.
Memory: permite visualizar la memoria del microcontrolador. El menú de contexto nos
permite variar la dirección de memoria a visualizar, el formato de los datos visualizados,
etc. Haciendo un doble clic sobre algún dato podemos modificar directamente la
memoria. Hay que tener en cuenta que el comportamiento de la memoria puede diferir
según estemos en el modo simulación o utilizando el hardware real. Por ejemplo, en
modo simulación, muchas posiciones de memoria tienen un valor indefinido (u:
undefined). Pulsando sobre un dato en memoria que corresponde a la dirección de un
registro de entrada/salida, en la parte superior de la ventana se muestra el nombre
específico de ese registro de Entrada/Salida.
-7-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
-8-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
Figura 4. Modificar la opción indicada en la figura para usar el Hardware (en lugar de la simulación)
Tras finalizar los pasos anteriores el programa será compilado y descargado en la memoria de la
placa de experimentos. A continuación aparecerá una ventana de depuración similar a la que se
mostró en la Figura 3. La diferencia es que ahora el programa obtiene su información
directamente del hardware, a través del bus USB y usando el módulo interno BDM (Background
Debug Mode).
ORG RAMStart
Vector dc.b $01,$03,$07,$0F,$1F,$3F,$7F,$FF
-9-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
ORG ROMStart
Entry
LDAB #$FF
STAB DDRT
LDY #Vector
LDAA #0
Bucle0:
LDX #50000
Bucle1:
DEX
BNE Bucle1
LDAB 0,Y
STAB PTT
INY
INCA
CMPA #8
BNE Bucle0
STOP
ORG $FFFE
fdb Entry
-10-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
DirBase: es la dirección del primer elemento (elemento 0) del vector (la dirección más
pequeña). El segundo elemento sigue directamente al primero en memoria, y así
sucesivamente. DirBase se obtiene usando el nombre de la etiqueta que encabeza la
definición del vector.
TamElemento: es el tamaño en bytes de un elemento del vector (.b indica 1 bytes, .w
indica 2 bytes).
Si el vector en realidad pretende representar una estructura de dos o más dimensiones,
entonces esta estructura de datos se denomina matriz de n dimensiones. En todo caso, una
matriz siempre se representa como una secuencia de elementos, y la fórmula para acceder a los
elementos dependerá de cómo se hagan corresponder las dimensiones de la matriz en una
estructura lineal.
LABORATORIO (resolver las dudas con el profesor durante la sesión):
16) Crear un programa que declare tres vectores: V1, V2 y V3. El vector V1 contiene 10
elementos de tamaño de 1 byte, y se inicializa con los valores 1, 2, 3, 4, 5, 6, 7, 8, 9 y 10. El
vector V2 contiene 10 elementos de tamaño 2 bytes, y se inicializa con los valores $1000, $1001,
$1002, $1003, $1004, $1005, $1006, $1007, $1008 y $1009. El vector V3 contiene 10 elementos
de tamaño 2 bytes, y no se debe inicializar. El programa debe sumar los vectores V1 y V2 y dejar
el resultado en V3. Comprobar el funcionamiento correcto del programa ejecutándolo de forma
controlada: NUNCA se DEBE PROBAR un PROGRAMA ejecutándolo de golpe!
4. Entrada/Salida simple
Se debe realizar un programa que controle dos pulsadores (PAD04 y PAD05), y cuando se
detecte una pulsación encienda o apague un LED (DAO0). En concreto, el funcionamiento se
puede describir con esta tabla, o con el diagrama de estados siguiente:
Evento Acción Pulsación PAD05 Pulsación PAD04 Pulsación PAD04
Pulsación de PAD04 Encender LED DAO0 / nada / encender DAO0 / nada
Pulsación PAD05
/ apagar DAO0
-11-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
ORG RAMStart
ORG ROMStart
Entry:
LDAB #$FF
STAB DDRM ; configura puerto M de salida
STAB PERADLo ; Habilita alimentación entrada a PADLo
STAB ATDDIEN1 ; Habilita Puerto AD como entrada
LDAB #0
STAB DDRADLo ; Configura PTAD (bits 7-0) de entrada
LOOP:
BSR testPDA04 ; Mira si pulsador4 pulsado
BEQ OUTPUT ; Salta si hay cambio en el pulsador
BRA LOOP
-12-
Tutorial de Programación Básica en Ensamblador del Microprocesador HCS12
OUTPUT:
LDAB #??
STAB PTM ; Enciende el LED DAO0
BRA LOOP
testPDA04: ; SUBRUTINA
LDAA PTADLo
ANDA #$10 ; Testea el bit 4 de PAD04 (0= activo)
RTS ; Retorna de subrutina
-13-
Interrupciones con HC12 Estructura de computadores
Introducción
La sincronización con los periféricos puede realizarse mediante 2 técnicas diferentes: el polling y las
interrupciones. En la primera práctica hemos utilizado la primera técnica, el polling, también llamado
“encuesta”, que consistía en muestrear periódicamente los periféricos de entrada (en nuestro caso los
pulsadores). Esta técnica tiene varios inconvenientes. El primero, ya observado en la práctica anterior,
consiste en que los pulsadores no funcionan con precisión. Es decir, las pulsaciones no son siempre
detectadas por el programa, o por el contrario se interpretan varias veces. Aunque este problema podía
haberse solucionado realizando un programa que observara los flancos de los pulsadores, la manera
correcta es utilizar interrupciones. El segundo inconveniente al utilizar la técnica del polling consiste
en que el programa principal desconoce cuando va a producirse un cambio de estado en los pulsadores.
Ese desconocimiento nos obliga a realizar programas poco eficientes que dedican tiempo a preguntar a
los periféricos si han cambiado de estado. Por todo esto, parece más lógico que sea el dispositivo quien
avise al programa en caso de cambio de estado. Este mecanismo es el conocidísimo sistema de
interrupciones.
La sincronización con los periféricos mediante interrupciones es un mecanismo, soportado por los
procesadores, que permite “programar” la ejecución de un código (la Rutina de Servicio a la
Interrupción o RSI) cuando se produce un acontecimiento en el periférico (por ejemplo, se presiona un
pulsador, un timer llega a 0, etc). Veamos, paso a paso, los mecanismos necesarios para poner en
práctica un sistema de interrupciones.
1
Interrupciones con HC12 Estructura de computadores
Dentro del grupo de las enmascarables podemos distinguir 2 tipos de interrupciones, las internas y las
externas. Las internas son originadas por dispositivos que residen dentro del procesador y que no
requieren de interacción con el usuario (timers y puertos serie). Las externas son originadas por
dispositivos externos al procesador. Estos dispositivos utilizan la línea de Interrupt Request (IRQ) para
llamar la atención del procesador.
3.- Protocolo de sucesos y acciones desde que se reconoce una interrupción hasta
que finaliza la RSI asociada.
Existen varios requisitos para que una petición de interrupción sea atendida correctamente:
1. El flag I-bit del registro de estado debe estar habilitado. Este flag habilita/inhibe todas las
interrupciones.
2. El bit de enable del registro de control del periférico debe estar habilitado. Este bit habilita/inhibe
las interrupciones del periférico en cuestión.
3. El vector de interrupción que da servicio al periférico debe estar bien inicializado.
Si todos los requisitos anteriores se dan a la vez, una petición de interrupción será reconocida de
inmediato si no hay otra en curso. A continuación se detallan los sucesos (los ejecuta el sistema) y
acciones (las ejecuta el usuario) que se producen una vez reconocida una interrupción:
… Código de la RSI …
6. (Acción dentro RSI) Ejecutar la instrucción RTI. Esta instrucción se utiliza para salir de la RSI
y se diferencia de RTS en que debe rescatar de la pila más información.
7. (Suceso derivado de RTI) Se habilita el I-bit para permitir nuevas interrupciones.
8. (Suceso derivado de RTI) Se restaura el estado del procesador. Es decir, se rescata de la pila
los valores de X, Y, D y CCR anteriores a la interrupción.
9. (Suceso derivado de RTI) Se restaura en el PC la dirección de retorno, que se extrae de la pila.
10. (Acción fuera RSI) Desinstalar vector de interrupción antes de acabar el programa.
La relación de sucesos y acciones que se han descrito son necesarios en todos los procesadores. Lo que
puede suceder es que en algunos casos haya acciones que deba ejecutarlas el usuario ya que el sistema
no lo hace.
3
Interrupciones con HC12 Estructura de computadores
SESIÓN 1
Pre-laboratorio:
1. El alumno leerá con atención la sección 7 del “HC12 Reference Manual” y la sección 5 del
“Mc9S12E-Family Device User Guide V01.04”, además del capítulo introductorio que viene con
este tutorial.
2. Repasar el significado de las instrucciones BSET, BCLR, BRSET y BRCLR. Si existe alguna duda
preguntar al profesor.
3. El alumno entregará al profesor, al inicio de la sesión, un documento escrito con la respuesta a las
siguientes preguntas:
• ¿En qué registro se encuentra alojado el I-Bit y para qué sirve? ¿Qué lógica utiliza?
• ¿Es necesario ejecutar CLI en el programa para permitir las interrupciones? Razona tu
respuesta
• ¿Es necesario tener habilitado el I-Bit para que funcione el botón de reset de la placa y la
instrucción SWI? Razona tu respuesta.
• Cuándo una instrucción está en medio de su ejecución y se produce una interrupción, ¿Qué
sucede? ¿Se interrumpe esa instrucción o se deja acabar? Razona tu respuesta.
Laboratorio:
En esta sesión se realizan las acciones indicadas por el tutorial y se contestan las preguntas que en él se
formulan, siendo obligatorio la entrega de dichas respuestas. Para ello se partirá de un programa
ejemplo (ver Ejemplo 1), un programa que contabiliza las veces que se presiona PAD04, a partir del
cual se irá aprendiendo los entresijos de las interrupciones. Este programa configura de entrada el
puerto AD, habilita las interrupciones, y espera a que se pulse 5 veces PAD04 para finalizar el
programa. El programa principal es un bucle de 3 instrucciones (LDAA, CMP, BPL) que analiza
permanentemente el estado de la variable contador. La RSI incrementa esa variable cada vez que se
pulsa PAD04. Esta es la manera de sincronizar un programa principal con una RSI, a través de
variables globales.
4
Interrupciones con HC12 Estructura de computadores
A) Crear un proyecto con el programa que se os da como ejemplo nº 1. Poner un breakpoint en la RSI
(instrucción marcada en rojo). Ejecutar RUN. Apretar el pulsador PAD04. ¿Ha entrado en la RSI? No.
¿Por qué? ¿Por qué no funciona el botón? NO es el caso. Comprobar usando el depurador cómo el flag
se ha activado después de apretar el pulsador (ver dirección 27F). Lo que sucede es que alguno de los 3
requisitos vistos en el protocolo de sucesos y acciones no se ha realizado correctamente. Repásalos y
con ayuda del debugger encuentra los errores. Modifica el programa con la solución a los errores.
B) Ahora que la RSI ya se ejecuta, se ha parado la ejecución en el breakpoint de la RSI, ¿qué valores
han sido escritos en la pila como resultado de atender la interrupción? Responder a esta pregunta
utilizando una tabla donde aparezcan 3 columnas: la dirección de la pila, el contenido que allí se ha
almacenado (dirección de retorno, X, Y, D o CCR), y el valor que encontramos. Si ejecutamos varias
veces esta acción (resetear programa y empezar de nuevo en cada acción), ¿La dirección de retorno es
siempre la misma? Razona tu respuesta.
C) Nos encontramos parados en el breakpoint de la RSI. Ejecutemos RUN. ¿Qué sucede? ¿Vuelve a
entrar en la RSI? ¿Por qué? No hemos pulsado PAD04, ¿no? Razonar la respuesta y añade la
instrucción que falta para que eso no suceda.
D) Ahora que la RSI funciona correctamente y sólo se ejecuta una vez por pulsación de PAD04, ¿Qué
estado tiene el I-Bit antes de entrar en la RSI? ¿Qué estado tiene cuando nos encontramos dentro de la
RSI? ¿Qué estado tiene al salir de la RSI y volver al programa principal? Para contestar estas
preguntas habrá que añadir otro breakpoint en el bucle principal (p.e en BPL). ¿Coinciden los
resultados con lo visto en el protocolo de sucesos y acciones?
Añadir en el programa la funcionalidad necesaria para tratar el pulsador PAD05, de manera que este
nuevo pulsador decremente la variable “Contador_PAD04”.
Memoria:
El alumno deberá entregar una memoria donde se recojan las soluciones a las preguntas realizadas,
tanto en el pre-laboratorio como en el tutorial, una vez adquirido el conocimiento resultado de la
sesión.
5
Interrupciones con HC12 Estructura de computadores
; variable/data section
ORG RAMStart
; Insert here your data definition.
Contador_PAD04 dc.b 0
; code section
ORG ROMStart
CLI ;Habilitar todas las interrupciones enmascarables
Entry:
LDS #$1FFF
espera_infinita:
LDAA #$5
CMPA Contador_PAD04
BPL espera_infinita
RSI_PAD04:
;Código de la RSI
INC Contador_PAD04
RTI
;**************************************************************
;* Interrupt Vectors *
;**************************************************************
ORG $FFFE
fdb Entry ; Reset
ORG $FFD0
fdb RSI_PAD04 ; PAD04
Ejemplo nº1
6
Interrupciones con HC12 Estructura de computadores
Introducción
La sincronización con los periféricos puede realizarse mediante 2 técnicas diferentes: el polling y las
interrupciones. En la primera práctica hemos utilizado la primera técnica, el polling, también llamado
“encuesta”, que consistía en muestrear periódicamente los periféricos de entrada (en nuestro caso los
pulsadores). Esta técnica tiene varios inconvenientes. El primero, ya observado en la práctica anterior,
consiste en que los pulsadores no funcionan con precisión. Es decir, las pulsaciones no son siempre
detectadas por el programa, o por el contrario se interpretan varias veces. Aunque este problema podía
haberse solucionado realizando un programa que observara los flancos de los pulsadores, la manera
correcta es utilizar interrupciones. El segundo inconveniente al utilizar la técnica del polling consiste
en que el programa principal desconoce cuando va a producirse un cambio de estado en los pulsadores.
Ese desconocimiento nos obliga a realizar programas poco eficientes que dedican tiempo a preguntar a
los periféricos si han cambiado de estado. Por todo esto, parece más lógico que sea el dispositivo quien
avise al programa en caso de cambio de estado. Este mecanismo es el conocidísimo sistema de
interrupciones.
La sincronización con los periféricos mediante interrupciones es un mecanismo, soportado por los
procesadores, que permite “programar” la ejecución de un código (la Rutina de Servicio a la
Interrupción o RSI) cuando se produce un acontecimiento en el periférico (por ejemplo, se presiona un
pulsador, un timer llega a 0, etc). Veamos, paso a paso, los mecanismos necesarios para poner en
práctica un sistema de interrupciones.
alojada en el espacio de memoria que va desde $FF80 a $FFFF. Cada vector ocupa 2 bytes (una
dirección). Sólo hay que conocer el vector que corresponde a cada periférico (ver tabla 5-1) del
“Mc9S12E-Family Device User Guide V01.04”.
Dentro del grupo de las interrupciones enmascarables del HC12 podemos distinguir 2 tipos de
interrupciones, las internas y las externas. Las internas son originadas por dispositivos que residen
dentro del procesador y que no requieren de interacción con el usuario (timers y puertos serie). Las
externas son originadas por dispositivos externos al procesador. Estos dispositivos utilizan la línea de
Interrupt Request (IRQ) para llamar la atención del procesador.
3.- Protocolo de sucesos y acciones desde que se reconoce una interrupción hasta
que finaliza la RSI asociada.
Existen varios requisitos para que una petición de interrupción sea atendida correctamente:
1. El flag I-bit del registro de estado debe estar habilitado. Este flag habilita/inhibe todas las
interrupciones.
2. El bit de enable del registro de control del periférico debe estar habilitado. Este bit habilita/inhibe
las interrupciones del periférico en cuestión.
3. El vector de interrupción que da servicio al periférico debe estar bien inicializado.
Si todos los requisitos anteriores se dan a la vez, una petición de interrupción será reconocida de
inmediato si no hay otra en curso. A continuación se detallan los sucesos (los ejecuta el sistema) y
acciones (las ejecuta el usuario) que se producen una vez reconocida una interrupción:
los dispositivos llevan asociado un flag que se activa cuando producen interrupción. Este flag hay
que borrarlo antes de finalizar la RSI, porqué de lo contrario o no se producirá ninguna otra
interrupción de ese tipo, en el caso de Intel, o se repetirá la misma interrupción en el caso del
HC12.
… Código de la RSI …
6. (Acción dentro RSI) Ejecutar la instrucción RTI. Esta instrucción se utiliza para salir de la RSI
y se diferencia de RTS en que debe rescatar de la pila más información.
7. (Suceso derivado de RTI) Se habilita el I-bit para permitir nuevas interrupciones.
8. (Suceso derivado de RTI) Se restaura el estado del procesador. Es decir, se rescata de la pila
los valores de X, Y, D y CCR anteriores a la interrupción.
9. (Suceso derivado de RTI) Se restaura en el PC la dirección de retorno, que se extrae de la pila.
10. (Acción fuera RSI) Desinstalar vector de interrupción antes de acabar el programa.
La relación de sucesos y acciones que se han descrito son necesarios en todos los procesadores. Lo que
puede suceder es que en algunos casos haya acciones que deba ejecutarlas el usuario ya que el sistema
no lo hace, como por ejemplo, salvar y recuperar el estado del procesador.
3
Interrupciones con HC12 Estructura de computadores
SESIÓN 1
Pre-laboratorio:
1. El alumno leerá con atención la sección 7 del “HC12 Reference Manual” y la sección 5 del
“Mc9S12E-Family Device User Guide V01.04”, además del capítulo introductorio que viene con
este tutorial.
2. Repasar el significado de las instrucciones BSET, BCLR, BRSET y BRCLR. Si existe alguna duda
preguntar al profesor.
3. El alumno entregará al profesor, al inicio de la sesión, un documento escrito con la respuesta a las
siguientes preguntas:
• ¿En qué registro se encuentra alojado el I-Bit y para qué sirve? ¿Qué lógica utiliza?
• ¿Es necesario ejecutar CLI en el programa para permitir las interrupciones? Razona tu
respuesta
• ¿Es necesario tener habilitado el I-Bit para que funcione el botón de reset de la placa y la
instrucción SWI? Razona tu respuesta.
• Cuándo una instrucción está en medio de su ejecución y se produce una interrupción, ¿Qué
sucede? ¿Se aborta la ejecución de esa instrucción o se deja acabar? Razona tu respuesta.
Laboratorio:
En esta sesión se realizan las acciones indicadas por el tutorial y se contestan las preguntas que en él se
formulan, siendo obligatorio la entrega de dichas respuestas. Para ello se partirá de un programa
ejemplo (ver Ejemplo 1), un programa que contabiliza las veces que se presiona PAD04, a partir del
cual se irá aprendiendo los entresijos de las interrupciones. Este programa configura de entrada el
puerto AD, habilita las interrupciones, y espera a que se pulse 5 veces PAD04 para finalizar el
programa. El programa principal es un bucle de 3 instrucciones (LDAA, CMP, BPL) que analiza
permanentemente el estado de la variable contador. La RSI incrementa esa variable cada vez que se
pulsa PAD04. Esta es la manera de sincronizar un programa principal con una RSI, a través de
variables globales.
4
Interrupciones con HC12 Estructura de computadores
A) Crear un proyecto con el programa que se os da como ejemplo nº1. Poner un breakpoint en la RSI
(instrucción marcada en rojo). Ejecutar RUN. Apretar el pulsador PAD04. ¿Ha entrado en la RSI? No.
¿Por qué? ¿Porqué no funciona el botón? NO es el caso. Comprobar como el flag se activa después de
apretar el pulsador (ver dirección 27F). Lo que sucede es que alguno de los 3 requisitos vistos en el
protocolo de sucesos y acciones no se ha realizado correctamente. Repásalos y con ayuda del debugger
encuentra los errores. Modifica el programa con la solución a los errores.
B) Ahora que la RSI ya se ejecuta, se ha parado la ejecución en el breakpoint de la RSI, ¿qué valores
han sido escritos en la pila como resultado de atender la interrupción? Responder a esta pregunta
utilizando una tabla donde aparezcan 3 columnas: la dirección de la pila, el contenido que allí se ha
almacenado (dirección de retorno, X, Y, D o CCR), y el valor que encontramos. Si ejecutamos varias
veces esta acción (resetear programa y empezar de nuevo en cada acción), ¿La dirección de retorno es
siempre la misma? Razona tu respuesta.
C) Nos encontramos parados en el breakpoint de la RSI. Ejecutemos RUN. ¿Qué sucede? ¿Vuelve a
entrar en la RSI? ¿Porqué? No hemos pulsado PAD04, ¿no? Razonar la respuesta y añade la
instrucción que falta para que eso no suceda.
D) Ahora que la RSI funciona correctamente y sólo se ejecuta una vez por pulsación de PAD04, ¿Qué
estado tiene el I-Bit antes de entrar en la RSI? ¿Qué estado tiene cuando nos encontramos dentro de la
RSI? ¿Qué estado tiene al salir de la RSI y volver al programa principal? Para contestar estas
preguntas habrá que añadir otro breakpoint en el bucle principal (p.e en BPL). ¿Coinciden los
resultados con lo visto en el protocolo de sucesos y acciones?
Añadir en el programa la funcionalidad necesaria para tratar el pulsador PAD05, de manera que este
nuevo pulsador decremente la variable “Contador_PAD04”.
Memoria:
El alumno deberá entregar una memoria donde se recojan las soluciones a las preguntas realizadas,
tanto en el pre-laboratorio como en el tutorial, una vez adquirido el conocimiento resultado de la
sesión.
5
Interrupciones con HC12 Estructura de computadores
; variable/data section
ORG RAMStart
; Insert here your data definition. For demonstration, temp_byte is used.
Contador_PAD04 dc.b 0
; code section
ORG ROMStart
CLI ;Habilitar todas las interrupciones enmascarables
Entry:
LDS #$1FFF
espera_infinita:
LDAA #$5
CMPA Contador_PAD04
BPL espera_infinita
RSI_PAD04:
;Código de la RSI
INC Contador_PAD04
RTI
;**************************************************************
;* Interrupt Vectors *
;**************************************************************
ORG $FFFE
fdb Entry ; Reset
ORG $FFD0
fdb RSI_PAD04 ; PAD04
Ejemplo nº1
6
Tutorial de Programación en C con el Microprocesador HCS12
Material:
Computador Personal (MS-Windows) con un puerto USB disponible y cable USB
Metrowerks CodeWarrior HC(S)12 (http://www.codewarrior.com/MW/download)
SofTec Microsystems PK-HCS12E128 “System Software” (Campus Virtual)
1. Programas en C
Un programa es un fichero de texto escrito según la sintaxis y la semántica del lenguaje C. Se
puede crear un programa a partir de múltiples ficheros, aunque este tema queda fuera de los
objetivos de este tutorial. Se supone conocida tanto la sintaxis como la semántica del lenguaje C
(al menos de las instrucciones más comunes).
El siguiente código ejemplo en lenguaje C servirá de base para este tutorial. En él se incluyen
dentro del código instrucciones en ensamblador que utilizan variables definidas en C (la variable
e). También se utilizan las variables predefinidas DDRT y PTT (que se encuentran definidas en
el fichero mc9s12e128.h).
#include <hidef.h> /* common defines and macros */
#include <mc9s12e128.h> /* derivative information */
void main(void) {
char e;
EnableInterrupts;
c = a+b;
e = c;
asm {
LDAA 0xFF ;
STAA 0x242
LDAA e ;
STAA 0x240 ;
}
DDRT = 0xff;
PTT = e;
for(;;) {} /* wait forever */
}
-1-
Tutorial de Programación en C con el Microprocesador HCS12
-2-
Tutorial de Programación en C con el Microprocesador HCS12
Figura 1. Entorno de Edición. Programa ejemplo que aparece por defecto: SE DEBE SUSTITUIR POR EL
CÓDIGO de la página 1.
2.2 Compilando y Depurando el programa
Para compilar y activar el depurador utilizamos directamente la opción Project>Debug. En caso
de errores aparecerá una ventana con mensajes que nos ayudarán a solucionar los problemas.
Comprobar que habéis copiado correctamente el código, y en caso de no saber continuar
preguntar al profesor. Por defecto, el entorno arranca con la opción de la simulación activada, y
de este modo no es necesario disponer de la placa hardware, o se puede tener apagada. Tras
seguir todos los pasos, la ventana del depurador (True-Time Simulator & Real-Time Debugger)
permitirá analizar el código, su funcionamiento, y el estado del procesador. Ampliar al máximo
esta ventana para disponer del máximo espacio para visualizar los datos. En ella se encuentran
ocho sub-ventanas donde podemos obtener mucha de la información necesaria para analizar y
depurar nuestro programa. Las ventanas Assembly, Register y Memory están descritas en el
“Tutorial de Ensamblador”. En este tutorial analizaremos la ventana:
Source: permite visualizar el programa C original y controlar la ejecución de
instrucciones en lenguaje C. Pulsando con el botón derecho del ratón sobre esta
ventana aparecerá un menú de contexto que nos permite variar la información
visualizada.
Los programas en lenguaje C necesitan ejecutar un código de inicialización (startup) antes de
ceder el control a la función principal de nuestro programa (función main). Hasta que no se
ejecuta este código, el depurador no es capaz de conocer cierta información. En la ventana
Source poner un punto de parada sobre la línea que contiene la instrucción “EnableInterrupts”
(→ver Tutorial de Ensamblador para recordar cómo hacerlo). A continuación invocar la ejecución
continua de las instrucciones del programa usando el menú Run, o la tecla <F11>. La ejecución
se detendrá al inicio de la instrucción “EnableInterrupts” y las dos ventanas inferiores de la
-3-
Tutorial de Programación en C con el Microprocesador HCS12
-4-
Tutorial de Programación en C con el Microprocesador HCS12
3. Entrada/Salida simple
Se debe realizar un programa que controle dos pulsadores (PAD04 y PAD05), y cuando se
detecte una pulsación encienda o apague un LED (DAO0). En concreto, el funcionamiento se
puede describir con esta tabla, o con el diagrama de estados siguiente:
Evento Acción Pulsación PAD05 Pulsación PAD04 Pulsación PAD04
Pulsación de PAD04 Encender LED DAO0 / nada / encender DAO0 / nada
Pulsación PAD05
/ apagar DAO0
-5-
Tutorial de Programación en Assembler Bajo
Linux
10 de julio de 2006
2
Índice general
Introducción III
i
ii ÍNDICE GENERAL
3. Funciones y Modularidad 15
3.1. Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2. Resolviendo Un Primer Problema . . . . . . . . . . . . . . . . . . 17
3.2.1. Solución en Pseudocódigo . . . . . . . . . . . . . . . . . . 18
3.2.2. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2.3. Implementando el Algoritmo . . . . . . . . . . . . . . . . 18
3.2.4. Ensamblando y Enlazando . . . . . . . . . . . . . . . . . . 19
3.3. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3.1. Paso de Parámetros . . . . . . . . . . . . . . . . . . . . . 20
3.3.2. Parámetros por Referencia . . . . . . . . . . . . . . . . . 20
3.3.3. Funciones Recursivas . . . . . . . . . . . . . . . . . . . . . 20
Introducción
iii
iv INTRODUCCIÓN
Capı́tulo 1
Programación, Ensamblado,
Enlazado y Depuración
1. /*
2. Este es un tipo de comentario
3. */
4. #Otro tipo de comentario
5. #nombre de archivo (opcional)
6. .file "Ejemplo1.s"
7. #secciones
8. .section .data
9. # <- datos
10. # <- datos
11. #PROGRAMA
12. .section .text
13. .global _start
14. _start:
15. #FINALIZA PROGRAMA
1
2CAPÍTULO 1. PROGRAMACIÓN, ENSAMBLADO, ENLAZADO Y DEPURACIÓN
1.1.1. Comentarios
Realizar comentarios en los programas de Assembler pasa de ser una buena
costumbre de programación a una necesidad vital. En as se permite realizar
comentarios de 2 formas:
1.1.2. Secciones
El código de Assembler debe ser relocalizado en la fase de enlazado con el fin
de que cada parte ocupe la sección que le corresponde. Existen básicamente 5
secciones de enlazado pero, por razones prácticas, nos ocuparemos únicamente
de la de datos .data y la de “texto”.text, para ver las otras secciones se puede
recurrir a [1] (sección 4).
Las secciones .text y .data (que aparecen en las lı́neas 8 y 10) son muy
parecidas, la única diferencia es que la sección .text es comúnmente compartida
entre procesos, además, contiene instrucciones y constantes (el código es .text).
la sección .data es usualmente alterable1 .
Label
Los códigos de instrucción que operen sobre 32 bits se les debe agregar el
sufijo “l”
xorl %eax, %eax: Realiza un or exclusivo de eax con eax. Como eax es igual a
eax, el resultado de esta operación, deja eax en ’0’.
int $0x80: Esta es una llamada a una interrupción, le dice al sistema operativo
que el programa terminó su ejecución.
Input: N1 , N2 , N3 , N4 , N5
Output: Sumatoria
return N1 + N2 + N3 + N4 + N5 ;
Algoritmo 1: Primera Aproximación
Ahora bien, si tenemos en cuenta que Assembler es un lenguaje donde las
operaciones son predominantemente binarias, valdrı́a la pena convertir nuestro
algorı́tmo a uno que solo requiera operaciones de éste tipo.
Input: N1 , N2 , N3 , N4 , N5
Output: Sumatoria
Acumulador ←− 0;
Acumulador += N1 ;
Acumulador += N2 ;
Acumulador += N3 ;
Acumulador += N4 ;
Acumulador += N5 ;
return Acumulador
1.2.2. Variables
Algo importante en la programación en Assembler es tener claras las vari-
ables que se utilizarán, Para esto, se debe tener en cuenta lo siguiente:
<label>: <tama~
no> <valor inicial>
.section .data
Numero1: .long 100
Numero2: .long 0144
Numero3: .long 0x64
Numero4: .long 0b1100100
Numero5: .long -100
las instrucciones se puede buscar en [2] o también existe una hoja de referencia
con las instrucciones más utilizadas en http://www.jegerlehner.ch/intel/
IntelCodeTable_es.pdf.
La primera instrucción, pone el acumulador (EAX) en 0. La instrucción
clrl %eax nos realizará esta tarea.
Para sumar utilizaremos (add origen, destino). Asi nos quedará el código del
programa de esta forma:
1. .file "Sumatoria.s"
2. .section .data
3. Numero1: .long 100
4. Numero2: .long 0144
5. Numero3: .long 0x64
6. Numero4: .long 0b1100100
7. Numero5: .long -100
8. .global _start
8.1. .text
9. _start:
10. clrl %eax
11. addl Numero1,%eax
12. addl Numero2,%eax
13. addl Numero3,%eax
14. addl Numero4,%eax
15. addl Numero5,%eax
16. xorl %eax, %eax
17. incl %eax
18. xorl %ebx, %ebx
19. int $0x80
20. .end
2
Las opciones que nos interesan de as son las siguientes (para mas información
ver [1] Sección 1).
ld -o Sumatoria Sumatoria.o
Sumatoria es el ejecutable.
gdb <ejecutable>
l ist: muestra el código fuente, es útil para tener las lineas exactas donde se
ponen los puntos de parada (break).
break <linea>: pone un punto de parada en la lı́nea indicada.
break *<dir>: pone un punto de parada en la dirección indicada.
r un: ejecuta el programa
k ill: termina el programa
q uit: sale de gdb
i nfo r egisters: muestra el estado de los registros.
i nfo variables: muestra el estado de las variables.
8CAPÍTULO 1. PROGRAMACIÓN, ENSAMBLADO, ENLAZADO Y DEPURACIÓN
1.3. Ejercicios
1.3.1. Manejo de variables
Cambiar el programa de 1.2.3 para que trabaje con variables de 16 bits y de
8 bits.
1.3.2. Invertir
Hacer un programa que dados 5 números alojados en memoria N1 , N2 , N3 , N4 , N5 ,
invierta el orden de los valores asignados en un principio. es decir: N1 −→ N5
N2 −→ N4 N3 −→ N3 N4 −→ N2 N5 −→ N1
Control de flujo y
Estructuras Indexadas
Input: Entrada
Output: Salida
for i ←− n to 1 do
//Secuencia de pasos;
end
9
10 CAPÍTULO 2. CONTROL DE FLUJO Y ESTRUCTURAS INDEXADAS
1. mov n, %ecx
2. bucle:
3. ##SECUENCIA
4. loop bucle
Una cosa importante a tener en cuenta es que dado que el valor que controla
el número de saltos está en ECX, dentro de la secuencia es importante que el
valor no se altere, o si se altera, conservarlo en una variable, para cuando se
ejecute la instrucción Loop, restaurarlo.
CMP: Sirve para comparar. Internamente es una resta entre los 2 operandos
que se comparan
JE: Éste es un salto que se ejecuta cuando la comparación anterior dio como
resultado que los 2 operandos son iguales.
Input: Entrada
Output: Salida
if A operador B then
#SECUENCIA DE PASOS SI SE CUMPLE LA CONDICIÓN;
else
#SECUENCIA DE PASOS SI NO SE CUMPLE LA CONDICIÓN;
end
Algoritmo 3: operador es cualquiera de (=, 6=, ≤, ≥, <, >)
1. cmp A,B
2. <Salto> else
3. #SECUENCIA DE PASOS SI SE CUMPLE LA CONDICIÓN}
4. jmp fin
5. else:
6. #SECUENCIA DE PASOS SI \textbf{NO} SE CUMPLE LA CONDICIÓN
7. fin:
Implementando el While
Input: Entrada
Output: Salida
while A operador B do
#SECUENCIA DE PASOS DENTRO DEL WHILE;
end
Algoritmo 4: operador es cualquiera de (=, 6=, ≤, ≥, <, >)
1. while:
2. cmp a,b
3. <Salto> salir
4. #SECUENCIA DE PASOS DENTRO DEL WHILE\
5. jmp while
6. salir:
Input: Arreglo[], T am
Output: M ayor
M ayor ←− Arreglo[T am];
for i ←− T am to 0 do
if Arreglo[i] > M ayor then
M ayor ←− Arreglo[i]
end
end
return Mayor
Algoritmo 5: Número Mayor en Arreglo
.section .data
Tam: .long 5
Arreglo: .int 0,2,4,8,10
Por ahora utilizaremos una variable en memoria llamada prueba, con el fin
de garantizar que el fragmento este correcto, despues reemplazaremos esto por
la correspondiente posición.
Una vez hayamos probado la parte del If según lo indicado en 1.2.4, podemos
implementar el for según lo visto en 2.1.1.
.file "MayorenArreglo.s"
.section .data
Tam: .long 5
Arreglo: .int 0,2,4,8,10
prueba: .long 4
.text
.global _start
_start:
movl Tam, %ecx
loop1:
cmpl %eax, Arreglo(,%ecx,4)
JLE else
movl Arreglo(,%ecx,4), %eax
jmp fin
else:
#En este caso no hay Else
fin:
loop loop1
xorl %eax, %eax
incl %eax
xorl %ebx, %ebx
int $0x80
.end
2.3. Ejercicios
2.3.1. Problema del Programa Anterior
En la solución de la busqueda del número mayor hay un grave error, ¿Cuál
és? ¿Cómo se soluciona?
Funciones y Modularidad
3.1. Funciones
A medida que un programa aumenta de complejidad, se detectan ciertas
porciones de código que realizan lo mismo basados en 0 o más parámetros. A
estos fragmentos, podemos agruparlos en funciones.
Independiente de la arquitectura utilizada, una función está constituida por
dos componentes: El Llamador y el Llamado
Invocar el Llamado
15
16 CAPÍTULO 3. FUNCIONES Y MODULARIDAD
16.
17. .global _start
18. _start:
19.
20. # "Main"
21. pushl a
22. pushl b
23. call sumar
24. popl %ebx
25. popl %ebx
26.
27. # Finalizo el programa
28. xorl %eax, %eax
29. incl %eax
30. xorl %ebx, %ebx
31. int $0x80
32. .end
Input: Arreglo[], T am
Output: Sumatoria
Sumatoria ←− 0;
i ←− 0;
while i < T am do
Sumatoria ←− sumar(Arreglo[i], Sumatoria);
i + +;
end
return Sumatoria
Algoritmo 6: Sumatoria de N números en Arreglo
3.2.2. Variables
Nombre Tamaño Lugar
T am 32 bits Memoria
Arreglo[] 32 bits Memoria
Sumatoria 32 bits EAX
i 32 bits ECX
1. .file "Suma.s"
2. .section .text
3. .global suma
4. suma:
5. pushl %ebp
7. movl %esp, %ebp
8. movl 8(%ebp), %ebx
9. movl 12(%ebp), %eax
10. addl %ebx, %eax
11. leave
12. ret
.file "Principal.s"
.section .data
Tam: .long 5
Arreglo: .int 0,2,4,8,10
.section .text
.global _start
.extern suma
_start:
pushl Arreglo(,%ecx,4)
pushl %eax
call suma
pop %ebx
pop %ebx
inc %ecx
jmp while1
finwhile1:
# Finalizo el programa
xorl %eax, %eax
incl %eax
xorl %ebx, %ebx
int $0x80
.end
3.3. Ejercicios
3.3.1. Paso de Parámetros
Cambie la función para trabajar con otras formas de paso de parámetros
(por registros y area de memoria)
[1] Dean Elsner and Jay Fenlason. Using as, Enero 1994.
21
EE 371 LAB 1 - F05 Name ___________________
MC68HCS12 Programming - Introduction
Why is it your feet smell and your nose runs? Partner_________________
Meeting Day _____
References: EE371 texts, Hitchhiker's Guide to CodeWarrior HR ______
Schedule: 9/7, 8 Do the lab Demo:
9/14, 15 Programs demonstrated (3)__________
(8) __________
1. Pre-Lab:Read
Extra credit (9) __________
2. Follow steps 1-18 in the Hitchhiker's Guide to CodeWarrior to enter and make the
following program.
a. Type the following code into main.asm (step 10) after the comment ; Your program code goes here.
;********************************
; Your program code goes here
; Initialize I/O
main_loop:
; DO
nop ; No operation
ldx #main_loop ; Initialize pointer
ldab #$02 ; Load Reg B
loop:
ldaa 0,x ; Load Reg A
staa VarData ; Save it
ldaa 2,x ; Load Reg A again
staa VarData+1 ; Save it again
inx ; Increment pointer
decb ; Decrement counter
bne loop ; If counter not zero loop
nop ; Do nothing again
; FOREVER
bra main_loop
MyConst:SECTION
; Place constant data here
;********************************
MyData: SECTION
; Place variable data here
VarData: DS.B 2 ; Two bytes of storage
After you have successfully compiled (assembled!) and made the program, go to step 16 and 17 to use the True-Time Simulator
and P&E ICD Target.
After the simulator has been launched, have a look at the display.
The Source window shows your source program.
The Assembly window shows the program as it looks in memory. Right Click in the Assembly window and check Display
Code to make your display show the code in the memory locations $C000 - $C025. Right Click again and check Display
Symbolic to show symbolic instead of decimal addresses.
The Registers window shows the current status/contents of all registers.
The Data window will show the current value of variable data in your program. Click on the +VarData to show the two variable
bytes. Right Click on VarData and select Format… Hex.
The Procedure window shows what procedure you are currently in and the Command window allows you to enter
simulator/debugger commands. We will see more of these windows in future labs.
The Memory window allows the display of memory contents. Right Click in the Memory window and select Address . . . and
in the Display Address window enter C000.
In the Source window position the cursor pointer over the nop instruction and Right Click and select Set Breakpoint.
Click the Green Run Arrow or click Run > Start/Continue. The program should run to your breakpoint and stop. (Note: A
breakpoint stops the program before it executes that statement.)
1
Now, step through your program one assembly language statement at a time by clicking on the single-
step button or pressing F11 until you reach the nop instruction at the beginning of the program you
entered. (We will see what the LDS instruction is all about later.)
At each step inspect the Register window to see what is happening to the registers. Try to predict what will happen at each step
BEFORE you click on the step button.
3. Explain to your lab instructor what you see on the screen. In particular, explain what is happening to each register and to the
condition code register.
5. Create a new project by entering the following program. To save some typing, you can get the source file from the “N” drive. (If
you haven’t done so all ready, you can map drive N to ohm\\ececourses$.) The source file is N:\EE371\lab01_f05\lab_01_f05.asm.
In the project manager, File > Open, browse to the file, and then after opening the file do File > Save As … and be sure to position
to your project folder in the Sources folder. You can also rename the file if you wish. Then Project > Add lab_01_f05.asm to
Project…
2
staa PORTA
stab PORTB
; Delay some time
jsr delay_sub ; Use a subroutine
; Complement the display values
coma ; Complement A register
comb ; Complement B register
; FOREVER
bra main_loop
;********************************
; Simple Delay Subroutine
; Registers modified: CCR
;********************************
delay_sub:
pshx ; Save the registers
pshy
ldy #DELAY2 ; Initialize outer loop counter
outer:
; WHILE the Y register is not zero
; Decrement the outer loop counter
dey
beq all_done ; Branch when Y equal to zero
; DO the inner loop
ldx #DELAY1 ; Initialize inner loop counter
inner:
; WHILE the X register is not zero
; DO Decrement the inner loop counter
dex
bne inner ; Branch when X NOT equal to zer0
; ENDWHILE X not zero
bra outer
; ENDWHILE Y not zero
all_done:
puly ; Restore the registers
pulx
rts
;********************************
MyConst:SECTION
; Place constant data here
;********************************
MyData: SECTION
; Place variable data here
6. Run the program. You should see the two LEDs on the CSM-12C32 microcontroller board flashing.
7. Step through the program to see how it works.
8. Modify the program so that it flashes at about ½ the rate.
9. Extra Credit: Modify the program so that it flashes LED1 twice while LED2 is off and then LED2 twice while LED1 is off and repeats.
10. Grading: Program demo s 5 points each, extra credit 5 points
3
EE 308 Spring 2006
Writing Assembly Language Programs — Use Flowcharts to Help Plan Program Structure
START
LABEL:
OPERATION
YES
CONDITIONAL BRANCH
NO
END
1
EE 308 Spring 2006
if (C)
{
A;
}
FALSE
C?
TRUE
L1:
L2:
EXAMPLE:
OR:
CMPA #10
BGE L2
LDAB #5
STAB var
L2: next instruction
2
EE 308 Spring 2006
if (C)
{
A;
}
else
{
B;
}
FALSE
B C?
TRUE
L1:
L2:
3
EE 308 Spring 2006
do
{
A;
}
while (C);
L1:
TRUE
C?
FALSE
EXAMPLE:
i = 0; LDX #table
do CLRA
{ L1: ASR 1,X+
table[i] = table[i]/2; INCA
i = i+1; CMPA #LEN
} BLE L1
while (i <= LEN);
4
EE 308 Spring 2006
while (C)
{
A;
}
L1:
TRUE
A C?
L2:
FALSE
L3:
EXAMPLE:
i = 0; LDX #table
while (i <= LEN) CLRA
{ L1: CMPA #LEN
table[i] = table[i]*2; BLT L2
i = i + 1; BRA L3
} L2: ASL 1,X+
INCA
BRA L1
L3: next instruction
5
EE 308 Spring 2006
SPAGHETTI CODE
DO NOT USE
6
EE 308 Spring 2006
Problem: Start with a table of data. The table consists of 5 values. Each
value is between 0 and 255. Create a new table whose contents are the original
table divided by 2.
$2000 table1:
COUNT
table2:
7
EE 308 Spring 2006
START
table1 X Init
Pointers
COUNT
Get
Entry
table2 Y Divide
by 2
Store
Result
Inc
Pointers
8
EE 308 Spring 2006
START
Init
Counter
table1 X Init
Pointers
L1:
COUNT
Get
Entry
table2 Y Divide
by 2
Store
Result
Inc
Pointers
Dec
Counter
YES
More?
NO
STOP
9
EE 308 Spring 2006
START
Init
Counter LDAA #COUNT
Store
Result STAB 0,Y
Inc INX
Pointers INY
Dec
Counter DECA
YES BNE L1
More?
NO
STOP SWI
10
EE 308 Spring 2006
8. Write program:
count: equ 5
org data
table1: dc.b $07,$c2,$3a,$68,$F3
table2: ds.b count
11
EE 308 Spring 2006
count: equ 5
org data
table1: dc.b $07,$c2,$3a,$68,$F3
table2: ds.b count
12
EE 308 Spring 2006
13
Programación con HC12 Estructura de computadores
Se dispone de 4 sesiones de prácticas para realizarla. Es obligatorio entregar el prelaboratorio antes del
inicio de cada sesión, su falta implica suspender las prácticas. Al finalizar cada sesión debe mostrarse
el funcionamiento de la práctica al profesor.
A continuación, se define el trabajo a realizar para cada sesión.
SESIÓN 1
Prelaboratorio:
1. Explicar cómo realizar el acceso indexado a la matriz de la figura 1 a través del array de la figura 2.
Implementar el código de la función que realiza este tipo de acceso a la matriz.
Práctica:
figura 2
Implementar un programa que acceda a los elementos de la matriz mediante los diferentes métodos:
a) Por filas
b) Por columnas
c) Indexado a través del array definido en la figura 2
El programa debe visualizar el valor obtenido de la matriz, para cada método de acceso, encendiendo
los leds correspondientes.
1
Programación con HC12 Estructura de computadores
SESIÓN 2
Prelaboratorio:
2. Mostrar un organigrama y el pseudocódigo del programa que se pide en el apartado 2.1 y 2.2 de la
práctica.
Práctica:
tabla 1
Nota: X=led encendido
0 =led apagado
2.2 Una vez seleccionado el método de acceso a la matriz, guardar el identificador del método en
una variable global, mostrar el valor de la matriz mediante los leds, esperar 1 segundo
aproximadamente y mostrar el siguiente valor de la matriz.
Nota: Cuando se accede a la última posición de la matriz, volver a la posición inicial.
2
Programación con HC12 Estructura de computadores
SESIÓN 3
Prelaboratorio:
Práctica:
3.1 Durante la ejecución del apartado 2.2 pueden apretarse los pulsadores. La tabla 2 define los
cambios a realizar en el programa al apretarse alguno de los pulsadores
tabla 2
3.2 Durante la ejecución del programa pueden apretarse los 2 pulsadores (PAD04 y PAD05). En este
caso, finaliza el programa
SESIÓN 4
3
Interrupciones con HC12 Estructura de computadores
Introducción
Al final del primer cuatrimestre introdujimos las interrupciones del HC12 como 2º método de
sincronización con los periféricos, método que solucionaba los inconvenientes del anterior, el polling,
poco eficiente, impreciso en la detección de los pulsadores, etc. Para ello realizamos un tutorial que nos
sirvió para aprender:
Uno de los objetivos de las prácticas de este 2º cuatrimestre es profundizar en el conocimiento del
sistema de interrupciones. Para ello estudiaremos cómo funciona el temporizador del HC12 (práctica 2)
y cómo funcionan las comunicaciones serie y paralela (práctica 3).
El timer del HC12 consiste básicamente en un registro contador de 16 bits (TCNT) que se auto-
incrementa en cada ciclo de reloj (16 Mhz). ¿Cómo se cuenta tiempo? Observando cuántas veces el
TCNT da la vuelta (pasa de FFFF a 0000). Para ayudar al programador el HC12 provee de un flag que
nos avisa de ese hecho. Contar es entonces tan sencillo como conocer cuánto tiempo necesita TCNT
para dar una vuelta y multiplicar ese tiempo por el número de avisos del flag (nº de veces que TCNT da
la vuelta). Para añadir más flexibilidad al sistema, el HC12 incorpora un divisor de frecuencia
(prescaler), que divide la frecuencia inicial (16 Mhz) por 2, 4, 8, 16, …, 256, según se programe.
1
Interrupciones con HC12 Estructura de computadores
El objetivo de esta práctica es resolver los problemas detectados en la práctica desarrollada en el 1er
cuatrimestre:
¿Cómo vamos a resolver estos problemas? Convirtiendo el polling en Interrupciones. El objetivo final
es contener todo nuestro código en 2 RSIs, la del timer y la de los pulsadores. La función principal
únicamente debería contener la inicialización del sistema y la finalización.
En definitiva, esta segunda práctica mantiene la misma funcionalidad que la primera. La diferencia es
que el código se reorganiza para eliminar el polling y crear las interrupciones. Por lo tanto, es
condición necesaria venir a clase con los fuentes de la práctica del primer cuatrimestre.
2
Interrupciones con HC12 Estructura de computadores
SESIÓN 1
Pre-laboratorio:
1. Repasar el tutorial sobre interrupciones visto en el cuatrimestre anterior.
2. El alumno leerá con atención la sección 1 y 3 del “ECT_16B8C Block User Guide V01.06”, además
del capítulo introductorio que viene con esta práctica.
3. El alumno entregará al profesor, al inicio de la sesión, un documento escrito de manera legible con
la respuesta a las siguientes preguntas:
• (En segundos) ¿Cuál es el mínimo tiempo necesario para que TCNT de una vuelta? ¿Y el
máximo? Tener en cuenta la frecuencia del reloj base y la programación del prescaler.
• ¿En qué registro se programa el divisor de frecuencia? ¿Con cuántos bits se implementa?
• ¿Cómo se llama el flan que avisa de que TCNT ha dado una vuelta? ¿En qué registro se
encuentra?
• Para que el registro contador (TCNT) empiece a contar, o lo que es lo mismo, funcione en
modo normal, debe habilitarse un bit de un registro de control. ¿Cuál es y dónde se encuentra?
Laboratorio:
El objetivo de esta sesión es medir los tiempos con precisión. Para ello utilizaremos el timer del HC12
en su versión polling. Organizaremos el trabajo de la siguiente manera:
1. Escribir una rutina (retardo_250) que genere un retardo de 250 milisegundos, utilizando el
temporizador. Calcular correctamente el prescaler necesario para que TCNT de una sola vuelta
en ese tiempo.
2. Modificar la práctica nº1 (1er cuatrimestre) para que los tiempos de retardo sean contados
mediante la rutina anterior, es decir, para contar 1 segundo llamar 4 veces a la rutina
retardo_250. Será tan fácil como almacenar en una variable global el nº de veces que se llama a
esta rutina. Los pulsadores (PAD4 y PAD5) incrementarán o disminuirán dicha variable. Como
resultado de esto eliminaremos de la práctica la rutina de pérdida de tiempo.
3
Interrupciones con HC12 Estructura de computadores
SESIÓN 2
Pre-laboratorio:
1. Repasar el tutorial sobre interrupciones visto en el cuatrimestre anterior.
2. El alumno leerá con atención la sección 1 y 3 del “ECT_16B8C Block User Guide V01.06”, además
del capítulo introductorio que viene con esta práctica.
3. El alumno entregará al profesor, al inicio de la sesión, un documento escrito de manera legible con
la respuesta a las siguientes preguntas:
• En esta sesión pretendemos eliminar el polling de TOF y controlar el temporizador a través de
su RSI. ¿Qué acciones debemos realizar para que la RSI se ejecute? (Recordar los 3
prerrequisitos vistos en el tutorial. Nombrar los bits y registros involucrados en las acciones)
Laboratorio:
El objetivo de esta sesión es escribir la RSI del timer donde se incluya todo el código que controla el
cambio de configuración de los leds. Organizaremos el trabajo de la siguiente manera:
Versión 1
1. RSI timer: Convertir la rutina retardo_250 en RSI del timer. Esta rutina será llamada por el
sistema cada vez que TOF se active, siempre y cuando hayamos sido capaces de implementar
los 3 prerrequisitos. La RSI debe contabilizar (incrementando la var. global “contador_250”)
el nº de interrupciones producidas (1 cada 250 mseg.). Implementar en la RSI todo lo
necesario para su buen funcionamiento (recordar cómo se implementaba la RSI de los
pulsadores en el tutorial).
2. Programa principal: Se encarga de la fase inicial de selección del método de acceso al array,
de inicializar el sistema de interrupciones y el temporizador. Controla (haciendo polling sobre
la variable global) si ha transcurrido el tiempo de retardo y cambia a la siguiente configuración
de leds. Controla los pulsadores. Controla también la condición de salida del programa.
Versión 2
1. RSI timer: Añadir a la RSI anterior el control del encendido de los leds. Es decir, las
instrucciones que controlan el cambio de configuración de los leds se trasladan del programa
principal a la RSI. Ojo! No podemos implantar bucles dentro de la RSI. Se ha de salir
rápidamente.
2. Programa principal: Se encarga de la fase inicial de selección del método de acceso al array,
de inicializar el sistema de interrupciones y el temporizador. Controla los pulsadores. Controla
también la condición de salida del programa.
Nota importante: En esta sesión aparece la necesidad de crear 2 vars. globales, “contador_250” y
“total_250”. La primera contabiliza el nº de interrupciones del timer producidas hasta el momento
mientras la segunda contiene el número de interrupciones necesarias para contar un determinado
tiempo. Es importantísimo entender cómo se interrelacionan las 2 variables y cómo se actualizan.
4
Interrupciones con HC12 Estructura de computadores
SESIÓN 3
Pre-laboratorio:
1. El alumno entregará al profesor, al inicio de la sesión, un documento escrito de manera legible con
la siguiente información:
Laboratorio:
El objetivo de esta sesión es escribir la RSI de los pulsadores donde se incluya todo el código que
controla el cambio de velocidades de display. Partiendo del programa de la sesión anterior, crear la RSI
de los pulsadores y obtener la siguiente estructura:
5
Interrupciones con HC12 Estructura de computadores
SESIÓN 4
Pre-laboratorio:
1. El alumno entregará al profesor, al inicio de la sesión, un documento escrito de manera legible con
la siguiente información:
(Buscar información en los diagramas de bloques del manual “MC9S12E-Family Device User
Guide V01.04”)
Laboratorio:
El objetivo de esta sesión es manejar el osciloscopio/analizador lógico.
1. Cristal Oscilador. Demostrar gráficamente al profesor la frecuencia del reloj base de la placa
de evaluación.
2. Interrupt request: Demostrar gráficamente al profesor la frecuencia con la que se producen las
interrupciones. Variar la velocidad mediante los pulsadores y demostrar con el osciloscopio
cómo varia dicha frecuencia.
Memoria:
El grupo de alumnos deberá entregar al profesor un informe de la práctica antes de empezar la siguiente
sesión de prácticas. Dicho informe deberá cumplir con la normativa de la asignatura a tal efecto.
6
Comunicaciones con HC12 Estructura de computadores
Objetivos
El objetivo principal de esta práctica consiste en conocer cómo funcionan las comunicaciones, tanto
serie como paralelas. Para ello utilizaremos los medios que nos proporciona el HC12. Otro de los
objetivos es gestionar las comunicaciones mediante interrupciones. Por último sería interesante
comprobar con el analizador lógico el cambio de alguna de las señales involucradas.
1
Comunicaciones con HC12 Estructura de computadores
Tanto el emisor como el receptor necesitan saber la duración de cada bit transmitido. Para ello se utiliza
el concepto de tasa de transferencia medida en BAUDIOS. Dicha tasa define el número de bits que se
transmiten por segundo. Así, con una tasa de transferencia de 9600 Baudios, el tiempo entre el envío de
dos bits consecutivos, y el tiempo entre el muestreo de un bit y del siguiente será 1/9600 seg. = 100
useg.
Observamos como el método de sincronización (bits estart/stop) se entremezcla con los datos en el
protocolo serie. Otro punto a tener en cuenta es la necesidad de negociar emisor y receptor la tasa
de transferencia, antes de iniciar una comunicación (tiene que ser la misma). Veremos como en el
protocolo paralelo esto no es necesario.
Comunicaciones paralelas
En el protocolo paralelo los datos y las señales de sincronismo viajan por caminos separados. Por
un lado tenemos un bus de 8 bits para los datos (Data) y 2 señales de control para implementar el
método de sincronización (Avail y Busy). ¿Cómo funciona el protocolo?
1. Emisor (Microcontroler) envía un dato a Receptor (Output Device) poniendo el dato (1 byte) en
el bus de datos (Data).
2. Emisor avisa a Receptor, activando la señal ‘dato disponible’ (Avail), de que ya puede leer del
bus el nuevo dato.
3. Receptor recibe la señal ‘dato disponible’ enviada por Emisor.
4. Receptor lee el dato del bus de datos.
5. Receptor avisa a Emisor, activando la señal ‘dato recibido’ (Busy), de que ya puede enviar otro
2
Comunicaciones con HC12 Estructura de computadores
3
Comunicaciones con HC12 Estructura de computadores
1. Programa Principal.
- Fase inicial (pooling) donde se pregunta al jugador por el método de acceso a la matriz
seleccionado.
- Inicialización del Timer.
- Inicialización del Sistema de Interrupciones.
- Bucle de espera hasta que se produzca la condición de salida (var. global).
2. RSI Timer.
incrementar ticks_contados.
SI ticks_contados >= ticks_a_contar ENTONCES
ticks_contados = 0
Realizar cambio de luces (acceder a la siguiente posición de la matriz según el método de
acceso seleccionado en fase inicial).
FINSI
Limpiar flag que ha provocado la interrupción.
3. RSI Pulsadores.
SI (han sido pulsados los 2 pulsadores a la vez) ENTONCES salir = 1
SINO SI (se ha pulsado PAD4) ENTONCES ticks_a_contar +++
SINO SI (se ha pulsado PAD5) ENTONCES ticks_a_contar ---
Limpiar flag que ha provocado la interrupción.
¿Qué pretendemos en esta tercera práctica? Mantener la funcionalidad anterior e integrar en ella las
comunicaciones. ¿Cómo lo vamos a hacer? Supondremos que cada grupo tendrá 2 placas de evaluación
MC9S12E128 (HC12) conectadas por un canal de comunicaciones (serie o paralelo). La idea es que el
programa corra en las 2 HC12 a la vez. ¿Cómo? Cargando el programa (download) en una y luego en
4
Comunicaciones con HC12 Estructura de computadores
otra. Recordar que la placa guarda el programa en memoria no volátil, hecho que nos permite trabajar
con ellas aunque no estén conectadas al PC. ¿Qué debe hacer el programa? Básicamente lo mismo que
en la práctica anterior (ver pseudocódigo) salvo el siguiente matiz:
• El cambio de luces en los leds será provocado por el HC12 remoto. Esto quiere decir que
nuestro programa enviará la nueva codificación de leds al HC12 remoto, mediante el canal de
comunicaciones.
Aunque el enunciado de la práctica podría formularse de manera más exigente pidiendo que la
comunicación fuera bidireccional en todo momento (los 2 HC12s se intercambiarían sus
codificaciones), nos conformaremos con que funcione en un solo sentido a la vez. Por otro lado,
desconocemos si se dispondrá finalmente de 2 placas HC12 por grupo. Si no es posible, el grupo
trabajará con una sola placa HC12 emulando que tiene 2. ¿Cómo? Conectando la salida (canal
de comunicaciones) de la placa a la entrada de la misma. De esta manera lo que el HC12 envíe será
recibido por él mismo. Aunque parezca mentira la funcionalidad es equivalente.
5
Comunicaciones con HC12 Estructura de computadores
¿Cómo se implementa un canal de comunicaciones serie? Muy sencillo. Necesitamos 1 puerto serie
(SCI) en cada extremo y un cable que los conecte (ver figura 1). Este sería el esquema a utilizar en caso
de que los grupos de prácticas tuvieran a su alcance 2 placas HC12.
TXD RXD
HC12A SCI SCI HC12B
En el caso de que los grupos sólo dispongan de 1 placa de evaluación HC12, teniendo en cuenta que
cada HC12 contiene 3 puertos serie bidireccionales (SCI0, SCI1, SCI2), esto es, puertos que pueden
enviar datos a la vez que reciben, varias son las alternativas de conexionado que se nos presentan (ver
figuras 2 y 3):
TXD0 TXD0
HC12A SCI0 HC12B SCI0
RXD2 RXD0
SCI2
Figura 2: Esquema con 1 HC12 y 2 puertos serie Figura 3: Esquema con 1 HC12 y 1 puerto serie
6
Comunicaciones con HC12 Estructura de computadores
El micro HC12 define 3 puertos series llamados SCI0, SCI1, SCI2. Cada uno de los puertos serie tiene
unos registros asociados, que sirven para controlar su funcionamiento. La siguiente tabla presenta el
nombre de estos registros, indica su posición dentro del espacio de memoria (relativa a una dirección
base asociada a cada uno de los puertos serie), e indica también si el registro es de entrada, de salida, o
de entrada/salida.
7
Comunicaciones con HC12 Estructura de computadores
La siguiente figura muestra el diagrama de bloques detallado del puerto serie (SCI) del HC12. En él se
muestran todos los elementos del puerto serie que pueden ser programados, y que se describen con
detalle más adelante.
8
Comunicaciones con HC12 Estructura de computadores
9
Comunicaciones con HC12 Estructura de computadores
SCIDRL: Registro de datos del puerto serie, en el se escribe el dato (8 bits) a enviar o del que se
lee el dato recibido
SCIDBH y SCIDBL: Registros de control que permiten definir la tasa de trasferencia (Baudios) de
la comunicación serie. Esta tasa se define con 13 bits [SBR12:SBR0], donde los 5 bits más
significativos se corresponden con los bits [4:0] del registro SCIDBH, y los 8 bits menos
significativos se corresponden con los bits [7:0] del registro SCIDBL. La siguiente formula indica
el valor decimal que hay que utilizar:
SCICR1: Registro 1 de control del puerto serie. Los siguientes bits tienen funciones específicas:
- bit M (SCICR1[4]): Longitud de los datos, 8 o 9 bits (usaremos 8 bits)
- bit PE (SCICR1[1]): Activación de la paridad (usaremos sin paridad)
- bit PT (SCICR1[0]): Tipo de paridad Al usar el protocolo sin paridad, no tiene efecto).
SCICR2: Registro 2 de control del puerto serie. Contiene el bit que se habilita la transmision de
datos (bit SCICR2[3] =1, TE, Transmit Enable), el bit que habilita la recepción de datos (bit
SCICR2[2] =1, RE, Receive Enable), y el bit que activa la interrupción de la recepción de datos (
bit SCICR2[5] =1, RIE, Receive Interrupt Enable).
SCISR1: Registro 1 de estado del puerto serie. Los bits de condición (flags) de este registro
informan del estado del puerto serie. Los bits más importantes son:
- bit RDRF (SCISR1[5]): Se activa cuando se ha completado la recepción de un dato
completo. Para desactivar el bit de condición hay que leer el registro SCISR1 y
posteriormente el registro de datos (SCIDRL)
- bit TDRE (SCISR1[7]): Se activa cuando ha acabado la transmisión de un dato y se puede transmitir
el siguiente dato. Para desactivar el bit de condición hay que leer el registro SCISR1 y posteriormente
escribir en el registro de datos (SCIDRL).
10
Comunicaciones con HC12 Estructura de computadores
La siguiente tabla muestra la posición de cada uno de los bits de condición, y del resto de campos de
los registros asociados al puerto serie.
Para más información es interesante (y en algunos casos aconsejable) consultar los manuales:
Puerto Serie (SCI's): HCS12 Serial Communications Interface (SCI) Block Guide.
Registros puertos e interrupciones HCS12: MC9S12E-Family Device User Guide.
11
Comunicaciones con HC12 Estructura de computadores
SESIONES 1 y 2
Pre-laboratorio:
1. Repasar los fuentes de la práctica anterior y no olvidar traerlos a las sesiones de laboratorio.
2. Leer atentamente toda la documentación adjunta al enunciado de esta práctica. Preguntar al profesor,
el día del laboratorio, las dudas aparecidas en esa lectura.
3. El alumno leerá con atención las secciones 3 y 4 del “SCI Block Guide V03.02”.
4. El alumno entregará al profesor, al inicio de la sesión, un documento escrito de manera legible con
la respuesta a las siguientes preguntas:
12
Comunicaciones con HC12 Estructura de computadores
Laboratorio:
Aunque el objetivo de la práctica ha quedado ya explicado en las introducciones anteriores a
continuación se describe, mediante pseudocódigo, la funcionalidad que debe cumplir esta entrega (en
rojo encontrareis las nuevas funcionalidades respecto a la práctica anterior).
1. Programa Principal.
- Fase inicial (pooling) donde se pregunta al jugador por el método de acceso a la matriz
seleccionado.
- Inicialización del Timer.
- Inicialización del Sistema de Interrupciones.
- Bucle de espera hasta que se produzca la condición de salida (var. global).
- Inicialización del puerto/puertos serie (SCI).
2. RSI Timer.
incrementar ticks_contados.
SI ticks_contados >= ticks_a_contar ENTONCES
ticks_contados = 0
Cambio de luces (acceder a la siguiente posición de la matriz según el método de acceso
seleccionado en fase inicial). Hay que eliminar la escritura en los leds locales y cambiar
esta acción por una escritura en el registro de datos de envío del puerto serie.
FINSI
Limpiar flag que ha provocado la interrupción.
3. RSI Pulsadores.
SI (han sido pulsados los 2 pulsadores a la vez) ENTONCES salir = 1
SINO SI (se ha pulsado PAD4) ENTONCES ticks_a_contar +++
SINO SI (se ha pulsado PAD5) ENTONCES ticks_a_contar ---
Limpiar flag que ha provocado la interrupción.
4. RSI SCI0.
SI hay varios motivos de interrupción asociados al SCI= controlarlos.
Leer del registro de datos de recepción del puerto serie.
Displayar en los leds el valor recibido.
Limpiar flag que ha provocado la interrupción.
13
Comunicaciones con HC12 Estructura de computadores
El alumno deberá entregar funcionando una práctica con esta funcionalidad según los esquemas
siguientes:
14
Comunicaciones con HC12 Estructura de computadores
PTS PTS
Dato enviado
PAD1 PAD6
Dato recibido (ack)
PAD2 PAD7
PAD7 PAD2
PAD6 PAD1
En el caso de que los grupos sólo dispongan de 1 placa de evaluación HC12 realizaremos el siguiente
conexionado (ver figura 2). Como puede observarse la comunicación no es bidireccional!
15
Comunicaciones con HC12 Estructura de computadores
Datos
PTA
HC12
PTS
PAD2
Dato enviado
PAD1
PAD6
PAD7
ACK
Puerto A
• PORTA (Datos): 0000H
• DDRA (Dirección datos): 0002H
Puerto S
• PORTS (Datos): 0248H
• DDRS(Dirección datos): 024AH
Puerto AD
• ATDDIEN1 (Habilita entrada): 008DH
• PTADLo (Datos): 0271H
• DDRADLo (Dirección datos ): 0275H
• PERADLo (Alimentación de entrada): 0279H
• PIEADLo (Habilita interrupciones): 027DH
• PIFADLo (Registro de flags): 027FH
SESIONES 3 y 4
Pre-laboratorio:
1. Leer atentamente toda la documentación adjunta al enunciado de esta práctica. Preguntar al profesor,
el día del laboratorio, las dudas aparecidas en esa lectura.
2. El alumno entregará al profesor, al inicio de la sesión, un documento escrito de manera legible con
la respuesta a las siguientes preguntas:
• En una configuración con 1 placa de evaluación, ¿Qué pines conectaréis para establecer el
canal de comunicación? Responder nombrando el número de los pines afectados (consultar el
diagrama de bloques de la placa de evaluación MC9S12E128).
• En la versión anterior, la serie, habíamos tenido 3 RSIs diferentes. ¿Cuántas necesitamos en la
versión paralela? ¿Cuáles son?
• Una de las RSIs tendrá 4 motivos de interrupción. ¿Cuál es? Describe cada uno de los motivos.
• ¿Creéis que el handshaking es necesario en nuestra práctica? ¿Por qué? Razonar la respuesta de
manera detallada (observar cómo funciona el flujo de los datos!).
Laboratorio:
La funcionalidad de la entrega que se os pide es equivalente a la realizada con el protocolo de
comunicación serie, sólo que modificada convenientemente para utilizar ahora el protocolo paralelo en
vez del serie. A continuación se describe, mediante pseudocódigo, la funcionalidad que debe cumplir
esta entrega:
1. Programa Principal.
- Fase inicial (pooling) donde se pregunta al jugador por el método de acceso a la matriz
seleccionado.
- Fase de Inicialización (Timer, puertos de comunicaciones, etc)
- Inicialización del Sistema de Interrupciones.
- Bucle de espera hasta que se produzca la condición de salida (var. global).
ack = 0
2. RSI Timer.
incrementar ticks_contados.
SI ticks_contados >= ticks_a_contar ENTONCES
ticks_contados = 0
SI ack = =0 ENTONCES
17
Comunicaciones con HC12 Estructura de computadores
ack=1
leer siguiente codificación de luces y enviar por el canal de comunicaciones.
activar señal de control “Dato enviado”.
desactivar señal de control “Dato enviado”.
FINSI
FINSI
Limpiar flag que ha provocado la interrupción.
3. RSI PAD.
SI (han sido pulsados los 2 pulsadores a la vez) ENTONCES salir = 1
SI (se ha pulsado PAD4) ENTONCES ticks_a_contar +++
SI (se ha pulsado PAD5) ENTONCES ticks_a_contar ---
SI (se ha activado PAD6) ENTONCES
leer byte recibido y displayarlo en los leds
activar señal de control “ack”.
desactivar señal de control “ack”.
FINSI
SI (se ha activado PAD2) ENTONCES ack = 0
Limpiar flag que ha provocado la interrupción.
Memoria:
El grupo de alumnos deberá entregar al profesor un informe de la práctica antes de la fecha indicada.
Dicho informe deberá cumplir con la normativa de la asignatura a tal efecto.
18
EE 308 Spring 2006
1
EE 308 Spring 2006
0x3AF9
A B
0x3AFA
D
0x3AFB
0x3AFC X
0x3AFD
Y
0x3AFE
0x3BFF SP
0x3B00
PC
0x3B01
0x3B02 CCR
0x3B03
2
EE 308 Spring 2006
Stack Pointer:
0x3BF5
CODE: section .text
0x3BF6 org 0x1000
0x3BFD pulx
pula
0x3BFE
0x3BFF A
0x3C00
X
SP
3
EE 308 Spring 2006
CCR
Effects S X H I N Z V C
– – – – – – – –
Code and
CPU Source Form Address Machine CPU Cycles
Mode Code (Hex)
Cycles
PSHA INH 36 Os
439
4
EE 308 Spring 2006
Subroutines
jmp label
5
EE 308 Spring 2006
– To avoid this problem, the subroutine should save the HC12 registers
before it uses them, and restore the HC12 registers after it is done
with them.
6
EE 308 Spring 2006
CCR
Effects S X H I N Z V C
– – – – – – – –
Code and
CPU Source Form Address Machine CPU Cycles
Mode Code (Hex)
Cycles
BSR rel8 REL 07 rr SPPP
333
7
EE 308 Spring 2006
CCR
Effects S X H I N Z V C
– – – – – – – –
Code and
CPU Source Form Address Machine CPU Cycles
Mode Code (Hex)
Cycles
RTS INH 3D UfPPP
463
8
EE 308 Spring 2006
• To solve, save the values of A and X on the stack before using them, and
restore them before returning.
9
EE 308 Spring 2006
org prog
delay: psha
pshx
ldaa #250
loop2: ldx #800
loop1: dex
bne loop1
deca
bne loop2
pulx
pula
rts
10
EE 308 Spring 2006
0x3AF8
0x3AF9
A B
0x3AFA
D
0x3AFB
0x3AFC X
0x3AFD
Y
0x3AFE
0x3AFF SP
0x3B00
PC
0x3B01
0x3B02 CCR
0x3B03
11
EE 308 Spring 2006
ldx $str
loop: ldaa 1,x+ ; get next char
beq done ; char == 0 => no more
jsr putchar
bra loop
swi
12
EE 308 Spring 2006
org prog
lds #stack
ldx #str
loop: ldaa 1,x+ ; get next char
beq done ; char == 0 => no more
jsr putchar
bra loop
done: swi
org data
str: fcc "hello"
dc.b $0a,$0d,0 ; CR LF
13
EE 308 Spring 2006
+5V
14
EE 308 Spring 2006
PB1
PB0
+5V
• When the switch is open, the input port sees a logic 1 (+5 V)
• When the switch is closed, the input sees a logic 0 (0 V)
15
EE 308 Spring 2006
ldaa PORTB
cmpa #b0110
beq task
• If PB7-PB4 are anything other than 0000, you will not execute the task.
• You need to mask out the Don’t Care bits before checking for the pattern
on the bits you are interested in
ldaa PORTB
anda #b00001111
cmpa #b00000110
beq task
16
EE 308 Spring 2006
PA0
17
EE 308 Spring 2006
f b
g
e c
d
18
EE 308 Spring 2006
0x3f X START
table
0x5b
Output to
PORTA staa PORTA
Inc
Pointer inx
cpx #table_end
X < end? bls l2
bra l1
19
EE 308 Spring 2006
org prog
delay: psha
pshx
ldaa #250
loop2: ldx #8000
loop1: dex
bne loop1
deca
bne loop2
pulx
pula
rts
org data
table: dc.b $3f
dc.b $5b
dc.b $66
dc.b $7d
table_end: dc.b $7F
20