Vous êtes sur la page 1sur 157

CURSO MSP430 Ensamblador y C http://todomcu.scienceontheweb.net/index.html http://todomcu.scienceontheweb.net/msp430/ejemplos-asm/asm.

html

Contenido
QUE ESPERAR DE ESTA PAGINA?. ADEMAS DEL CURSO. RETORALIMENTACION. EL CURSO DE MSP430. ......................................................................................... 9 .............................................................................................................. 9 ......................................................................................................... 10 .......................................................................................................... 10 ................................................................................... 10

CARACTERISTICAS DE LOS MSP430. ACERCA DE LOS PERIFERICOS. DESARROLLO DE APLICACIONES. LAUNCHPAD eZ430 IAR

.............................................................................................. 11 .......................................................................................... 11

.......................................................................................................................... 12

................................................................................................................................. 15

......................................................................................................................................... 17 ................................................................................................................ 18 .......................................................................... 18

LA ARQUILECTURA

CARACTERISTICAS PRINCIPALES EN LA CPU LOS REGISTROS DE LA CPU.

.................................................................................................. 21 .................................................... 23 ................................................. 23

R2 y R3.-Generador de constantes (Constant Generator). R4-R15.-Registros de propsito general (General Prupose). MODOS DE DIRECCIONAMIENTO. Modo registro. Modo Indexado. Modo simblico. Modo Absoluto. Modo Indirecto.

........................................................................................ 23

...................................................................................................................... 24 .................................................................................................................... 25 ................................................................................................................... 26 .................................................................................................................... 27 .................................................................................................................... 28 .................................................................................. 29

Modo indirecto con autoincremento.

Modo Inmediato.

.................................................................................................................. 30 ..................................................................................................... 31 ........................................................................................................ 31 .............................................................................................................. 31 ........................................................................................ 32

Instrucciones Aritmeticas Suma Destino y C.- ADC Aadir.- ADD [0101]

Aadir con acarreo.- ADDC [0110] Suma decimal con C.- DADC Suma en BCD.- DADD [1010] Decremento.- DEC

................................................................................................. 32 ................................................................................................. 32

................................................................................................................. 32 .................................................................................................... 32

Doble Decremento.- DECD Incremento.- INC

................................................................................................................... 33 ....................................................................................................... 33 ............................................................................................................ 33 ....................................................................................... 33

Doble Incremento.-INCD Sustraer.- SUB [1000]

Sustrae con acarreo.- SUBC [0111] Instrucciones Logicas. Y lgica.-AND [1111]

........................................................................................................... 33 ............................................................................................................. 34 ................................................................. 34 ................................................................ 34

Borra bits seleccionados en destino.- BIC [1100] Coloca bits seleccionados en destino.- BIS [1101] Comprobar bits en destino.- BIT [1011] Negacin.- INV

................................................................................ 34

...................................................................................................................... 35 ........................................................................................... 35 .................................................................................. 35 ..................................................... 35 ................................................... 35

Corrimiento a la izquierda.- RLA

Corrimiento a la izquierda con C.- RLC

Corrimiento aritmtico a la derecha.- RRA [000100010] Corrimiento a la derecha con acarreo.- RRC [000100000] Intercambia Bytes.- SWPB [000100001] Extiende el signo.- SXT [000100001] O exclusiva lgica.- XOR [1110] Instrucciones De Datos. Borrar.- CLR

............................................................................... 36 ..................................................................................... 36

............................................................................................. 36

........................................................................................................ 36

........................................................................................................................... 37

Borra Acarreo.- CLRC Borra Negativo.- CLRN Borra Cero CLRZ

............................................................................................................. 37 .......................................................................................................... 37

.................................................................................................................... 37 ........................................................................................................ 37 ............................................................................................................. 37 ............................................................................................ 38 ............................................................................. 38

Comparar.- CMP [1001] Mover.- MOV [1000]

Sacar elemento de la pila.- POP

Almacena en la pila.- PUSH [000100100] Colocar C.- SETC Colocar N.- SETN Coloca Z.- SETZ Prueba.- TST

.................................................................................................................... 38 ................................................................................................................... 38 ...................................................................................................................... 38 .......................................................................................................................... 39

............................................................................................................................................... 39 Incremento.- INC Decremento.- DEC ................................................................................................................... 39 ................................................................................................................. 39 ....................................................................................................... 39 .................................................................................................... 39 ........................................................................................... 39 .................................................................................. 40

Doble Incremento.-INCD Doble Decremento.- DECD

Corrimiento a la izquierda.- RLA

Corrimiento a la izquierda con C.- RLC Suma Destino y C.- ADC Suma decimal con C.- DADC Negacin.- INV

........................................................................................................ 40 ................................................................................................. 40

...................................................................................................................... 40 ...................................................................................................... 40

Instrucciones De Control. Brinco.- BR

............................................................................................................................. 41 ................................................................................... 41 ...................................................................................... 41 ......................................................................................... 41

Llamar subrutina.- CALL [000100101] Inhabilita las interrupciones.- DINT Habilita las interrupciones.- EINT Salta si C.- JC [001011]

.......................................................................................................... 41 .................................................................................... 42

Salta si mayor o igual.- JGE [001101]

Salta si menor.- JL [001110] Salta.- JMP [001000] Salta si N.- JN [001100]

.................................................................................................. 42

............................................................................................................. 42 ......................................................................................................... 42 ...................................................................................... 42 ................................................................................. 42

Salta si C no es cero.- JNC [001010] Salta si Z no es cero JNE/JNZ [001000] Salta si Z.- JEQ/JZ [001001] Sin operacin.- NOP

................................................................................................... 42

.............................................................................................................. 42 .................................................................................................. 43 ..................................... 43

Regreso de Subrutina.- RET

Regreso de la interrupcin.- RETI [0001001100000000 completo] ORGANIZACIN DE LA MEMORIA REGISTROS DE FUNCION ESPECIFICA REGISTROS DE LOS PERIFERICOS RAM

......................................................................................... 43 .................................................................................... 43 .......................................................................................... 44

...................................................................................................................................... 45 ..................................................................................................... 45 ............................................................................................... 45

MEMORIA DE ARRANQUE MEMORIA DE INFORMACIN MEMORIA DE CODIGO

.......................................................................................................... 45 ............................................................................................... 46

VECTORES DE INTERRUPCION TIPOS DE MEMORIA

.............................................................................................................. 46 ......................................................................................... 47

ESTRUCTURA DE UN PROGRAMA LAS SUBRUTINAS

................................................................................................................... 49 .................................................................................................... 51

SUBRUTINAS DE RETARDO INTERRUPCIONES

.................................................................................................................. 53 .............................................................................................. 55 ................................................................................................. 55 ...................................................................................................... 57 .......................................................................................... 60 ............................................................................................ 62

BANDERAS DE INTERRUPCION VECTOR DE INTERUPCIONES TABLAS Y APUNTADORES

CORRIMIENTOS A LA IZQUIERDA CORRIMIENTOS A LA DERECHA SUMA Y RESTA A 32 BITS

...................................................................................................... 63

SUMA Y RESTA A 64 BITS PROGRAMA DE APLICACIN Obtener codigo fuente

...................................................................................................... 64 ................................................................................................. 64

.......................................................................................................... 67 .......................................................................................... 67 ........................................................................................... 71 ............................................................................................ 73

MULTIPLICACION DE 16X16 BITS DESARROLLO DE LA SUBRUTINA EL PROGRAMA DE APLICACIN Obtener codigo fuente

.......................................................................................................... 77 ........................................................................ 77

PUERTOS DIGITALES DE ENTRADA Y SALIDA FUNCIONAMIENTO Y NOTACION SELECCIN DE FUNCION LOS REGISTROS I/O

.......................................................................................... 78

....................................................................................................... 79

............................................................................................................... 81 ................................................................................................ 85 ......................................................................................... 86 ................................................................................... 86 .............................................................. 88

CONFIGURAR COMO SALIDA

INTERRUPCION EN LOS PUERTOS CONFIGURAR LAS INTERRUPCIONES.

BANDERA DE INTERRUPCION PARA LOS PUERTOS. HABILITAR LA INTERRUPCION.

.............................................................................................. 88 .................................................................... 89

DECLARANDO EL VECTOR PARA LOS PUERTOS APLICACIN DE EJEMPLO EL SISTEMA BASICO DE RELOJ LAS FUENTES DE RELOJ LAS SEALES DE RELOJ EL TIMER A

..................................................................................................... 91 ............................................................................................... 94

......................................................................................................... 94 .......................................................................................................... 95

............................................................................................................................ 96 ........................................................................................ 97

TIMER_A COMO TEMPORIZADOR MODOS DE CUENTA TIMER EN CAPTURA

.............................................................................................................. 98 ............................................................................................................ 100 .................................................................................................. 102

TIMER EN COMPARACION EL PERRO GUARDIN MODO GUARDIN

.......................................................................................................... 106 .............................................................................................................. 107

MODO INTERVALOS OPERACIN SEGURA

............................................................................................................ 108 ........................................................................................................... 109 ....................................................................... 109

ACERCA DE IAR EMBEDDED WORKBENCH DESCARGA E INSTALACION DE IAR.

.................................................................................... 110

Descarga e instalacion IAR - VIDEO ........................................................................................... 110 CREAR PROYECTO EN ENSAMBLADOR. .............................................................................. 111

Configuras IAR en Ensamblador - VIDEO................................................................................... 111 CREAR PROYECTO EN C++. .................................................................................................. 111

Configurar IAR en C++ - VIDEO .................................................................................................. 112 CONFIGURACION DEBUG/RELEASE. ................................................................................... 112

Debug Release con IAR - VIDEO ................................................................................................ 112 PARA QUE CONFIGURAR DEBUG Y RELEASE?. EJEMPLOS EN ENSAMBLADOR DE MSP430 Arquitectura: Puertos: Timer_A: .................................................................. 113 ..................................................................... 113

....................................................................................................................... 114

............................................................................................................................... 114 .............................................................................................................................. 114 .................................................................................................................... 114

Perro Guardian

EJEMPLO 1: TABLAS Y APUNTADORES ...................................................................................... 114 EJEMPLO 2: CORRIMIENTOS A LA IZQUIERDA .......................................................................... 117 CORRIMIENTOS A LA DERECHA .......................................................................................... 119

EJEMPLO 3: SUMA Y RESTA A 32 BITS ....................................................................................... 120 SUMA Y RESTA A 64 BITS PROGRAMA DE APLICACIN .................................................................................................... 121 ............................................................................................... 122

Obtener codigo fuente - suma-resta.s43 .................................................................................. 125 EJEMPLO 4: MULTIPLICACION DE 16X16 BITS........................................................................... 125 DESARROLLO DE LA SUBRUTINA EL PROGRAMA DE APLICACIN ......................................................................................... 128 .......................................................................................... 130

Obtener codigo fuente - multiplicacion.s43.............................................................................. 134 PRACTICAS MANEJO DE PUERTOS ............................................................................................ 135 PRACTICA 1 - Encender un led al pulsar .............................................................................. 135

CODIGO FUENTE

................................................................................................................. 135

Practica 1.flv - VIDEO http://www.youtube.com/watch?v=rRrhoKI3HbE&feature=player_embedded ..................... 136 PRACTICA 2 - Encender un led, apagar otro al pulsar CODIGO FUENTE ......................................................... 136

................................................................................................................. 136

Practica 2.flv - VIDEO................................................................................................................. 137 PRACTICA 3 - Encender un led por 10 segundos CODIGO FUENTE Practica 3.flv - VIDEO ................................................................ 137

................................................................................................................. 137 .......................................................................................................... 139 ....................................................................................... 139

PRACTICA 4 - Secuencia de 8 leds CODIGO FUENTE

................................................................................................................. 139 .................................................................................... 141

PRACTICA 5 - PWM de 10% en 10% CODIGO FUENTE Practica 5.flv - VIDEO

................................................................................................................. 141 .......................................................................................................... 143 .......................................................................... 143

PRACTICA 6 - Cuenta de display de 0 a 99 CODIGO FUENTE Practica 6.flv - VIDEO

................................................................................................................. 143 .......................................................................................................... 145

Timer_A ..................................................................................................................................... 145 PRACTICA 1 - Encender un led por 10 segundos CODIGO FUENTE ................................................................. 145

................................................................................................................. 146 ............................................................................................ 147 ........................................................................... 147

Timer_A Practica 1.flv - VIDEO

PRACTICA 2 - Secuencia con corrimientos CODIGO FUENTE

................................................................................................................. 147 ............................................................................................ 149 ................................................................... 149

Timer_A Practica 2.flv - VIDEO

PRACTICA 3 - Secuencia cualquiera con tablas CODIGO FUENTE

................................................................................................................. 149 ............................................................................................ 151 ........................................................... 151

Timer_A Practica 3.flv - VIDEO

PRACTICA 4- PWM automatico con Time_A y WDT CODIGO FUENTE

................................................................................................................. 152

Timer_A Practica 4.flv - VIDEO

............................................................................................ 153

PERRO GUARDIAN ..................................................................................................................... 153 PRACTICA 1 - Conmutar un led cada 5s CODIGO FUENTE .............................................................................. 153

................................................................................................................. 153 .................................................................................. 154

Perro guardin practica1.flv - VIDEO

PRACTICA 2 - La entrada digital numero 11 .............................................................................. 154 CODIGO FUENTE ................................................................................................................. 155

Perro guardian practica 2 version 1.flv - VIDEO ........................................................................ 156 Perro guardian practica 2 versin 2.flv - VIDEO ........................................................................ 157

QUE ESPERAR DE ESTA PAGINA?.


En esta pgina encontraras un curso completo y gratuito en espaol del desarrollo con los microcontroladores MSP430 de Texas Instruments tanto en lenguaje C/C++ como e ensamblador, este abarcara desde la arquitectura bsica, set de instrucciones, los modos de direccionamiento hasta el uso de los perifricos como los puertos de entrada y salida, el Timer_A, el Perro guardin, el sistema bsico de reloj que son los que actualmente estn disponibles pero pronto aadiremos mas descripciones del uso y configuracin de otros perifricos. Adems como el nombre de la direccin URL lo indica (todomcu) en este sitio pretendemos con posterioridad incluir el uso y configuracin de otros microcontroladores por el importante papel que desempean en las reas de diseo a pequea y gran escala, adems de que contribuyen a la formacin integral de un profesionista o aficionado, ya que saber utilizar solo una arquitectura de microcontroladores es reducir mucho las consideraciones de diseo. Cabe aclarar que por el momento nos centraremos en el completar los contenidos de los MSP430 para poder as continuar con otro tipo de microcontroladores, los prximos sern de ATMEL y posteriormente de Freescale.

ADEMAS DEL CURSO.


Como complemento a todo curso descrito en esta pgina tendremos a disposicin de ustedes ejemplos 100% funcionales los cuales en el caso de poseer el hardware necesario los puedes probar sin falla alguna. Tambin estar disponible el diagrama de flujo de dichos ejemplos, todo esto en C/C++ y en ASM. Los proyectos tambin son de vital importancia ya que aqu es donde en verdad se pone a prueba el potencial de cada arquitectura en cuanto a desempeo y facilidad de programacin, esta es ciertamente una seccin en desarrollo ya que aun estamos preparando los proyectos que sern incluidos en esta seccin entre los cuales esta un robot de sumo, un control de nivel de agua a travs del efecto capacitivo y con posterioridad desarrollaremos un sistema operativo funcional para esta arquitectura. Todos estos proyectos sern completamente documentados, adems de que su cdigo fuente estar completamente disponible para visualizacin o descarga. Tambin disponemos de video tutoriales los cuales te ensearan de manera muy adecuada como es que se realizan algunas configuraciones en el software de desarrollo que utilizaremos.

RETORALIMENTACION.
Ya que esta pagina surge como un servicio para los estudiantes y personas interesadas en el tema, es de vital importancia su ayuda, comentarios y criticas las cuales nos ayuden a proporcionar un servicio mas adecuado para los requerimientos personales de los visitantes, para ello ponemos a tu disposicin una forma de contacto por medio de internet y otra a travs de correo electrnico. As que esperamos tu colaboracin para que nos enves programas o proyectos los cuales hayas desarrollado y desees difundir, as como ejemplos o cualquier tipo de informacin que tu consideres til para los dems. Tambin podrs solicitar nuevos temas o arquitecturas a estudiar y publicar, as como ejemplos que desees que desarrollemos. Recuerda que tu colaboracin y opinin es muy importante.

EL CURSO DE MSP430.
En esta seccin tratamos de explicarte de una manera clara y entendible como es que se usan estos microcontroladores a travs del uso de ejemplos los cuales estn disponibles en la seccin de Ejemplos en ASM o Ejemplos en C/C++. Al concluir el curso sers capaz de crear programas en 2 lenguajes distintos (ensamblador y C/C++), sabrs como configurar la mayora de perifricos, adems de que sabrs ejecutar programas paso a paso y detectar problemas de lgica con las herramientas de Debug y Release.

CARACTERISTICAS DE LOS MSP430.


Los microcontroladores MSP430 tiene varias caractersticas que los hacen muy competentes a la hora de realizar aplicaciones. Hablaremos un poco de esas caractersticas a manera de introduccin en esta pequea seccin. Para empezar MSP quiere decir Mixed Signal Processor lo cual significa procesadores de seal mixta, esto nos habla micho de sus funciones, al ser una familia de microcontroladores estn preparados nativamente para el uso y generacin de seales de forma digital, pero tambin cuentan con perifricos que hacen que estos puedan trabajar con seales analgicas, esto los hace tiles para aplicaciones de control, medicin y electrnica de consumo. Estos microcontroladores son los que menos energa consumen incluso por debajo de los PICs esto se logra combinado de marera correcta las varias fuentes de interrupcin, los perifricos independientes a la CPU y la seleccin correcta de las fuentes de reloj para la CPU y los perifricos. Cuentan con una CPU RISC de 16 bits y una arquitectura Von Neuman adems como ya se menciono tiene un sistema de reloj muy flexible. Esta familia esta formada por 5

generaciones las cuales en total suman mas de 200 dispositivos, cada generacin ofrece diferentes niveles de integracin analgica, perifricos digitales y protocolos de comunicacin lo cual ayuda a los desarrolladores a solventar de la manera mas apropiada sus necesidades. Por ltimo la caracterstica mas destacable es que sus herramientas son muy fciles de usar y de bajo costo as como sus dispositivos, un ejemplo de ello es que cuentan con la plataforma de desarrollo mas barata en el mercado, estamos hablando del LaunchPad, la cual nos ser de mucha utilidad a la hora de hacer nuestros desarrollos en formato DIL (Dual In Line) en una Protoboard sin necesidad de realizar circuitos impresos para su prueba de funcionalidad. Una caracterstica que hay que resaltar es que la mayora de sus dispositivos son de montaje superficial lo cual nos permitir hacer desarrollos poderosos, de menor tamao y con un mejor atractivo visual. A lo largo de esta web aprenders a utilizar los perifricos mas bsicos de estos microcontroladores como los puertos de entrada y salida, temporizadores, sistemas de reloj hasta los mas avanzados como los diversos tipos de convertidores, comunicaciones seriales, controlador de la FLASH, controlador de acceso directo a memoria etc.

ACERCA DE LOS PERIFERICOS.


Muy importante mencionar que la configuracin y uso de los perifricos del microcontrolador se realiza a travs de registros (de 8 y 16 bits) con este propsito, lo que debes de saber es la manera de configurar estos registros para obtener una funcin especfica del perifrico a configurar, para ello te daremos a conocer los registros que son involucrados en el uso y configuracin de los perifricos, te mostraremos tambin de manera dinmica como usar estos registros para funciones especificas. En cada captulo buscaremos crear una aplicacin til en el mismo momento que te expliquemos el cdigo ya que esta manera nos ha parecido la mas didctica debido a que el momento en que aprendes aplicas el conocimiento adquirido, esto es mucho mejor que presentarte solo contenido que no tiene una aplicacin prctica inmediata. Al final de cada seccin encontraras links a ejemplos que siguen esta misma dinmica, adems encontraras su diagrama de flujo, la explicacin de su funcionamiento, algn video o foto y el cdigo completo listo para ser descargado o visualizado.

DESARROLLO DE APLICACIONES.
Cuando estamos dispuestos a desarrollar aplicaciones para los microcontroladores MSP430 tendremos que hacer uso de distintas herramientas tanto de software como de hardware, en esta seccin te presentaremos estas herramientas a manera introductoria para posteriormente a lo largo de los contenidos de esta pgina las conozcas ms a fondo.

Conforme obtengamos mas herramientas de hardware y comencemos a experimentar con software nuevo (tanto propio como suministrado por Texas Instruments ) esta seccin ir creciendo. Por lo pronto comenzaremos por el Launchpad. El objetivo de esta seccin es mostrar las herramientas de desarrollo con las cuales disponemos para poder ensearte el uso de la mayor cantidad de perifricos, as como tambin mostrarte las ventajas y desventajas de estas herramientas que para nosotros son importantes y pueden ayudarte a ti a tomar una buena decisin.

LAUNCHPAD
Esta es la herramienta que mas usaremos debido a su bajo costo la cual en Mxico puede obtenerse desde los $100 a $150 aproximadamente, lo cual es mucho menos que otros programadores que proporcionan otros fabricantes. En el caso de los PIC pueden ser programados con muy pocos componentes como en el caso de NOPP pero con este hardware "hecho en casa" solo podemos programar algunos PIC, pero no estar ni cerca de lo que el LAUNCHPAD ofrece. Ya que no es solo un programador, sino una herramienta de desarrollo muy completa. Adems de poder programar todos los dispositivos de la lnea de evaluacin MSP430G2xx (alrededor de 40 dispositivos) podemos correr paso a paso nuestro programa en tiempo real desde nuestra PC, consultar todos los registros e incluso modificarlos, a esto se le conoce como depurar. En forma adicional se puede establecer comunicacin serial entre el dispositivo y la computadora va USB, esto a travs de un puerto COM emulado. Con estas prestaciones podremos crear aplicaciones como esta:
http://www.youtube.com/watch?v=U0mGoRtYbyg&feature=player_embedded#!

El kit de desarrollo LAUNCHPAD contiene dos microcontroladores de la lnea de evaluacin, un cable USB, conectores, un oscilador de 32KHz, una gua de inicio rpido, la tarjeta de desarrollo y dos lindas etiquetas. El microcontrolador que viene insertado en la tarjeta de desarrollo tiene un programa cargado desde fabrica, el cual es el que vimos en el video, bsicamente lo que hace este programa es utilizar el sensor de temperatura que tiene integrado para generar una seal de PWM proporcional a la temperatura de su superficie y adems enviar las lecturas de temperatura a la PC va USB. Texas Instruments provee tambin una GUI (Graphical User Interface) escrita en java para hacer lo que en el video, es decir mostrar la medicin de temperatura en la PC. En lo prximo crearemos un tutorial en el cual te mostraremos el procedimiento para probar esta aplicacin. Con este programa de demostracin podemos ver el potencial de este kit que a pesar de su bajo costo tiene caractersticas superiores a la de muchos disponibles en el mercado al doble de su precio.

Esta herramienta es la que mas recomendamos para comenzar a desarrollar aplicaciones con los MSP430 ya que el microcontrolador est en formato DIP lo cual permite su fcil insercin en Protoboard, cabe aclarar que la mayora de dispositivos MSP430 son de montaje superficial (SMD) lo cual dificulta su desarrollo para proyectos a pequea escala, ya hallaremos una forma de utilizar los miembros ms poderosos de esta familia que se encuentran en este tipo de encapsulados. Es precisamente esta su caracterstica ms sobresaliente (adems de su precio), el formato DIP ya que hay herramientas de desarrollo con mejores prestaciones pero en formato SMD lo cual dificulta su flexibilidad a la hora de modificar el hardware disponible, con este formato DIP lo nico que requerimos es sacar nuestro microcontrolador ya programado para situarlo en una Protoboard y hacer las conexiones necesarias para comenzar con nuestros proyectos.

ACERCA DEL MSP430G2231


-Cuenta con 10 entradas y salidas digitales (11 utilizando la interrupcin no enmascarable) -Puede trabajar hasta 1MHz -Convertidor Analgico-Digital de 10 bits -USI con SPI e I2C -Emulacin va Spy Bi-Wire -Timer_A con 2 mdulos de captura y comparacin -2Kb de memoria Flash y 128b de RAM

ACERCA DEL MSP430G2211


-Cuenta con 10 entradas y salidas digitales (11 utilizando la interrupcin no enmascarable) -Puede trabajar hasta 1MHz -Comparador analgico -Emulacin va Spy Bi-Wire -Timer_A con 2 mdulos de captura y comparacin -2Kb de memoria Flash y 128b de RAM

eZ430
Esta es al igual que el LAUNCHPAD una herramienta de desarrollo muy completa, su costo no es tan reducido ya que ronde entre los $500 en Mxico, lo mejor de esta herramienta de desarrollo es su atractivo visual ya que adems de tener un reducido tamao parece una memoria flash USB.

Esta herramienta consta de dos partes, una de ellas es el emulador USB y la otra de ellas es el microcontrolador a programar que en este caso es el MSP430F2013 el cual puede ser desprendido del emulador USB, podemos adaptar esta tarjeta para proporcionar una conexin fcil con una Protoboard. Con esta herramienta de desarrollo podemos programar todos los miembros de la familia MSP430F2xx con 48 dispositivos aproximadamente va Spy Bi-Wire. El kit que se puede obtener directamente de Texas Instruments contiene una herramienta de desarrollo, una gua de inicio rpido y un CD con el software de desarrollo y la documentacin necesaria para comenzar a crear aplicaciones. La desventaja de esta herramienta es que no habilita la comunicacin serial entre el microcontrolador y la PC pero fuera de esto ofrece casi las mismas prestaciones que el LaunchPad a diferencia de que los dispositivos que puede programar cuentan con mayos memoria y frecuencia de trabajo. ACERCA DEL MSP430F2013 Este microcontrolador ofrece las mismas caractersticas de bajo consumo de los MSP430, no es un dispositivo tan poderoso ni extenso como otros de la familia MSP430F2xx pero posee caractersticas que lo hacen muy til.

-Cuenta con 10 entradas y salidas digitales (11 utilizando la interrupcin no enmascarable) -Puede trabajar hasta 16MHz -Convertidor Analgico-Digital de 16 bits -USI con SPI e I2C -Emulacin va Spy Bi-Wire -Timer_A con 2 mdulos de captura y comparacin -2Kb de memoria Flash y 128b de RAM

IAR
Esta es una herramienta de desarrollo muy importante ya que con esta escribiremos, simularemos, emularemos y depuraremos nuestros programas ya que la gran flexibilidad de este software lo permite, la versin completa de este software tiene un costo el cual desconozco pero Texas Instruments en conjunto con la compaa que desarrolla este software ofrecen una versin gratuita con la cual podremos crear aplicaciones las cuales tienen un limite en el tamao pero es suficiente para utilizar en nuestras herramientas de desarrollo que actualmente contamos como el LaunchPad y el eZ430 . Con este software de desarrollo podremos editar programas tanto en C/C++ como en ensamblador y adems de ello podremos mezclar ambos lenguajes para sacarle provecho a las caractersticas mas resaltables de ambos. Esto nos proporciona una mayor flexibilidad de diseo al tomar el poder de C/C++ y la eficiencia de ensamblador.

LA ARQUILECTURA
Antes de comenzar a crear aplicaciones para los MSP430 debemos de conocer la arquitectura de su CPU para lograr un manejo mas dinmico a la hora de programar, hacer ms eficientes nuestros programas y conocer nuestros lmites en cuanto al hardware a utilizar. En adelante explicaremos algunas de las caractersticas con las que cuentan los MSP430.

CARACTERISTICAS PRINCIPALES EN LA CPU


ALU de 16 bits que efecta operaciones lgicas (AND, OR, XOR), substracciones, adiciones y comparaciones. RISC(Reduced Instruction Set Computing) con 27 instrucciones y 7 modos de direccionamiento.

Arquitectura Ortogonal, adems cualquier instruccin se puede usar con cualquier modo de direccionamiento. Todos los registros en la CPU son completamente accesibles. Las operaciones entre registros se llevan a cabo en un ciclo. Los registros de 16 bits reducen la cantidad de veces que se accede a la memoria al ejecutar una instruccin. El bus de direcciones de 16 bits permite el acceso y los brincos a lo largo de todo el mapa de memoria. El generador de constantes proporciona las 6 constantes mas usadas para reducir el tamao del cdigo y facilitar la programacin a travs de instrucciones emuladas. Transferencias de memoria a memoria sin necesidad de registros intermedios. Instrucciones y modos de direccionamiento para 8 y 16 bits (Byte y Word). 12 registros de propsito general que pueden almacenar tanto datos como direcciones. Construida utilizando lgica esttica con la cual no hay un mnimo de frecuencia de operacin, lo cual permita que la CPU pueda ser detenida.

Estas caractersticas son logradas al tomar las mejores caractersticas de la arquitectura RISC y mejorarlas. Por ejemplo los PICs contienen un solo registro de trabajo (W) donde se almacena un operando, el otro operando es tomado de otro registro, despus se ejecuta la instruccin y el resultado se almacenado ya sea en el registro de trabajo o en el otro registro que fue usado como segundo operando, adems el direccionamiento indirecto solo esta disponible para un nico registro. En el caso de los HCS12 de Freescale cuentan con un registro acumulador para almacenar datos y dos registros ndices para almacenar direcciones. Al comparar la CPU de los MSP430 con otras CPU que pertenecen a microcontroladores podemos notar que la arquitectura de los MSP430 nos permite una programacin mas eficiente, reduce el tamao de cdigo que una aplicacin pueda requerir, permite tambin realizar una funcin especfica con menos instrucciones que en otro tipo de microcontroladores y brinda al desarrollador una flexibilidad y portabilidad que en verdad se agradece, por supuesto todo esto reduce el costo de los productos finales. Tambin nos hace pensar si en realidad estos microcontroladores en verdad son RISC ya que no cumplen unas cuantas caractersticas de esta filosofa ya que la longitud de las instrucciones cambia, y no todas las instrucciones se ejecutan en un ciclo de reloj ya que pueden tardar de 1 a 5 ciclos de reloj, esto hace que estos microcontroladores sean una mezcla entre las principales arquitecturas (CISC y RISC).

En este diagrama a bloques de la CPU MSP430 proporcionado por Texas Instruments podemos observar los 16 registros que la conforman, as como la ALU de 16 bits la cual puede recibir sus operandos de cualquiera de los 16 registros los cuales a su vez a travs del bus de direcciones y datos pueden acceder a cualquier parte de la memoria. Tambin podemos ver las banderas del Registro de Estado que son afectadas cuando se ejecuta una instruccin, las dems banderas en el registro de estado solo son afectadas para entrar a un modo de ahorro de energa o permitir las interrupciones enmascarables. Otro punto interesante en esta diagrama a bloques es que la ALU toma su seal de reloj desde MCLK (Ver seccin SISTEMA DE RELOJ) y solamente esta.

LOS REGISTROS DE LA CPU.


La CPU cuenta en total con 16 registros, los primeros 4 cumplen con funciones especificas y sus valores tienen repercusiones inmediatas en el dispositivo, mas adelante veremos porque. Los otros 12 son como ya lo mencionamos de propsito general y pueden ser usados para contener datos y direcciones lo cual permite usarlos como variables o apuntadores ya que todos son de 16 bits. A continuacin describimos cada uno de ellos:

Se encarga de apuntar a la siguiente instruccin a ejecutar. Como cada instruccin emplea un numero par de bytes (2, 4 o 6) el PC se incrementa de acuerdo a esa cantidad de bytes correspondiente. Ya que el PC solo contiene nmeros pares el bit menos significativo de este registro siempre ser cero. Generalmente se trata de evitar la manipulacin de este registro, salvo que se desee implementar un switch-case estilo C/C++ o un manipulador de interrupciones.

Como su nombre lo dice es un registro apuntador lo que quiere decir que contiene una direccin. Direccin de qu? , pues la direccin de la Pila la cual es de tipo FILO (First In Last Out es decir primero en entrar ltimo en salir) y se sita en la posicin de la RAM que asignemos a este registro. Nos es til para que las subrutinas e interrupciones se lleven a cabo de manera correcta, se recomienda que sea lo primero que se inicialice y que despus de eso se evite su uso ya que puede provocar que el programa se descontrole. Si es completamente necesario el uso de la pila se recomienda usar una instruccin POP por cada instruccin PUSH (ver el set de instrucciones). Todo esto quedara claro ms adelante cuando comencemos con los primeros programas.

Cabe mencionar que por ejemplo en los PICs la pila tiene un numero de niveles fijo, en algunos casos es de 8 o mas, esto limita nuestros programas ya que no puede haber mas de cierto numero de subrutinas o interrupciones.

En este registro se hallan diversas banderas que nos informaran como su nombre lo dice del estado del microcontrolador, a pesar de que el registro es de 16 bits, solo estn implementados 9 por lo que los otros 7 sern usados por el generador de constantes. En este registro se almacenan 4 banderas las cuales reflejan el estado de la ALU despus de que una instruccin es ejecutada, estos son: C( Acarreo), Z(Cero), N(Negativo), V(Sobre flujo). Tambin contiene 4 bits ms que definen el modo de operacin en el que se encuentra el microcontrolador, los cuales se explican en la seccin de Modos De Ahorro De Energa, por lo pronto enunciamos la funcin de cada uno de estos 4 bits. SCG1(Sistema generador de reloj 1), SCG0(Sistema generador de reloj 0), OSCOFF, CPUOFF. El ultimo bit por mencionar es el de GIE (General Interrupt Eneable o Habilitar Interrupciones Globales) el cual al estar en 1 permite las interrupciones de manera global. Muchos bits aqu mencionados se explicaran en su momento, por ahora es suficiente con entender por ejemplo los bits que por lo regular vienen en otro tipo de

microcontroladores (C, Z, N y V) los dems son solo implementados en los MSP430 y por lo tanto describiremos su uso en los perifricos a los cuales de alguna manera pertenecen.

R2 y R3.-Generador de constantes (Constant Generator).


Estos registros contienen las 6 constantes ms usadas las cuales sirven para emular instrucciones, esto con el objetivo de hacer ms gil y fcil la programacin, por ejemplo para incrementar se usa 1 y 2, para borrar un registro se usa 0 etc. A travs de el generador de constantes se pueden obtener 24 instrucciones emuladas.

R4-R15.-Registros de propsito general (General Prupose).


Como ya se ha mencionado, estos registros pueden guardar tanto datos como direcciones ya que todos son de 16 bits. Es bueno mencionar que las operaciones entre registros son mucho ms rpidas que las que tienen que acceder a la memoria (ver modos de direccionamiento). Se recomienda usar estos registros lo ms posible. En el momento de la programacin se hara referencia de estos registros mediante las notaciones aqu expuestas, es decir PC,SP,SR,R4-R15.

MODOS DE DIRECCIONAMIENTO.
Los modos de direccionamiento al igual que el set de instrucciones sern empleados solo por el lenguaje ensamblador o cuando se mescle este lenguaje con C/C++, as que si solo deseas programar los MSP430 usando C/C++ no es necesario que leas esta seccin ni la de set de instrucciones. Los modos de direccionamiento son usados para que la CPU conozca la manera en que le sern accedidos los operandos de la instruccin a ejecutar. Las instrucciones se dividen en dos grandes grupos:

Operando Simple del tipo: [instruccin] destino Doble Operando del tipo: [instruccin] fuente, destino

Los MSP430 soportan 7 modos de direccionamiento, de los cuales solo 4 de ellos son implementados fsicamente en la CPU (Registro, Indexado, Indirecto e Indirecto con autoincremento) es decir grabados en cilicio, 2 de ellos resultan de usar el PC como un registro (Simblico e Inmediato) y el ultimo se obtiene indexando un registro cuyo valor es cero (Absoluto), es decir SR cuando se usa como Generador De Constantes. Las instrucciones de Operando Simple pueden ser usadas con los 7 modos de direccionamiento, en el caso de las instrucciones de Doble Operando, para el caso de su operando fuente se pueden usar los 7 modos de direccionamiento, pero para el caso de el operando destino solo se pueden usar 4.

A continuacin se describen los 7 modos de direccionamiento con ejemplos, una breve descripcin, ya que no es el objetivo aburrir con teora complicada acerca de los modos de direccionamiento y por ultimo una tabla con la cantidad de ciclos de reloj que se tarda en ejecutar alguna instruccin dependiendo sus modos de direccionamiento.

Modo registro.
Ejemplo de Operando simple: Registro Antes. Instruccin Registro Despus. R8=0000h INC R8 R8=0001h

Descripcin: Dado que utilizamos la instruccin INC, lo que hace este ejemplo es incrementar en 1 el valor del registro 8 (R8).
Ejemplo de Operando doble: Registros Antes. Instruccin Registro Despus. R4=0010h, R5=07F0h MOV R4,R5 R4=0010h, R5=0010h

Descripcin: Ya que se usa la instruccin MOV lo que hace el ejemplo es que mueve el contenido de R4 a R5.Como podemos ver independientemente de la instruccin a usar se nota que solo se usaron registros de la CPU, de hecho este modo de direccionamiento solo se puede usar con los 16 registros de la CPU lo cual hace que este modo sea de los mas veloces y que menos espacio ocupa. Para mas instrucciones ve al set de instrucciones. Ciclos requeridos:
Operandos 2 2 1 1 Modo en el destino Por registro Instruccin Cualquiera Ciclos Longitud 1 4 1 2 1 1

Indexado, Simbolico o Absoluto Cualquiera -------------------

RRA, RRC, SWPB o SXT 1 CALL o PUSH 5

Usos: Cuando utilizamos o accedemos un valor mas de 4 o 5 veces se recomienda cargarlo en un registro de la CPU y trabajar con este modo de direccionamiento para as reducir los tiempos de ejecucin.

Modo Indexado.
Sintaxis: [instruccin] [instruccin] n(destino) n(fuente), *otro modo

Donde: [instruccin] es cualquiera en el set de instrucciones, fuente y destino son cualquier registro de la CPU, n es un numero cualquiera y *otro modo significa cualquier otro modo de direccionamiento disponible para el destino incluyendo indexado.
Ejemplo de Operando simple: Registro Antes. Locacin de memoria antes. Instruccion DEC 3(R8) R8=0300h 0303h=FF0Eh

Registro Despus. R8=0300h Locacin de memoria despues. 0303h=FF0Dh

Descripcin: La instruccin no altera a R8 si no que altera a la locacin de memoria R8 + 3, es decir 300+3=303 que es donde se realiza el decremento ya que se utilizo la instruccin DEC.
Ejemplo de Operando doble: Registro Antes. Locacin de memoria antes Instruccin R4=0240h, R5=A0F1h 0245h=FFFFh y A0F7=O777h MOV 5(R4), 6(R5)

Registro Despus. R4=0240h, R5=A0F1h Locacin de memoria despues 0245h=FFFFh y A0F7=FFFFh

Descripcin: Como en el caso anterior no se modifican los registros R4 ni R5 si no que se modifica el contenido de la direccin R4 +5 y R5+6 es decir (240h+5h=245h) y (A0F1h+6h=A0F7h). As como con el modo registro, los operandos solo pueden ser registros de la CPU. Para mas instrucciones ve al set de instrucciones. Ciclos requeridos:
Operandos 2 2 Modo en el destino Por registro Instruccin Cualquiera Ciclos Longitud 3 6 2 3

Indexado, Simbolico o Absoluto Cualquiera

Operandos 1 1

Modo en el destino -------------------

Instruccin

Ciclos Longitud 2 2

RRA, RRC, SWPB o SXT 4 CALL o PUSH 5

Usos: Se suele usar para la bsqueda en tablas, as como para medir la distancia entre localidades de memoria, tambin para crear listas, apuntadores, matrices etc.

Modo simblico.
Sintaxis: [instruccin] etiqueta1 [instruccin] etiqueta1, *otro modo

Donde: [instruccin] es cualquiera en el set de instrucciones, etiqueta1 es como su nombre lo dice una etiquete la cual contiene una direccin y *otro modo significa cualquier otro modo de direccionamiento disponible para el destino incluyendo el simblico.
Ejemplo de Operando simple: Locacin de memoria antes Instruccin Locacin de memoria despus ETQ1=FF0Eh CLR ETQ1 ETQ1=0000h

Descripcin: ETQ1 es una etiqueta que hace referencia a una localidad de memoria, en este caso borra la localidad de memoria ya que eso hace CLR.
Ejemplo de Operando doble: Locacin de memoria antes Instruccin Locacin de memoria despus ETQ1=FEAFh y ETQ2=7421h MOV ETQ1, ETQ2 ETQ1=FEAFh y EQT2=FEAFh

Descripcin: Como podemos ver el contenido de ETQ1 se mueve a ETQ2. Para mas instrucciones ve al set de instrucciones. Ciclos requeridos:
Operandos 2 Modo en el destino Por registro Instruccin Cualquiera Ciclos Longitud 3 2

Operandos 2 1 1

Modo en el destino

Instruccin

Ciclos Longitud 6 3 2 2

Indexado, Simbolico o Absoluto Cualquiera -------------------

RRA, RRC, SWPB o SXT 4 CALL o PUSH 5

Usos: Para acceder a cualquier locacin de memoria incluida la RAM.

Modo Absoluto.
Sintaxis: [instruccin] &etiqueta1 [instruccin] &etiqueta1, *otro modo

Donde: [instruccin] es cualquiera en el set de instrucciones, etiqueta1 es una etiqueta la cual contiene una direccin , *otro modo significa cualquier otro modo de direccionamiento disponible para el destino incluido Absoluto y "&" es el que caracteriza a este modo.
Ejemplo de Operando simple: Locacin de memoria antes Instruccin Locacin de memoria despus ETQ1=FF0Eh CLR &ETQ1 ETQ1=0000h

Descripcin: Como podemos ver ocurre exactamente lo mismo que con el modo simblico esto porque la funcin que cumplen es la misma, lo nico que cambia es como la hacen, aunque como usuarios nunca nos enteramos de la diferencia.
Ejemplo de Operando doble: Locacin de memoria antes Instruccin Locacin de memoria despus ETQ1=FEAFh y ETQ2=7421h MOV &ETQ1, &ETQ2 ETQ1=FEAFh y EQT2=FEAFh

Descripcin: Ocurre lo mismo que en el modo anterior, edemas de que estos modos cumplen la misma funcin adems generan la misma cantidad de cdigo. Ciclos requeridos:
Operandos Modo en el destino Instruccin Ciclos Longitud

Operandos 2 2 1 1

Modo en el destino Por registro

Instruccin Cualquiera

Ciclos Longitud 3 6 2 3 2 2

Indexado, Simbolico o Absoluto Cualquiera -------------------

RRA, RRC, SWPB o SXT 4 CALL o PUSH 5

Usos: Especficamente este modo de direccionamiento lo usaremos para referirnos a los registros de funcin especial (SFR) y para los registros de los perifricos por ejemplo P1IN, TAR, WDTCTL, etc. para conservar la portabilidad entre dispositivos.

Modo Indirecto.
Sintaxis: [instruccin] @fuente [instruccin] @fuente, *otro modo

Donde: [instruccin] es cualquiera en el set de instrucciones, fuente es cualquier registro de la CPU, *otro modo significa cualquier otro modo de direccionamiento disponible para el destino y "@" caracteriza a este modo.
Ejemplo de Operando simple: Registro Antes. Locacin de memoria antes Instruccin Registro Despus. Locacin de memoriaantes R5=0240h 0240h=0021h CLR @R8

R5=0240h 0240h=0000h

Descripcin: Podemos notar que R5 no se ve afectado si no el contenido de R5


Ejemplo de Operando doble: Registro Antes. Locacin de memoria antes Instruccin Registro Despus. Locacin de memoria despues R4=0060h, R9=1000h 0060h=AAA0 MOV @R4, R9

R4=0060h, R9=AAA0h 0060h=AAA0

Descripcin: R4 esta actuando como apuntador, lo que hace la instruccin es mover el contenido de la direccin apuntada por R4 al registro 9 (R9) esto se hace sin alterar R4. Hay que mencionar que este modo de direccionamiento es exclusivo de la fuente. Ciclos requeridos:
Operandos 2 2 1 1 Modo en el destino Por registro Instruccin Cualquiera Ciclos Longitud 2 5 1 2 1 1

Indexado, Simbolico o Absoluto Cualquiera -------------------

RRA, RRC, SWPB o SXT 3 CALL o PUSH 4

Usos: El que realmente saca provecho de esta instruccion es el compilador de C/C++ ya que com el se pueden hacer apuntadores y arreglos, aunque nosotros lo usaremos de manera mas especifica en tablas o arreglos pero implementados en lenguaje ensamblador.

Modo indirecto con autoincremento.


Sintaxis: [instruccin] @fuente+ [instruccin] @fuente+, *otro modo

Donde: [instruccin] es cualquiera en el set de instrucciones, fuente es cualquier registro de la CPU, *otro modo significa cualquier otro modo de direccionamiento disponible para el destino y "@" junto con "+" caracterizan a este modo.
Ejemplo de Operando simple: Registro Antes. Locacin de memoriaantes Instruccin Registro Despus. Locacin de memoria despues R7=0F28h 0F28h=0062h DINC @R7+

R7=0F29h 0F28h=0064h

Descripcin: En este caso se usa la instruccin de doble incremento, lo cual se hace sobre el contenido de la direccin a la que apunta R7, pero aqu si se modifica el registro que usamos como apuntador, es decir R7=R7+1.

Ejemplo de Operando doble: Registro Antes. Locacin de memoria antes Instruccin Registro Despus. Locacin de memoria despues R5=FF00h R9=00A0h FF00h=0034h MOV @R5+, R9

R5=FF01h R9=0034h FF00h=0034h

Descripcin: Dado que R5 actua como apuntador, lo que se modifica es R9 ya que se copia el valor apuntado por R5 a R9 y tambin R5 ya que se incrementa en 1. Tambin hay que mencionar que este modo solo es para la fuente al igual que el anterior. Ciclos requeridos:
Operandos 2 2 1 1 Modo en el destino Por registro Instruccin Cualquiera Ciclos Longitud 2 5 1 2 1 1

Indexado, Simbolico o Absoluto Cualquiera -------------------

RRA, RRC, SWPB o SXT 3 CALL o PUSH 4

Usos: Este modo es til para recorrer tablas, para copiar o leer secciones enteras de memoria etc.

Modo Inmediato.
Sintaxis: [instruccin] #cte, *otro modo

Donde:: es cualquiera en el set de instrucciones, cte es un valor numrico constante, *otro modo significa cualquier otro modo de direccionamiento disponible para el destino y "#" caracteriza a este modo.
Ejemplo de Operando doble: Registro Antes. Instruccin Registro Despus. R15=0FF0h MOV #000F, R15 R15=00Fh

Descripcin: Mueve la constante 000Fh al registro 15 (R15), este modo es solo para el operando fuente. Ciclos requeridos:
Operandos 2 2 1 1 Modo en el destino Por registro Instruccin Cualquiera Ciclos Longitud 2 5 2 3 2

Indexado, Simbolico o Absoluto Cualquiera -------------------

RRA, RRC, SWPB o SXT CALL o PUSH 5

Usos: Se emplea para asignar valores constantes a registros o localidades de memoria, si esas constantes son valores especificos como 0000h,0001h,0002h,0004h,0008h, y FFFFh pueden ser generados por los registros R2 y R3 y en ese caso el modo de direccionamiento se convierte en el modo por registros.

Instrucciones Aritmeticas
Con estas instrucciones las utilizaremos para realizar operaciones tanto de forma binaria como decimal, adems realizar multiplicaciones esto es til de muchas formas, solo pretendemos darte un panorama general para que puedas llevar a cabo tus ideas de forma mas sencilla.

Suma Destino y C.- ADC


Sintaxis: ADC (.B o .W) destino

Descripcin: Suma el destino con la bandera de acarreo Emulada por: ADDC (.B o .W) #0 , destino

Aadir.- ADD [0101]


Sintaxis: ADD (.W o .B) fuente, destino

Descripcin: El operando fuente es sumado al operando destino, el resultado es almacenado en destino. Operacin realizada: destino = destino + fuente Banderas afectadas: Todas las banderas son afectadas normalmente.

Aadir con acarreo.- ADDC [0110]


Sintaxis: ADDC (.B o .W) fuente, destino

Descripcin: Se realiza la suma entre la fuente, el destino y la bandera de acarreo, el resultado se almacena en destino. Instruccin til para realizar sumas de cifras mayores a 16 bits. Operacin realizada: destino = destino + fuente + C Banderas afectadas: Todas las banderas son afectadas normalmente.

Suma decimal con C.- DADC


Sintaxis: DADC (.B o .W) destino

Descripcin: La bandera de acarreo es sumada al destino de forma decimal, es decir 9+1=10 (en hexadecimal 9+1=A como normalmente se hace) Emulada por: DADD (.B o .W) #0 , destino

Suma en BCD.- DADD [1010]


Sintaxis: DADD (.B o .W) fuente, destino

Descripcin: La fuente y el acarreo son sumados en formato decimal con el destino almacenando el resultado en destino. til para operaciones decimales como BCD lo permite. Operacin realizada: destino = destino + fuente + C (Todo en BCD) Banderas afectadas: Z si el resultado es 0, C si el resultado es mayor a 9999(si se usa .W) o si el resultado es mayor a 99 (si se usa .B), N toma el valor del bit mas significativo (MSB), V resulta indefinido.

Decremento.- DEC
Sintaxis: DEC (.B o .W) destino

Descripcin: El destino es decrementado por 1 Emulada por: SUB (.B o .W) #1 , destino

Doble Decremento.- DECD


Sintaxis: DECD (.B o .W) destino

Descripcin: Decrementa por dos el destino Emulada por: SUB (.B o .W) #2 , destino

Incremento.- INC
Sintaxis: INC (.B o .W) destino

Descripcin: Incrementa en 1 el destino. Emulada por: ADD (.B o .W) #1 , destino

Doble Incremento.-INCD
Sintaxis: INCD (.B o .W) destino

Descripcin: Incrementa por dos el destino Emulada por: ADD (.B o .W) #2 , destino

Sustraer.- SUB [1000]


Sintaxis: SUB (.B o .W) fuente, destino

Descripcin: Sustrae o resta la fuente del destino, el resultado es almacenado en destino. Instruccin parecida a CMP solo que aqu los registros si son modificados. Operacin realizada: destino = destino - fuente Banderas afectadas: Z si el resultado es cero, C si se produce un acarreo al sumar destino y el complemento a dos de la fuente, N si fuente>=destino , V si ocurre un sobre flujo aritmtico.

Sustrae con acarreo.- SUBC [0111]


Sintaxis: SUBC (.B o .W) fuente, destino

Descripcin: Resta la fuente y el acarreo del destino, el resultado se almacena en destino. Instruccin til para realizar restas con valores que ocupen mas de 16 bits. Operacin realizada: destino = destino - fuente -1 + C Banderas afectadas: Z si el resultado es cero, C si se produce un acarreo al sumar destino y el complemento a dos de la fuente, N si fuente>=destino , V si ocurre un sobre flujo aritmtico.

Instrucciones Logicas.
Estas instrucciones nos sern de utilidad para configurar de manera especifica ciertos mdulos de algn perifrico, adems de ello nos sern tiles para implementar lgica binaria con cualquier dato en el sistema, bien nos podran ser tiles para filtrados digitales, para codificacin y decodificacin.

Y lgica.-AND [1111]
Sintaxis: AND (.W o .B) fuente destino

Descripcin: Realiza la operacin lgica "y" entre el operando fuente y el operando destino, esto lo usamos mara poner ciertos bits del destino a 0, bits que son seleccionados por la fuente. Operacin realizada: destino = destino & fuente Banderas afectadas: Z si el resultado es cero, C es contraria a Z, N toma el valor del MSB (bit mas significativo) y V se pone a 0.

Borra bits seleccionados en destino.- BIC [1100]


Sintaxis: BIC (.B o .W) fuente, destino

Descripcin: Los bits especificados en la fuente sern borrados en el destino, esto nos es til para modificar los SFR (Registros de Funcin especifica) y adems los registros de los perifricos. Operacin realizada: destino= destino & (-fuente) Banderas afectadas: Ninguna bandera afectada.

Coloca bits seleccionados en destino.- BIS [1101]


Sintaxis: BIS (.B o .W) fuente, destino

Descripcin: Pone a 1 los bits del destino en las posiciones que indiquen los bits de la fuente, esta instruccin la usamos para poner a 1 bits especficos en un registro cualquiera aunque la usaremos mas con los registros de los perifricos. Operacin realizada: destino=destino | fuente. Banderas afectadas: Ninguna bandera afectada.

Comprobar bits en destino.- BIT [1011]


Sintaxis: BIT (.B o .W) fuente, destino

Descripcin: Sirve para saber si el o los bits especificados en fuente son 1 o 0 en destino, esta instruccin de utiliza en conjunto con los saltos condicionales para obtener sentencias de control de flujo. Cabe mencionar que la instruccin no afecta a los operandos, solo afecta a las banderas. Operacin realizada: destino & fuente Banderas afectadas: Z si el resultado es cero, C es contraria a Z, N toma el valor del MSB (bit mas significativo) y V se pone a 0.

Negacin.- INV
Sintaxis: INV (.B o .W) destino

Descripcin: Los bits en el destino son invertidos, es decir el destino es negado Emulada por: XOR #0FFFFh , destino (Con .W) XOR #0FFh , destino (Con .B)

Corrimiento a la izquierda.- RLA


Sintaxis: RLA (.B o .W) destino

Descripcin: Realiza un corrimiento aritmtico de bits a la izquierda Emulada por: ADD (.B o .W) destino , destino

Corrimiento a la izquierda con C.- RLC


Sintaxis: RLC (.B o .W) destino

Descripcin: Realiza el corrimiento de bits a la izquierda a travs de la bandera de acarreo Emulada por: ADDC (.B o .W) destino , destino

Corrimiento aritmtico a la derecha.- RRA [000100010]


Sintaxis: RRA (.B o .W) DESTINO

Descripcin: Realiza un corrimiento de bits aritmtico, el MSB es conservado y el LSB es desplazado a la bandera de acarreo. Operacin realizada: Banderas afectadas: Z si el resultado es cero, C toma el valor del LSB, N si el resultado es mayor a cero, V =0.

Corrimiento a la derecha con acarreo.- RRC [000100000]


Sintaxis: RRC (.B o .W) destino

Descripcin: Todos los bits en el destino son rotados hacia la derecha por una posicin, el acarreo es recorrido a el MSB y el LSB es recorrido a la bandera de acarreo. Operacin realizada: Banderas afectadas: Z si el resultado es cero, C toma el valor del LSB, N si el resultado es mayor a cero, V si destino es mayor a cero y C=1.

Intercambia Bytes.- SWPB [000100001]


Sintaxis: SWPB destino

Descripcin: El byte alto y el byte bajo de destino son intercambiados, el resultado es almacenado en el destino. Operacin realizada: Intercambia Bytes. Banderas afectadas: Las banderas no son afectadas.

Extiende el signo.- SXT [000100001]


Sintaxis: SXT destino

Descripcin: El signo del byte bajo (bit7) es copiado en todo el byte alto (bits 8-15). Operacin realizada: bits 8-15 de destino= bit7 de destino Banderas afectadas: Z si el resultado es 0, C es contrario a Z, N si el resultado es mayor a cero, V=0.

O exclusiva lgica.- XOR [1110]


Sintaxis: XOR (.B o .W) fuente, destino

Descripcin: Esta instruccin realiza la operacin lgica o exclusiva (XOR) entre la fuente y el destino, esto sirve para cambiar de estado los bits en destino seleccionados por la fuente es decir si un bit es 0 lo cambiamos a 1 sin afectar el resto. Operacin realizada: destino = destino XOR fuente Banderas afectadas: Z si el resultado es cero, C es contraria a Z, N toma el valor del MSB (bit mas significativo) y V se pone a 1 si ambos operandos son negativos (MSB=1).

Instrucciones De Datos.
Estas instrucciones nos sern tiles para la manipulacin de datos en registros o bien en localidades de memoria, as como manipular de manera fcil e intuitiva las banderas del registro de estado. La manipulacin de datos es de suma importancia ya que con ayuda de estas instrucciones y otras mas podremos configurar nuestros perifricos de manera deseada. Adems de ello tambin tendremos acceso a la pila la cual utilizaremos para resguardar la informacin en los registros durante una interrupcin o bien para guardar copias de seguridad de datos o direcciones.

Borrar.- CLR
Sintaxis: CLR (.B o .W) destino

Descripcin: Borra el destino. Emulada por: MOV (.B o .W) #0 , destino

Borra Acarreo.- CLRC


Sintaxis: CLRC

Descripcin: Borra la bandera de acarreo en el registro de estado (Status) Emulada por: BIC #1 , SR

Borra Negativo.- CLRN


Sintaxis: CLRN

Descripcin: Borra la bandera de negativo en el registro de estado (Status) Emulada por: BIC #4 , SR

Borra Cero CLRZ


Sintaxis: CLRZ

Descripcin: Borra la bandera de cero en el registro de estado (Status) Emulada por: BIC #2 , SR

Comparar.- CMP [1001]


Sintaxis: CMP (.B o .W) fuente, destino

Descripcin: La fuente es restada del destino pero no altera a ninguno de los operandos, esto con el objetivo de solo modificar las banderas. Esta instruccin es usada junto con los saltos condicionales. Operacin realizada: destino - fuente Banderas afectadas: Z si el resultado es cero, C si se produce un acarreo al sumar destino y el complemento a dos de la fuente, N si fuente>=destino , V si ocurre un sobre flujo aritmtico.

Mover.- MOV [1000]


Sintaxis: MOV (.B o .W) fuente, destino

Descripcin: esta instruccin hace que la fuente sea copiada en el destino. Es una de las instrucciones mas tiles ya que la usaremos para asignar valores a cualquiera de los registros, conforme avancemos con los ejemplos veras lo til que es. Operacin realizada: destino = fuente Banderas afectadas: Ninguna bandera afectada.

Sacar elemento de la pila.- POP


Sintaxis: POP (.B o .W) destino

Descripcin: El valor en la cima de la pila es movido a el destino Emulada por: MOV (.B o .W) @SP+ , destino

Almacena en la pila.- PUSH [000100100]


Sintaxis: PUSH (.B o .W) fuente

Descripcin: Almacena la fuente en la pila Operacin realizada: SP=SP-2 y @SP=fuente Banderas afectadas: Las banderas no son afectadas.

Colocar C.- SETC


Sintaxis: SETC

Descripcin: Coloca la bandera de acarreo del registro de estado (Status) en 1 Emulada por: BIS #1 , SR

Colocar N.- SETN


Sintaxis: SETN

Descripcin: Coloca la bandera de negativo del registro de estado (Status) en 1 Emulada por: BIS #1 , SR

Coloca Z.- SETZ


Sintaxis: SETZ

Descripcin: Coloca la bandera de cero del registro de estado (Status) en 1 Emulada por: BIS #2 , SR

Prueba.- TST
Sintaxis: TST (.B o .W) destino

Descripcin: Comprueba el estado de el destino con respecto a cero Emulada por: CMP (.B o .W) #0 , destino

Incremento.- INC
Sintaxis: INC (.B o .W) destino

Descripcin: Incrementa en 1 el destino. Emulada por: ADD (.B o .W) #1 , destino

Decremento.- DEC
Sintaxis: DEC (.B o .W) destino

Descripcin: El destino es decrementado por 1 Emulada por: SUB (.B o .W) #1 , destino

Doble Incremento.-INCD
Sintaxis: INCD (.B o .W) destino

Descripcin: Incrementa por dos el destino Emulada por: ADD (.B o .W) #2 , destino

Doble Decremento.- DECD


Sintaxis: DECD (.B o .W) destino

Descripcin: Decrementa por dos el destino Emulada por: SUB (.B o .W) #2 , destino

Corrimiento a la izquierda.- RLA


Sintaxis: RLA (.B o .W) destino

Descripcin: Realiza un corrimiento aritmtico de bits a la izquierda Emulada por: ADD (.B o .W) destino , destino

Corrimiento a la izquierda con C.- RLC


Sintaxis: RLC (.B o .W) destino

Descripcin: Realiza el corrimiento de bits a la izquierda a travs de la bandera de acarreo Emulada por: ADDC (.B o .W) destino , destino

Suma Destino y C.- ADC


Sintaxis: ADC (.B o .W) destino

Descripcin: Suma el destino con la bandera de acarreo Emulada por: ADDC (.B o .W) #0 , destino

Suma decimal con C.- DADC


Sintaxis: DADC (.B o .W) destino

Descripcin: La bandera de acarreo es sumada al destino de forma decimal, es decir 9+1=10 (en hexadecimal 9+1=A como normalmente se hace) Emulada por: DADD (.B o .W) #0 , destino

Negacin.- INV
Sintaxis: INV (.B o .W) destino

Descripcin: Los bits en el destino son invertidos, es decir el destino es negado Emulada por: XOR #0FFFFh , destino (Con .W) XOR #0FFh , destino (Con .B)

Instrucciones De Control.
Recordando la sintaxis de varios lenguajes de programacin de alto nivel utilizan cierto conjunto de instrucciones denominadas de Control de Flujo (if, else, while, do-while, shitch, foreach, etc) ya que estas logran que el programa tenga ramificaciones las cuales suceden dependiendo de ciertas condiciones. Las instrucciones de Control de Flujo de los lenguajes son traducidas a instrucciones en lenguaje ensamblador como las que mostraremos aqu. Estas instrucciones de Control de Flujo han demostrado ser capaces de resolver los problemas que se enfrentan a la hora de programar de una manera eficiente y sencilla. Adems de esto los problemas que suelen suscitarse al implementar estas instrucciones de control son solo de lgica del programa los cuales son fciles de resolver con tan solo cambiar las condiciones de salto, sin embargo al utilizar saltos (JMP) y brincos

(BR) de manera no controlada podemos llegar a un momento en la ejecucin del programa en el que este se descontrole. Para lograr programas robustos, fciles de mantener y extender es muy recomendable utilizar saltos condicionales los cuales solo se sucintan si cierta condicin se cumple.

Brinco.- BR
Sintaxis: BR destino

Descripcin: Realiza un brinco incondicional a cualquier locacin en la memoria Emulada por: MOV destino , PC

Llamar subrutina.- CALL [000100101]


Sintaxis: CALL destino

Descripcin: Se realiza la llamada de una subrutina indicada por destino, esto alterara el flujo del programa, se recomienda el uso de subrutinas cuando una porcin de cdigo se tenga que repetir muchas veces. Operacin realizada: PUSH PC (Almacena el PC en la pila) y PC= destino (se carga el PC con la direccin de la subrutina) Banderas afectadas: Ninguna, las banderas no son afectadas.

Inhabilita las interrupciones.- DINT


Sintaxis: DINT

Descripcin: No permite que las interrupciones sean generadas de manera glogal Emulada por: BIC #8 , SR

Habilita las interrupciones.- EINT


Sintaxis: EINT

Descripcin: Las interrupciones sern permitidas de manera global Emulada por: BIS #8 , SR

Salta si C.- JC [001011]


Descripcin: Ocurre un salto a el destino si la bandera de acarreo es 1, de lo contrario realiza un NOP

Salta si mayor o igual.- JGE [001101]


Descripcin: Ocurre un salto a destino si la bandera de sobre flujo y la de negativo tienen el mismo valor, de lo contrario realiza un NOP.

Salta si menor.- JL [001110]


Descripcin: Ocurre un salto a destino si la bandera de sobre flujo y la de negativo tienen valores opuestos, de lo contrario ocurre un NOP

Salta.- JMP [001000]


Descripcin: Ocurre un salto incondicional a destino

Salta si N.- JN [001100]


Descripcin: Ocurre un salto a destino cuando si la bandera de negativo es 1, de lo contrario ocurre un NOP

Salta si C no es cero.- JNC [001010]


Descripcin: Ocurre un salto a destino si la bandera de acarreo es cero, de lo contrario realiza un NOP

Salta si Z no es cero JNE/JNZ [001000]


Descripcin: Ocurre un salto a destino si la bandera de cero es cero, de lo contrario realiza un NOP

Salta si Z.- JEQ/JZ [001001]


Descripcin: Ocurre un salto a destino si la bandera de cero es 1, de lo contrario realiza un NOP

Sin operacin.- NOP


Sintaxis: NOP

Descripcin: Consume un ciclo de reloj sin hacer nada, esta instruccin tampoco contiene fuente o destino Emulada por: MOV #0 , R3

Regreso de Subrutina.- RET


Sintaxis: RET

Descripcin: Es el complemento a toda instruccin CALL, sirve para regresar de una subrutina. Como podemos notar este no tiene ningn argumento. Emulada por: MOV @SP+ , PC

Regreso de la interrupcin.- RETI [0001001100000000 completo]


Sintaxis: RETI

Descripcin: Regresa el flujo del programa desde una interrupcin al punto donde se genero. Para mas informacin consulte la seccin de Interrupciones y Sub rutinas. Operacin realizada: POP SR (Saca SR de la Pila) y POP PC (Saca el PC de la pila) Banderas afectadas: Todas, ya que son restauradas las banderas tal y como estaban antes de que sucediera la interrupcin.

ORGANIZACIN DE LA MEMORIA
La ventaja mas critica de la estructura de la memoria es que los registros de los perifricos, as como los de las interrupciones, los de funcin especifica estn rodos mapeados dentro de las direcciones 0x0000 hasta la 0xFFFF, esto nos da una eficiencia alta, ya que todos los registros pueden ser accesados con cualquier instruccin y modo de direccionamiento. En el caso de los PICs que cuentan con dos bancos de memoria es un tanto ineficiente tener que perder un ciclo de reloj para cambiar la seleccin entre banco y banco, esto no ocurre con esta arquitectura. A continuacin veremos la forma en la que se organiza la memoria en estos microcontroladores, as como la funcin que cumple cada segmento.

REGISTROS DE FUNCION ESPECIFICA


Estos se encuentran en las primeras localidades de memoria, desde la 0x0000 a la 0x000F (16 registros), por lo regular solo los primeros 6 se usan, el primero se encarga de habilitar interrupciones, las localidades 0x002 y 0x0003 contienen banderas de interrupcin, y en las ultimas dos (0x0004 y 0x0005) contienen bits que son utilizados por la USART (Universal Synchronous Asynchronous Receiver Transmitter). Esto es claro de manera general, pero para el caso del MSP430G2231 o el MSP430F2013 solo se usan los 4 primeros registros de 8 bits, es decir el de habilitacin

de interrupciones y las banderas de interrupcin. A continuacin se muestran esos dos registros.

Solo son presentados a manera de ejemplo ya que posteriormente utilizaremos algunos bits de estos registros para algunos perifricos. En el datasheet especifico de cada dispositivo podremos ver la configuracin de estos 16 registros y la funcin que cumplen si es que estn implementados

REGISTROS DE LOS PERIFERICOS


Todos los registros de los perifricos estn mapeados en la memoria justo despus de los registros de funcin especial, esto para facilitar el acceso a ellos. Existen dos tipos de registros de perifricos:

Los que pueden accederse con instrucciones de byte (.B) que se encuentran en 0x010 a 0x0FF. Los que pueden accederse con instrucciones de word (.W) y se encuentran desde 0x100 a 0x1FF.

Estos se utilizan para la configuracin de los perifricos como puertos de entrada y salida digital, convertidor, temporizadores, mdulos de reloj bsico, etc. El uso y repercusin de los valores que pueden contener estos registros se detallaran en la seccin dedicada a cada perifrico.

RAM
La memoria RAM comienza en la direccin 0x200 en todos los dispositivos y dependiendo de la cantidad de cantidad que tenga cada dispositivo, depender el lugar donde termine ya que hay modelos con 128, 256, 512, 1024, y 2048 bytes de RAM, esta nos ser til en tiempo de ejecucin de los programas cargados en la memoria de programa. La RAM se usa para guardar variables que sern utilizadas muchas veces dentro del programa, para almacenar variables globales y lo mas importante: la pila. Hay que ser muy consientes de localizar a la pila dentro de la RAM, ya que de no ser situada en un lugar optimo, puede ocurrir que el programa se descontrole por completo, as se recomienda situar la pila despus de la mitad de la RAM.

MEMORIA DE ARRANQUE
La memoria de arranque solo esta disponible en los dispositivos FLASH en las localidades que van de 0x0C00 a 0xFFF, esta seccin de la memoria es la nica que no se puede modificar, ya que cuenta con un cargador de arranque el cual es utilizado para programar los bloques de la memoria FLASH.

MEMORIA DE INFORMACIN
Al igual que el segmento anterior solo se aplica en los dispositivos con memoria flash ya que esta informacin es la encargada de llevar a cabo la grabacin de la memoria FLASH. Tambin contiene las constantes de calibracin para el DCO (Ver seccin de SISTEMA DE RELOJ)

MEMORIA DE CODIGO
La direccin de inicio de este segmento es variable ya que depende de la cantidad de memoria disponible para este objetivo. Hay dispositivos con 2,4,8,12,16,24,32,48,60 kilobytes de memoria de programa.

En este lugar se almacenara lo correspondiente a instrucciones, tablas, las constantes mas usadas, etc. El final de este segmento es constante para todos los dispositivos y termina en la direccin 0xFFDF.

VECTORES DE INTERRUPCION
Los vectores de interrupcin estn localizados al final de la memoria desde la localidad 0xFFE0 a 0xFFFF, estos son de vital importancia para sacar el mayor provecho a esta familia de microcontroladores, ya que como su nombre lo dice nos ayudaran con el uso de las interrupciones (Ver seccin de Interrupciones). El contenido del vector depende de los perifricos implementados en cada dispositivo, pueden ser consultados en el datasheet del dispositivo en cuestin a continuacin se muestra un ejemplo del vector de interrupciones del MSP430G2231.

TIPOS DE MEMORIA
Los MSP430 estn disponibles con diferentes tipos de memoria obviamente para distintas aplicaciones comerciales, la forma de identificar que memoria posee cada dispositivo es a travs de su matricula ya que la letra despus de MSP430 representa el tipo de memoria que ese dispositivo posee. ROM

Los dispositivos de este tipo se entregan ya programados por el distribuidor, el costo de estos dispositivos es muy bajo, pero solo en grandes cantidades de produccin adems de que deben ser programados con cdigo que haya comprobado su estabilidad, de lo contrario para corregir errores no detectados se debe de repetir cierta parte del diseo inicial. En la matricula se identifica con la letra "C". OTP Es la solucin ideal a diseos en los que aun de duda de su estabilidad, adems de ser muy adecuado para producciones medianas ya que aunque son un poco mas caros que los dispositivos ROM estos se pueden programar en el momento que sea necesario. En la matricula se identifica con la letra "P". EPROM Dispositivos que no han sido pensados para producciones a gran escala ya que su costo es en realidad muy elevado en comparacin con dispositivos con otro tipo de memoria, han sido creados para etapas de diseo, para emular el funcionamiento de dispositivos ROM, estos cuentan con ventanas por las cuales el programa puede ser borrado va luz UV. En la matricula se identifica con la letra "E". FLASH Este tipo de memoria puede ser borrada y reprogramada miles de veces si es necesario con lo cual se puede poner a disposicin del usuario final actualizaciones de software y a pesar de que es mas cara este tipo de memorias, es mucho mas flexible En la matricula se identifica con la letra "F".

ESTRUCTURA DE UN PROGRAMA
En esta seccin te mostramos la estructura de un programa escrito en lenguaje ensamblador ya que todos los programas siguen esta misma estructura. Tambin te describiremos parte por parte los elementos que conforman a esta plantilla. Comenzaremos por la seccin de libreras y definicin, en esta seccin antes que nada nos servir para incluir la librera correspondiente al dispositivo con el cual trabajaremos la cual contiene las direcciones de los Registros de Funcin Especifica, los Registros para la configuracin de los puertos, la notacin para los registros de la CPU. Lo que sigue son las definiciones que haremos, la mas importante es la de inicioSP, adems de ello se recomienda poner en este lugar otras constantes numricas ya que desde esta parte las podemos identificar y modificar de manera muy sencilla y hacerle cambios de ultimo momento a nuestros programas con el mnimo esfuerzo.
#include "msp430g2231.h" #define inicioSP .mas definiciones tiles 0x240

Despus de esta parte sigue la palabra main requerida por el IDE para un correcto funcionamiento. A continuacin estn la direccin de inicio de la memoria de programa la cual inicia para nuestro caso en la direccin 0xF800, la palabra ORG la utilizamos para indicarle al compilador a partir de que direccin puede comenzar a grabar el cdigo que hay a continuacin.
ORG 0xF800 ;Inicio del programa

Despus viene la declaracin de la etiqueta RESET correspondiente al vector que se definir al final del programa para la condicin de RESET, despus de eso se inicia la pila a la mitad de la RAM, si deseamos la podemos cambiar de posicin, con solo modificar el valor de la definicin de inicioSP.
RESET MOV.W #inicioSP,SP

Despus de esto de apagara el perro guardin para evitar un reinicio del sistema por que se agoto la cuenta del Perro Guardin (Ver seccin Perro Guardian).
MOV.W #WDTPW+WDTHOLD,&WDTCTL

A continuacin podemos escribir nuestro cdigo, se recomienda que se hagan las inicializaciones de los puertos en esta zona. Despus de el programa se sita la definicin de las sub-rutinas y rutinas de servicio a la interrupcin, continuando por la definicin de las tablas y por ltimo de los vectores de interrupcin. Al final de todo esto se coloca la palabra END la cual al igual que main es necesaria para un funcionamiento optimo de IAR.
;-----------------------------------------------------------------------------; Zona de librerias y definicion de constantes ;-----------------------------------------------------------------------------#include "msp430g2231.h" #define inicioSP 0x240 main ; Necesario para el buen funcionamiento de IAR

;-----------------------------------------------------------------------------ORG 0xF800 ; Direccion de inicio del programa ;-----------------------------------------------------------------------------RESET MOV.W #inicioSP,SP ; Inicializacin del stackpointer MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Detener el Perro Guardian ;-----------------------------------------------------------------------------; Zona del programa principal ; Aadir aqui las instrucciones que tu programa requiera

;-----------------------------------------------------------------------------;-----------------------------------------------------------------------------; Zona de declaracion de sub-rutinas y ; rutinas de servicio a la interrupcion en ese orden ;-----------------------------------------------------------------------------;-----------------------------------------------------------------------------; Definicion de las tablas ;-----------------------------------------------------------------------------;-----------------------------------------------------------------------------; Vectores de Interrupcin y Reset ;-----------------------------------------------------------------------------ORG 0xFFFE ;Vector de RESET del MSP430 DW RESET . . . ; mas vectores para las interrupciones . . . END

LAS SUBRUTINAS
Las subrutinas son una de las herramientas mas tiles de el lenguaje ensamblador ya que nos permiten reducir el cdigo de un programa ya que estas las utilizaremos cuando una pequea seccin de cdigo se tenga que repetir muchas veces, ya que en lugar de escribir toda esa seccin de cdigo en el programa principal cada vez que se use, solo la escribimos una vez y despus de eso solo la mandamos a llamar con la instruccin CALL. Una analoga con el lenguaje de alto nivel C/C++ serian las funciones, ya que estas se llaman solo cuando se necesitan y adems solo se escriben una sola vez. Las funciones adems alteran el flujo normal del programa principal de igual manera lo hacen las subrutinas. El proceso que se lleva acabo cuando la CPU se encuentra con una subrutina es el siguiente:

Almacena el registro Contador de Programa (PC) en la pila. Carga en el registro Contador de Programa la direccin en donde inicia la subrutina. El cdigo de la subrutina se ejecuta. Se saca el valor del Contador de Programa (PC) de la pila y se restablece.

Ahora veremos como es que se implementan utilizando las instrucciones correspondientes en lenguaje ensamblador, adems tambin te haremos algunas recomendaciones para que no cometas los errores mas comunes. La declaracin de una subrutina se puede hacer en cualquier parte del programa pero te recomendamos ampliamente que la hagas justo antes de las rutinas de servicio a la interrupcin, a continuacin declararemos una subrutina que enciende y apaga un led 100 veces, esta subrutina tendr en nombre de "SUB1" y el led esta ubicado en P1.0.
;-----------------------------------------------------------------------------SUB1; Prende y apaga un led en P1.0 ;-----------------------------------------------------------------------------MOV #100,R15 ; Guarda en R15 el numero 100 ETQ1 BIS.B #BIT0,P1OUT ; Enciende el led en P1.0 BIC.B #BIT0,P1OUT ; Apaga el led en P1.0 DEC R15 ; Decrementa R15 JNZ ETQ1 ; Cuando R15 sea cero continua, de lo contrario ; salta a ETQ1 RET ; Termina la subrutina y se regresa el programa a donde ; fue llamada

SUB1 es una etiqueta necesaria para llamar e identificar a la subrutina, las dems instrucciones las puedes ver en la seccin de arquitectura, aunque en el cdigo anterior se da una pequea explicacin de su funcionamiento especifico para este ejemplo. Para llamar a esta subrutina lo nico que tenemos que hacer es lo siguiente:
CALL #SUB1

As en cualquier parte del programa podremos llamar a esta subrutina con la instruccin anterior sin necesidad de escribir de nuevo todo el cdigo de la subrutina. Otro punto interesante por mencionar es que una subrutina comienza con una etiqueta (en este caso SUB1) y termina con RET, si no lo hacemos as obtendremos errores o bien nuestro programa se comportara de manera impredecible y por tanto incorrecta.
ETIQUETA CODIGO DE LA SUBRUTINA . .. ... .... ..... RET

SUBRUTINAS DE RETARDO
Las subrutinas de retardo son una herramienta til para diferentes aplicaciones de tiempo donde no se requiera de gran precisin como encender un led durante cierto tiempo, generar secuencias de luces, rechazo de rebotes generados pos los pulsadores. Incluimos esta explicacin en la seccin de puertos digitales ya que para leer botones desde los puertos es necesario aplicar una subrutina de tiempo para evitar que el microcontrolador reaccione a los rebotes generados por la imperfeccin fsica de los pulsadores. Como veremos en algunas aplicaciones en las que se use solo los puertos de entrada y salida es necesario el uso de subrutinas para diversos fines, en la seccin de ejemplos en ASM podremos ver como es que una subrutina se implementa para diversos fines. El principio bsico de una subrutina de retardo es mantener ocupada a la CPU y que consuma tiempo ocioso de acuerdo a nuestra necesidad, claro que esto estar en una subrutina. A continuacin te mostramos una forma de realizar esto en ensamblador.
;-----------------------------------------------------------------------------RETARDO; Surrituna de retardo ;-----------------------------------------------------------------------------MOV #700,R14 ; Guarda en R14 el numero 700 ETIQ3 DEC R14 ; Decrementa R14 JNZ ETIQ3 ; Cuando R14 sea cero continua, de lo contrario ; salta a ETQ1 RET ; Termina la subrutina y se regresa el programa a donde ; fue llamada

Aqu como podemos ver declaramos una subrutina llamada RETARDO, lo primero que hace es cargar en el registro R15 el numero 700, despus decrementa este registro hasta que sea cero y despus regresa. Para calcular el tiempo total de la subrutina recurriremos al numero de ciclos que se tarda cada una en ejecutarse.
MOV DEC JNZ RET #700,R14 R14 ETIQ3 ; ; ; ; 2 2 2 2 ciclos ciclos ciclos ciclos en en en en ejecutarse ejecutarse ejecutarse ejecutarse

Crearemos una ecuacin para modelar el comportamiento del tiempo de la subrutina y averiguar cuanto tiempo se tarda en ejecutar.
Tiempo = [ 2 + 100 * ( 2+2 ) + 2 ] * periodo Tiempo = [ 4 + 100 * 4 ] * periodo

Donde periodo es el periodo de la frecuencia principal, como siempre trabajaremos a 1MHz entonces este siempre ser de 1ms (microsegundo). As el tiempo en ejecutarse es:
Tiempo = 404 * 1x10e-6=404us

Si queremos por ejemplo una subrutina de 1ms utilizaremos la formula siguiente:


Tiempo = [ 4 + constante * 4 ] * periodo Tiempo = [ 4 + constante * 4 ] * periodo Constante = [ (tiempo/4*periodo) - 1 ]

Sustituyendo:
Constante = [ (1ms/4*1us) - 1 ] = 249

As para lograr una subrutina que sea capaz de durar 1ms se utiliza el siguiente cdigo:
;-----------------------------------------------------------------------------RETARDO; Surrituna de retardo ;-----------------------------------------------------------------------------MOV #249,R14 ; Guarda en R14 el numero 700 ETIQ3 DEC R14 ; Decrementa R14 JNZ ETIQ3 ; Cuando R14 sea cero continua, de lo contrario ; salta a ETQ1 RET ; Termina la subrutina y se regresa el programa a donde ; fue llamada

Notemos que esta seccin de programa es diferente al anterior solo por la instruccin MOV ya que en lugar de poner 100 ponemos 249. El limite de esta subrutina es de 262.144ms ya que el valor mas grande que podemos almacenar en un registro es 65,535 y utilizando una de las formulas anteriores obtenemos este valor, para obtener valores mas grandes de tiempo utilizaremos la instruccin NOP la cual no realiza ninguna operacin mas que gastar dos ciclos de reloj. A continuacin mostraremos un programa para extender el tiempo que puede durar la subrutina.
;-----------------------------------------------------------------------------RETARDO; Surrituna de retardo ;-----------------------------------------------------------------------------MOV #cte,R14 ; 2 ciclos en ejecutarse ETIQ3 NOP ; 2 ciclos en ejecutarse ; .. mas NOP si son necesarios DEC R14 ; 2 ciclos en ejecutarse JNZ ETIQ3 ; 2 ciclos en ejecutarse RET ; 2 ciclos en ejecutarse

As la formula con la cual obtendremos el tiempo mximo as como un tiempo especifico es la siguiente:
Tiempo = [ 4 + ( 4+2*n ) * constante ] * periodo Donde: Tiempo= el tiempo que durara la subrutina. Periodo= periodo del reloj principal, para nuestro caso siempre ser 1us. Cte= valor a poner al inicio de la subrutina esta entre 0 y 65,535. N= numero de NOP en la subrutina.

INTERRUPCIONES
Las interrupciones son el elemento de hardware mas importante para las aplicaciones de bajo consumo de energa ya que mediante ellas es posible activar a la CPU cuando sea necesario. Es cierto que no por usarlas ya tendremos una aplicacin de ultra bajo consumo ya que esto implica la combinacin de diversos aspectos que esta arquitectura permite, pero nos sern de muchsima utilidad para hacer el manejo de programas mas sencillo. El concepto de interrupcin viene precisamente de la accin que realiza ya que interrumpe a la CPU en el momento que sea para realizar una subrutina. Esta es principalmente la diferencia entre una interrupcin y una subrutina, la subrutina es llamada en un momento especifico que el programador define, en cambio una interrupcin puede ocurrir en cualquier momento. Hay que aclarar que las interrupciones deben de ser generadas por algn perifrico ya que si estas no ocurren, la "subrutina" dedicada a la interrupcin nunca se ejecutara, todos los perifricos de los MSP430 pueden generar interrupciones hacia la CPU lo cual es una tremenda ventaja para las aplicaciones de bajo consumo. Es en cierta manera correcto llamar subrutina a la porcin de cdigo que se ejecuta cuando es generada una interrupcin pero para explicaciones posteriores sern llamadas rutinas de servicio a la interrupcin (ISR por sus siglas en ingles). Existen dos tipos de interrupciones las cuales pueden ocurrir en cualquier tipo de microcontrolador y estas son las enmascarables y las no enmascarables. INTERRUPCIONES NO ENMASCARABLES Las interrupciones no enmascarables son generadas por perifricos de gran importancia como el controlador de la memoria FLASH, el Perro Guardin, el Sistema de Reloj, el Supervisor de Alimentacin ya que este tipo de interrupcin se generara sin importar el estado del bit GIE en el Registro de Estado, estas suelen tener las prioridades ms altas porque se generan en las ocasiones en las cuales el sistema puede dejar de funcionar si no se hace algo al respecto, o bien el sistema dejara de funcionar despus de ejecutar la ISR. Son muy pocas las fuentes de este tipo de interrupciones pero de gran importancia ya que su debida configuracin da robustez y confiabilidad al sistema desarrollado.

INTERRUPCIONES ENMASCARABLES Las interrupciones enmascarables son las que pueden ser ignoradas si el bit llamado GIE en el Registro de Estado es cero, adems cada perifrico tiene la posibilidad de permitir o no las interrupciones que pudiese generar. As para que una interrupcin no enmascarable sea atendida deben de cumplirse tres condiciones:

Que la interrupcin sea generada poniendo a 1 su respectiva bandera de interrupcin Que la interrupcin sea habilitada de manera local (Esto depende de cada perifrico) Que la interrupcin sea habilitada de manera global, es decir que GIE en el Registro de Estado sea 1 lo cual se logra con la siguiente instruccin:
MOV #GIE,SR

O bien:
EINT

Tambin hay que aclarar que las interrupciones NO SE GENERAN CON NIVELES ESTTICOS si en el cambio de niveles, es decir cuando se producen flancos ascendentes o descendentes. A continuacin una imagen la cual muestra grficamente estas dos condiciones y el momento en el que la interrupcin es generada.

El proceso que se lleva acabo cuando la CPU es interrumpida por cualquier perifrico es el siguiente:

Se termina cualquier instruccin que se este ejecutando. Contador de Programa (PC) es colocado en la pila. Se carga el contenido del Registro de Estado (SR) en la pila. Si ocurrieron mltiples interrupciones se selecciona la de mayor prioridad. La bandera de interrupcin es borrada automticamente si solo hay una bandera de interrupcin, de lo contrario debe ser borrada por software. Se borra el Registro de Estado (SR) con lo cual se termina con cualquier modo de ahorro de energa presente. El contenido del vector de interrupciones es cargado en el Contador de Programa, as la CPU ejecuta la rutina de servicio a la interrupcin.

El proceso que ocurre al terminar la rutina de servicio a la interrupcin es el siguiente:

El Registro de Estado es restablecido en su lugar surtiendo efecto en ese mismo instante. El Contador de Programa es sacado de la pila y restablecido regresando al mismo punto donde estaba antes de la interrupcin.

BANDERAS DE INTERRUPCION
Una bandera es un bit el cual indica que algo ha ocurrido o no, como las banderas del registro de estado, una de ellas es la bandera de Cero la cual es igual a 1 si el bit mas significativo de un registro (ya sea 8 o 16 bits) es 1 despus de una instruccin. Las banderas de interrupcin son bits los cuales indican si se produjo o no una interrupcin, estas banderas pueden estar situadas en registros de control de perifricos o bien pueden estar en registros los cuales contienen otras banderas de interrupcin. Adems de indicar si existe una interrupcin pendiente son tiles para saber de donde proviene la interrupcin en el caso de que varias banderas estn situadas en un solo registro, tambin para crear una lista de espera que ejecute las de mayor prioridad en caso de que muchas interrupciones sucedan a la vez. Otro punto importante acerca de las banderas de interrupcin es que ocurre con ellas al terminar la ISR y esto depende de si son las nicas que puede generar un perifrico o no. Si un perifrico puede generar solo una interrupcin entonces la bandera se borrara automticamente al terminar la ISR. Si un perifrico puede generar mltiples interrupciones entonces la bandera de interrupcin deber ser borrada por software. La importancia de mencionar esto radica en que si la bandera o banderas de interrupcin no son borradas entonces la CPU jams podr salir de la ISR. Esto de no borrar por software las banderas de interrupcin antes de salir de una ISR es un problema muy comn el cual solo puede ser solucionado revisando la sintaxis del programa o bien depurando el programa a travs de una simulacin o emulacin paso a paso cosa que te explicamos en la seccin de tutoriales.

VECTOR DE INTERUPCIONES
Un vector de interrupciones es una tabla la cual se localiza al final de la memoria de programa, la cual cumple un objetivo en especifico el cual es almacenar direcciones de inicio de las rutinas de servicio a la interrupcin. Cuando sucede una interrupcin como ya vimos antes la CPU recurre a este vector para saber donde se hallan las instrucciones que ejecutara como respuesta a que la interrupcin fue generada. Cada perifrico tiene su propio lugar en el vector de interrupciones, esto para evitar confusin de rutinas de servicio a la interrupcin. El vector mas importante es el de RESET ya que sin este el programa no funcionara, ya que la CPU no sabe que hacer en caso de RESET (Cuando se enciende por primera vez

el microcontrolador se genera una interrupcin de RESET), es decir no sabe donde se haya la primera instruccin del programa principal. Para definir un vector de interrupciones no es necesario que inicialicemos vectores de perifricos que no vamos a utilizar, si no solo definiremos los vectores correspondientes a cada perifrico que utilizaremos con interrupciones. Los vectores comienzan en la direccin 0xFFE0 de la memoria, y en todo datasheet de cada dispositivo de esta familia podemos hallar los vectores de interrupcin y su correspondiente posicin en la tabla, he notado que estn estandarizados, es decir que son los mismos en todo dispositivo los MSP430. A continuacin tenemos una tabla con los vectores con los que cuenta nuestro MSP430G2231 con su respectiva direccin, prioridad y perifrico al que pertenece.

Para saber como utilizar los vectores utilizaremos como ejemplo el vector del primer programa para entender la definicin del vector mas importante, el de RESET y conociendo esto podremos definir cualquier otro vector.
;-----------------------------------------------------------------------------; Vectores de interrupcion y reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET END main

A continuacin veremos como es que se define el vector RESET con ayuda de la tabla que se encuentra en el datasheet y conociendo el uso de las interrupciones en los puertos podremos configurar el vector del puerto 1 y 2.
ORG 0FFFEh ; Vector de reset

Esta instruccin define donde se comenzara a grabar en la memoria, la direccin que tiene en seguida como podemos ver en la tabla se encuentra con la prioridad mas alta y corresponde al RESET y es generada al encender el sistema, a un reset externo mediante un pulsador por ejemplo, al perro guardin, a la violacin del acceso en la flash o a que el Contador de Programa salga de rango.
DW RESET

Esta instruccin significa definir palabra, y lo que hace es escribir en la memoria un numero de 16 bits, en este caso es una etiqueta llamada RESET, pero hay que recordar que las etiquetas contienen direcciones, en este casi de 16 bits y solo son usadas para hacer mas fcil la programacin. Por tanto la etiqueta RESET debe de estar junto a la primera instruccin del programa que siempre ser:
MOV #midram,SP

En conjunto las dos instrucciones escriben en la direccin especificada por ORG la direccin contenida por la etiqueta despus de DW. Lo importante en saber cmo es que trabajan las interrupciones radica principalmente en que una interrupcin anula cualquier modo de ahorro de energa haciendo que se ejecute la ISR con la CPU a la mxima frecuencia, al terminar la ISR se restaura el modo de ahorro de energa anterior o incluso uno diferente, esto nos ayuda a ahorrar energa ya que podemos hacer uso de la CPU cuando sea necesario. As podremos sacarle mayor provecho a cada perifrico que pueda trabajar mediante interrupciones para hacer as amigables con el medio ambiente. JA!!

TABLAS Y APUNTADORES
Otro recurso de software muy importante es el de los apuntadores ya que a travs de ellos podemos acceder a gran cantidad de informacin a partir de solo una direccin, haciendo la analoga con C/C++ podemos implementar arreglos de informacin. Las tablas nos permiten almacenar informacin en la FLASH junto con el programa principal en el momento de la grabacin, esta informacin puede ser til o no dependiendo la manera en que la implementemos, pueden ser algoritmos, secuencias para motores paso a paso, valores de una funcin continua, valores de una funcin discreta, aproximaciones para el clculo de funciones matemticas, posiciones de objetos etc. Todo depende de nuestro hardware conectado y adems de nuestro programa.

En esta seccin te ensearemos como declarar un apuntador y asociarlo a una tabla ya que a menudo utilizaremos estos conceptos en programas de ejemplo. Adems de que ser de gran ayuda conocer estas herramientas. DEFINIENDO UNA TABLA Para esto tenemos dos opciones, una de ellas es guardar datos de 8 bits o bien de 16 bits, tu decidirs cual es la que se ajusta ms a tus opciones. Para ello seguiremos la siguiente sintaxis primero para 8 bits:
ETIQ FINT DC8 DC8 00000001b,00000010b,00000100b,00001000b 0

ETIQ es el nombre de la tabla y para cada tabla este debe de ser diferente, el segundo rengln llamado FINT indica que la tabla ha acabado, esto hace fcil el proceso de aadir ms elementos a la tabla adems de que es til al momento de programar para detectar el fin de la tabla. La palabra clave DC8 es la que se encarga de indicarle al compilador que los datos que estn a continuacin debern guardarse en la FLASH tal como estn. Tambin podemos ver que cada elemento de la tabla es separado por una coma. En este ejemplo los datos se ingresan de manera binaria, pero tambin se pueden hacer de forma hexadecimal (valor mximo 0xFF), decimal (valor mximo 255) e incluso con caracteres los cuales sern codificados en la FLASH en cdigo ASCII. As se pueden definir tablas de la siguiente manera:
ETIQ FINT ETIQ1 FINT1 ETIQ2 FINT2 DC8 DC8 DC8 DC8 DC8 DC8 10,20,30,40,50,60,70,80,90,100 0 0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x100 0 'HOLA MUNDO CRUEL!!' 0

La palabra reservada DC8 solo aplica a un rengln, si se nos acaba el espacio disponible en el editor de IAR entonces debemos de poner otro DC8 y continuar con la definicin de la tabla. As si queremos agregar mas elementos a la tabla llamada ETIQ haremos lo siguiente:
ETQT FINT DC8 DC8 DC8 00000001b,00000010b,00000100b,00001000b 00010000b,00100000b,01000000b,10000000b 0

Para definir tablas con datos de 16 bits lo nico que debemos hacer es cambiar DC8 por DC16 y entonces comenzar a definir los datos de forma binaria(no muy recomendada por la longitud de los datos al momento de la edicin), decimal (valor mximo 65,535), hexadecimal (valor mximo 0xFFFF) o con caracteres de la misma forma que lo hicimos con la tabla con datos de 8 bits. DECLARANDO UN APUNTADOR

Para crear un apuntador primero requerimos una direccin a la cual apuntara, esa direccin puede ser la de la tabla llamada Sec0 declarada a continuacin:
Sec0 FIN0 DC8 DC8 DC8 'Copiando letra por letra a la RAM' 'Copia finalizada!!' 0

As para asignar un apuntador a esa tabla (arreglo de datos haciendo una analoga con C/C++) haremos la siguiente instruccin:
MOV #Sec0,R4

Recordemos que los registros de la CPU pueden ser utilizados para guardar tanto datos como direcciones, en el caso de guardar direcciones entonces serian considerados como apuntadores. Lo que estamos haciendo con esta instruccin es convertir a R4 en un registro apuntador ya que estamos copiando la direccin de la tabla llamada Sec0 en su interior. Ahora lo que haremos es mover el contenido de la tabla a la RAM solo como ejemplo. La RAM para el MSP430G2231 inicia en la posicin 0x200 as que comencemos definiendo la constante inicioRAM con un valor de 0x200 as:
#define inicioRAM 0x200

Ya que tenemos el registro el cual apunta a nuestra tabla necesitamos uno que nos indique a partir de que direccin iniciara la copia, este ser R5 el cual hay que inicializar.
CLR R5

Utilizaremos la siguiente instruccin para mover el contenido de la direccin apuntada (el primer elemento de la tabla) a la primera posicin de la RAM
MOV.B @R4+,inicioRAM(R5)

El apuntador R4 tiene la direccin del siguiente elemento de la tabla pero R5 tiene la misma direccin, por lo cual para hacer que apunte a la prxima posicin en la RAM debemos incrementar a R5 con la siguiente instruccin:
INC R5

Si esto lo combinamos con un ciclo el cual pare hasta que se llegue al fin de la tabla entonces tendremos lo que hemos estado buscando, donde R4 apunta al dato de la tabla y R5 apunta a la direccin donde ser copiado el dato. Este ciclo quedara definido as:
ETQ0 MOV.B INC CMP JNE @R4+,inicioRAM(R5) R5 #FIN0,R4 ETQ0

Podemos notar que despus del incremento comparamos la direccin de fin de la tabla con la direccin que contiene R4, si no son iguales significa que aun no se ha finalizado la copia de la tabla, cuando la direccin del fin de la tabla sea igual a la direccin contenida por R4 significara que se ha concluido la transferencia. Veras que esto de los apuntadores y las tablas nos ser de gran utilidad, adems con este programa podemos copiar cualquier posicin de la memoria a la RAM lo cual ser til cuando escribamos en la FLASH o bien para implementar un administrador de memoria en un sistema operativo o para que tu apliques tus propias variaciones para tus aplicaciones.

CORRIMIENTOS A LA IZQUIERDA
Los corrimientos son importantes para crear algoritmos tiles, entre sus aplicaciones mas destacadas estn las de multiplicacin, divisin, registros de corrimiento para comunicaciones seriales, secuencias de multiplexaje y otras ms que puedes descubrir a medida que desarrollas aplicaciones. En esta seccin haremos introduccin a el concepto de los corrimientos, as como tambin te ensearemos la flexibilidad de esta arquitectura para extender el tamao de sus operandos. Esta arquitectura tiene 4 tipos de corrimientos en sus set de instrucciones, ya sean emuladas o no, de estas cuatro dos son para realizar corrimientos a la izquierda y dos mas para realizar corrimientos a la derecha. Comenzaremos con los corrimientos a la izquierda, el set de instrucciones de los MSP430 cuenta como acabamos de mencionar con dos instrucciones con las cuales se pueden realizar corrimientos hacia la izquierda, estas son las siguientes:
RLA(.B) dst RLC(.B) dst

La primera es el corrimiento aritmtico el cual coloca un cero en la posicin cero del registro de destino, despus el bit que antes estaba en la posicin 0 pasa a la posicin 1, el bit que estaba en la posicin 1 pasa a la posicin 2 y as hasta que el bit en la posicin numero 15 pasa a la bandera de acarreo. La imagen siguiente ejemplifica el proceso de manera grafica.

Esto si se realiza la instruccin con 16 bits, es decir sin el modificador .B si elegimos realizar esta instruccin con solo 8 bits entonces ignoraremos los 8 bits mas altos as:

Se le conoce como corrimiento aritmtico debido a que esta instruccin realiza una multiplicacin aritmtica dst x 2. Para demostrar esto un ejemplo. Suponiendo que en el registro R15 de la CPU tenemos el siguiente valor binario: 0011011100101101, el cual tiene el valor decimal de 14125, al realizar la siguiente instruccin:
RLA R15

El valor en R15 es 0110111001011010 el cual tiene un valor binario de 28250 el cual como podemos notar es el numero contenido en R15 de manera inicial multiplicado por dos. Ademas de esto si realizamos esta instruccin ya sea 16 (sin el modificador .B) u 8 veces(con el modificador .B) entonces nuestro registro se encontrara vacio. La otra instruccin de corrimiento a la izquierda es RLC la diferencia principal entre esta instruccin y la vista anteriormente es que en lugar de aadir un cero en el bit 0 se aade el contenido del acarreo. A continuacin mostramos el proceso para ambas versiones de esta instruccin.

Para 8 bits.

Esta instruccin sirve como complemento a la primera ya que en la primera el mximo de bits con los cuales se puede realizar un corrimiento es 16, pero utilizando dos registros podemos hacer un corrimiento con un numero de 32 bits con solo combinar estas dos instrucciones de la siguiente manera:
RLA RLC R14 R15

Con lo que grficamente obtendramos lo siguiente:

Como podemos ver el acarreo que genera el bit 15 es rescatado por la segunda instruccin la cual en lugar de introducir un cero, introduce el valor del acarreo. De esta manera podemos incrementar la longitud del corrimiento hasta el valor que deseemos o que requiramos, por ultimo veremos que para un corrimiento de 64 bits lo nico que debemos hacer es aadir dos instrucciones RLC mas.
RLA RLC RLC RLC R12 R13 R14 R15

El resultado estar contenido entonces por 4 registros de 16 bits los cuales para este caso han sido R12,R13,R14 Y R15 como veremos en secciones posteriores esto puede ser til para realizar operaciones con ms de 16 bits e incluso para operaciones con nmeros menores a 16 bits.

CORRIMIENTOS A LA DERECHA
En principio este tipo de corrimientos son muy parecidos a los mostrados anteriormente, es decir en lugar de desplazar los bits a la izquierda los desplazan a la derecha. Las dos instrucciones correspondientes para realizar este tipo de corrimientos son RRA y RRC, la sintaxis es la misma que para los corrimientos hacia la izquierda, en realizad tienen funciones simtricas a excepcin de RRA la cual acta de la siguiente manera:

Como podemos ver el bit 15 permanece sin cambio, pero en la posicin 14 se copia el valor del bit 15, esto para conservar el signo, as en lugar de realizar una multiplicacin por 2 binaria realiza la divisin entre 2. Esto no es en realidad cierto si el bit mas significativo es 1, ya que este bit representa el signo de un numero por ejemplo en el caso de 1000100101101001 puede ser interpretado como 35177 en decimal o bien como -33129 por lo cual si aplicamos un corrimiento de este tipo obtendremos el siguiente numero: 1100010010110100 el cual puede ser interpretado como 50356 en decimal o bien como -17588 el cual es el primer numero dividido entre -2, para realizar una divisin entre 2 con 16 bits recomendamos la otra instruccin de corrimiento la cual presentaremos a continuacin o bien despus de ejecutar esta instruccin verificar si la bandera N fue colocada, si este es el caso aplicaremos la siguiente instruccin:
BIC #80h,dst

Donde dst es el registro o localidad de memoria donde fue ejecutada la instruccin RRA previamente, esta instruccin borra el bit mas significativo del registro o localidad de memoria de 16 bits. Esto tambin puede ser interpretado como quita el signo.

Para la versin a 8 bits de la instruccin a travs del modificador (.B) obtenemos el mismo resultado.

El set de instrucciones incluye de igual manera una instruccin de corrimiento a la derecha con acarreo, esta nos es til para realizar divisiones entre dos sin necesidad de verificar si el resultado es positivo o negativo. A continuacin una imagen.

Para 8 bits.

Como podemos ver esta instruccin es igual a RLC solo que los bits cambian de posicin en sentido contrario, es decir hacia le derecha en lugar de a la izquierda, tambin se pueden combinar las dos instrucciones para poder realizar corrimientos a la derecha de 16, 36, 64 bits y hasta mas, dependiendo de nuestras necesidades.

SUMA Y RESTA A 32 BITS


En esta seccin solo te demostramos como realizar sumas y restas con operandos de mas de 16 bits de longitud si es que algn da lo requieres, adems es til para demostrar la flexibilidad que nos brinda el set de instrucciones. Utilizaremos 6 identificadores para esta seccin los cuales al final asignaremos a registros de la CPU mediante las directivas define. Dos identificadores sern para almacenar el primer operando de 32 bits, estos son OP1L y OP2H. Otros dos sern para almacenar el segundo operando de 32 bits y estos son OP2L y OP2H, adems de almacenar el segundo operando estos identificadores almacenaran el resultado una ves que se ejecute la suma. Comenzaremos entonces por realizar sumas de 32 bits con el uso de solo dos instrucciones:
ADD ADDC OP1L,OP2L OP1H,OP2H

La primera instruccin suma la parte baja de ambos operandos y guarda el resultado en OP2L, si se genera un acarreo en esta suma entonces a travs de la siguiente instruccin consideraremos este acarreo para obtener un resultado correcto ya que ADDC suma los

dos operandos junto con el acarreo y el resultado es almacenado en OP2H, as el resultado de la suma se encontrara en OP2L y OP2H. Para realizar una resta de 32 bits utilizaremos los mismos identificadores de manera que las instrucciones que realizan una resta de 32 bits son las siguientes:
SUB SUBC OP1L,OP2L OP1H,OP2H

Como podemos notar solo sustituimos la instruccin ADD por SUB y la instruccin ADDC por SUBC, el resultado es almacenado en OP2L y OP2H.

SUMA Y RESTA A 64 BITS


Para guardar un nmeros de 64 bits requerimos 4 registros de 16 bits por lo que para realizar tanto sumas como restas con nmeros de 64 bits requerimos 8 registros en total. Para ello utilizaremos identificadores como en la seccin anterior, para almacenar el operando 1 utilizaremos OP1_0, OP1_1, OP1_2 y OP1_3, para el operando 2 y resultado utilizaremos los siguientes OP2_0, OP2_1, OP2_2 u OP2_3. Ya definidos los identificadores veremos que realizar una suma o resta de 64 bits es mas sencillo de lo que parece. A continuacin el cdigo necesario para ejecutar la suma:
ADD ADDC ADDC ADDC OP1_0,OP2_0 OP1_1,OP2_1 OP1_2,OP2_2 OP1_3,OP2_3

As si entre cada 16 bits se genera un acarreo este ser considerado por la instruccin ADDC ya que esta suma ambos operandos junto con el acarreo para depositar el resultado en el Segundo operando. La resta como en el caso de 32 bits se hace solo sustituyendo instrucciones ADD por SUB e instrucciones ADDC por SUBC para obtener lo siguiente:
SUB SUBC SUBC SUBC OP1_0,OP2_0 OP1_1,OP2_1 OP1_2,OP2_2 OP1_3,OP2_3

Como podemos ver es fcil implementar sumas, restas y corrimientos con valores mayores a los 16 bits esto gracias al set de instrucciones que proporciona soluciones fciles a problemas fciles.

PROGRAMA DE APLICACIN
Realizaremos un programa el cual realice sumas y restas tanto con 32 como 64 bits para demostrar el uso de estas subrutinas, adems como extra de la seccin mostraremos un

video donde te enseamos a verificar tus algoritmos mediante el uso de IAR Embedded Workbench a travs de la herramienta de simulacin que este IDE contiene. A continuacin te mostramos el cdigo que hemos desarrollado para esta seccin.
01|#include "msp430f2013.h" 02| 03|#define inicioSP 027Fh // Locacion en la RAM para la pila 04|// Operando 1: 05|// |Parte3||Parte2||Parte1||Parte0| 06|#define OP1_0 R8 // Operando 1 parte 0 07|#define OP1_1 R9 // Operando 1 parte 1 08|#define OP1_2 R10 // Operando 1 parte 2 09|#define OP1_3 R11 // Operando 1 parte 3 10|// Operando 2: 11|// |Parte3||Parte2||Parte1||Parte0| 12|#define OP2_0 R12 // Operando 2 parte 0 13|#define OP2_1 R13 // Operando 2 parte 1 14|#define OP2_2 R14 // Operando 2 parte 2 15|#define OP2_3 R15 // Operando 2 parte 3 16| 17|main 18| 19|;-----------------------------------------------------------------------------20| ORG 0xF800 ; Direccion de inicio del programa 21|;-----------------------------------------------------------------------------22|RESET MOV #inicioSP,SP ; Inicio de la pila 23| MOV #WDTPW+WDTHOLD,WDTCTL ; Apaga el perro guardian 24| 25|;**************************** Operaciones con 32 bits*************************** 26| 27| MOV #0xAF70,OP1_0 ; El numero 0x11FAAF70 (301641584 decimal) 28| MOV #0x11FA,OP1_1 ; es colocado en OP1_0 y OP1_1 29| MOV #0x00FA,OP2_0 ; El numero 0x1A0F00FA (437190906 decimal) 30| MOV #0x1A0F,OP2_1 ; es colocado en OP2_0 y OP2_1 31| CALL #SUMA32 ; Se realiza la suma de estos dos numeros, el 32| ; resultado 0x2C09B06A (738832490) se almacena 33| ; en OP2_0 y OP2_1 34| 35| MOV #0xAF70,OP1_0 ; Se carga en OP1_0 y OP1_1 el mismo valor para 36| MOV #0x11FA,OP1_1 ; obtener los valores iniciales 37| CALL #RESTA32 ; Se realiza la resta como resultado obtenemos 38| ; 0x1A0F00FA (437190906 decimal) 39| 40|;**************************** Operaciones con 64 bits*************************** 41| 42| MOV #0xAF70,OP1_0 ; Cargamos en el operando 1 0x4000B00111FAAF70

43| MOV #0x11FA,OP1_1 ; (4611879537070485360 en decimal) en los cuatro 44| MOV #0xB001,OP1_2 ; registros correspondientes 45| MOV #0x4000,OP1_3 46| 47| MOV #0x00FA,OP2_0 ; Cargamos en el operando 2 0x500O21321A0F00FA 48| MOV #0x1A0F,OP2_1 ; (360324469258911994 en decimal) en los cuatro 49| MOV #0x2132,OP2_2 ; registros correspondiente 50| MOV #0x5000,OP2_3 51| CALL #SUMA64 ; Al sumar obtenemos 0x4500D1332C09B06A 52| ; (4972204006329397354 en decimal) 53| 54| MOV #0x00FA,OP2_0 ; Cargamos el operando 1 con los valores que 55| MOV #0x1A0F,OP2_1 ; tenia desde el principio para que al realizar 56| MOV #0x2132,OP2_2 ; la suma obtengamos en el operando 2 lo que 57| MOV #0x500,OP2_3 ; teniamos antes de realizar la suma 58| CALL #RESTA64 ; es decir: 0x500O21321A0F00FA 59| ; (4611879537070485360 en decimal) 60| 61| 62| BIS #CPUOFF,SR 63| NOP 64|;-----------------------------------------------------------------------------65|; Suma Con Operandos De 32 bits 66|;-----------------------------------------------------------------------------67|SUMA32 ADD OP1_0,OP2_0 68| ADDC OP1_1,OP2_1 69| RET 70| 71|;-----------------------------------------------------------------------------72|; Resta Con Operandos De 32 bits 73|;-----------------------------------------------------------------------------74|RESTA32 SUB OP1_0,OP2_0 75| SUBC OP1_1,OP2_1 76| RET 77| 78|;-----------------------------------------------------------------------------79|; Suma Con Operandos De 64 bits 80|;-----------------------------------------------------------------------------81|SUMA64 ADD OP1_0,OP2_0 82| ADDC OP1_1,OP2_1 83| ADDC OP1_2,OP2_2 84| ADDC OP1_3,OP2_3 85| RET 86| 87|;-----------------------------------------------------------------------------88|; Resta Con Operandos De 64 bits 89|;------------------------------------------------------------------------------

90|RESTA64 SUB OP1_0,OP2_0 91| SUBC OP1_1,OP2_1 92| SUBC OP1_2,OP2_2 93| SUBC OP1_3,OP2_3 94| RET 95| 96|;-----------------------------------------------------------------------------97|; Vectores de Interrupcin y Reset 98|;-----------------------------------------------------------------------------99| ORG 0xFFFE ; Vector para el RESET 100| DW RESET ; Etiqueta correspondiente 101| 102| END

Primero debemos acordar algunas definiciones para hacer mas clara la programacin y la legibilidad, es decir definir que registros de la CPU formaran parte del operando 1 y que registros forman parte del operando 2 para operaciones a 32 y 64 bits. Para ello en las lneas 6-9 vemos que asignamos de la siguiente manera los registros que forman parte del operando 1, OP1_0 a R8, OP1_1 a R9, OP1_2 a R10 y OP1_3 a R11 de igual forma para el operando 2 definimos OP2_0 a R12, OP2_1 a R13, OP2_2 a R14 y por ultimo OP2_3 aR15. Podemos ver tambin que las instrucciones vistas en secciones anteriores fueron convertidas en subrutinas con nombres muy representativos. En las lneas 67-69 se encuentra la subrutina que realiza una suma a 32 bits, en las lneas 74-76 se encuentra la resta a 32 bits, en las lneas 81-85 esta la suma a 64 bits y por ultimo en las lneas 90-94 se encuentra la resta a 64 bits. El programa principal el cual utilizara estas subrutinas est definido desde la lnea 22 hasta la 63, antes de mandar a llamar a cada subrutina cargamos valores tanto en el operando 1 como en el operando 2 a travs de instrucciones MOV. A continuacin te mostramos un video en el cual realizamos la simulacin mediante IAR para verificar que realmente el programa hace lo que debe. Como estas subrutinas son elementos puramente de software no podemos armar un circuito y comprobar que todo va bien, si no que debemos de simular a la CPU.

Obtener codigo fuente

MULTIPLICACION DE 16X16 BITS


Las practicas de la seccin de arquitectura te introduciremos al uso de algunos algoritmos tiles para la realizacin de otras aplicaciones o programas ms complejos, te presentamos los algoritmos a manera de apoyo para que refuerces tus conocimientos, as como para que puedas adaptarlos a tus aplicaciones si as lo ameritan.

En esta pgina en especifico realizaremos la multiplicacin de dos nmeros de 16 bits sin signo, esto a manera introductoria para los dems algoritmos de multiplicacin que continan. Antes de comenzar con el desarrollo de este programa hay que mencionar que una multiplicacin binaria se realiza de igual forma que una multiplicacin decimal. Para entender mejor el algoritmo realizaremos un ejemplo en el cual multiplicaremos de forma binaria los nmeros 1011010111010011 y 1101100. Primero hay que ordenar de cierta manera a los dos operandos, nosotros los hemos ordenado de esta manera ya que as el algoritmo es ms corto pero recordemos que en la multiplicaciones el orden de los factores no altera el producto. Despus de eso lo que haremos es recorrer el operando 1 que se encuentra en la parte inferior bit a bit.

Comenzando por el bit menos significativo del operando 1 remarcado en azul multiplicaremos este bit por el operando 2 y lo pondremos como resultado.

Ahora haremos lo mismo con el segundo bit, el cual para este caso es cero por lo cual obtendremos lo siguiente:

El procedimiento continua as hasta terminar con el bit mas significativo del operando 1

Ya que hayamos terminado de recorrer todos los bits del operando 1 entonces estaremos listos para realizar la suma que nos llevara a obtener el resultado correcto.

De esta manera es como se realiza la multiplicacin binaria, al analizar el algoritmo descrito podemos notar algunos aspectos los cuales nos sern tiles al momento de realizar el algoritmos correspondiente. Esos aspectos se mencionan a continuacin.

1.-En cada iteracin se realiza un corrimiento a la izquierda. 2.-El bit del operando 1 que ya fue utilizado jams en el proceso vuelve a ser utilizado.

Tomando esto en cuenta podemos realizar el algoritmo de la siguiente manera:

El primer bit es cero por lo cual haremos un corrimiento a la izquierda en el operando 2 y un corrimiento a la derecha en el operando 1

Como podemos notar en verde aadimos un cero como resultado del corrimiento a la izquierda en el operando 2, pero en el operando 1 eliminamos el cero que comprobamos, como ese bit era cero el resultado permanece en ceros. Ahora como el siguiente bit a comprobar tambin es cero haremos lo mismo, es decir un corrimiento a la izquierda al operando 2 y un corrimiento a la derecha en el operando 1.

Como podemos ver el resultado continua en ceros, esto debido a que los bits que hasta ahora hemos comprobado han sido cero, pero ahora vemos que es lo que ocurre cuando el bit a comprobar es un 1.

Primero sumamos el operando 2 a resultado.

Despus hacemos lo mismo que cuando encontramos un cero, es decir realizar un corrimiento a la izquierda en operando 2 y uno a la derecha en operando 1. Esta es una forma distinta de ver el proceso de la multiplicacin la cual nos ser ms til.

DESARROLLO DE LA SUBRUTINA
Primero definiremos los registros con los cuales trabajaremos para realizar la multiplicacin. Como registro donde guardaremos al primer operando esta R5 al cual definiremos de la siguiente manera para escribir OP1 a lo largo del programa y no R5
#define OP1 R5

Para el segundo operando requerimos dos registros ya que con los corrimientos, en un caso extremo puede llegar a tener el doble de la longitud. Por lo cual definiremos a R6 y R7 como OP2L (parte baja "low") y OP2H (parte alta "high")
#define #define OP2L OP2H R6 R7

El resultado en varios casos puede resultar ser mayor a 16 bits por lo cual tambin estar formado por dos registros, es decir R8 y R9 por lo que los definiremos como RESL y RESH respectivamente con las siguientes directivas del preprocesador.
#define #define RESL RESH R8 R9

Como resultado del anlisis hemos desarrollado un diagrama de flujo el cual explica de manera grafica el algoritmo el cual hay que seguir para obtener la multiplicacin. El diagrama lo mostramos a continuacin.

Ya realizadas las definiciones correspondientes comenzaremos a traducir nuestro algoritmo en instrucciones que la CPU pueda interpretar. Este algoritmo estar en una subrutina la cual podremos llamar con la instruccin CALL, al final crearemos un programa que implemente esta subrutina. Primero debemos borrar o inicializar los registros que utilizaremos, es decir RESL, RESH y OP2, los dems registros no son borrados ya que antes de llamar a la subrutina debemos de cargarlos con los operandos correspondientes.
MULT CLR CLR CLR RESL RESH OP2H

Como podemos notar adems de borrar los registros declaramos la etiqueta llamada MULT la cual nos servir cuando empleemos la instruccin CALL. Comprobaremos el valor del bit menos con la instruccin BIT la cual realiza una operacin and entre la fuente y el destino sin modificar los valores, esto para nicamente alterar las banderas. Esta instruccin la utilizaremos en conjunto con un salto condicional JZ el cual se efectuara si al bit menos significativo es 0, de lo contrario (que sea 1) no se ejecuta el salto y el programa continua ejecutando la siguiente instruccin. A continuacin mostramos las instrucciones que harn lo antes mencionado.

ET_02

BIT JZ

#1,OP1 ET_01

Auxilindonos del diagrama de flujo podemos ver que si el bit es uno entonces debemos aadir el operando 2 al resultado, de lo contrario solo ejecutaremos los corrimientos correspondientes, adems de que en cualquier caso los corrimientos se llevaran a cabo. As si el bit menos significativo es 1 la CPU no ejecuta el salto por lo tanto a continuacin de las instrucciones anteriores debemos colocar las instrucciones correspondientes para llevar a cabo la suma del operando 2 con el resultado as:
ET_02 BIT JZ ADD ADDC #1,OP1 ET_01 OP2L,RESL OP2H,RESH

Si el bit es cero entonces se ejecuta el salto y los corrimientos se llevan a cabo por lo cual completaremos la rutina de la siguiente manera:
MULT ET_02 CLR CLR CLR BIT JZ ADD ADDC RLA RLC RRC JNZ RET RESL RESH OP2H #1,OP1 ET_01 OP2L,RESL OP2H,RESH OP2L OP2H OP1 ET_02

ET_01

Esta es la forma final de la subrutina donde podemos ver las etiquetas para los saltos condicionales, adems los corrimientos tanto del operando 2 (dos instrucciones ya que es de 32 bits de largo) como del operando 1 (hacia la derecha). Por ultimo vemos que despus del corrimiento del operando 1 encontramos otro salto condicional el cual nos ayudara a saber cuando debe terminar la subrutina. Esta terminara cuando el operando 1 haya sido desplazado completamente hasta estar vacio, lo cual ocurrir en el caso extremo a las 16 iteraciones. Para nuestro ejemplo solo sern 7 veces.

EL PROGRAMA DE APLICACIN
Como podemos ver esta subrutina altera nuestros operandos despus de que la multiplicacin se llevo a cabo, por lo regular el operando dos es muy diferente al introducido inicialmente y el operando 1 termina siendo cero, as que tomando esto en cuenta crearemos un programa el cual a partir de un valor inicial y un incremento generara el cuadrado de cada valor en la serie colocndolo en la RAM, por ejemplo si ponemos como valor inicial a 1 y un incremento de 1 obtendremos 1, 4 ,9 , 16, 25, 36 y as en lo sucesivo.

Para comprender mejor el proceso que llevara a cabo nuestro programa te mostramos a continuacin su diagrama de flujo.

A continuacin mostramos el programa completo con la descripcin correspondiente.


01|#include "msp430f2013.h" 02| 03|#define inicioSP para la pila 04|#define inicioRAM RAM

027Fh 200h

// Locacion en la RAM // Lugar de inicio de la

05|#define finRAM 270h // Lugar donde termina la RAM 06| 07|#define TEST R4 // Registro para la posicion 08|#define OP1 R5 // Primer operando de 16 bits 09|#define OP2L R6 // Segundo operando de 16 bits 10|#define OP2H R7 // Parte alta del segundo operando 11|#define RESL R8 // Resultado parte baja 12|#define RESH R9 // Resultado parte alta 13| 14|#define valinicial 0FFh // Valor inicial para la serie 15|#define incremento 0Ah // Incremento entre cada valor 16| 17|main 18| 19|;-----------------------------------------------------------------------------20| ORG 0xF800 ; Direccion de inicio del programa 21|;-----------------------------------------------------------------------------22|RESET MOV #inicioSP,SP ; Inicio de la pila 23| MOV #WDTPW+WDTHOLD,WDTCTL ; Apaga el perro guardian 24| 25| CLR R15 ; Inicializa el indice a cero 26| MOV #valinicial,OP1 ; Primer operando 27|CUAD MOV OP1,OP2L ; Segundo operando = Primer operando 28| PUSH OP1 ; Guarda una copia del OP1 en la pila 29| CALL #MULT ; Llamada a la rutina de multiplicacion 30| POP OP1 ; Recupera la copia de OP1 31| ADD #incremento,OP1 ; Aade el incremento a OP1 32| 33| MOV RESL,inicioRAM(R15) ; Resultado parte baja a la RAM 34| INCD R15 ; Siquiente localidad de la RAM 35| MOV RESH,inicioRAM(R15) ; Resultado parte altaa la RAM 36| INCD R15 ; Siquiente localidad de la RAM 37| 38| CMP #finRAM-inicioRAM,R15 ; Se ha terminado de llenar la RAM? 39| JNZ CUAD 40| 41| BIS #CPUOFF,SR 42| NOP 43|;-----------------------------------------------------------------------------44|; Rutina que realiza la multiplicacion 45|;-----------------------------------------------------------------------------46|MULT CLR RESL ; Borrar el registro de resultado parte baja 47| CLR RESH ; Borrar el registro de resultado parte alta 48| CLR OP2H ; Borrar la parte alta del operando 49|ET_02 BIT #1,OP1 ; Es 1 o 0 el bit menos significativo? 50| JZ ET_01 ; Si es cero continua en ET_01

51| ADD OP2L,RESL ; Suma el operando 2 a resultado 52| ADDC OP2H,RESH ; tanto parte baja como parte alta 53|ET_01 RLA OP2L ; Realizar corrimiento para la siguiente 54| RLC OP2H ; iteracion 55| RRC OP1 ; Corrimiento a la derecha para el bit siguiente 56| JNZ ET_02 ; Termino? 57| RET 58| 59|;-----------------------------------------------------------------------------60|; Vectores de Interrupcin y Reset 61|;-----------------------------------------------------------------------------62| ORG 0xFFFE ; Vector para el RESET 63| DW RESET ; Etiqueta correspondiente 64| 65| END

Podemos ver que se han definido los valores inicioRAM y finRAM en las lneas 4 y5 los cuales indicaran a nuestro programa a partir de donde podrn iniciar a escribir la informacin y cuando debern detenerse. Despus en el mismo bloque de definiciones se encuentran los identificadores correspondientes para realizar la multiplicacin los cuales ya conocemos (lneas 7-12). Adicionalmente definimos las constantes que nos permitirn controlar la serie de nmeros a los cuales obtendremos su cuadrado, es decir un valor inicial y un incremento. Posteriormente se encuentran las partes indispensables de un programa las cuales ya conocemos y son la palabra main, la direccin de inicio de programa (ORG 0xF800 ), la etiqueta de RESET junto con las instrucciones para asignar a la pila en la RAM y apagar el perro guardin en las lneas 20-23. Ahora vemos que en la lnea 25 borramos el contenido de R15, esto porque lo utilizaremos como ndice para poder grabar los resultados en la RAM de manera correcta y ordenada. Como nuestra subrutina realiza la multiplicacin de dos nmeros, entonces requiere de dos parmetros, es decir OP1 y OP2L, pero como el programa que estamos desarrollando obtiene el cuadrado de una serie de nmeros entonces utilizaremos la subrutina de multiplicacin para este objetivo colocando tanto en OP1 como en OP2L el mismo nmero as que primero cargamos a OP1 con el valor inicial en la lnea 26 y despus copiamos OP1 en OP2L en las lneas 27 y 28. Como mencionamos anteriormente la subrutina que realiza la multiplicacin altera nuestros operandos (que en este caso son iguales) por lo cual debemos de respaldarlos, ya que son iguales basta con respaldar a OP1, una manera rpida de realizar esta accin es colocar a OP1 en la pila con la instruccin PUSH que vemos en la lnea 28, despus llamamos a la subrutina MULT lo cual altera a ambos operandos (OP1 se hace cero y OP2L termina con un valor impredecible) pero a travs de la operacin POP OP1 en la lnea 30 logramos recuperar el valor de OP1.

Como podemos ver utilizamos una instruccin POP por cada instruccin PUSH como recomendamos cuando se realiza cualquier manipulacin de la pila. Si posteriormente utilizamos este programa en otra aplicacin y en esta aplicacin utilizamos interrupciones debemos tener en cuenta que si nuestra ISR utiliza a la pila, entonces debemos seguir esta misma recomendacin, es decir por cada instruccin POP utilizar una instruccin PUSH, ya que de lo contrario puede ocurrir que el flujo del programa sea impredecible entrando este en descontrol. Ya que se recupero el valor de OP1 entonces le sumamos el incremento en la lnea 31, as se preparan las condiciones para la prxima iteracin. Por ltimo antes de repetir el mismo proceso para el siguiente valor, debemos de enviar los resultados a la RAM, esto porque es parte del objetivo del programa, lo cual hacemos con las lneas 33-36 donde utilizamos el registro ndice para indicar cuantas posiciones a partir del inicio de la RAM se guardara la informacin, utilizamos incrementos dobles en el registro ndice R15 ya que cada localidad de la RAM es de 8 bites por lo cual para apuntar a la prxima palabra (word) debemos de incrementar el ndice en 2. Cuando se realiza la multiplicacin de 8 bits veremos que solo se requiere incrementar el ndice en 1. Ya que se realizo la multiplicacin y adems se enviaron los resultados a la RAM solo queda verificar si es que ya se ha llegado al lmite de la RAM para entonces terminar las iteraciones, de lo contrario seguir con el siguiente valor lo cual hacemos en las lneas 38-39 en la cual restamos el valor del fin de la RAM con el de inicio y despus comparamos este valor con el registro ndice, es decir comparamos el nmero de localidades disponibles con el nmero de localidades que y hemos llenado. Si la comparacin resulta ser cero entonces significa que debemos de terminar, si no resulta ser cero entonces aun hay espacio disponible para poder seguir calculando los valores. Como podemos notar la RAM no termina en la direccin que asignamos, es decir 270h, ya que la RAM de nuestro MSP430F2231 termina en la posicin 027Fh, la razn principal de que no hayamos utilizado este valor para la constante finRAM es porque la pila esta localizada en la RAM, por lo cual declaramos el fin de la ram antes para que el programa no altere a la pila, como ya hemos mencionado el alterar a la pila puede traer consecuencias desastrosas para nuestras aplicaciones as que con esto damos cierto margen de error para que la pila pueda incrementarse hasta en 7 niveles mas.

Obtener codigo fuente

PUERTOS DIGITALES DE ENTRADA Y SALIDA


La parte ms importante de nuestro microcontrolador es la de los puertos de entrada y salida ya que a partir de ellos este se podr comunicar con el exterior con dispositivos que generen o acepten seales digitales, adems de importante es de lo ms bsico que se debe de saber utilizar en cualquier tipo de microcontrolador, en esta seccin describiremos el uso y configuracin de los puertos.

Al terminar esta seccin sers capaz configurar los puertos de entrada y salida, manejaremos el concepto de interrupcin y otros conceptos algo bsicos y muy tiles. Ahora comenzaremos a describir el funcionamiento de los puertos de entrada y salida.

FUNCIONAMIENTO Y NOTACION
Cada puerto de entrada y salida de todos los dispositivos de la familia MSP430 estn formados por grupos de 8 bits, donde cada bit representa fsicamente a un pin del encapsulado, algunos de los dispositivos de la familia MSP430 cuentan con hasta 8 puertos, es decir 64 pines de entrada y salida e incluso ms. En nuestro caso el modelo de la familia MSP430 que utilizaremos cuenta con dos puertos de entrada y salida, pero el segundo puerto solo tiene dos pines, es decir que en lugar de tener 16 pines, solo tenemos 10 pines disponibles para que sean usados como entradas y salidas digitales. La notacin utilizada para hacer referencia a cada pin es Pn.m; donde n es el numero de puerto y m es el bit especifico del puerto, as en la siguiente imagen se puede ver como estn distribuidos los 10 pines de entrada y salida para el MSP430G2231.

Encerrados en rojo podemos ver los pines del puerto 1 (P1.m) donde m va desde el 0 hasta el 7, en total 8 bines. De color verde podemos ver los nicos dos pines que pertenecen al puerto 2, cero podemos notar que la numeracin no comienza con P2.0 y P2.1 si no que en lugar de eso tenemos P2.7 y P2.8, esto es cuestin del fabricante. Las dems notaciones que aparecen en el PinOut de este microcontrolador son otras funciones que tiene cada pin, las cuales se seleccionan dependiendo de nuestras necesidades. Podemos usar un pin por ejemplo para que sea la entrada del temporizador, o para conectar un cristal de cuarzo o para introducir una seal analgica para que sea convertida o tambin podemos obtener una frecuencia del oscilador interno u obtener un voltaje de referencia para circuitos analgicos externos, pero todo esto depende no solo del pin, ya que no todos tienen estas funciones secundarias de las que hablamos, sino que tambin depende de configurar ese pin para que cumpla la funcin especfica que hayamos seleccionado.

La parte importante de los puertos de entrada y salida es la configuracin, ya que en algunos casos esta configuracin solo se hace una ves al inicio de cada programa y muy pocas veces se ve alterada. Para la configuracin bsica los puertos existen 5 registros para ello y en algunos casos son 6 y son:

PXSEL y PXSEL2 Se utiliza para la seleccin de funcin de cada pin, PXSEL2 no esta disponible en todos los dispositivos como en el caso del MSP430G2231 PXDIR Nos ser til para poder seleccionar como es que funcionaran los pines de cada puerto, es decir como entradas o como salidas PXIN En caso de que hayamos seleccionado un pin como entrada podremos leer su estado con este registro PXOUT Cuando se selecciono un pin como salida, es con este registro con el cual podemos escribir estados lgicos en el pin seleccionado PXREN Este nos sirve para elegir si habilitamos las resistencias PULL-UP o PULL-DOWN

Cabe mencionar que todos los registros aqu mencionados son de 8 bits, gracias a esto se puede relacionar la posicin de cada bit individual con un pin del encapsulado. Como ejemplo el bit 7 de cualquier registro de los mencionados antes representa a el pin denominado PX.7, donde X es el puerto al que corresponde dicho pin. Por lo tanto si tenemos dos puertos de entrada y salida, entonces tendremos dos de cada unos de estos registros, es decir uno por cada puerto: P1SEL, P2SEL, P1DIR, P2DIR, P1IN, P2IN, P1OUT, P2OUT, P1REN, P2REN. Y cada uno de esos registros tendr 8 bits correspondientes a cada uno de sus pines.

SELECCIN DE FUNCION
Como lo dice el titulo de esta seccin, estos registros nos sern tiles para seleccionar la funcin la cual tendr cada uno de los pines de cada uno de los puertos, ya que cada pin del encapsulado del microcontrolador tiene como mnimo 2 funciones. A continuacin te mostramos como esta estructurado este registro de 8 bits de manera grafica y la funcin de cada uno de sus bits la cual explicaremos mas adelante.

As modificando este registro lograremos establecer la funcin de cada pin, por ejemplo el pin denominado P1.0 tiene tres funciones, esto porque en el PinOut tiene escrito lo siguiente P1.0/TA0CLK/ACLK (Ovalo Rojo), la funcin por defecto es la que aparece al principio, en este caso P1.0 sea entrada/salida digital.

Para el caso de P2.7 se puede ver que tiene escrito lo siguiente: XOUT/P2.7 (Ovalo Azul). Esto quiere decir que la funcin por defecto es la de XOUT, sea que podemos conectar un oscilador externo entre P2.7 y P2.6 ya que P2.6 tiene escrito lo siguiente: XIN/P2.6/TA0.1 (Ovalo Verde). De aqu obtenemos como conclusin que la funcin principal es la que esta descrita al principio de cada rengln (Subrayadas en morado) , la notacin que sigue separada por diagonales son otras funciones que pueden ser configuradas a travs de las combinaciones entre PXSEL y PXDIR. Como esta seccin esta dedicada a el uso de los pines como entradas y salidas digitales simplemente haremos que todos los bits de este registro tanto para el puerto 1 y 2 sean 0 con las siguientes instrucciones:
CLR.B CLR.B &P1SEL &P2SEL

En realidad solo es necesaria la segunda instruccin ya que como podemos ver las funciones por defecto de los pines de puerto 1 son de entrada y salida digital. Observemos tambin que hemos utilizado el modificador ".B", esto es porque como ya hemos mencionado nuestros registros son de 8 bits, si hiciramos cualquiera de los dos casos siguientes obtendramos un error.
CLR.W CLR &P1SEL &P1SEL

Esto porque estamos tratando de borrar un registro de 16 bits cuando fsicamente nuestro registro solo tiene 8. Tambin hay que notar el "&" el cual como lo mencionamos en la seccin de MODOS DE DIRECCIONAMIENTO este modo (absoluto) siempre se usara cuando en cualquier instruccin se haga referencia a algn registro de cualquier perifrico. Este microcontrolador al tener un numero muy reducido de pines disponibles y de pocos perifricos no requiere de un registro PXSEL2, ya qu como mencionamos con

anterioridad, las funciones de cada pin se pueden seleccionar por completo con dos bits en 2 registros (PXDIR y PXSEL), pero en caso de que exista el registro PXSEL podremos encontrar en el datasheet de el dispositivo a emplear las tablas para la seleccin de funciones. Te invitamos a ver los ejemplos de puertos de entrada y salida tanto en C/C++ como en ASM (Ensamblador) para que puedas aplicar y entender mejor lo que aqu te explicamos.

LOS REGISTROS I/O


Para configurar como entrada haremos uso del mismo registro llamado PxDIR en el cual ahora pondremos en 0 los bits que deseemos utilizar como entradas.

As si por ejemplo en el puerto 2 queremos que los bits 6 y 7 sean entradas haremos lo siguiente:
BIS.B #BIT6+BIT7,&P1DIR

O bien:
BIS.B #11000000b,&P1DIR

Ahora para la lectura de los bits utilizaremos un registro llamado PxIN mostrado a continuacin:

Ya que un bit de un puerto ha sido seleccionado como entrada, a partir de este registro podemos leer el estado actual de la entrada lgica, dado a esto el registro es de solo lectura. Para leer el estado directo de la entrada lgica utilizaremos instrucciones de testeo o comparacin. Por ejemplo para leer el BIT6 utilizamos la siguiente instruccin:
BIT.B #BIT6,&P1IN

Para saber su estado podemos implementar el siguiente salto condicional:


BIT.B JZ ES-CERO . . . . ES-UNO . . . . #BIT6,&P1IN ES-UNO

En electrnica digital existen dos circuitos para la generacin de estados lgicos a travs de un botn, tanto normalmente abierto como normalmente cerrado, de acuerdo a su configuracin el botn puede generar 1 en estado de reposo y 0 al ser presionado o bien de manera contraria es decir 0 en estado de reposo y 1 al ser presionado, a continuacin se muestran las 2 combinaciones para cuando se utilizan interruptores normalmente abiertos.

Para nuestro caso en especifico esta sera la manera de conectar un interruptor a cualquier terminal configurada como entrada , en el caso PULL-DOWN cuando el botn no se presione se estara generando un cero, al oprimir el botn se generara un uno lgico. Para el caso PULL-UP si no se oprime el botn se esta generando un uno lgico, al presionar el botn se genera un cero.

Cuando tenemos un botn normalmente cerrado las condiciones se invierten, es decir para la configuracin PULL-DOWN al no presionar el botn se tiene un uno, al oprimirlo tenemos un cero. En la configuracin PULL-UP al no oprimir el botn tenemos un cero, al oprimirlo tenemos un uno lgico. El objetivo de todo esto es mostrarte como configurar estos circuitos de manera interna en los microcontroladores MSP430 ya que disponen de este hardware. Para configurar las resistencias PULL-UP/DOWN haremos uso de dos registros, uno de ellos es PxOUT y el otro es PxREN.

Para que el registro PxOUT obtenga su segunda funcin es importante que se seleccionen los bits correspondientes como entrada, as si por ejemplo el bit 6 del puerto 2 fue seleccionado como entrada, entonces si queremos implementar una resistencia PULL-UP con un interruptor normalmente cerrado para que al presionarlo genere un uno lgico, entonces en el registro P2OUT en la posicin llamada BIT6 colocaremos un 1 as:
BIS.B #BIT6,&P2OUT

De esta manera la resistencia esta seleccionada pero no habilitada, para ello haremos uso del registro PxREN mostrado a continuacin:

El cual se encarga de habilitar las resistencias PULL-UP/DOWN en bits seleccionados como entradas nicamente, as para continuar con el ejemplo si queremos habilitarla solo hay que poner un uno en la posicin llamada BIT6 as:
BIS.B #BIT6,&P2REN

As con las configuraciones adecuadas podemos tener los siguientes circuitos de manera simplificada, lo cual ayuda al reducir la circuitera necesaria para comenzar a realizar aplicaciones.

CONFIGURAR COMO SALIDA


Para poder enviar datos digitales al exterior utilizaremos dos registros de los antes mencionados para configurar ya sean solo bits o puertos enteros para trabajar como salida de datos digitales. Estos registros necesarios los presentamos a continuacin:

En este proceso de configuracin para enviar datos lo primero que debes de hacer es configurar la direccin de los datos, ya que los bits de un puerto pueden trabajar tanto entrada o salida, para decidir con cual de las dos formas funcionara utilizaremos el registro PxDIR, en la tabla vemos que si queremos que por ejemplo seleccionar todo el puerto uno utilizamos la siguiente instruccin:
MOV.B #11111111b,&P1DIR

Lo cual hace que todos los bits en el registro P1DIR sean 1, lo cual indica que todos los bits en el puerto 1 son seleccionados como salida que es precisamente lo que queremos. Con esto solo le hemos indicado a los puertos como es que se comportaran si como entrada o salida, pero aun no podemos ver un estado lgico reflejado en la salida. Para esto haremos uso del registro mostrado en la siguiente tabla:

Este registro tiene una doble funcin: seleccionar estados lgicos de salida y seleccin de resistencias PULL-UP/DOUWN( mas adelante veremos que significa esto), en esta seccin solo nos enfocaremos a la primera funcin. Con este registro modificaremos

directamente el estado de los pines relacionados a este registro los cuales hayan sido configurado como salida. Por ejemplo para poner en estado alto los 4 bits de mayor peso utilizaremos por ejemplo esta instruccin:
MOV.B #11110000b,&P1OUT

O bien:
BIS.B #11110000b,&P1OUT

En este caso como todos los pines en el puerto 1 se seleccionaron como salidas, entonces este registro P1OUT reflejara el estado actual de la salida digital.

INTERRUPCION EN LOS PUERTOS


Ya que las interrupciones nos son tiles para apagar la CPU del microcontrolador y encendarla solo cuando sea necesario, esto es como ya lo mencionamos de vital importancia para el diseo de aplicaciones de bajo consumo (ya que esta tan de moda), debido a esto los microcontroladores de la familia MSP430 tienen dos puertos completos para generar interrupciones a la CPU, es decir 16 fuentes de interrupcin, en nuestro caso ya que solo tenemos diez pines, 8 del puerto 1 y 2 para el puerto 2 solo tenemos 10 fuentes de interrupcin por parte de los puertos. Cada bit es configurable de manera independiente, si se desea que solo un pin del puerto 1 admita interrupciones se puede hacer o que todos los bits del puerto 1 y 2 admitan interrupciones tambin es posible. Para los puertos solo se puede configurar las interrupciones por obvias razones a pines que hayan sido configurados anteriormente como entradas, al igual que los registros como PxIN, PxOUT, PxREN, PxDIR y PxSEL, hay tres registros mas para la configuracin de las interrupciones en los puertos, estos sol los siguientes:

PxIFG En este registro se puede ver si se renero una interrupcin o no. PxIES Es til para seleccionar el flanco con el cual ser generada nuestra interrupcin. PxIE Con este registro seleccionaremos si permitimos localmente las interrupciones de cada bit por puerto.

Cabe mencionar que las interrupciones no se generan con niveles estticos si no mediante una transicin de niveles lgicos, es decir de 0 a 1 o de 1 a 0 sea si se generan flancos de subida o de bajada, de lo contrario la interrupcin no ocurrir.

CONFIGURAR LAS INTERRUPCIONES.


Para ello es necesario configurar previamente el bit correspondiente como entrada digital, cosa que ya sabemos hacer, tambin configurar las resistencias PULLUP/DOWN si es que colocaremos un pulsador. Despus de ello seleccionaremos el

flanco con el cual la interrupcin ser generada, esto se hace con el registro llamado PxIES mostrado a continuacin.

Cuando se genera un cambio de estado bajo (0) a estado alto (1) se dice que se genera un flanco de subida, cuando se genera un cambio de estado alto (1) a estado bajo (0) se genera un flanco de bajada. Dependiendo de cada aplicacin es el flanco que elegiremos, ya que por ejemplo si a la entrada digital conectamos un pulsador de acuerdo a su configuracin la interrupcin se generara cuando se oprima el botn o cuando lo soltemos.

Si a la entrada digital le conectamos un conductor por donde fluye informacin de forma serial, entonces es importante elegir el flanco de bajada ya que eso indica el inicio de la transmisin. Despus de haber seleccionado el flanco haremos algo muy importante antes de poder permitir que las interrupciones se generen, esto es borrar la bandera de interrupcin, pero antes tenemos que saber que significa esto. Una bandera de interrupcin es un bit contenido en un registro cualquiera el cual indica el estado de la interrupcin, es decir si ese bit contiene un 1 significa que hay una interrupcin pendiente, si ese bit tiene 0 entonces quiere decir que no hay interrupciones pendientes, debemos recordar que muchas interrupciones se pueden generar al mismo tiempo .

BANDERA DE INTERRUPCION PARA LOS PUERTOS.


A continuacin mostramos una imagen la cual podremos observar los 8 bits que la forman, as como los valores que puede tomar y la funcin que cumplir dependiendo del valor tomado.

Es importante mencionar que las banderas de los puertos al ser mltiples no son borradas automticamente si no que hay que borrarlas por software mediante este registro ya que de lo contrario el programa no seguir su curso normalmente, si no que se quedara en la rutina de servicio a la interrupcin. Antes de permitir cualquier interrupcin por primera vez es necesario borrar su bandera correspondiente ya que en ocasiones suelen estar colocadas a 1, esto por diversos factores. Si no borramos las banderas antes de permitir las interrupciones podemos llamar a la ISR en un momento no adecuado. Esto lo podemos hacer con la instruccin CLR.B as:
CLR.B &P1IFG

De esta manera hemos configurado el pin por donde entrara la bandera, adems de ello podemos seleccionar el flanco con el cual se generara, adems borrado su bandera de interrupcin, lo que sigue es permitir la interrupcin de manera local.

HABILITAR LA INTERRUPCION.
Para seleccionar que pines pueden o no generar interrupciones utilizaremos el registro llamado PxIE el cual se muestra a continuacin:

Se puede seleccionar de manera individual si es que un pin configurado como entrada puede o no interrumpir a la CPU, ahora ya podemos configurar las interrupciones en los puertos, cuando estn configuradas todas las interrupciones incluso las de otros perifricos entonces estaremos listos para permitirlas de manera global con:
EINT

SI lo que deseamos es solo permitir las interrupciones pero si adems de eso modificaremos otro bit del Registro de estado podemos utilizar la instruccin MOV como se muestra a continuacin:
BIS #GIE+LPM2,SR

Donde adems de permitir las interrupciones de manera global hacemos que el microcontrolador entre en el modo de bajo consumo 2.

DECLARANDO EL VECTOR PARA LOS PUERTOS


La configuracin es algo que debemos de hacer cuando deseamos trabajar con interrupciones, despus de configurarlas y permitirlas debemos definir su vector correspondiente as como su rutina de servicio a la interrupcin ISR, segn la siguiente tabla los vectores correspondientes para el puerto 1 y 2 son los siguientes:

Para P1 es 0FFE4h para P2 es 0FFFE6h, como ya hemos mencionado en la seccin de arquitectura, la tabla especifica de los vectores de interrupcin se encuentran en el datasheet del dispositivo a programar, aunque en muchos casos no son muy diferentes nunca esta de mas revisar el datasheet ya que adems de los vectores de interrupcin encontraremos ah mas informacin importante. Ahora definiremos estos vectores despus del vector de reset en la parte final de programa de la siguiente manera:
;-----------------------------------------------------------------------------; Vectores de Interrupcin y Reset ;-----------------------------------------------------------------------------ORG 0xFFFE DW RESET ORG DW ORG DW END 0xFFE4 ISR_P1 0xFFE6 ISR_P2

Lo nico que resta es definir las ISR las cuales comenzaran con las etiquetas definidas comoISR_P1 e ISR_P2, las cuales definirn que es lo que ocurre cuando se genere la

interrupcin, lo cual definirs de manera individual en tus programas, pero no olvides que deben de terminar con RETI para evitar un mal funcionamiento de tu programa. Te recomendamos que veas el ejemplo de aplicacin donde te guiaremos en la construccin de un programa para que puedas comprender por completo lo descrito en esta seccin y puedas ver cmo es que todo lo aqu mencionado se implementa.

APLICACIN DE EJEMPLO
Es momento de realizar una aplicacin para aplicar los conocimientos obtenidos, en este caso realizaremos un secuenciador sencillo para as tambin utilizar algunos conceptos de secciones pasadas como las tablas, apuntadores y rutinas de retardo. Lo que har nuestro programa es en todo el puerto uno tendr conectados leds, la activacin de estos leds depender de cual de los dos botones conectados en el puerto 2 se oprima, as lo primero que debemos hacer es configurar el puerto uno como salida.
MOV.B #11111111b,&P1DIR

Despus pondremos en estado bajo las salidas, ya que al ejecutar la instruccin anterior los estados de las salidas toman valores aleatorios cosa que debemos evitar en lo posible.
CLR.B &P1OUT

O bien:
MOV.B #00000000b,&P1OUT

Posteriormente configuraremos los bits del puerto 2, primero seleccionaremos su funcin de entrada y salida digital ya que como recordamos que vimos en la seccin de FUNCIONAMIENTO Y NOTACION la funcin principal del P2.6 y P2.7 es la de tener conectado un cristal, as si borramos el contenido en P2SEL tendremos a ambos pines como entrada y salida digital.
CLR.B &P2SEL

Ahora seleccionaremos los dos bits del puerto 2 como entradas modificando los bits 6 y 7 del registro PxDIR.
BIC.B #BIT6+BIT7,&P2DIR

En este ejemplo pondremos interruptores normalmente abiertos configurados de tal manera que al ser oprimidos generen un 1, si no se oprimen se leern como cero. Para ello requerimos una configuracin de resistencias PULL-DOWN. As que primero pondremos en el registro P2OUT que queremos resistencias PULL-DOWN poniendo los bits 6 y 7 a 0.
BIC.B #BIT6+BIT7,&P2OUT

Ya que tenemos seleccionadas las resistencias PULL-DOWN solo basta con habilitarlas, para esto haremos uso del registro P2REN poniendo los bits 6 y 7 a 1 para que queden habilitadas.
BIS.B #BIT6+BIT7,&P2REN

As tenemos listas las configuraciones listas para poder comenzar con nuestro programa principal, como se menciona en el inicio de la seccin de puertos, la configuracin de los puertos suele hacerse solo una vez en todo el programa a menos que nuestra aplicacin lo requiera. Despus de hacer las configuraciones de los puertos lo que haremos es que nuestro programa espere hasta que sea presionado cualquiera de los dos botones mediante el mtodo de encuesta el cual consiste en leer continuamente el valor de PxIN en espera de que sea presionado un botn. Esto lo logramos de la siguiente manera:
NoPres TST.B JZ &P2IN NoPres

As la instruccin TST nos indica si hay algn valor en P2IN si no lo hay entonces se sigue ejecutando esta instruccin hasta que haya un valor en P2IN, cuando hay un valor en P2IN entonces la CPU sale de este ciclo y continua con la siguiente instruccin. En este momento sabemos que un botn se oprimi, pero no sabemos cual, as que lo siguiente es averiguar cual de los dos fue oprimido. Para averiguar cual fue debemos primero copiar el contenido de PxIN en un registro de la CPU (R6) ya que este puede cambiar su estado a lo largo de este proceso. Ahora realizaremos una resta, ya que solo hay dos opciones, es decir que R6 tenga 10000000 o 01000000 le restaremos 10000000 si el resultado da cero quiere decir que se oprimi el BIT7, de lo contrario fue BIT6 el que se oprimi.
SUB.B JNZ #BIT7,R6 SEC1

Si BIT7 se presiono entonces el resultado de la resta ser cero por lo tanto no se realizara el salto y la CPU continuara ejecutando el cdigo despus de la instruccin JNZ. Si se oprimi el BIT6 entonces saltara a donde este la etiqueta SEC1. Con esto ya averiguamos cual de los dos botones ha sido oprimido, aunque hay una posibilidad que ignoramos la cual sucede cuando se oprimen ambos botones, en ese caso por la lgica de nuestra solucin no se ejecutara el salto. Ahora lo que resta es ejecutar las secuencias para cada caso, que es muy semejante, el proceso de mostrar las secuencias es a travs de un apuntador el cual antes de cambiar de direccin mueve el contenido de la direccin apuntada al puerto 1 y se espera un tiempo, hasta que el apuntador tenga la direccin de la etiqueta FIN0, despus de eso se realiza un salto incondicional al inicio de programa justo donde se espera a que un botn sea presionado.
SEC0 ETQ0 MOV MOV.B #Sec0,R4 @R4+,&P1OUT

CALL CMP JNE CLR.B JMP

#RETARDO #FIN0,R4 ETQ0 &P1OUT Inicio

Las tablas definidas casi al final del programa definen las dos secuencias que sern ejecutadas, as podemos seguir agregando valores como de la funcin SENO, o la COSENO para as realizar una conversin digital-analgico para sintetizar audio.

Aqu esta el diagrama de flujo de este programa, te invitamos a que veas mas ejemplos de como es que se utilizan los puertos, en realidad para un programa funcional no solo se utilizan una sola parte del microcontrolador si no que varias partes se combinan para lograr el objetivo deseado.

EL SISTEMA BASICO DE RELOJ


El principal motivo por el cual existe este perifrico es por la flexibilidad requerida por la arquitectura, adems de que los perifricos exigen este para su implementacin con una mayor eficiencia. En otro tipo de microcontroladores solo es necesario una fuente de reloj, es decir un oscilador de uno o varios tipos (RC, de cuarzo, etc.) conectado a dos de sus terminales. En nuestro caso tenemos tres fuentes de reloj las cuales proveern tanto a la CPU como a los perifricos, de seales de reloj completamente independientes y configurables por software. Estas tres fuentes de reloj son completamente internas y gracias a esto podemos ahorrar tanto en componentes como en espacio, ya que podemos comenzar a realizar aplicaciones con un numero mnimo de elementos externos. El sistema bsico de reloj es el que se encarga de la generacin y distribucin de seales de reloj tanto para los dispositivos como para los perifricos. Es muy importante conocer el funcionamiento de este perifrico ya que solo as podremos implementar las soluciones de bajo consumo de energa as como obtener la mayor precisin en nuestras aplicaciones.

LAS FUENTES DE RELOJ


Todo dispositivo requiere de una seal peridica para funcionar, ya que de lo contrario este no podra generar mas que estados finitos e invariantes en el tiempo, estos microcontroladores no son la excepcin. Existen tres fuentes de reloj las cuales alimentaran a las seales que este modulo puede entregar. Estas fuentes son VLOCLK, LFXT1CLK, DCOCLK. VLO.- Oscilador de bajo consumo y frecuencia. Cada dispositivo cuenta con un oscilador interno con un frecuencia de 12KHz el cual es de bajo consumo, cuando este se selecciona entonces LFXT1 es apagado para evitar consumos inesesarios de energa. LFXT1.-Oscilador de alta o baja frecuencia. Soporta un oscilador de baja frecuencia de 32,768Hz conectado en las terminales llamadas XIN y XOUT sin componentes externos ya que internamente tiene capacitores de 1, 6, 10 y 12.5 pF. Para ello se debe de seleccionar su modo de baja frecuencia. Adems pueden conectarse cristales de mayor frecuencia o resonadores mediante las mismas terminales en el modo de alta frecuencia, en este caso se deben de adicionar capacitores externos segn las especificaciones del cristal. De forma adicional se pueden introducir seales externas de reloj solo en el pin XIN en cualquier modo, para ello debemos de asegurarnos que la frecuencia de la seal externa

este dentro de los parmetros enunciados en el datasheet del dispositivo ya que de ser mayor el sistema de reloj la bloqueara para evitar que esta llegue a la CPU. Este oscilador de puede inhabilitar desde uno de los bits del registro de estado llamado OSCOFF si este no se usa para MCLK o SMCLK, es decir que solo si se usa para ACLK este no se podr apagar por software. DCO.- Oscilador Controlado Digitalmente Este oscilador puede generar frecuencias de hasta 16MHz las cuales son ajustadas por los bits llamados DCOx, MODx y RSELx en los registros de control de este modulo. La caracterstica mas importante de este oscilador es su rpida estabilizacin al encenderse, esto lo hace ideal para aplicaciones de bajo consumo de energa. Ya que es un oscilador controlado digitalmente, habr unos registros los cuales nos servirn para controlar la frecuencia de este oscilador. Estos son los DCOCLK y BCSCTL1 cuando usamos el MSP430G2231 solo se puede llegar a 1MHz pero para otros dispositivos existe una tabla en el datasheet la cual proporciona los valores que deben de tomar estos bits para lograr obtener ciertas frecuencias. En algunos dispositivos tienen constantes de calibracin en el rea de memoria de intormacion en el segmento A, estas constantes tienen los valores necesaros para lograr frecuencias especificas como 1MHz, 2MHz, 4MHz y para el caso de por ejemplo el MSP430F2013 se puede llegar a los 16MHz. Podemos apagar este oscilador mediante el bit en el registro de estado llamado SCG0 si no es usado para MCLK o SMCLK, al igual que el oscilador anterior no se puede apagar si este es usado por ACLK.

LAS SEALES DE RELOJ


Existen tres seales que este modulo puede proporcionar a los perifricos que as lo requieran, estas son ACLK, MCLK, SMCLK, cada una de ellas tiene sus caractersticas especificas. ACLK es el reloj auxiliar, este puede ser alimentado por LFXT1CLK o VLOCLK y ser dividida por 1,2,4 y 8. Es usado para los perifricos segn sea seleccionado por software, como podemos notar este no se puede apagar mediante un modo de bajo consumo, por lo cual se usara para proveer a nuestros perifricos de una fuente de reloj cuando la CPU este apagada. MCLK es el reloj principal el cual puede ser seleccionado por software como LFXT1CLK, VLOCLK o DCOCLK. Esta seal puede ser dividida por 1,2,4 y 8 y es usada por la CPU. SMCLK es el reloj sub principal puede ser alimentado por LFXT1CLK o VLOCLK y ser dividido por 1,2,4 y 8. Es utilizado por los perifricos segn su configuracin por software.

A continuacin mostramos un diagrama a bloques de cmo est formado este modulo en donde en ovalo rojo estn las fuentes de reloj y en ovalo rojo estn las seales de reloj.

Este modulo lo configuraremos al principio de aplicaciones mas complejas donde apliquemos soluciones de bajo consumo esto para que una ves configuradas las seales de reloj puedan ser usadas por los perifricos que la requieran .

EL TIMER A
El timer a es un temporizador/contador el cual utilizaremos para nuestras aplicaciones con distintos fines ya que con el podemos medir y generar intervalos de tiempo, utilizarlo como contador de eventos, generar PWM a distintas frecuencias, muestrear seales etc.

Para ello requerimos de conocer este perifrico para poder configurarlo a convenca, para ello dividiremos esta seccin en 2, una de ellas es el uso de el timer a como temporizador, la otra es el uso del timer a en modo captura comparacin.

TIMER_A COMO TEMPORIZADOR


Si tenemos un contador de pulsos al cual le insertamos una seal cuadrada de cierto periodo conocido, entonces despus de cierto tiempo al consultar la cuenta podremos calcular el tiempo que ha transcurrido desde que iniciamos la cuenta. En si este es el principio bsico de este perifrico.

Podemos ver en el diagrama a bloques del Timer_A que hay un multiplexor de 4 entradas y una salida el cual es controlado por TASSELx despus de ello hay un divisor de frecuencias controlado por IDx el cual puede dividir la seal por 2, 4 y 8, despus esta seal ya seleccionada y dividida pasa a alimentar al contador/temporizador de 16 bits almacenando la cuenta en el registro llamado TAR, adems este contador/temporizador es controlado por los bits MCx los cuales se encargan de controlar el modo de cuenta del contador/temporizador. Tambin podemos ver que tanto al divisor de frecuencia como al contador/temporizador cuentan con un bit mas llamado TACLR el cual se encarga de resetear los valores tanto del TAR como del IDx. Por ultimo podemos ver que la nica salida con la que cuenta este modulo es la TAIFG, es decir que depende como configuremos a este modulo en conjunto de en que momento ser enviada la interrupcin a la CPU. A continuacin describiremos los bits especficos antes mencionados junto con los valores que pueden tomar. TAR En este modo existe un registro de 16 bits llamado TAR (Timer A Register) el cual es incrementado o decrementado por cada flanco ascendente de la seal cuadrada del reloj, es decir que en este registro se almacena la cuenta de pulsos de periodo conocido de la seal cuadrada que incide en el contador. Este registro es el mas importante de el timer a el cual se puede tanto leer como escribir en el. TASSELx e IDx El contador se puede alimentar de diferentes fuentes de reloj tanto internas como externas, la seleccin de esto se hace mediante los bits llamados TASSELx (Timer A Source Select) y adems estas fuentes pueden ser divididas por 2, 4, 8 con los birs llamados IDx (Input Divider) ambos se encuentran en el registro llamado TACTLx

(Timer A Control Register) . Tanto TASSELx como IDx son conjuntos de 2 bits dentro de este registro. (Para mayor informacin con respecto a las fuentes de reloj visitar la seccin del sistema de reloj). TASSELx ocupa las posiciones 8 y 9 del registro de 16 bits TACTL y puede adquirir los siguientes valores.

00 TACLK Reloj del Timer_A (Timer_A Clock) 01 ACLK Reloj auxiliar (Auxiliary Clock) 10 SMCLK Reloj sub principal (Semi Master Clock) 11 INCLK No disponible para nuestro caso

IDx ocupa las posiciones 6 y 7 del registro de 16 bits TACTL y puede adquirir los siguientes valores.

00 Frecuencia de entrada/1 01 Frecuencia de entrada/2 10 Frecuencia de entrada/4 11 Frecuencia de entrada/8

MCx El modo de cuenta es controlado por estos dos bits dependiendo del valor de estos dos bits podemos elegir entre los 4 modos de cuenta disponibles: detenido, ascendente, continuo, ascendente/descendente. Depende de los modos de cuenta el momento en el que la interrupcin ser generada, a continuacin te mostramos una tabla con sus valores, despus de ello su descripcin individual mas detallada.

00 detenido 01 ascendente 10 continuo 11 ascendente/descendente

MODOS DE CUENTA
1.- MODO ASCENDENTE En este modo el contador/temporizador contara desde cero hasta el valor almacenado en TACCR0, despus de eso la cuenta se reinicia y continua de nuevo. En la siguiente imagen se puede ver mejor este modo de cuenta.

La interrupcin se genera en el momento en el que la cuenta en TAR cambia de el valor de TACCR0 a 0. Imaginemos que tenemos una frecuencia de 4MHZ externa mediante un cristal de cuarzo conectado en las terminales del puerto dos, con esta seal alimentaremos a nuestro contador/temporizador, por lo cual TASSELx debe ser 01, adems utilizaremos un divisor por 4 para obtener una frecuencia de 1MHz y as un periodo de 1us, para eso IDx debe ser 10. Lo que deseamos es interrumpir a la CPU cada 1ms por lo que deben de transcurrir 1000 pulsos de la seal que hemos configurado para que esto ocurra, para ello cargamos 1000 en TACCR0 y por ultimo iniciaremos la cuenta al poner en MCx el valor de 01. Lo nico que resta es definir la rutina de servicio a la interrupcin adems del vector de interrupcin correspondiente para por ejemplo encender y apagar un led cada 1ms. 2.- MODO CONTINUO En este modo el contador/temporizador cuenta de manera repetida hasta el valor mximo permitido el cual es 0xFFFF y despus regresa a cero, as la bandera de interrupcin es colocada cuando la cuenta pasa desde 0xFFFF a 0x0, as podemos generar interrupciones con periodo de 65535(Tsrc) donde Tsrc es el periodo de la fuente que seleccionamos con su respectivo divisor de frecuencia. A continuacin una imagen que ilustra de mejor manera este modo.

En el ejemplo anterior este Tsrc es de 1us por tanto con esas configuraciones se pueden generar interrupciones con un periodo de 65.535ms. Adems de generar estos periodos podemos hacer uso de los registros TACCR0 y TACCR1, con ellos podemos generar intervalos de tiempo independientes, posteriormente veremos como implementar esto para generar intervalos de tiempo independientes. 3.- MODO ASCENDENTE/DESCENDENTE En este modo el contador/temporizador cuenta desde cero hasta el valor de TACCR0 de manera ascendente y despus cuenta de manera descendente hasta cero. Esto nos ser til para la generacin de pulsos simtricos, as el periodo ser de el doble del valor almacenado en TACCR0. A continuacin una imagen que muestra este modo de cuenta.

En este modo la interrupcin se genera cuando la cuenta pasa de 0x0001 a 0x0000, como podemos ver en todos los casos la bandera de interrupcin TAIFG es generada cuando la cuenta pasa por cero.

TIMER EN CAPTURA
Casi todos los dispositivos cuentan con tres de estos mdulos de captura y comparacin, en nuestro caso el microcontrolador MSP430G2231 solo cuenta con 2 (CCR0 y CCR1), lo mismo ocurre con los dispositivos mas pequeos de esta familia. Es bueno mencionar que independientemente del numero de mdulos todos son idnticos. El modo de captura nos servir para realizar mediciones de tiempo, como por ejemplo para medir velocidades de computo o bien para medir periodos de tiempo generados por fuentes externas. La precisin de la medicin depende de muchos factores como la interferencia que puede generar la CPU o el hardware con el que se realiza, as como de la fuente de reloj aplicada adems de el numero de bits involucrados en la medicin. A continuacin mostramos un diagrama a bloques de un modulo de captura y comparacin, donde te explicaremos los bits que interfieren en la configuracin de este modulo.

CAP El bit CAP (Capture Mode) nos servir para seleccionar este modo ya que el modulo en si puede trabajar en captura o comparacin, este ocupa la posicin 8 del registro llamado TACCTLx.

0 Modo de comparacin 1 Modo de captura

El grupo de bits llamado CCISx (Capture Compare Input Select) nos ayudara a seleccionar de donde provendr nuestra seal a medir, este esta en los bits 12 y 13 de TACCTLx.

00 Bit CCIxA del encapsulado 01 Bit CCIxB del encapsulado 10 GND 11 VCC

Nuestro dispositivo solo cuenta con CCI0A y CCI1A los cuales se ubican en los puertos P1.1 y P1.2, estos los configuramos para esta funcin a travs del registro P1SEL poniendo a 1 los bits 1 y 2 de este registro. CMx Los bits CMx nos ayudaran a seleccionar el flanco de captura de la seal de entrada, ya sea flaco de bajada, de subida o ambos. Cuando una captura ocurre el valor del TAR es copiado en TACCRx y la bandera de interrupcin llamada CCIFG es colocada, estos bits estn en las posiciones 14 y 15 de TACCTLx

00 No hay captura 01 Captura con flanco ascendente 10 Captura en flanco descendente 11 Captura en ambos flancos

CCI El bit CCI nos ayudara para leer en cualquier momento el nivel lgico de la entrada, este esta ubicado en la posicin 3 del registro TACCTLx. SCS El bit llamado SCS nos ayudara a sincronizar la entrada con el reloj del contador/temporizador.

0 Captura asincrona 1 Captura sncrona

COV Un sobre flujo lgico es provisto en cada registro de captura comparacin para indicar que una segunda captura ha ocurrido antes de que el valor de la primera captura sea ledo.

0 No ha ocurrido sobre flujo en la captura 1 Ocurri sobre flujo en la captura

Como podemos ver el registro utilizado para la configuracin de este modulo aun tiene muchos bits que no hemos usado, estos bits que no hemos mencionado sern utilizados para la configuracin del modo de comparacin.

TIMER EN COMPARACION
Este modo es seleccionado cuando CAP=1, este modo lo usaremos principalmente para generar PWM o interrupciones a intervalos especficos en el momento en que TAR cuente al valor de los registros TACCRx. A continuacin mostramos un diagrama a bloques de los mdulos de comparacin y captura, para explicar esta seccin usaremos el mismo diagrama que la seccin anterior.

La unidad de salida esta presente en todo modulo de captura comparacin esta es la que usaremos para generar seales PWM cada unidad cuenta con ocho modos de operacin que generan diferentes seales de salida, estos modos de salida sern configurados por el grupo de tres bits llamados OUTMODx que se encuentran en TACCTLx. A continuacin una lista con los valores que pueden tomar estos tres bits adems de una descripcin de la funcin que cumplen de acuerdo a cada valor asignado. 000.-Modo Salida. En este modo la salida es igual al contenido del bit OUTx en este mismo registro 001.-Modo Colocar. La salida pasa a 1 cuando el contador/temporizador cuenta al valor en TACCRx y permanece as hasta que el contador/temporizador sea reiniciado u otro modo de salida sea seleccionado. 010.-Modo Conmutar/Reiniciar.- La salida es conmutada cuando el contador/temporizador cuenta al valor en TACCRx y es reiniciada cuando el contador/temporizador cuenta al valor de TACCR0. 011.- Modo Colocar/Reiniciar.- La salida es puesta a 1 cuando en contador/temporizador cuenta al valor de TACCRx y es puesto a 0 cuando el contador/temporizador cuenta al valor de TACCR0. 100.- Modo Conmutar.- La salida es conmutada cuando el contador/temporizador cuenta al valor de TACCRx, el periodo de salida es el doble que el periodo del contador/temporizador

101.- Modo Reiniciar.- La salida es puesta a cero cuando el contador/temporizador cuenta al valor de TACCRx y permanece ah hasta que otro modo de salida sea seleccionado. 110.- Modo Conmutar/Colocar.- La salida es conmutada cuando el contador/temporizador cuenta al valor de TACCRx, es puesta a 1 cuando el contador/temporizador cuenta al valor en TACCR0 111.- Modo Reiniciar/Colocar.- La salida es reiniciada cuando el contador/temporizador cuenta al valor en TACCRx, despus es puesta a 1 cuando el contador/temporizador cuenta al valor de TACCR0 A continuacin mostraremos unas imgenes donde podemos ver como es que esto afecta a la seal de PWM en la salida segn cada modo de cuenta y su respectivo modo de salida. MODO ASCENDENTE

MODO CONTINUO

MODO ASENDENTE/DESCENDENTE

A partir de conocer tanto el modo de cuenta como el modo de salida podremos obtener la seal de PWM que mejor nos convenga con el periodo y ciclo til que queramos.

EL PERRO GUARDIN
Este perifrico esta implementado en muchos microcontroladores ya que mas que un perifrico el cual podamos utilizar para fines de desarrollo, es una medida de seguridad para nuestras aplicaciones ya que este temporizador forzara un reinicio del sistema cuando transcurra cierto tiempo, esto para evitar que nuestro microcontrolador se quede en espera de algn dato que nunca llegara por ejemplo. Adems de esto lo podemos configurar para que cada cierto tiempo genere una interrupcin sin reiniciar el sistema. Este perifrico solo ser utilizado en muy escasas situaciones ya que en la mayora de las aplicaciones se apagara para evitar que forc un reinicio del sistema. Debemos de apagarlo antes de que ocurra este intervalo del que hablamos, por lo regular es la segunda instruccin en la que realizamos esta accin.

Para configurar las opciones de este perifrico se valdra de un registro llamdo WDTCTL el cual esta protegido por una contrasea la cual esta situada en su parte superior y tiene el valor de 05Ah para acceder a este registro se debe de proporcionar esta contrasea, de lo contrario el sistema se reiniciara. El registro de 16 bits llamado WDTCNT es el que contara el tiempo necesario hasta que se efectu el reinicio del sistema, para ello se recomienda que la fuente de reloj que se seleccione sea igual o mayor que la de la CPU. Este modulo puede ser alimentado por las fuentes de reloj ACLK o SMCLK lo cual es seleccionado con el bit llamado WDTSSEL en el registro de control mostrado a continuacin en la imagen. Adems de esto el modulo de perro guardin tiene la posibilidad de configurar el pin llamado RST/NMI del encapsulado.

Como ya mencionamos el perro guardin tiene dos modos de operacin:

MODO GUARDIN
En este modo se provocara un reinicio del sistema cuando pasen 32,768 ciclos del DCOCLK, es decir que se tienen precisamente este numero de ciclos para configurar, detener o borrar el perro guardin, en la mayora de las aplicaciones lo detendremos con la siguiente instruccin la cual se situara despus de configurar la pila.

MOV.W

#WDTPW+WDTHOLD,&WDTCTL

En esta instruccin se suma la contrasea (WDTPW el cual es 05Ah) con el bit WDTHOLD (el cual vale 128) para as moverlos al registro de control, si no se aadiera la contrasea se generara un reinicio de forma inmediata. Cualquier configuracin que deseemos hacer a este perifrico deber ser dentro del intervalo antes mencionado de lo contrario el sistema ser reiniciado.

MODO INTERVALOS
Para configurarlo en este modo lo debemos hacer antes de que los 32,768 ciclos ocurran, para esto configuraremos algunos bits del registro de control uno de los principales es el llamado WDTTMSEL el cual al ponerlo a 1 selecciona este modo. Tambin podremos seleccionar los intervalos a los cuales deseamos que sea generada la interrupcin ya que solo tenemos 4 (64, 512, 8192, 32768 ciclos de la fuente seleccionada), as como la fuente de reloj que usaremos ya sea SMCLK si el bit WDTSSEL=0 o ACLK si WDTSSEL=1. Cabe aclarar que cuando la cuenta expire no se producir un reinicio del sistema, sino que se activara una bandera de interrupcin para que posteriormente mediante una rutina de servicio a la interrupcin podamos realizar alguna accin. Adems de las configuraciones realizadas en el registro WDTCTL debemos de permitir la interrupcin en este modo a intervalos en el registro llamado IE1 mostrado a continuacin, cabe aclarar que este registro tiene banderas para habilitar a otros dispositivos representados en la imagen por una X, los cuales poco a poco se conocern e implementaran.

Adems de este registro existe otro llamado IFG1 el cual contiene el estado de las interrupciones que fueron habilitadas en el registro anterior, este al igual que el anterior

contiene las banderas de interrupcin para otros perifricos por lo cual debemos de tener cuidado de solo modificar los que necesitemos como lo indica la nota en la imagen.

OPERACIN SEGURA
El perro guardin est diseado para operar de manera adecuada ante la falla de algn reloj ya sea SMCLK o ACLK, esto para asegurar que el reloj utilizado para alimentar este modulo no se pueda apagar, esto hace que en algunos casos no se puedan implementar ciertos modos de ahorro de energa. Este mecanismo tambin es capaz de cambiar la fuente del perro guardin si es que ACLK o SMCLK fallan, en este caso la fuente del perro guardin ser cambiada a MCLK, en caso de que MCLK sea un cristal externo y este falle entonces este mecanismo activa al DCO y lo utiliza para alimentar al perro guardin.

ACERCA DE IAR EMBEDDED WORKBENCH


Esta seccin est dedicada a mostrar cmo es que se usa el IAR Embedded Workbench para el desarrollo de nuestros ejemplos, proyectos y aplicaciones completas, as como para editarlos en C/C++ o en Ensamblador, tambin para realizar la descarga de nuestros programas en los microcontroladores y la deteccin de errores de lgica a travs de la depuracin (Debug). Cabe aclarar que este es el principal componente de software que utilizaremos para desarrollo debido a sus caractersticas, posteriormente te mostraremos como es que se utiliza CCE Software que es proporcionado por la misma empresa Texas Instruments .

IAR Systems es una empresa dedicada en su mayora a la creacin de herramientas de software para sistemas empotrados (embedded) desarrollados por las empresas ms reconocidas en este hambito, colaborando con estas empresas son capaces de ofrecer entornos de desarrollo integrado (IDE) muy potentes y flexibles. Uno de sus objetivos es proporcionar compiladores que generen cdigo eficiente logrando un alto grado de optimizacin y que sus herramientas sean agradables adems de ser fciles de usar. IAR Embedded Workbench es como ya lo mencionamos un entorno de desarrollo integrado el cual tiene diferentes versiones, dependiendo el tipo de microcontroladores a usar como los AVR de Atmel, HCS12 de Freescale, PIC de Microchip, MSP430 de Texas Instruments y algunos mas no tan conocidos. El que nosotros usaremos es el de MSP430, en la parte izquierda de la web podrs encontrar un link para obtener una versin de prueba de 30 das (tienes que registrarte) o una versin limitada en cdigo pero ilimitada en tiempo la cual recomendamos, cualquiera que elijas es gratuita y ambas nos servirn.

DESCARGA E INSTALACION DE IAR.


Antes de comenzar a editar programas es necesario tener un IDE adecuado, con IAR Embedded Workbench adems de un editor tenemos compiladores tanto de C, C++ y ensamblador as como otras herramientas muy tiles para crear hardware muy completo. A continuacin mostramos un video tutorial para que puedas seguir de manera mas didctica la forma de descargar e instalar este programa, cualquier sugerencia, duda o problemas con tu instalacin envanos un mensaje en la seccin de contctanos.

Descarga e instalacion IAR - VIDEO


http://www.youtube.com/watch?feature=player_embedded&v=Dck8pC9E39o Pasos:

1.- Seleccionar el link de "Descarga IAR" en el men lateral. 2.- En la pagina que se abre ir casi al final y seleccionar el segundo botn de "Download" que es el que dice "Code size limited Kickstart version download". 3.- Descomprimir en una carpeta conocida. 4.- Ejecutar FET_R604. 5.- Seleccionar SETUP. 6.- Clic en siguiente. 7.- Aceptar la Licencia y presiona siguiente. 8.- Siguiente a todo lo dems (a menos de que quieras cambiar el lugar donde se instalara el programa).

Con esto queda instalado el IAR en tu disco duro, puedes ejecutarlo al terminar la instalacin e ir al siguiente tutorial para configurarlo ya sea para que trabaje con C/C++ o el lenguaje ensamblador.

CREAR PROYECTO EN ENSAMBLADOR.


Ahora en este video tutorial te mostramos como configurar IAR Embedded Workbench para crear un proyecto en Ensamblador, el programa por defecto nos va a crear una plantilla, esta plantilla la ignoraremos, es decir la borraremos y en su lugar pondremos alguno de los ejemplos que se muestran en la web o algn programa propio ya que esta plantilla contiene instrucciones del preprocesador que no se requiere conocer a fondo para comenzar a desarrollar aplicaciones de pequea escala.

Configuras IAR en Ensamblador - VIDEO


http://www.youtube.com/watch?feature=player_embedded&v=oKAbuVCLlHQ Pasos:

1.- Ejecutar IAR Embedded Workbench. 2.- Ir a menu Proyect>Create New Proyect. 3.- En donde dice Project Templates Seleccionamos ASM para abrir la lista. 4.- Seleccionamos ASM y damos en OK. 5.- Seleccionamos una ruta donde guardar nuestro proyecto. 6.- Ya que seleccionamos la ruta, ahora creamos una carpeta donde se alojaran los archivos de nuestro proyecto. 7.- Despus de crear la carpeta, nombramos nuestro proyecto y oprimimos guardar.

Con esto tendremos en la parte izquierda de la pantalla el administrador de proyectos el cual nos muestra todos los archivos que forman parte de nuestro proyecto, en este caso el mas importante es el cdigo fuente que tiene la extensin *.s43 (no es *.asm como con los PICs), posteriormente cuando creemos nuestras propias bibliotecas o libreras las podremos incluir y visualizar en esta parte. En la parte derecha tenemos un editor de texto, el cual contiene una plantilla generada por IAR Embedded Workbench, la cual borraremos casi en su totalidad ya que contiene instrucciones del preprocesador y por ahora no tiene mucho sentido saber que hacen. En esta seccin escribiremos nuestros programas como lo indica la seccin de tutorial de teora bsica.

CREAR PROYECTO EN C++.


El proceso para crear un proyecto en C++ es muy similar a crear un proyecto en ensamblador. Es necesaria esta configuracin para poder compilar nuestros programas ya que de lo contrario no tendremos esta opcin.

Configurar IAR en C++ - VIDEO


http://www.youtube.com/watch?feature=player_embedded&v=2cKknOFF0k&noredirect=1 Pasos:

1.- Ejecutar IAR Embedded Workbench. 2.- Ir a menu Proyect>Create New Proyect. 3.- En donde dice Project Templates Seleccionamos C++ para abrir la lista. 4.- Seleccionamos main y damos en OK. 5.- Seleccionamos una ruta donde guardar nuestro proyecto. 6.- Ya que seleccionamos la ruta, ahora creamos una carpeta donde se alojaran los archivos de nuestro proyecto. 7.- Despus de crear la carpeta, nombramos nuestro proyecto y oprimimos guardar.

De igual manera obtenemos un administrador de proyectos en la parte izquierda donde podremos incluir otro tipo de cdigo fuente y navegar por los archivos de nuestro proyecto, en la parte del editor de textos obtenemos una plantilla con la caracterstica sintaxis de C/C++, a diferencia de la plantilla en ensamblador, esta si nos ser til, solo como base claro pero no hay necesidad de borrarla.

CONFIGURACION DEBUG/RELEASE.
Con los tutoriales anteriores ya estamos listos para editar nuestros programas pero aun no est configurado IAR para transferirlos al microcontrolador, tampoco lo est para simular ni emular. Es necesaria esta configuracin para trabajar con un dispositivo conectado va puerto USB, paralelo o serial (el Launchpad se conecta va USB) . A continuacin el tutorial que muestra cmo hacerlo, cabe mencionar que esta configuracin es igual para programas en C/C++ o en ensamblador.

Debug Release con IAR - VIDEO


http://www.youtube.com/watch?feature=player_embedded&v=wDLMnASBYVE Pasos:

1.- Abrir o crear un proyecto. 2.- Men Project>Options. 3.- En la categora de General Options, en la parte donde dice device presionamos el icono en la parte derecha del cuadro de texto y seleccionamos el dispositivo que usaremos y damos en Ok. 4.-En la pestaa del administrador de proyectos seleccionamos Release. 5.- Men Project>Options. 6.- En la categora de General Options, en la parte donde dice device presionamos el icono en la parte derecha del cuadro de texto y seleccionamos de nuevo el dispositivo que usaremos.

7.- En la categora de Debugger en la parte donde dice Driver seleccionamos la opcin de FET Debugger. 8.- En la categora de FET Debuger seleccionamos la pestaa de Download y activamos la casilla de Verify Download. 9.- Presionamos Ok

As concluimos con las configuraciones necesarias para editar, simular y emular nuestros programas escritos en C/C++ o ensamblador.

PARA QUE CONFIGURAR DEBUG Y RELEASE?.


Estas configuraciones las hicimos primero que nada para seleccionar el dispositivo a usar y para asociar a IAR con alguna herramienta de emulacin (Flash Emulation Tools) las cuales sirven para comunicar al microcontrolador con la PC va puerto serial o USB. En la seccin de espacio de trabajo (Workspace) podemos seleccionar el modo en el que deseamos trabajar ya sea debug o release.

Debug lo configuramos para simular nuestro programa, esto nos permite detectar errores antes de transferir la informacin al microcontrolador ya que se nos permite correr el programa paso por paso, insertar puntos de ruptura, modificar registros, simular interrupciones, ver el mapa de memoria etc. Release lo utilizamos para transferir nuestro programa al microcontrolador, en este modo tambin podemos correr el programa paso a paso y en el caso de tener conectado el hardware necesario podemos ver como se ejecuta cada una de las instrucciones, es importante mencionar que en este modo no podemos simular interrupciones, ya que en algunos casos debern ser generadas por hardware.

Tambin es importante mencionar que en el modo Release, despus de que se estableci la comunicacin esta no se puede interrumpir, es decir desconectar el cable USB ya que esto puede llegar a daar tanto al puerto USB como a nuestra Launchpad. Para desconectar nuestro microcontrolador debemos finalizar la sesin de emulacin.

EJEMPLOS EN ENSAMBLADOR DE MSP430


El ensamblador proporciona un "control total" del dispositivo, ya que solo as podemos configurarlo de la manera ms cmoda para nuestra aplicacin, la lgica a veces suele ser un poco complicada pero dividiendo el trabajo en subrutinas el trabajo se vuelve ms sencillo. Con este lenguaje tenemos acceso a funciones e instrucciones que no son tan accesibles desde C/C++, eso si es un poco ms largo el proceso de aprendizaje pero realmente vale la pena. Aqu est disponible una lista de ejemplos sencillos para el uso de los microcontroladores MSP430 con la herramienta de desarrollo LaunchPad, te recomendamos que visites la seccin de tutoriales para ver como programar los microcontroladores utilizando el IAR Embedded Workbench.

Cabe mencionar que todos estos programas estn bien documentados y son a prueba de errores, trataremos de incluir videos de los programas en ejecucin para que veas la forma en que trabajan, posteriormente incluiremos tambin los diagramas de flujo correspondientes y los circuitos elctricos en caso de que estos sean necesarios.

Arquitectura:

Practica 1: Tablas y apuntadores Practica 2: Corrimientos Practica 3: Sumas y Restas Practica 4: Multiplicacion 16x16

Puertos:

Practica 1: Encender un led al pulsar Practica 2: Encender un led, apagar otro al pulsar Practica 3: Encender un led por 10 segundos Practica 4: Secuencia de 8 leds Practica 5: PWM de 10% en 10% Practica 6: Cuenta de display de 0 a 99

Descargar todos en RAR.-puertos.rar

Timer_A:

Practica 1: Encender un led por 10 segundos Practica 2: Secuencia con corrimientos Practica 3: Secuencia cualquiera con tablas Practica 4: PWM automatico con Time_A y WDT

Descargar todos en RAR.-timera.rar

Perro Guardian

Practica 1: Conmutar un led cada 5s Practica 2: La entrada digital numero 11

Descargar todos en RAR.-wdt.rar

EJEMPLO 1: TABLAS Y APUNTADORES


Otro recurso de software muy importante es el de los apuntadores ya que a travs de ellos podemos acceder a gran cantidad de informacin a partir de solo una direccin, haciendo la analoga con C/C++ podemos implementar arreglos de informacin.

Las tablas nos permiten almacenar informacin en la FLASH junto con el programa principal en el momento de la grabacin, esta informacin puede ser til o no dependiendo la manera en que la implementemos, pueden ser algoritmos, secuencias para motores paso a paso, valores de una funcin continua, valores de una funcin discreta, aproximaciones para el clculo de funciones matemticas, posiciones de objetos etc. Todo depende de nuestro hardware conectado y adems de nuestro programa. En esta seccin te ensearemos como declarar un apuntador y asociarlo a una tabla ya que a menudo utilizaremos estos conceptos en programas de ejemplo. Adems de que ser de gran ayuda conocer estas herramientas. DEFINIENDO UNA TABLA Para esto tenemos dos opciones, una de ellas es guardar datos de 8 bits o bien de 16 bits, tu decidirs cual es la que se ajusta ms a tus opciones. Para ello seguiremos la siguiente sintaxis primero para 8 bits:
ETIQ FINT DC8 DC8 00000001b,00000010b,00000100b,00001000b 0

ETIQ es el nombre de la tabla y para cada tabla este debe de ser diferente, el segundo rengln llamado FINT indica que la tabla ha acabado, esto hace fcil el proceso de aadir ms elementos a la tabla adems de que es til al momento de programar para detectar el fin de la tabla. La palabra clave DC8 es la que se encarga de indicarle al compilador que los datos que estn a continuacin debern guardarse en la FLASH tal como estn. Tambin podemos ver que cada elemento de la tabla es separado por una coma. En este ejemplo los datos se ingresan de manera binaria, pero tambin se pueden hacer de forma hexadecimal (valor mximo 0xFF), decimal (valor mximo 255) e incluso con caracteres los cuales sern codificados en la FLASH en cdigo ASCII. As se pueden definir tablas de la siguiente manera:
ETIQ FINT ETIQ1 FINT1 ETIQ2 FINT2 DC8 DC8 DC8 DC8 DC8 DC8 10,20,30,40,50,60,70,80,90,100 0 0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x100 0 'HOLA MUNDO CRUEL!!' 0

La palabra reservada DC8 solo aplica a un rengln, si se nos acaba el espacio disponible en el editor de IAR entonces debemos de poner otro DC8 y continuar con la definicin de la tabla. As si queremos agregar mas elementos a la tabla llamada ETIQ haremos lo siguiente:
ETQT FINT DC8 DC8 DC8 00000001b,00000010b,00000100b,00001000b 00010000b,00100000b,01000000b,10000000b 0

Para definir tablas con datos de 16 bits lo nico que debemos hacer es cambiar DC8 por DC16 y entonces comenzar a definir los datos de forma binaria(no muy recomendada por la longitud de los datos al momento de la edicin), decimal (valor mximo 65,535), hexadecimal (valor mximo 0xFFFF) o con caracteres de la misma forma que lo hicimos con la tabla con datos de 8 bits. DECLARANDO UN APUNTADOR Para crear un apuntador primero requerimos una direccin a la cual apuntara, esa direccin puede ser la de la tabla llamada Sec0 declarada a continuacin:
Sec0 FIN0 DC8 DC8 DC8 'Copiando letra por letra a la RAM' 'Copia finalizada!!' 0

As para asignar un apuntador a esa tabla (arreglo de datos haciendo una analoga con C/C++) haremos la siguiente instruccin:
MOV #Sec0,R4

Recordemos que los registros de la CPU pueden ser utilizados para guardar tanto datos como direcciones, en el caso de guardar direcciones entonces serian considerados como apuntadores. Lo que estamos haciendo con esta instruccin es convertir a R4 en un registro apuntador ya que estamos copiando la direccin de la tabla llamada Sec0 en su interior. Ahora lo que haremos es mover el contenido de la tabla a la RAM solo como ejemplo. La RAM para el MSP430G2231 inicia en la posicin 0x200 as que comencemos definiendo la constante inicioRAM con un valor de 0x200 as:
#define inicioRAM 0x200

Ya que tenemos el registro el cual apunta a nuestra tabla necesitamos uno que nos indique a partir de que direccin iniciara la copia, este ser R5 el cual hay que inicializar.
CLR R5

Utilizaremos la siguiente instruccin para mover el contenido de la direccin apuntada (el primer elemento de la tabla) a la primera posicin de la RAM
MOV.B @R4+,inicioRAM(R5)

El apuntador R4 tiene la direccin del siguiente elemento de la tabla pero R5 tiene la misma direccin, por lo cual para hacer que apunte a la prxima posicin en la RAM debemos incrementar a R5 con la siguiente instruccin:
INC R5

Si esto lo combinamos con un ciclo el cual pare hasta que se llegue al fin de la tabla entonces tendremos lo que hemos estado buscando, donde R4 apunta al dato de la tabla y R5 apunta a la direccin donde ser copiado el dato. Este ciclo quedara definido as:
ETQ0 MOV.B INC CMP JNE @R4+,inicioRAM(R5) R5 #FIN0,R4 ETQ0

Podemos notar que despus del incremento comparamos la direccin de fin de la tabla con la direccin que contiene R4, si no son iguales significa que aun no se ha finalizado la copia de la tabla, cuando la direccin del fin de la tabla sea igual a la direccin contenida por R4 significara que se ha concluido la transferencia. Veras que esto de los apuntadores y las tablas nos ser de gran utilidad, adems con este programa podemos copiar cualquier posicin de la memoria a la RAM lo cual ser til cuando escribamos en la FLASH o bien para implementar un administrador de memoria en un sistema operativo o para que tu apliques tus propias variaciones para tus aplicaciones.

EJEMPLO 2: CORRIMIENTOS A LA IZQUIERDA


Los corrimientos son importantes para crear algoritmos tiles, entre sus aplicaciones mas destacadas estn las de multiplicacin, divisin, registros de corrimiento para comunicaciones seriales, secuencias de multiplexaje y otras ms que puedes descubrir a medida que desarrollas aplicaciones. En esta seccin haremos introduccin a el concepto de los corrimientos, as como tambin te ensearemos la flexibilidad de esta arquitectura para extender el tamao de sus operandos. Esta arquitectura tiene 4 tipos de corrimientos en sus set de instrucciones, ya sean emuladas o no, de estas cuatro dos son para realizar corrimientos a la izquierda y dos mas para realizar corrimientos a la derecha. Comenzaremos con los corrimientos a la izquierda, el set de instrucciones de los MSP430 cuenta como acabamos de mencionar con dos instrucciones con las cuales se pueden realizar corrimientos hacia la izquierda, estas son las siguientes:
RLA(.B) dst RLC(.B) dst

La primera es el corrimiento aritmtico el cual coloca un cero en la posicin cero del registro de destino, despus el bit que antes estaba en la posicin 0 pasa a la posicin 1, el bit que estaba en la posicin 1 pasa a la posicin 2 y as hasta que el bit en la posicin numero 15 pasa a la bandera de acarreo. La imagen siguiente ejemplifica el proceso de manera grafica.

Esto si se realiza la instruccin con 16 bits, es decir sin el modificador .B si elegimos realizar esta instruccin con solo 8 bits entonces ignoraremos los 8 bits mas altos as:

Se le conoce como corrimiento aritmtico debido a que esta instruccin realiza una multiplicacin aritmtica dst x 2. Para demostrar esto un ejemplo. Suponiendo que en el registro R15 de la CPU tenemos el siguiente valor binario: 0011011100101101, el cual tiene el valor decimal de 14125, al realizar la siguiente instruccin:
RLA R15

El valor en R15 es 0110111001011010 el cual tiene un valor binario de 28250 el cual como podemos notar es el numero contenido en R15 de manera inicial multiplicado por dos. Ademas de esto si realizamos esta instruccin ya sea 16 (sin el modificador .B) u 8 veces(con el modificador .B) entonces nuestro registro se encontrara vacio. La otra instruccin de corrimiento a la izquierda es RLC la diferencia principal entre esta instruccin y la vista anteriormente es que en lugar de aadir un cero en el bit 0 se aade el contenido del acarreo. A continuacin mostramos el proceso para ambas versiones de esta instruccin.

Para 8 bits.

Esta instruccin sirve como complemento a la primera ya que en la primera el mximo de bits con los cuales se puede realizar un corrimiento es 16, pero utilizando dos registros podemos hacer un corrimiento con un numero de 32 bits con solo combinar estas dos instrucciones de la siguiente manera:
RLA RLC R14 R15

Con lo que grficamente obtendramos lo siguiente:

Como podemos ver el acarreo que genera el bit 15 es rescatado por la segunda instruccin la cual en lugar de introducir un cero, introduce el valor del acarreo. De esta manera podemos incrementar la longitud del corrimiento hasta el valor que deseemos o que requiramos, por ultimo veremos que para un corrimiento de 64 bits lo nico que debemos hacer es aadir dos instrucciones RLC mas.
RLA RLC RLC RLC R12 R13 R14 R15

El resultado estar contenido entonces por 4 registros de 16 bits los cuales para este caso han sido R12,R13,R14 Y R15 como veremos en secciones posteriores esto puede ser til para realizar operaciones con ms de 16 bits e incluso para operaciones con nmeros menores a 16 bits.

CORRIMIENTOS A LA DERECHA
En principio este tipo de corrimientos son muy parecidos a los mostrados anteriormente, es decir en lugar de desplazar los bits a la izquierda los desplazan a la derecha. Las dos instrucciones correspondientes para realizar este tipo de corrimientos son RRA y RRC, la sintaxis es la misma que para los corrimientos hacia la izquierda, en realizad tienen funciones simtricas a excepcin de RRA la cual acta de la siguiente manera:

Como podemos ver el bit 15 permanece sin cambio, pero en la posicin 14 se copia el valor del bit 15, esto para conservar el signo, as en lugar de realizar una multiplicacin por 2 binaria realiza la divisin entre 2. Esto no es en realidad cierto si el bit mas significativo es 1, ya que este bit representa el signo de un numero por ejemplo en el caso de 1000100101101001 puede ser interpretado como 35177 en decimal o bien como -33129 por lo cual si aplicamos un corrimiento de este tipo obtendremos el siguiente numero: 1100010010110100 el cual puede ser interpretado como 50356 en decimal o bien como -17588 el cual es el primer numero dividido entre -2, para realizar una divisin entre 2 con 16 bits recomendamos la otra instruccin de corrimiento la cual presentaremos a continuacin o bien despus

de ejecutar esta instruccin verificar si la bandera N fue colocada, si este es el caso aplicaremos la siguiente instruccin:
BIC #80h,dst

Donde dst es el registro o localidad de memoria donde fue ejecutada la instruccin RRA previamente, esta instruccin borra el bit mas significativo del registro o localidad de memoria de 16 bits. Esto tambin puede ser interpretado como quita el signo. Para la versin a 8 bits de la instruccin a travs del modificador (.B) obtenemos el mismo resultado.

El set de instrucciones incluye de igual manera una instruccin de corrimiento a la derecha con acarreo, esta nos es til para realizar divisiones entre dos sin necesidad de verificar si el resultado es positivo o negativo. A continuacin una imagen.

Para 8 bits.

Como podemos ver esta instruccin es igual a RLC solo que los bits cambian de posicin en sentido contrario, es decir hacia le derecha en lugar de a la izquierda, tambin se pueden combinar las dos instrucciones para poder realizar corrimientos a la derecha de 16, 36, 64 bits y hasta mas, dependiendo de nuestras necesidades.

EJEMPLO 3: SUMA Y RESTA A 32 BITS


En esta seccin solo te demostramos como realizar sumas y restas con operandos de mas de 16 bits de longitud si es que algn da lo requieres, adems es til para demostrar la flexibilidad que nos brinda el set de instrucciones. Utilizaremos 6 identificadores para esta seccin los cuales al final asignaremos a registros de la CPU mediante las directivas define. Dos identificadores sern para almacenar el primer operando de 32 bits, estos son OP1L y OP2H. Otros dos sern para almacenar el segundo operando de 32 bits y estos son

OP2L y OP2H, adems de almacenar el segundo operando estos identificadores almacenaran el resultado una ves que se ejecute la suma. Comenzaremos entonces por realizar sumas de 32 bits con el uso de solo dos instrucciones:
ADD ADDC OP1L,OP2L OP1H,OP2H

La primera instruccin suma la parte baja de ambos operandos y guarda el resultado en OP2L, si se genera un acarreo en esta suma entonces a travs de la siguiente instruccin consideraremos este acarreo para obtener un resultado correcto ya que ADDC suma los dos operandos junto con el acarreo y el resultado es almacenado en OP2H, as el resultado de la suma se encontrara en OP2L y OP2H. Para realizar una resta de 32 bits utilizaremos los mismos identificadores de manera que las instrucciones que realizan una resta de 32 bits son las siguientes:
SUB SUBC OP1L,OP2L OP1H,OP2H

Como podemos notar solo sustituimos la instruccin ADD por SUB y la instruccin ADDC por SUBC, el resultado es almacenado en OP2L y OP2H.

SUMA Y RESTA A 64 BITS


Para guardar un nmeros de 64 bits requerimos 4 registros de 16 bits por lo que para realizar tanto sumas como restas con nmeros de 64 bits requerimos 8 registros en total. Para ello utilizaremos identificadores como en la seccin anterior, para almacenar el operando 1 utilizaremos OP1_0, OP1_1, OP1_2 y OP1_3, para el operando 2 y resultado utilizaremos los siguientes OP2_0, OP2_1, OP2_2 u OP2_3. Ya definidos los identificadores veremos que realizar una suma o resta de 64 bits es mas sencillo de lo que parece. A continuacin el cdigo necesario para ejecutar la suma:
ADD ADDC ADDC ADDC OP1_0,OP2_0 OP1_1,OP2_1 OP1_2,OP2_2 OP1_3,OP2_3

As si entre cada 16 bits se genera un acarreo este ser considerado por la instruccin ADDC ya que esta suma ambos operandos junto con el acarreo para depositar el resultado en el Segundo operando. La resta como en el caso de 32 bits se hace solo sustituyendo instrucciones ADD por SUB e instrucciones ADDC por SUBC para obtener lo siguiente:
SUB SUBC SUBC OP1_0,OP2_0 OP1_1,OP2_1 OP1_2,OP2_2

SUBC

OP1_3,OP2_3

Como podemos ver es fcil implementar sumas, restas y corrimientos con valores mayores a los 16 bits esto gracias al set de instrucciones que proporciona soluciones fciles a problemas fciles.

PROGRAMA DE APLICACIN
Realizaremos un programa el cual realice sumas y restas tanto con 32 como 64 bits para demostrar el uso de estas subrutinas, adems como extra de la seccin mostraremos un video donde te enseamos a verificar tus algoritmos mediante el uso de IAR Embedded Workbench a travs de la herramienta de simulacin que este IDE contiene. A continuacin te mostramos el cdigo que hemos desarrollado para esta seccin.
01|#include "msp430f2013.h" 02| 03|#define inicioSP 027Fh // Locacion en la RAM para la pila 04|// Operando 1: 05|// |Parte3||Parte2||Parte1||Parte0| 06|#define OP1_0 R8 // Operando 1 parte 0 07|#define OP1_1 R9 // Operando 1 parte 1 08|#define OP1_2 R10 // Operando 1 parte 2 09|#define OP1_3 R11 // Operando 1 parte 3 10|// Operando 2: 11|// |Parte3||Parte2||Parte1||Parte0| 12|#define OP2_0 R12 // Operando 2 parte 0 13|#define OP2_1 R13 // Operando 2 parte 1 14|#define OP2_2 R14 // Operando 2 parte 2 15|#define OP2_3 R15 // Operando 2 parte 3 16| 17|main 18| 19|;-----------------------------------------------------------------------------20| ORG 0xF800 ; Direccion de inicio del programa 21|;-----------------------------------------------------------------------------22|RESET MOV #inicioSP,SP ; Inicio de la pila 23| MOV #WDTPW+WDTHOLD,WDTCTL ; Apaga el perro guardian 24| 25|;**************************** Operaciones con 32 bits*************************** 26| 27| MOV #0xAF70,OP1_0 ; El numero 0x11FAAF70 (301641584 decimal) 28| MOV #0x11FA,OP1_1 ; es colocado en OP1_0 y OP1_1 29| MOV #0x00FA,OP2_0 ; El numero 0x1A0F00FA (437190906 decimal) 30| MOV #0x1A0F,OP2_1 ; es colocado en OP2_0 y OP2_1 31| CALL #SUMA32 ; Se realiza la suma de estos dos numeros, el 32| ; resultado 0x2C09B06A (738832490) se almacena 33| ; en OP2_0 y OP2_1 34|

35| MOV #0xAF70,OP1_0 ; Se carga en OP1_0 y OP1_1 el mismo valor para 36| MOV #0x11FA,OP1_1 ; obtener los valores iniciales 37| CALL #RESTA32 ; Se realiza la resta como resultado obtenemos 38| ; 0x1A0F00FA (437190906 decimal) 39| 40|;**************************** Operaciones con 64 bits*************************** 41| 42| MOV #0xAF70,OP1_0 ; Cargamos en el operando 1 0x4000B00111FAAF70 43| MOV #0x11FA,OP1_1 ; (4611879537070485360 en decimal) en los cuatro 44| MOV #0xB001,OP1_2 ; registros correspondientes 45| MOV #0x4000,OP1_3 46| 47| MOV #0x00FA,OP2_0 ; Cargamos en el operando 2 0x500O21321A0F00FA 48| MOV #0x1A0F,OP2_1 ; (360324469258911994 en decimal) en los cuatro 49| MOV #0x2132,OP2_2 ; registros correspondiente 50| MOV #0x5000,OP2_3 51| CALL #SUMA64 ; Al sumar obtenemos 0x4500D1332C09B06A 52| ; (4972204006329397354 en decimal) 53| 54| MOV #0x00FA,OP2_0 ; Cargamos el operando 1 con los valores que 55| MOV #0x1A0F,OP2_1 ; tenia desde el principio para que al realizar 56| MOV #0x2132,OP2_2 ; la suma obtengamos en el operando 2 lo que 57| MOV #0x500,OP2_3 ; teniamos antes de realizar la suma 58| CALL #RESTA64 ; es decir: 0x500O21321A0F00FA 59| ; (4611879537070485360 en decimal) 60| 61| 62| BIS #CPUOFF,SR 63| NOP 64|;-----------------------------------------------------------------------------65|; Suma Con Operandos De 32 bits 66|;-----------------------------------------------------------------------------67|SUMA32 ADD OP1_0,OP2_0 68| ADDC OP1_1,OP2_1 69| RET 70| 71|;-----------------------------------------------------------------------------72|; Resta Con Operandos De 32 bits 73|;-----------------------------------------------------------------------------74|RESTA32 SUB OP1_0,OP2_0 75| SUBC OP1_1,OP2_1 76| RET 77| 78|;-----------------------------------------------------------------------------79|; Suma Con Operandos De 64 bits

80|;-----------------------------------------------------------------------------81|SUMA64 ADD OP1_0,OP2_0 82| ADDC OP1_1,OP2_1 83| ADDC OP1_2,OP2_2 84| ADDC OP1_3,OP2_3 85| RET 86| 87|;-----------------------------------------------------------------------------88|; Resta Con Operandos De 64 bits 89|;-----------------------------------------------------------------------------90|RESTA64 SUB OP1_0,OP2_0 91| SUBC OP1_1,OP2_1 92| SUBC OP1_2,OP2_2 93| SUBC OP1_3,OP2_3 94| RET 95| 96|;-----------------------------------------------------------------------------97|; Vectores de Interrupcin y Reset 98|;-----------------------------------------------------------------------------99| ORG 0xFFFE ; Vector para el RESET 100| DW RESET ; Etiqueta correspondiente 101| 102| END

Primero debemos acordar algunas definiciones para hacer mas clara la programacin y la legibilidad, es decir definir que registros de la CPU formaran parte del operando 1 y que registros forman parte del operando 2 para operaciones a 32 y 64 bits. Para ello en las lneas 6-9 vemos que asignamos de la siguiente manera los registros que forman parte del operando 1, OP1_0 a R8, OP1_1 a R9, OP1_2 a R10 y OP1_3 a R11 de igual forma para el operando 2 definimos OP2_0 a R12, OP2_1 a R13, OP2_2 a R14 y por ultimo OP2_3 aR15. Podemos ver tambin que las instrucciones vistas en secciones anteriores fueron convertidas en subrutinas con nombres muy representativos. En las lneas 67-69 se encuentra la subrutina que realiza una suma a 32 bits, en las lneas 74-76 se encuentra la resta a 32 bits, en las lneas 81-85 esta la suma a 64 bits y por ultimo en las lneas 90-94 se encuentra la resta a 64 bits. El programa principal el cual utilizara estas subrutinas est definido desde la lnea 22 hasta la 63, antes de mandar a llamar a cada subrutina cargamos valores tanto en el operando 1 como en el operando 2 a travs de instrucciones MOV. A continuacin te mostramos un video en el cual realizamos la simulacin mediante IAR para verificar que realmente el programa hace lo que debe. Como estas subrutinas son elementos puramente de software no podemos armar un circuito y comprobar que todo va bien, si no que debemos de simular a la CPU.

Obtener codigo fuente - suma-resta.s43

EJEMPLO 4: MULTIPLICACION DE 16X16 BITS


Las practicas de la seccin de arquitectura te introduciremos al uso de algunos algoritmos tiles para la realizacin de otras aplicaciones o programas ms complejos, te presentamos los algoritmos a manera de apoyo para que refuerces tus conocimientos, as como para que puedas adaptarlos a tus aplicaciones si as lo ameritan. En esta pgina en especifico realizaremos la multiplicacin de dos nmeros de 16 bits sin signo, esto a manera introductoria para los dems algoritmos de multiplicacin que continan. Antes de comenzar con el desarrollo de este programa hay que mencionar que una multiplicacin binaria se realiza de igual forma que una multiplicacin decimal. Para entender mejor el algoritmo realizaremos un ejemplo en el cual multiplicaremos de forma binaria los nmeros 1011010111010011 y 1101100. Primero hay que ordenar de cierta manera a los dos operandos, nosotros los hemos ordenado de esta manera ya que as el algoritmo es ms corto pero recordemos que en la multiplicaciones el orden de los factores no altera el producto. Despus de eso lo que haremos es recorrer el operando 1 que se encuentra en la parte inferior bit a bit.

Comenzando por el bit menos significativo del operando 1 remarcado en azul multiplicaremos este bit por el operando 2 y lo pondremos como resultado.

Ahora haremos lo mismo con el segundo bit, el cual para este caso es cero por lo cual obtendremos lo siguiente:

El procedimiento continua as hasta terminar con el bit mas significativo del operando 1

Ya que hayamos terminado de recorrer todos los bits del operando 1 entonces estaremos listos para realizar la suma que nos llevara a obtener el resultado correcto.

De esta manera es como se realiza la multiplicacin binaria, al analizar el algoritmo descrito podemos notar algunos aspectos los cuales nos sern tiles al momento de realizar el algoritmos correspondiente. Esos aspectos se mencionan a continuacin.

1.-En cada iteracin se realiza un corrimiento a la izquierda. 2.-El bit del operando 1 que ya fue utilizado jams en el proceso vuelve a ser utilizado.

Tomando esto en cuenta podemos realizar el algoritmo de la siguiente manera:

El primer bit es cero por lo cual haremos un corrimiento a la izquierda en el operando 2 y un corrimiento a la derecha en el operando 1

Como podemos notar en verde aadimos un cero como resultado del corrimiento a la izquierda en el operando 2, pero en el operando 1 eliminamos el cero que comprobamos, como ese bit era cero el resultado permanece en ceros. Ahora como el siguiente bit a comprobar tambin es cero haremos lo mismo, es decir un corrimiento a la izquierda al operando 2 y un corrimiento a la derecha en el operando 1.

Como podemos ver el resultado continua en ceros, esto debido a que los bits que hasta ahora hemos comprobado han sido cero, pero ahora vemos que es lo que ocurre cuando el bit a comprobar es un 1.

Primero sumamos el operando 2 a resultado.

Despus hacemos lo mismo que cuando encontramos un cero, es decir realizar un corrimiento a la izquierda en operando 2 y uno a la derecha en operando 1. Esta es una forma distinta de ver el proceso de la multiplicacin la cual nos ser ms til.

DESARROLLO DE LA SUBRUTINA
Primero definiremos los registros con los cuales trabajaremos para realizar la multiplicacin. Como registro donde guardaremos al primer operando esta R5 al cual definiremos de la siguiente manera para escribir OP1 a lo largo del programa y no R5
#define OP1 R5

Para el segundo operando requerimos dos registros ya que con los corrimientos, en un caso extremo puede llegar a tener el doble de la longitud. Por lo cual definiremos a R6 y R7 como OP2L (parte baja "low") y OP2H (parte alta "high")
#define #define OP2L OP2H R6 R7

El resultado en varios casos puede resultar ser mayor a 16 bits por lo cual tambin estar formado por dos registros, es decir R8 y R9 por lo que los definiremos como RESL y RESH respectivamente con las siguientes directivas del preprocesador.
#define #define RESL RESH R8 R9

Como resultado del anlisis hemos desarrollado un diagrama de flujo el cual explica de manera grafica el algoritmo el cual hay que seguir para obtener la multiplicacin. El diagrama lo mostramos a continuacin.

Ya realizadas las definiciones correspondientes comenzaremos a traducir nuestro algoritmo en instrucciones que la CPU pueda interpretar. Este algoritmo estar en una subrutina la cual podremos llamar con la instruccin CALL, al final crearemos un programa que implemente esta subrutina. Primero debemos borrar o inicializar los registros que utilizaremos, es decir RESL, RESH y OP2, los dems registros no son borrados ya que antes de llamar a la subrutina debemos de cargarlos con los operandos correspondientes.
MULT CLR CLR CLR RESL RESH OP2H

Como podemos notar adems de borrar los registros declaramos la etiqueta llamada MULT la cual nos servir cuando empleemos la instruccin CALL. Comprobaremos el valor del bit menos con la instruccin BIT la cual realiza una operacin and entre la fuente y el destino sin modificar los valores, esto para nicamente alterar las banderas. Esta instruccin la utilizaremos en conjunto con un

salto condicional JZ el cual se efectuara si al bit menos significativo es 0, de lo contrario (que sea 1) no se ejecuta el salto y el programa continua ejecutando la siguiente instruccin. A continuacin mostramos las instrucciones que harn lo antes mencionado.
ET_02 BIT JZ #1,OP1 ET_01

Auxilindonos del diagrama de flujo podemos ver que si el bit es uno entonces debemos aadir el operando 2 al resultado, de lo contrario solo ejecutaremos los corrimientos correspondientes, adems de que en cualquier caso los corrimientos se llevaran a cabo. As si el bit menos significativo es 1 la CPU no ejecuta el salto por lo tanto a continuacin de las instrucciones anteriores debemos colocar las instrucciones correspondientes para llevar a cabo la suma del operando 2 con el resultado as:
ET_02 BIT JZ ADD ADDC #1,OP1 ET_01 OP2L,RESL OP2H,RESH

Si el bit es cero entonces se ejecuta el salto y los corrimientos se llevan a cabo por lo cual completaremos la rutina de la siguiente manera:
MULT ET_02 CLR CLR CLR BIT JZ ADD ADDC RLA RLC RRC JNZ RET RESL RESH OP2H #1,OP1 ET_01 OP2L,RESL OP2H,RESH OP2L OP2H OP1 ET_02

ET_01

Esta es la forma final de la subrutina donde podemos ver las etiquetas para los saltos condicionales, adems los corrimientos tanto del operando 2 (dos instrucciones ya que es de 32 bits de largo) como del operando 1 (hacia la derecha). Por ultimo vemos que despus del corrimiento del operando 1 encontramos otro salto condicional el cual nos ayudara a saber cuando debe terminar la subrutina. Esta terminara cuando el operando 1 haya sido desplazado completamente hasta estar vacio, lo cual ocurrir en el caso extremo a las 16 iteraciones. Para nuestro ejemplo solo sern 7 veces.

EL PROGRAMA DE APLICACIN
Como podemos ver esta subrutina altera nuestros operandos despus de que la multiplicacin se llevo a cabo, por lo regular el operando dos es muy diferente al introducido inicialmente y el operando 1 termina siendo cero, as que tomando esto en

cuenta crearemos un programa el cual a partir de un valor inicial y un incremento generara el cuadrado de cada valor en la serie colocndolo en la RAM, por ejemplo si ponemos como valor inicial a 1 y un incremento de 1 obtendremos 1, 4 ,9 , 16, 25, 36 y as en lo sucesivo. Para comprender mejor el proceso que llevara a cabo nuestro programa te mostramos a continuacin su diagrama de flujo.

A continuacin mostramos el programa completo con la descripcin correspondiente.

01|#include "msp430f2013.h" 02| 03|#define inicioSP 027Fh // Locacion en la RAM para la pila 04|#define inicioRAM 200h // Lugar de inicio de la RAM 05|#define finRAM 270h // Lugar donde termina la RAM 06| 07|#define TEST R4 // Registro para la posicion 08|#define OP1 R5 // Primer operando de 16 bits 09|#define OP2L R6 // Segundo operando de 16 bits 10|#define OP2H R7 // Parte alta del segundo operando 11|#define RESL R8 // Resultado parte baja 12|#define RESH R9 // Resultado parte alta 13| 14|#define valinicial 0FFh // Valor inicial para la serie 15|#define incremento 0Ah // Incremento entre cada valor 16| 17|main 18| 19|;-----------------------------------------------------------------------------20| ORG 0xF800 ; Direccion de inicio del programa 21|;-----------------------------------------------------------------------------22|RESET MOV #inicioSP,SP ; Inicio de la pila 23| MOV #WDTPW+WDTHOLD,WDTCTL ; Apaga el perro guardian 24| 25| CLR R15 ; Inicializa el indice a cero 26| MOV #valinicial,OP1 ; Primer operando 27|CUAD MOV OP1,OP2L ; Segundo operando = Primer operando 28| PUSH OP1 ; Guarda una copia del OP1 en la pila 29| CALL #MULT ; Llamada a la rutina de multiplicacion 30| POP OP1 ; Recupera la copia de OP1 31| ADD #incremento,OP1 ; Aade el incremento a OP1 32| 33| MOV RESL,inicioRAM(R15) ; Resultado parte baja a la RAM 34| INCD R15 ; Siquiente localidad de la RAM 35| MOV RESH,inicioRAM(R15) ; Resultado parte altaa la RAM 36| INCD R15 ; Siquiente localidad de la RAM 37| 38| CMP #finRAM-inicioRAM,R15 ; Se ha terminado de llenar la RAM? 39| JNZ CUAD 40| 41| BIS #CPUOFF,SR 42| NOP 43|;-----------------------------------------------------------------------------44|; Rutina que realiza la multiplicacion 45|;-----------------------------------------------------------------------------46|MULT CLR RESL ; Borrar el registro de resultado parte baja

47| CLR RESH ; Borrar el registro de resultado parte alta 48| CLR OP2H ; Borrar la parte alta del operando 49|ET_02 BIT #1,OP1 ; Es 1 o 0 el bit menos significativo? 50| JZ ET_01 ; Si es cero continua en ET_01 51| ADD OP2L,RESL ; Suma el operando 2 a resultado 52| ADDC OP2H,RESH ; tanto parte baja como parte alta 53|ET_01 RLA OP2L ; Realizar corrimiento para la siguiente 54| RLC OP2H ; iteracion 55| RRC OP1 ; Corrimiento a la derecha para el bit siguiente 56| JNZ ET_02 ; Termino? 57| RET 58| 59|;-----------------------------------------------------------------------------60|; Vectores de Interrupcin y Reset 61|;-----------------------------------------------------------------------------62| ORG 0xFFFE ; Vector para el RESET 63| DW RESET ; Etiqueta correspondiente 64| 65| END

Podemos ver que se han definido los valores inicioRAM y finRAM en las lneas 4 y5 los cuales indicaran a nuestro programa a partir de donde podrn iniciar a escribir la informacin y cuando debern detenerse. Despus en el mismo bloque de definiciones se encuentran los identificadores correspondientes para realizar la multiplicacin los cuales ya conocemos (lneas 7-12). Adicionalmente definimos las constantes que nos permitirn controlar la serie de nmeros a los cuales obtendremos su cuadrado, es decir un valor inicial y un incremento. Posteriormente se encuentran las partes indispensables de un programa las cuales ya conocemos y son la palabra main, la direccin de inicio de programa (ORG 0xF800 ), la etiqueta de RESET junto con las instrucciones para asignar a la pila en la RAM y apagar el perro guardin en las lneas 20-23. Ahora vemos que en la lnea 25 borramos el contenido de R15, esto porque lo utilizaremos como ndice para poder grabar los resultados en la RAM de manera correcta y ordenada. Como nuestra subrutina realiza la multiplicacin de dos nmeros, entonces requiere de dos parmetros, es decir OP1 y OP2L, pero como el programa que estamos desarrollando obtiene el cuadrado de una serie de nmeros entonces utilizaremos la subrutina de multiplicacin para este objetivo colocando tanto en OP1 como en OP2L el mismo nmero as que primero cargamos a OP1 con el valor inicial en la lnea 26 y despus copiamos OP1 en OP2L en las lneas 27 y 28. Como mencionamos anteriormente la subrutina que realiza la multiplicacin altera nuestros operandos (que en este caso son iguales) por lo cual debemos de respaldarlos,

ya que son iguales basta con respaldar a OP1, una manera rpida de realizar esta accin es colocar a OP1 en la pila con la instruccin PUSH que vemos en la lnea 28, despus llamamos a la subrutina MULT lo cual altera a ambos operandos (OP1 se hace cero y OP2L termina con un valor impredecible) pero a travs de la operacin POP OP1 en la lnea 30 logramos recuperar el valor de OP1. Como podemos ver utilizamos una instruccin POP por cada instruccin PUSH como recomendamos cuando se realiza cualquier manipulacin de la pila. Si posteriormente utilizamos este programa en otra aplicacin y en esta aplicacin utilizamos interrupciones debemos tener en cuenta que si nuestra ISR utiliza a la pila, entonces debemos seguir esta misma recomendacin, es decir por cada instruccin POP utilizar una instruccin PUSH, ya que de lo contrario puede ocurrir que el flujo del programa sea impredecible entrando este en descontrol. Ya que se recupero el valor de OP1 entonces le sumamos el incremento en la lnea 31, as se preparan las condiciones para la prxima iteracin. Por ltimo antes de repetir el mismo proceso para el siguiente valor, debemos de enviar los resultados a la RAM, esto porque es parte del objetivo del programa, lo cual hacemos con las lneas 33-36 donde utilizamos el registro ndice para indicar cuantas posiciones a partir del inicio de la RAM se guardara la informacin, utilizamos incrementos dobles en el registro ndice R15 ya que cada localidad de la RAM es de 8 bites por lo cual para apuntar a la prxima palabra (word) debemos de incrementar el ndice en 2. Cuando se realiza la multiplicacin de 8 bits veremos que solo se requiere incrementar el ndice en 1. Ya que se realizo la multiplicacin y adems se enviaron los resultados a la RAM solo queda verificar si es que ya se ha llegado al lmite de la RAM para entonces terminar las iteraciones, de lo contrario seguir con el siguiente valor lo cual hacemos en las lneas 38-39 en la cual restamos el valor del fin de la RAM con el de inicio y despus comparamos este valor con el registro ndice, es decir comparamos el nmero de localidades disponibles con el nmero de localidades que y hemos llenado. Si la comparacin resulta ser cero entonces significa que debemos de terminar, si no resulta ser cero entonces aun hay espacio disponible para poder seguir calculando los valores. Como podemos notar la RAM no termina en la direccin que asignamos, es decir 270h, ya que la RAM de nuestro MSP430F2231 termina en la posicin 027Fh, la razn principal de que no hayamos utilizado este valor para la constante finRAM es porque la pila esta localizada en la RAM, por lo cual declaramos el fin de la ram antes para que el programa no altere a la pila, como ya hemos mencionado el alterar a la pila puede traer consecuencias desastrosas para nuestras aplicaciones as que con esto damos cierto margen de error para que la pila pueda incrementarse hasta en 7 niveles mas.

Obtener codigo fuente - multiplicacion.s43

PRACTICAS MANEJO DE PUERTOS PRACTICA 1 - Encender un led al pulsar


Este primer programa realiza la conmutacin de un led conectado en el bit P1.0 al oprimir un botn conectado en el bit P1.3, con este programa podemos poner en practica las configuraciones realizadas con los puertos as como ver como es que se configura el vector de interrupciones del puerto 1 y se crea la rutina de servicio a la interrupcin. Tambin podemos ver un video el cual nos muestra el programa en ejecucin.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo"

#include #define midram 0240h #define time 4000 /* Constante para el retardo*/ main ;-----------------------------------------------------------------------------ORG 0F800h ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Configuracion de la pila MOV.w #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado MOV.B MOV.B CLR.B MOV.B P1.3 MOV.B Up en P1.3 BIS.B BIC.B BIC.B BIS.B MOV NOP #00001000B,&P1OUT #BIT3,&P1REN #BIT3,&P1IES #BIT3,&P1IFG #BIT3,&P1IE #GIE+CPUOFF,SR ; Apagar P1 y resistencia Pull; ; ; ; Resistencia Pull-Up habilitada Flanco de bajada en P1.3 Borrado de la bandera P1.3 Interrupcion local permitida &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL &P1SEL #11110111b,&P1DIR ; Calibracion del ; oscilador a 1MHz ; P1 como e/s digital ; Todo P1 como salida excepto

; Interrupciones habilitadas y ; CPU apagado

;-----------------------------------------------------------------------------P1_ISR; Rutina de Servicio a la Interrupcin ;-----------------------------------------------------------------------------XOR.B #BIT0,&P1OUT ; Conmuta el estado del led BIC.B #BIT3,&P1IFG ; Borrar bandera por software para poder

RETI la rutina termino

; Salir de la interrupcion ; Instruccion para indicar que ; de servicio a la interrupcion

;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Reset DW RESET ; Etiqueta para Reset ORG 0FFE4h ; Vector para la int del P1 DW P1_ISR ; Etiqueta de la RSI END main

Practica 1.flv - VIDEO http://www.youtube.com/watch?v=rRrhoKI3HbE&feature=playe r_embedded

PRACTICA 2 - Encender un led, apagar otro al pulsar


Este programa es similar al anterior pero en este hacemos uso de los dos leds disponibles en el LaunchPad, tras hacer dos pequeas modificaciones en el programa anterior logramos este, el cual al oprimir el botn conectado en P1.3 hacemos que los leds conmuten su estado, es decir el led que estaba apagado se enciende y el que estaba encendido se apaga. Al igual que en el anterior hacemos uso de las interrupciones por lo cual no requerimos de subrutinas de retardo para eliminar los rebotes.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo"

#include #define midram 0240h main ;-----------------------------------------------------------------------------ORG 0F800h ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP MOV.w #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado

MOV.B MOV.B CLR.B MOV.B P1.3 MOV.B Up en P1.3 BIS.B BIC.B BIC.B BIS.B MOV NOP

&CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL &P1SEL #11110111b,&P1DIR #00001001b,&P1OUT #BIT3,&P1REN #BIT3,&P1IES #BIT3,&P1IFG #BIT3,&P1IE #GIE+CPUOFF,SR

; Calibracion del ; oscilador a 1MHz ; P1 como e/s digital ; Todo P1 como salida excepto ; Apagar P1 y resistencia Pull; ; ; ; Resistencia Pull-Up habilitada Flanco de bajada en P1.3 Borrado de la bandera P1.3 Interrupcion local permitida

; Interrupciones habilitadas y ; modo de ahorro de energia

;-----------------------------------------------------------------------------P1_ISR; Rutina de Servicio a la Interrupcin ;-----------------------------------------------------------------------------XOR.B #BIT0+BIT6,&P1OUT BIC.B #BIT3,&P1IFG RETI ;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Reset DW RESET ; Etiqueta para Reset ORG 0FFE4h ; Vector para la int del P1 DW P1_ISR ; Etiqueta de la RSI END main

Practica 2.flv - VIDEO


http://www.youtube.com/watch?v=4aDGxlQ2hBs&feature=player_embedded

PRACTICA 3 - Encender un led por 10 segundos


Aqu hacemos uso de las subrutinas y subrutinas de tiempo para lograr un retardo de 10 segundos, el cual podemos visualizar mediante el encendido de un led. Al igual que en programas anteriores hacemos uso de las interrupciones del puerto 1 para que esto sea posible, un ejemplo mas de interrupciones y vector de interrupcin.

CODIGO FUENTE
; Autor: Humberto Aparicio Osorio ; Fuente: http:/todomcu.scienceontheweb.net ; Enviar dudas a: humbert_frig@hotmail.com

; "Haz Tuyo El Conocimiento y Difndelo" #include #define midram 0240h #define time 60000 #define time1 55 main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio del programa ;-----------------------------------------------------------------------------RESET MOV #midram,SP ; Inicializacion del SP MOV #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado MOV.B MOV.B CLR.B MOV.B MOV.B BIS.B BIS.B BIC.B interrupcion BIS.B habilitadas MOV NOP habilitadas &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL &P1SEL #11110111B,&P1DIR #00001000B,&P1OUT #BIT3,&P1REN #BIT3,&P1IES #BIT3,&P1IFG #BIT3,&P1IE #GIE+CPUOFF,SR ; Calibracion del DCO ; ; ; ; ; ; P1 como E/S digital P1.3 como entrada Resistencia Pull-Up Resistencia habilitada Flanco de bajada Borrar la bandera de

; Interrupciones locales ; Modo de bajo consumo e ; interrupciones globales

;-----------------------------------------------------------------------------P1_ISR; Rutina de servicio a la interrupcion ;-----------------------------------------------------------------------------BIS.B #BIT0,&P1OUT ; Enciende el led CALL #RETARDO ; Retraso aproximado de 10 seg BIC.B #BIT0,&P1OUT ; Apaga el led BIC.B #BIT3,&P1IFG ; Borra la bandera de la interrupcion RETI ;-----------------------------------------------------------------------------; Sub-rutina de Retardo ;-----------------------------------------------------------------------------RETARDO MOV #time,R4 ; 60000 a R4 para loop interno MOV #time1,R5 ; 55 a R5 para loop externo INT DEC R4 ; R4-JNZ INT ; R4 es cero? DEC R5 ; R5-JNZ INT ; R5 es cero? RET ;------------------------------------------------------------------------------

; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector para el reset DW RESET ORG 0FFE4h ; Vector para la interrupcion del P1 DW P1_ISR END main

Practica 3.flv - VIDEO


http://www.youtube.com/watch?v=C26oWKynd54&feature=player_embedded

PRACTICA 4 - Secuencia de 8 leds


En este programa implementamos una secuencia en la cual si conectamos 8 leds en todo el puerto 1 entonces al oprimir un botn colocado en P2.7 entonces obtenemos una secuencia en la cual enciende el led conectado a P1.0, despus el conectado en P1.1 y as hasta que se encienda el led conectado en P1.7 y entonces se encender el P1.6 despus el P1.5 hasta llegar al P1.0. En este programa implementamos una secuencia en la cual si conectamos 8 leds en todo el puerto 1 entonces al oprimir un botn colocado en P2.7 entonces obtenemos una secuencia en la cual enciende el led conectado a P1.0, despus el conectado en P1.1 y as hasta que se encienda el led conectado en P1.7 y entonces se encender el P1.6 despus el P1.5 hasta llegar al P1.0.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo" "msp430x20x3.h"

#include

#define posc R4 /* Variable para almacenar la posicion*/ #define limizq 128 /* Constante para el limite a la izquierda*/ #define limder 1 /* Constante para el limite a la derecha*/ #define midram 0240h /* Constante para desirnar el lugar de la pila*/ #define time 40000 /* Constante para el retardo*/ main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash ;-----------------------------------------------------------------------------RESET mov.w #midram,SP ; Inicio del SP

mov.w mov.b mov.b clr.b bis.b clr.b clr.b mov.b bic.b bis.b habilitadas bis.b bic.b bis.b P1.7 mov interrupciones nop

#WDTPW+WDTHOLD,&WDTCTL &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL &P1SEL #0FFh,&P1DIR &P1OUT &P2SEL #01000000b,&P2DIR #BIT7,&P2OUT #BIT7,&P2REN #BIT7,&P2IES #BIT7,&P2IFG #BIT7,&P2IE #GIE+CPUOFF,SR

; WDT apagado ; Calibracion del ; oscilador a 1MHz ; P1 como i/o digital ; Todo P1 como salida ; P1 en estado bajo ; ; ; ; P2.7 como puerto digital P2.7 como entrada Resistencia PULL-DOWN P2.7 resistencias

; Flanco de bajada en P2.7 ; Limpiar bandera de int ; Int habilitadas en ; Modo de ahorro e ; globales habilitadas

;-----------------------------------------------------------------------------P2_ISR; Rutina de Servicio a la Interrupcion ;-----------------------------------------------------------------------------INICIO mov.b #limder,posc ; R4= 00000001 b IZQ mov.b posc,&P1OUT ; R4 a P1 rla.b posc ; Corrimiento <call #RETARDO ; Retardo cmp.b #limizq,posc ; Es 1000 0000 ? jne IZQ DER clrc rrc.b mov.b call cmp.b jne bic.b reti posc posc,&P1OUT #RETARDO #0h,posc DER #BIT7,&P2IFG ; Limpiar C ; Corrimiento -> ; Corrimiento a P1 ; Retardo ; Es 0000 0000 ? ; Borrar la bandera P2.7 ; Salir de la interrupcion

;-----------------------------------------------------------------------------; Subrrutina Retardo ;-----------------------------------------------------------------------------RETARDO mov #time,R5 ; Constante time a R5 CONT dec R5 ; R5 = R5-1 jnz CONT ; Es cero? RET ;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Reset

DW ORG DW END

RESET 0FFE6h P2_ISR main

; Etiqueta para Reset ; Vector para la int del P2 ; Etiqueta de la RSI

PRACTICA 5 - PWM de 10% en 10%


Con este programa realizamos el cambio de brillo de un led a travs de PWM, esto sin utilizar el Timer_A para comprobar que es posible su implementacin con conocimientos bsicos, esto no es muy recomendado ya que empleamos la CPU en todo momento cosa que no ocurre si utilizamos el Timer_A, esto seria absolutamente necesario si deseamos implementar mas de dos PWM que es el mximo que podemos generar con el Timer_A. Por lo pronto solo usamos rutinas de tiempo variables adems de que implementamos el concepto de tablas el cual es muy til para todo tipo de aplicaciones.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo"

#include #define midram 0240h #define time 60000 #define time1 55 #define CUENTA R14 #define AUX R15 main ;-----------------------------------------------------------------------------ORG 0F800h ; Programa Principal ;-----------------------------------------------------------------------------RESET MOV #midram,SP ; Inicializacion del SP MOV #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado MOV.B MOV.B CLR.B MOV.B como entradas MOV.B BIS.B BIS.B BIC.B interrupcin EINT habilitadas &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL &P1SEL #00000001b,&P1DIR #BIT3,&P1OUT #BIT3,&P1REN #BIT3,&P1IES #BIT3,&P1IFG ; Calibracion del DCO ;Puerto 1 como e/s digital ; P1.0 como salida, los demas ; ; ; ; P1.3 con resistencia PULL-UP Resistencia PULL-UP habilitada Flanco de subida Borrar la bandera de

; Interrupciones globales

ETQ0

BIT.B JNZ BIS.B

#BIT3,&P1IN ETQ0 #BIT3,&P1IE

; Esta presionado el Boton? ; Interrupcion local permitida

MOV #T1,R4 ; Direccion de la tabla 1 a R4 MOV #T2,R5 ; Direccion de la tabla 2 a R5 ETQ1 BIS.B #BIT0,&P1OUT ; Prende P1.0 CALL #SUB_TON ; Retraso segun tabla Ton BIC.B #BIT0,&P1OUT ; Apaga P1.0 CALL #SUB_TOFF ; Retraso segun tabla Toff CMP FIN,0(R4) ; Es el fin de la tabla? JNE ETQ1 JMP ETQ0 ;-----------------------------------------------------------------------------P1_ISR; Rutina de servicio a la interrupcion ;-----------------------------------------------------------------------------INCD R4 ; Incrementa direccion del apuntador1 INCD R5 ; Incrementa direccion del apuntador2 BIC.B #BIT3,&P1IFG ; Borra la bandera de la interrupcion RETI ;-----------------------------------------------------------------------------SUB_TON; S-Rutina Ton ;-----------------------------------------------------------------------------MOV @R4,AUX ; Elem x de la tabla1 en R_AUX ETQ3 DEC AUX ; AUX-JNZ ETQ3 ; AUX es cero? RET ;-----------------------------------------------------------------------------SUB_TOFF; S-Rutina Toff ;-----------------------------------------------------------------------------MOV @R5,AUX ; Elem x de la tabla2 en R_AUX ETQ4 DEC AUX ; AUX-JNZ ETQ4 ; AUX es cero? RET ;-----------------------------------------------------------------------------; Seccin de tablas ;-----------------------------------------------------------------------------T1 DC16 500,1000,1500,2000,2500,3000,3500,4000,4500 FIN DC16 0x00 T2 DC16 4500,4000,3500,3000,2500,2000,1500,1000,500 ;-----------------------------------------------------------------------------; Vectores de Interrupcin y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector para el reset

DW ORG del P1 DW END

RESET 0FFE4h P1_ISR main

; Vector para la interrupcion

Practica 5.flv - VIDEO


http://www.youtube.com/watch?v=6liYWg_x6tU&feature=player_embedded

PRACTICA 6 - Cuenta de display de 0 a 99


Este programa implementamos un circuito el cual puede realizar una cuenta de 0 a 99, esto lo mostramos en un display de 2 dgitos para lo cual utilizamos el multiplexaje de los displays, en realidad solo uno esta encendido a la vez, pero debido a la naturaleza de nuestro ojo humano es que podemos ver que los dos dgitos estn encendidos a la ves, con los 10 puertos que tenemos es posible ampliar el numero de dgitos a 4 con la misma tcnica, esto lo usaremos en programas posteriores para crear un sensor de temperatura.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo"

/* Descripcion: Despliega en un display de dos digitos una cuenta desde 1 hasta 99 al oprimir un boton situado en P1.7 */ #include #define midram 0240h /*Constante para el inicio de la RAM*/ #define ti1 100 /*Cte para el tiempo por caracter*/ #define ti2 700 /*Cte para el multiplexaje*/ #define APPT1_0 R4 /*Apuntador a la tabla1 unidades*/ #define APPT1_1 R5 /*Apuntador a la tabla1 decenas*/ #define UNID R6 /*Cuenta las unidades*/ #define DECN R7 /*Cuenta las decenas*/ #define TIME R14 /*Variable para el tiempo por digito*/ #define AUX R15 /*Registro auxiliar*/ main ;-----------------------------------------------------------------------------ORG 0F800h ;-----------------------------------------------------------------------------RESET MOV #midram,SP MOV #WDTPW+WDTHOLD,&WDTCTL MOV.B MOV.B &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL

CLR.B MOV.B salida MOV.B Up BIS.B BIS.B BIC.B interrupcion BIS.B CLR.B BIS.B MOV.B MOV habilitadas NOP

&P1SEL #01111111B,&P1DIR #10000000B,&P1OUT #BIT7,&P1REN #BIT7,&P1IES #BIT7,&P1IFG #BIT7,&P1IE &P2SEL #BIT6+BIT7,P2DIR #BIT6,&P2OUT #GIE+CPUOFF,SR

; Puerto1 como E/S digital ; P1.7 entrada otros bits como ; Apaga salidas y en P1.7 Pull; P1.7 resistencia habilatada ; Flanco de bajada para P1.7 ; Borrar bandera de la ; Interrupcion local permitida ; Puerto2 como E/S digital ; P2.6 y P2.7 como salidas ; P2.7 en bajo P2.6 en alto ; Interrupciones globales ; y modo de bajo consumo

;-----------------------------------------------------------------------------P1_ISR; Rutina de servivio a la interrupcion ;-----------------------------------------------------------------------------MOV #T1,APPT1_0 ; Mueve la direccion de T1 a R4 MOV #T1,APPT1_1 ; Mueve la direccion de T1 a R5 CLR UNID ; Unidades = 0 CLR DECN ; Decenas = 0 ETIQ2 ETIQ1 digitos MOV.B XOR.B CALL digitos DEC digito) JNZ INC INC CMP JNE CLR MOV INC INC CMP JNE MOV.B terminar ETIQ1 UNID APPT1_0 #10,UNID ETIQ2 UNID #T1,APPT1_0 DECN APPT1_1 #10,DECN ETIQ2 #10000000B,&P1OUT ; TIME es cero? ; Unidades = Unidades + 1 ; Direccion del apuntador0 + 1 ; Unidades es 9? ; Unidades = 0 ; Mueve la direccion de T1 a R4 ; Decenas = Decenas + 1 ; Direccion del apuntador1 + 1 ; Decenas es 9? ; Para apagar el display al TIME ; Decrementa TIME (Tiempo por @APPT1_1,&P1OUT #BIT6+BIT7,&P2OUT #RETARDO ; DATO->P1 ; Visualiza dato en posicion 1 ; Retardo para diferenciar los MOV MOV.B XOR.B CALL #ti1,TIME @APPT1_0,&P1OUT #BIT6+BIT7,&P2OUT #RETARDO ; TIME=100 ; DATO->P1 ; Visualiza dato en posicion 0 ; Retardo para diferenciar los

; y para que el ciclo siga correctamente BIC.B interrupcion RETI #BIT7,&P1IFG ; Limpia la bandera de

;-----------------------------------------------------------------------------RETARDO; Surrituna de retardo ;-----------------------------------------------------------------------------MOV #ti2,AUX ; AUX = 700 ETIQ3 DEC AUX ; AUX-JNZ ETIQ3 ; AUX es cero? RET ;-----------------------------------------------------------------------------T1; Tabla de 7 segmentos ;-----------------------------------------------------------------------------; 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 DC8 0BFh,86h,0DBh,0CFh,0E6h,0EDh,0FDh,87h,0FFh,0E7h ;-----------------------------------------------------------------------------; Vectores de interrupcion y reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ORG 0FFE4h ; Vector de interrupcion para P1 DW P1_ISR END main

Practica 6.flv - VIDEO


http://www.youtube.com/watch?v=Dcq6Gbyb9mY&feature=player_embedded

Timer_A

PRACTICA 1 - Encender un led por 10 segundos


Con este programa configuramos el Timer_A para que al oprimir un botn situado en P1.3 encienda un led conectado en P1.0 durante 10 segundos, despus de esto el led se apaga. Podemos ver que utilizamos el VLO de 12 KHz, existe un pequeo problema con este programa y es que al principio dura 10 segundos y despus dura 5, 7 , 8 segundos, es decir no se repite el tiempo del intervalo, estamos tratando de corregir este error que posiblemente se origina por el desborde del Timer_A, otra posible causa es la inestabilidad del oscilador ante los cambios de temperatura, para comprobar esto

debemos de revisar bien el datasheet del dispositivo y realizar mediciones, aunque lo mas probable es que sea un problema de software.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo" "msp430x20x3.h"

#include

#define midram 240h /* Lugar donde comenzara la PILA*/ main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Inicio del apuntador a la pila MOV.W MOV.B MOV.B MOV.B MOV.B 1.5KHz MOV.B como salida MOV.B los demas BIS.B BIS.B interrupcion CLR.B MOV.W NOP ;-----------------------------------------------------------------------------P1_ISR; Rutina de Servicio a la Interrupcion para P1 ;-----------------------------------------------------------------------------BIS.B #BIT0,&P1OUT ; Enciende el led MOV.W #CCIE,&CCTL0 ; Permite la interrupcion de TACCR0 MOV.W #15000,&CCR0 ; TACCR0=15,000 para obtener un periodo de 10s MOV.W #TASSEL_1+MC_1,&TACTL ; Alimentamos al timer con ; ACLK, en modo ascendente BIC.B #BIT3,&P1IFG ; Borramos la bandera de interrupcion ya que ; no se borra automaticamente como en RETI ; otros perifericos #11110111b,&P1DIR #BIT3,&P1OUT #BIT3,&P1IE #BIT3,&P1IES &P1IFG ; P1.3 como entrada los demas #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL #LFXT1S_2,&BCSCTL3 #DIVA_3,&BCSCTL1 ; Calibracion del ; oscilador a 1MHz ; VLO (12KHz) para ACLK ; Frecuencia de ACLK / 8 =

; Resistencia PULL-UP en P1.3 y apaga ; Habilita interrupcion para P1.3 ; Flanco descendente para la ; Borra bandera de interrupcion

#CPUOFF+GIE,SR ; Apaga CPU y permite las interrupciones ; de manera global

;-----------------------------------------------------------------------------TACCR0_ISR; Rutina de Servicio a la Interrupcion para WDT ;-----------------------------------------------------------------------------BIC.B #BIT0,&P1OUT BIC.W #TACLR+TAIFG,&TACTL ; Detiene el Timer_A RETI ;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ; Etiqueta para Reset (Inicio del programa) ORG 0FFF2h ; Vector para la interrupcion de TACCR0 CCIFG DW TACCR0_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion ORG 0FFE4h ; Vector para la interrupcion del Puerto 2 DW P1_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion END main

Timer_A Practica 1.flv - VIDEO


http://www.youtube.com/watch?v=Uc8I5NkLmHs&feature=player_embedded

PRACTICA 2 - Secuencia con corrimientos


Utilizando de nuevo el Timer_A podemos ver el concepto de corrimiento, pero en esta vez en el programa no utilizamos sub rutinas de tiempo si no que a travs de la interrupcin del puerto 2 configuramos el Timer_A para que funcione de manera ascendente y genere interrupciones cada segundo. La interrupcin que el Timer_A hace un corrimiento en un valor almacenado en R15 y despus de hacer esto el resultado lo refleja en el Puerto 1 que previamente ha sido configurado como salidas.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo" "msp430x20x3.h" midram 240h /* Lugar donde comenzara la PILA*/

#include #define main

;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Inicio del apuntador a la pila MOV.W MOV.B MOV.B MOV.B MOV.B 1.5KHz MOV.B CLR.B CLR.B MOV.B MOV.B P2.7 BIS.B BIS.B interrupcion CLR.B MOV.W NOP ;-----------------------------------------------------------------------------P2_ISR; Rutina de Servicio a la Interrupcion para P1 ;-----------------------------------------------------------------------------MOV.B #1,R15 ; Inicio de la secuencia BIS.B R15,&P1OUT ; Inicio de la secuencia en puerto 1 MOV.W #CCIE,&CCTL0 ; Permite la interrupcion de TACCR0 MOV.W #800,&CCR0 ; TACCR0=800 para obtener un periodo aprox de 1s MOV.W #TASSEL_1+MC_1,&TACTL ; Alimentamos al timer con ; ACLK, en modo ascendente BIC.B #BIT6,&P2IFG ; Borramos la bandera de interrupcion ya que ; no se borra automaticamente como en RETI ; otros perifericos ;-----------------------------------------------------------------------------TACCR0_ISR; Rutina de Servicio a la Interrupcion para WDT ;-----------------------------------------------------------------------------CMP.B #128,&P1OUT ; Es el fin de la secuencia? JNE NO ; Si es el fin: BIC.W #MC_0,&TACTL ; Detiene el Timer_A CLR.B &P1OUT ; Apaga las salidas de P1OUT BIC.W #TAIFG,&TACTL ; Borra la bandera de interrupcion RETI #BIT6,&P2IE #BIT6,&P2IES &P2IFG ; Habilita interrupcion para P2.6 ; Flanco descendente para la ; Borra bandera de interrupcion #0xFF,&P1DIR &P1OUT &P2SEL #BIT7,&P2DIR #BIT6,&P2OUT ; Todo P1 como salida ; Apagar las salidas en P1 ; P2 como E/S digital ; P2.7 como salida, P2.6 como entrada ; Resistencia PULL-UP en P2.6 y apaga #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL #LFXT1S_2,&BCSCTL3 #DIVA_3,&BCSCTL1 ; Calibracion del ; oscilador a 1MHz ; VLO (12KHz) para ACLK ; Frecuencia de ACLK / 8 =

#CPUOFF+GIE,SR ; Apaga CPU y permite las interrupciones ; de manera global

; No es el fin: NO RLA.B R15 MOV.B R15,&P1OUT BIC.W #TAIFG,&TACTL RETI

; Realiza corrimiento ; Refleja el corrimiento en la salida ; Borra la bandera de interrupcion

;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ; Etiqueta para Reset (Inicio del programa) ORG 0FFF2h ; Vector para la interrupcion de TACCR0 CCIFG DW TACCR0_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion ORG 0FFE6h ; Vector para la interrupcion del Puerto 2 DW P2_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion END main

Timer_A Practica 2.flv - VIDEO


http://www.youtube.com/watch?v=anseNiyW2kE&feature=player_embedded

PRACTICA 3 - Secuencia cualquiera con tablas


Haciendo uso del programa anterior modificamos nicamente la sub rutina de servicio a la interrupcin del Timer_A llamada TACCR0_ISR para que en lugar de hacer solo corrimientos haga una secuencia almacenada en una tabla, esta secuencia es la misma que en la practica del WDT solo que ahora esta implementada de una manera diferente.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo"

/* Descripcion: */ #include "msp430x20x3.h"

#define midram 240h /* Lugar donde comenzara la PILA*/ main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash

;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Inicio del apuntador a la pila MOV.W MOV.B MOV.B MOV.B MOV.B 1.5KHz MOV.B CLR.B CLR.B MOV.B MOV.B P2.7 BIS.B BIS.B interrupcion BIC.B MOV.W #BIT6,&P2IE #BIT6,&P2IES #BIT6,&P2IFG ; Habilita interrupcion para P2.6 ; Flanco descendente para la ; Borra bandera de interrupcion #0xFF,&P1DIR &P1OUT &P2SEL #BIT7,&P2DIR #BIT6,&P2OUT ; Todo P1 como salida ; Apagar las salidas en P1 ; P2 como E/S digital ; P2.7 como salida, P2.6 como entrada ; Resistencia PULL-UP en P2.6 y apaga #WDTPW+WDTHOLD,&WDTCTL ; WDT apagado &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL #LFXT1S_2,&BCSCTL3 #DIVA_3,&BCSCTL1 ; Calibracion del ; oscilador a 1MHz ; VLO (12KHz) para ACLK ; Frecuencia de ACLK / 8 =

#CPUOFF+GIE,SR ; Apaga CPU y permite las interrupciones ; de manera global

;-----------------------------------------------------------------------------P2_ISR; Rutina de Servicio a la Interrupcion para P1 ;-----------------------------------------------------------------------------MOV.W #TABLA1,R15 ; Inicia apuntador a la tabla MOV.W #CCIE,&CCTL0 ; Permite la interrupcion de TACCR0 MOV.W #800,&CCR0 ; TACCR0=800 para obtener un periodo aprox de 1s MOV.W #TASSEL_1+ID_1+MC_1,&TACTL ; Alimentamos al timer con ; ACLK / 2 = 750Hz, en modo ; ascendente BIC.B #BIT6,&P2IFG ; Borramos la bandera de interrupcion ya que ; no se borra automaticamente como en RETI ; otros perifericos ;-----------------------------------------------------------------------------TACCR0_ISR; Rutina de Servicio a la Interrupcion para WDT ;-----------------------------------------------------------------------------CMP.W FIN,0(R15) ; Es el fin de la tabla? JNE NO ; Si es el fin: BIC.W #MC_0,&TACTL ; Detiene el Timer_A CLR.B &P1OUT ; Apaga las salidas de P1OUT BIC.W #TAIFG,&TACTL ; Borra la bandera de interrupcion RETI ; No es el fin:

NO MOV.B @R15,&P1OUT apuntado por R15 INC R15 posicion BIC.W #TAIFG,&TACTL RETI

; Mueve el contenido de la tabla ; Desplaza el apuntador a la proxima ; Borra la bandera de interrupcion

;-----------------------------------------------------------------------------TABLA1; Definicion de la secuencia a seguir ;-----------------------------------------------------------------------------DC8 0,00011000b,00100100b,01000010b,10000001b,01000010b,00100100b DC8 00011000b,0 FIN DC8 0 ;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ; Etiqueta para Reset (Inicio del programa) ORG 0FFF2h ; Vector para la interrupcion de TACCR0 CCIFG DW TACCR0_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion ORG 0FFE6h ; Vector para la interrupcion del Puerto 2 DW P2_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion END main

Timer_A Practica 3.flv - VIDEO


http://www.youtube.com/watch?v=8fMfjEHk71I&feature=player_embedded

PRACTICA 4- PWM automatico con Time_A y WDT


En este programa realizamos el cambio de brillo de un led de manera automtica y a travs de la tcnica conocida como PWM, para ello hacemos uso de dos temporizadores, uno de ellos es el WDT en modo de intervalos el cual a travs de su rutina de servicio a la interrupcin podemos aumentar el brillo del LED conectado a P1.2 al modificar el valor almacenado en TACCR1. En el caso del Timer_A solo lo configuramos en el modo de salida numero 6 alimentado por ACLK en el modo de cuenta ascendente, as el valor en CCR0 define la frecuencia del pulso (100Hz para nuestro ejemplo) y CCR1 define el ciclo til por lo que al modificar CCR1 modificamos entonces el coclo til de nuestra seal de PWM.

Como conclusin de esta practica podemos notar que utilizando el modulo del Timer_A para generar seales de PWM es mucho mas fcil aplicarlo que con subrutinas de tiempo. En el video no se nota muy bien el cambio de luminosidad del led ya que este es muy sutil a diferencia de la practica de la seccin de puertos, as que te invitamos a que lo pruebes tu mismo.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo"

/* Descripcion: */ #include "msp430x20x3.h"

#define midram 240h /* Lugar donde comenzara la PILA*/ main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Inicio del apuntador a la pila MOV.W cada BIS.B permitida MOV.B MOV.B MOV.B BIS.B BIS.B MOV.W MOV.W MOV.W MOV.W MOV.W NOP ;-----------------------------------------------------------------------------WDT_ISR; Rutina de Servicio a la Interrupcion para WDT ;-----------------------------------------------------------------------------ADD.W #10,&TACCR1 reti #WDTIE,&IE1 ; 32768 ciclos del ACLK ; Interrupcion del modo intervalo ; Calibracion del ; oscilador a 1MHz ; VLO (12KHz) para ACLK #WDTPW+WDTTMSEL+WDTIS0+WDTSSEL,&WDTCTL ; Modo intervalo

&CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL #LFXT1S_2,&BCSCTL3 #BIT2,&P1DIR #BIT2,&P1SEL #120,&TACCR0 #OUTMOD_6,&CCTL1 #10,&TACCR1 #TASSEL_1+MC_1,&TACTL

#CPUOFF+GIE,SR ; Apaga CPU y permite las interrupciones ; de manera global

;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ; Etiqueta para Reset (Inicio del programa) ORG 0FFF4h ; Vector para la interrupcion del WDT DW WDT_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion END main

Timer_A Practica 4.flv - VIDEO


http://www.youtube.com/watch?v=P8KYCbHUA_M&feature=player_embedded

PERRO GUARDIAN

PRACTICA 1 - Conmutar un led cada 5s


En este programa aprendemos a utilizar el perro guardin como generador de interrupciones por intervalos, adems de eso configuramos el ACLK con una frecuencia provista internamente de 12KHz, con lo cual podemos ver como es que se utiliza tanto el ACLK como el WDT en este modo. El perro guardin interrumpe a la CPU aproximadamente cada 5 segundos, pudiendo ser el periodo mximo de interrupcin de casi 22 segundos, segn la configuracin seleccionada.

CODIGO FUENTE
; Autor: Humberto Aparicio Osorio ; Fuente: http:/todomcu.scienceontheweb.net ; Enviar dudas a: humbert_frig@hotmail.com ; "Haz Tuyo El Conocimiento y Difndelo" #include "msp430x20x3.h"

#define midram 240h /* Variable para almacenar la posicion*/ main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Inicio del SP MOV.B MOV.B #LFXT1S_2,&BCSCTL3 #DIVA_2,&BCSCTL1 ; ACLK= 12KHz ; Frecuencia de ACLK/2=6KHz

MOV.W cada BIS.B permitida BIS.B BIC.B MOV

#WDTPW+WDTTMSEL+WDTIS0+WDTSSEL,&WDTCTL ; Modo intervalo #WDTIE,&IE1 #BIT0,&P1DIR #BIT0,&P1OUT ; 32768 ciclos del ACLK ; Interrupcion del modo intervalo ; P1.0 como salida ; Apaga P1.0

#GIE+CPUOFF,SR ; Modo de ahorro e interrupciones ; globales habilitadas

;-----------------------------------------------------------------------------WDT_ISR; Rutina de Servicio a la Interrupcion para WDT ;-----------------------------------------------------------------------------XOR.B #BIT0,&P1OUT ; Conmuta el led reti ; Salir de la interrupcion ;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ; Etiqueta para Reset (Inicio del programa) ORG 0FFF4h ; Vector para la interrupcion del WDT DW WDT_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion END main

Perro guardin practica1.flv - VIDEO


http://www.youtube.com/watch?v=_iS9yjtRdqo&feature=player_embedded

PRACTICA 2 - La entrada digital numero 11


A travs de la configuracin del perro guardin, se puede generar un puerto digital exclusivamente de entrada el cual genera una interrupcin de casi mxima prioridad, esto lo podemos aplicar en el caso en donde los 10 puertos digitales de entrada y salida nos sean insuficientes y asignar as esta entrad a algn botn con el cual se inicie alguna accin (rutina de servicio a la interrupcin) importante. En el programa principal hacemos que un led conectado en P1.0 conmute indefinidamente y para probar que es una interrupcin no enmascarable, nunca modificamos el bit GIE en el registro de estado. Al oprimir el botn conectado al pin llamado RST/MNI/SBWTDIO se genera y atiende la interrupcin. La rutina de servicio a la interrupcin es un secuenciador de 8 canales con el cual atraves de apuntadores y tablas puede generar cualquier secuencia, en este caso la secuencia es la misma que en la practica 4 del capitulo de los puertos.

CODIGO FUENTE
; ; ; ; Autor: Humberto Aparicio Osorio Fuente: http:/todomcu.scienceontheweb.net Enviar dudas a: humbert_frig@hotmail.com "Haz Tuyo El Conocimiento y Difndelo" "msp430x20x3.h" midram 240h TIME 62500 /* Lugar donde comenzara la PILA*/ /* Cte para que la subrutina de tiempo

#include #define #define dure

aproximadamente 0.5 segundos*/ main ;-----------------------------------------------------------------------------ORG 0F800h ; Direccion de inicio el la flash ;-----------------------------------------------------------------------------RESET MOV.W #midram,SP ; Inicio del SP MOV.W #WDTPW+WDTHOLD+WDTNMI,&WDTCTL ; WDT apagado, Interrupcion no ; enmascarable activada en flanco ascendente MOV.B MOV.B MOV.B CLR.B BIS.B CICLO1 XOR.B CALL el cambio JMP &CALBC1_1MHZ,&BCSCTL1 &CALDCO_1MHZ,&DCOCTL #0XFF,&P1DIR &P1OUT #NMIIE,&IE1 #BIT0,&P1OUT #RETARDO CICLO1 ; Calibracion del ; oscilador a 1MHz

; Todo P1 como salida ; Los pines de P1 a estado bajo ; Permite la interrupcion localmente ; Conmuta a P1.0 ; Llama a retardo para que sea visible ; del led en un ciclo

;-----------------------------------------------------------------------------NMI_ISR; Rutina de Servicio a la Interrupcion para WDT ;-----------------------------------------------------------------------------MOV #TABLA1,R15 ; Crea un apuntador a la tabla CICLO INC R15 ; Incrementa en apuntador MOV.B @R15,&P1OUT ; Mueve el contenido de la tabla a P1OUT CALL #RETARDO ; Llama a retardo para poder visualizar CMP.W FIN,0(R15) ; Es el fin de la tabla? JNZ CICLO ; Si lo es continua, si no salta a ciclo BIC.B NMIIFG BIS.B RETI ;-----------------------------------------------------------------------------RETARDO; Rutina de Retardo #NMIIE,&IE1 ; Permite de nuevo la interrupcion #NMIIFG,&IFG1 ; Borra la bandera de interrupcion

;-----------------------------------------------------------------------------MOV #TIME,R14 ; TIME se carga en R14 para durar 0.5 s ETIQ3 NOP ; consume 2 ciclos de reloj NOP ; consume 2 ciclos de reloj mas DEC R14 ; Decrementa R14 JNZ ETIQ3 ; R14 es cero? RET ;-----------------------------------------------------------------------------TABLA1; Definicion de la secuencia a seguir ;-----------------------------------------------------------------------------DC8 1,2,4,8,16,32,64,128,1 FIN DC8 0 ;-----------------------------------------------------------------------------; Vectores de Interrupcion y Reset ;-----------------------------------------------------------------------------ORG 0FFFEh ; Vector de reset DW RESET ; Etiqueta para Reset (Inicio del programa) ORG 0FFFCh ; Vector para la interrupcion no enmascarable DW NMI_ISR ; Etiqueta de la rutina de servicio a la ; interrupcion END main

Perro guardian practica 2 version 1.flv - VIDEO


http://www.youtube.com/watch?v=dHRljmrKPDg&feature=player_embedded

La secuencia mostrada en el video se genera a traves del programa anterior, veremos que con una leve modificacin podemos generar cualquier secuencia en los 8 bits del puerto 1. Esta secuencia es diferente a la anterior, a conrinuacion mostramos el cambio que debes de efectuar en el programa anterior para obtener esta secuencia. Cambiar esto:
;-----------------------------------------------------------------------------TABLA1; Definicion de la secuencia a seguir ;-----------------------------------------------------------------------------DC8 1,2,4,8,16,32,64,128,1 FIN DC8 0

Por esto:

;-----------------------------------------------------------------------------TABLA1; Definicion de la secuencia a seguir ;-----------------------------------------------------------------------------DC8 0,00011000b,00100100b,01000010b,10000001b,01000010b,00100100b DC8 00011000b,0 FIN DC8 0

Perro guardian practica 2 versin 2.flv - VIDEO


http://www.youtube.com/watch?v=2GBLklHs95o&feature=player_embedded

En este caso introducimos los datos de forma binaria y no en hexadecimal lo cual es mas flexible, para cambiar las secuencias lo que resta es modificar estos valores, hasta que la memoria lo permita. En cada nuevo renglon es pertiente agregar DC8 al inicio como en este caso. Esto es util por ejemplo para guardar los valores de la funcion seno o cualquier otra funcin y los 8 bits concetarlos a un convertidor digital analogico para asi obtener un generador de funciones de bajo costo.

Vous aimerez peut-être aussi