Tutorial básico MSP430G2553

55
Tutorial MSP430 – Prender un Led “Bienvenido a mi casa. Venga libremente, váyase a salvo, y deje algo de la alegría que trae consigo” Dracula, de Bram Stoker Vamos a trabajar con el microcontrolador MSP430F2011, debido a que tiene sólo 14 pines, de los cuales podemos utilizar 10 pines como I/O, 2KB de memoria de programa (Flash Memory) y 12MB de memoria de datos (RAM). Naturalmente si en algún momento nos queda chico este micro migraremos a otro con mayor recursos. En esta direccion de la empresa Texas Instruments se encuentran dos archivos que necesitamos tener a nuestro lado como material de consulta absoluto: 1. Datasheet del MSP430F2011 2. Guia de Usuario de la Familia MSP430X2XX Como podemos ver en la imagen, vamos a realizar un código que active un nivel high en el pin 2 del MSP430F2011.

description

Tutorial con ejemplos demostrativos de microcontrolador MSP430

Transcript of Tutorial básico MSP430G2553

Page 1: Tutorial básico MSP430G2553

Tutorial MSP430 – Prender un Led

“Bienvenido a mi casa. Venga libremente, váyase a salvo, y deje algo de la alegría que trae

consigo”

Dracula, de Bram Stoker

Vamos a trabajar con el microcontrolador MSP430F2011, debido a que tiene sólo 14 pines, de los

cuales podemos utilizar 10 pines como I/O, 2KB de memoria de programa (Flash Memory) y 12MB

de memoria de datos (RAM). Naturalmente si en algún momento nos queda chico este micro

migraremos a otro con mayor recursos.

En esta direccion de la empresa Texas Instruments  se encuentran dos archivos que necesitamos

tener a nuestro lado como material de consulta absoluto:

1. Datasheet del MSP430F2011

2. Guia de Usuario de la Familia MSP430X2XX

Como podemos ver en la imagen, vamos a realizar un código que active un nivel high en el pin 2

del MSP430F2011.

Page 2: Tutorial básico MSP430G2553

El código que realizará esta tarea se muestra a continuación:

123456789101112131415161718

#include "io430.h"//libreria del propio IDE //#define LED1 P1OUT_bit.P1OUT_0//definicion del pin LED#define LED1 P1OUT_bit.P0//definicion del pin LED

 int main( void ) //funcion principal{  // Stop watchdog timer to prevent time out reset  WDTCTL = WDTPW + WDTHOLD;

   //CAPD = 0x00;//Habilitamos el output driver de todos los pines del puerto 1.  P1SEL = 0x00;//Seteamos la funcion de I/O en todos los pines del puerto 1.  P1DIR = 0xFF;//Seteamos todos los pines del puerto 1 como salida.

   LED1 = 1;//nivel high en el pin LED

   while(1);//bucle infinito}

Como pueden notar se trata de un lenguaje C que respeta el formato del ANSI C, practicamente no

hemos tocado aún varios aspectos como el oscilador, modo de arranques, etc. Estos temas los

iremos vislumbrando conforme avance el curso.

Pero por ahora toca entender que significan estos 3 registros: CAPD, P1SEL, P1DIR, y que

significa el label LED1.

Page 3: Tutorial básico MSP430G2553

CAPD, P1SEL, P1DIR se necesitan configurar de la siguiente manera para poder utilizar el pin 2

que corresponde con el P1.0, como output:

Observen que para que el pin P1.0 se comporte como un pin de salida (o de entrada) necesita que

el bit 0 del registro P1DIR sea cero, debido a que ese registro define el comportamiento de entrada

o salida del pin, donde un “1 ” significa “salida” y un “0″ es “entrada” (contrario a como trabajan los

PICs por ejemplo).

Así mismo el bit 0 de P1SEL tiene que ser cero, pues esto le indica al pin que se comporte como

un pin I/O, otro valor configuraría al pin para que trabaje con algun periférico que tiene

multiplexado. En otro proyecto usaremos esta configuración.

Y el bit 0 del registro CAPD también tiene que ser seteado a cero, para que habilite los buffers de

entrada/salida del pin. Este registro tiene mayor relevancia cuando se usa el pin P1.0 en el modo

comparador.

Page 4: Tutorial básico MSP430G2553

Después de todo esto ya tenemos el pin P1.0 configurado como salida (en el código lo hemos

aplicado a todos los pines del puerto 1), entonces creamos el label LED1 que referencia al bit 0 del

registro P1OUT (quien controla los pines de salida del puerto 1).

#define LED1 P1OUT_bit.P1OUT_0, donde:

P1OUT_bit = registro P1OUT

P1OUT_0 = bit 0 del registro P1OUT

Finalmente un video para que la visita sea más didáctica:

Tutorial MSP430 – Prender y Apagar un Led“Bienvenido a mi casa. Venga libremente, váyase a salvo, y deje algo de la alegría que trae

consigo”

Dracula, de Bram Stoker

En esta nueva entrada vamos a estudiar un programa en el cual haremos prender y apagar

(parpadear) un led con un determinado retardo. El programa aparenta ser simple y sencillo, sin

embargo la pondremos dificil porque hasta ahora no sabemos a que frecuencia estamos trabajando

con el MSP430F2011, es más, ni siquiera sabemos si estamos usando un oscilador externo o

interno, no hemos mencionado nada del sistema oscilador del microcontrolador en cuestión.

No es cuestión de poner un delay y ver como parpadea, se trata de entender como trabaja todo el

sistema, al inicio puede parecer complejo explorar como funciona la oscilacion del MSP430F2011,

pero veremos que ordenando la información y con algunos gráficos, todo se vuelve fácil de

comprender.

El Basic Clock System

Page 5: Tutorial básico MSP430G2553

La frecuencia de oscilación del MSP430F2011 (y de todos los MSP430xxx) depende de lo que se

conoce como el Basic Clock System, el cual si miran en el gráfico siguiente, se puede observar que

está constituido por 5 elementos globales:

1. Clock Sources

2. Clock Signals

3. Modos de Operacion

4. Registros para configurar Clock Sources y Clock Signals

5. Registros para configurar el Modo de Operacion

Parece mucha información, lo és!, pero ya dice el sabio refrán: “divide y vencerás”, por eso anticipo

que en esta entrada no exploraremos los puntos 3 y 5, simplemente lo dejaremos con su

configuración por defecto que es “Active Mode (AM)”, es decir no tocaremos sus registros de

configuración. La aplicación o utilidad de los puntos 3 y 5 se ve reflejado en el tema de ahorro de

consumo de energía, las diferentes configuraciones de low power mode permiten tener varios

consumos en el orden de micro amperios, según sea la necesidad de la aplicación.

Clock Sources y Clock Signals

Page 6: Tutorial básico MSP430G2553

“Y Odin creo primero los clock sources y después aparecieron los clock signals“. Igual tenemos que

hacer nosotros, primero debemos configurar los clock sources y después aparecieron los clock

signals. Porque? Por el siguiente gráfico, una imagen habla más que 1000 palabras:

El gráfico fue extraido del family users guide que les sugerí descargar en el primer post del tutorial,

el esquema representa los bloques de trabajo del Basic Clock System para el MSP430F2xxx,

observen además que he colocado unos apuntes de “no está implementado” para que sepan que

etapas no están implementadas en el MSP430F2011. Además podrán apreciar de izquierda a

derecha que los Clock Sources (VLOCLK, LFXT1CLK, DCOCLK) se concentran en un punto para

Page 7: Tutorial básico MSP430G2553

dar lugar a los Clock Signals (ACLK, MCLK, SMCLK). Tenemos que seleccionar de que fuente

(VLOCLK, LFXT1CLK, DCOCLK) provienen las señales de oscilación del sistema (ACLK, MCLK,

SMCLK).

Clock Sources

Entonces, los entendemos como la fuente de oscilación para las señales de reloj (Clock Signals)

del sistema, y tenemos que seleccionar sólo una de ellas, pero podemos cambiar entre una y otra

en el tiempo de ejecución del programa del microcontrolador:

• LFXT1CLK: Low-frequency/high-frequency oscillator that can be used with low-frequency “watch

crystals” or “external clock sources” of 32768 Hz or with standard crystals, resonators, or “external

clock sources” in the 400-kHz to 16-MHz range. En el caso del MSP430F2011 el LFXT1CLK solo

soporta bajas frecuencias en el rango de 10KHz hasta 50KHz.

• DCOCLK: “Internal” digitally controlled oscillator (DCO). Es un oscilador interno con un gran rango

de configuración de trabajo de hasta 16MHz.

• VLOCLK: Internal very low power, low frequency oscillator with 12kHz typical frequency. Es un

oscilador interno de solo 12KHz, utilizado para bajo consumo del sistema.

En esta entrada vamos a trabajar con el oscilador interno DCOCLK, por ello los demás clock

sources no serán analizados por el momento, ya tendrán su respectivo post.

DCOCLK: “Internal” digitally controlled oscillator (DCO)

Este oscilador interno es muy versátil, tiene un gran rango de trabajo que va desde 0.06MHz hasta

16MHz, en distintos niveles o pasos. El siguiente gráfico lo explicará todo:

Page 8: Tutorial básico MSP430G2553

El gráfico de arriba nos muestra en el eje horizontal los 8 (del 0 al 7) valores para el grupo de bits

DCO (son 3 bits) que se encuentran en el registro DCOCTL, y en el eje vertical los valores (en

realidad son 16 valores, del 0 al 15) del grupo de bits RSEL que se encuentran en el registro

BCSCTL1. Fijense el escalon que tiene por ejemplo RSEL = 0 para cada valor de DCO, a la

izquierda en el eje vertical podemos apreciar la frecuencia “aproximada” que conseguimos en

alguna de las configuraciones.

Page 9: Tutorial básico MSP430G2553

A esto me refería cuando les decía que tenemos un oscilador muy versátil para trabajar, ahora la

pregunta es y cómo saber la frecuencia aproximada que estaremos configurando al utlizalos los

bits DOC y RESL? Existen 2 caminos, utilizar los valores por defecto que ofrece el datasheet del

MSP430F2011 o averiguar por tu cuenta un valor de frecuencia experimental con que desees

trabajar.

En la siguiente tabla extraída del datasheet del MSP430F2011 están los valores que debemos

cargar alos registros BCSCTL1 (CALBC1_xMHZ) y DCOCTL (CALDCO_xMHZ) para obtener las

correspondientes frecuencias:

Como mencioné antes, existen otros valores de frecuencia para el DCO que no están en esta tabla,

sin embargo no son tema de esta entrada, tendrán su propio post y aplicación didáctica. Para este

proyecto utilizaremos la configuracion de 1MHz.

Page 10: Tutorial básico MSP430G2553

Clock Signals

Son 3 salidas para el source que seleccionemos, donde cada clock signal tiene su propia

configuración y aplicación:

• ACLK: Auxiliary clock (ACLK), sourced either from a 32768-Hz watch crystal or the internal LF

oscillator. Puede ser utilizado con los clock source: LFXT1CLK, VLOCLK. El source para esta señal

dependera de la configuracion de los bits LFXT1S (2 bits) del registro BCSCTL3 y del bit XTS (1

bit) del registro BCSCTL1.

• MCLK: Main clock (MCLK), the system clock used by the CPU. Puede utilizar todos los source

disponibles. Por defecto despues de un reset del chip siempre selecciona iniciar con el source

DCOCLK. Por código podemos cambiarlo a otro source si lo requerimos y se realiza esto con los

bits SELM (2 bits) que están en el registro BCSCTL2. Así mismo tiene un divisor de frecuencias en

los bits del DIVM (2 bits) también en el registro BCSCTL2.

• SMCLK:Sub-Main clock (SMCLK), the sub-system clock used by the peripheral modules. Puede

utilizar todos los source disponibles. Para seleccionar el source se utiliza los bits SELS (2 bits) que

están en el registro BCSCTL2 y un divisor de frecuencias en los bits del DIVS (2 bits) en el mismo

registro.

Page 11: Tutorial básico MSP430G2553
Page 12: Tutorial básico MSP430G2553

En este programa utlizaremos el DCO a 1MHz junto con el MCLK con divisor valor 1, así que hay

muy poco que manipular.

Programa de aplicacion

12345678910

#include "io430.h"//libreria del propio IDE#include "intrinsics.h" //#define LED1 P1OUT_bit.P1OUT_0//definicion del pin LED#define LED1 P1OUT_bit.P0//definicion del pin LED

 int main( void ) //funcion principal{  // Stop watchdog timer to prevent time out reset  WDTCTL = WDTPW + WDTHOLD;

   BCSCTL1 = CALBC1_8MHZ;// Use 1Mhz cal data for DCO

Page 13: Tutorial básico MSP430G2553

111213141516171819202122232425262728

  DCOCTL = CALDCO_8MHZ;// Use 1Mhz cal data for DCO

   CAPD = 0x00;//Habilitamos el output driver de todos los pines del puerto 1.  P1SEL = 0x00;//Seteamos la funcion de I/O en todos los pines del puerto 1.  P1DIR = 0xFF;//Seteamos todos los pines del puerto 1 como salida.

   LED1 = 0;//nivel low en el pin LED

   while(1)//bucle infinito  {    LED1 = 1;    __delay_cycles(160000);//500 milisegundos    LED1 = 0;    __delay_cycles(160000);//500 milisegundos      }}

Video

Todos los archivos los pueden encontrar en: 4shared, boxnet .

Estos nuevos enlaces estan compilador con la versión del software IAR 5.40 :

Tutorial MSP430 – Barra de Leds – Maskable Interrupts for Input Port“Bienvenido a mi casa. Venga libremente, váyase a salvo, y deje algo de la alegría que trae

consigo”

Dracula, de Bram Stoker

Vamos a realizar un proyecto en el cual con un boton (normalmente en bajo nivel) iremos

desplazando la activación de un led en la salida de un 74xx138 según un contador interno en el

MSP430. En este sencillo ejemplo aprenderemos a utilizar los pines del MSP430 como entradas

lógicas y también a configurar sus respectivas interrupciones de cambio de estado por flanco de

entrada.

Page 14: Tutorial básico MSP430G2553

Interrupciones en el MSP430

Así como en otros microcontroladores, el MSP430 también viene provisto de interrupciones por

hardware que permiten realizar diversas aplicaciones según la caraterística de la interrupción que

utilizemos. Podemos usar las interrupciones por ejemplo para los siguientes casos:

• Tareas urgentes que deben ser atendidas inmediatamente y con mayor prioridad que el código

principal.

• Tareas de poca frecuencia, como el manejo de pulsadores en un humano. Esto nos libera de

realizar un código con polling (bucle para evaluar constantemente en el orden de microsegundos

una entrada lógica).

• Despertar el CPU del modo Sleep. Esto es muy importante en el MSP430, ya que por lo general

se lo utiliza la mayor parte del tiempo en modo de bajo consumo (low-power mode) y puede volver

al modo activo (AM mode) con una interrupción.

Tipos de Interrupciones

En el MSP430 tenemos 3 tipos de interrupciones, éstas son:

Page 15: Tutorial básico MSP430G2553

Si revisamos el datasheet del MSP430F2011, en la pagina 13, está plasmada una tabla con todas

las interrupciones que soporta el microcontrolador (en realidad ese datasheet es para las series

MSP430F20x3/2/1):

Page 16: Tutorial básico MSP430G2553

Debemos observar en esta tabla que existen 32 posiciones de memoria (0-lowest … 31-highest) o

también llamados “vectores” reservados para almacenar la dirección de los ISR correspondientes a

la interrupción que los define (también conocidos como los “interrupt handler”). Como pueden

apreciar en dicha tabla están plasmados los 3 tipos de interrupciones del MSP430F2011,

separados por tipo y en orden descendente, donde dicho orden indica así mismo el rango de

prioridad de las interrupciones, es decir la interrupcion con prioridad 31 en la posicion de memoria

0xFFFEh correspondiente con el System Reset tiene la prioridad más alta de toda la tabla.

Y cómo sabemos cuales son las interrupciones que maneja exactamente el MSP430F2011? Pues

basta darle un vistazo al archivo “io430x20x1.h” que está en los programas que hacemos con el

IAR cuando seleccionamos el MSP430F2011, y buscan lo siguiente:

Page 17: Tutorial básico MSP430G2553

Para escribir el “interrupt handler” de la interrupción que queremos gestionar, necesitamos saber el

nombre del vector de la interrupción que tiene en el microcontrolador que estamos programando

(siempre y cuando sea desde el IAR), para eso sirven esos #defines.

En esta entrada sólo abarcaremos el estudio de las interrupciones enmascarables (MASKABLE

INTERRUPTS) , para los demás tipos prepararemos otras entradas ya que tienen su propio campo

de aplicación.

Maskable Interrupts for Input Port

Las interrupciones enmascarables (MASKABLE INTERRUPTS) tienen la propiedad de activarse

individualmente y también como en una capa superior se pueden activar colectivamente. Esto es,

despues de configurar el pin de entrada P2.7 para que genere una interrupcion en cada flanco de

subida, debemos utilizar la función intrinseca: “__enable_interrupt“, la cual setea a nivel global la

activación de todas las interrupciones enmascarables del MSP430. Sino la utlizamos ninguna de

las interrupciones enmascarables previamente y correctamente configuradas funcionarán. Siempre

se pone la linea “__enable_interrupt” al final de la configuración de todas las interrupciones

enmascarables. Para tener la función “__enable_interrupt” disponible necesitamos colocar en la

cabecera la inclusión: #include “intrinsics.h”.

Luego requerimos escribir el “interupt handler” o ISR, que es el lugar donde haremos el tratamiento

de la interrupción. En C para el IAR, existe un formato para escribir el “interrupt handler” o ISR de

la interrupción que queremos utilizar. El formato es el siguiente:

Page 18: Tutorial básico MSP430G2553

A continuación explicaremos los campos resaltados:

#pragma vector: esta directiva es usada para especificar la dirección del vector de interrupción

que se escriba en el campo <VECTOR_NAME>.

<VECTOR_NAME>: aquí escribimos el nombre del vector de la interrupción que deseamos utilizar,

el nombre lo obtenemos del archivo cabecera del micro que usemos, por ejemplo en esta entrada

usaremos una interrupción en el pin P2.7, por lo tanto el vector name será “PORT2_VECTOR”.

__interrupt: es usado para indicar al compilador que haga la llamada convencional que necesita

una función de tipo interrupción.

<ISR_NAME>: es simplemente el nombre del “interrupt handler”, es decir puede ser cualquier

nombre que prefiera el programador. En nuestro caso le he puesto de ISR_NAME el literal

“InterrupcionPuerto2″.

Dentro del “interrupt handler” escribimos el código que gestionará las acciones conjunto que

realizará la interrupción del hardware especificado. Finalmente NUNCA olvidar de borrar el flag de

la interrupción invocada.

Interrupcion de Cambio de Estado en el Pin de Entrada P2.7

Para configurar la interrupcion en el pin P2.7 necesitamos manipular los siguientes registros:

Page 19: Tutorial básico MSP430G2553

De la imagen entendemos que debemos configurar el bit 7 del registro P2DIR con valor 0 para

indicar “entrada”, luego el bit 7 del registro P2SEL con valor 0 para indicar funcion de I/O

(entrada/salida).

También debemos utlizar el bit 7 del registro P2REN, para especificar si el pin P2.7 tendrá una

resistencia de pullup (3.3V con el pin al aire) o pulldown (0V con el pin al aire) conectada a su

entrada. Esto por lo general se utiliza con pulsadores normalmente abiertos o cerrados.

Así mismo hacemos con el bit 7 del registro P2IES, que permite especificar el flanco de disparo de

la interrupción en el pin P2.7. Podemos seleccionar entre una transición de bajada a subida o

viceversa. En nuestro caso tenemos una señal normalmente en bajo nivel, por ello elegimos la

transición de bajada a subida.

A continuación habilitamos la interrupción del pin P2.7 escribiendo un 1 en el bit 7 del registro P2IE.

Luego borramos el flag de interrupcion en el bit 7 del registro P2IFG para evitar sorpresas

inesperadas. Recordar borrar este flag antes de salir del “interrupt hanlder” o ISR.

Page 20: Tutorial básico MSP430G2553

Finalmente agregaremos la linea de comando “__enable_interrupt();” para activar de forma global

todas las interrupciones enmascarables previamente configuradas, como és el caso del pin P2.7.

Programa de Aplicación:12345678910111213141516171819202122232425

#include "io430.h"//libreria del propio IDE#include "intrinsics.h" #define OUT_A P1OUT_bit.P1OUT_1//definicion del pin LED#define OUT_B P1OUT_bit.P1OUT_2//definicion del pin LED#define OUT_C P1OUT_bit.P1OUT_3//definicion del pin LED

 unsigned char aux;

 int main( void ) //funcion principal{     // Stop watchdog timer to prevent time out reset  WDTCTL = WDTPW + WDTHOLD;

   BCSCTL1 = CALBC1_1MHZ;// Use 1Mhz cal data for DCO  DCOCTL = CALDCO_1MHZ;// Use 1Mhz cal data for DCO

   CAPD = 0x00;//Habilitamos el output driver de todos los pines del puerto 1.  P1SEL = 0x00;//Seteamos la funcion de I/O en todos los pines del puerto 1.  P1DIR = 0xFF;//Seteamos todos los pines del puerto 1 como salida.  P1OUT = 0x00;  P1DIR_bit.P1DIR_7 = 0;//pin de entrada

   //Configuramos pin P2.6 y P2.7 como entradas logicas.  P2DIR_bit.P2DIR_6 = 0;//logic input   P2SEL_bit.P2SEL_6 = 0;//input/output function  P2DIR_bit.P2DIR_7 = 0;//logic input

Page 21: Tutorial básico MSP430G2553

26272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071

  P2SEL_bit.P2SEL_7 = 0;//input/output function

   //Primera capa de activacion de interrupcion  //Configuramos la interrupción en el pin P2.7  P2REN_bit.P2REN_7 = 0;//deshabilitamos la resistencia pullup/pulldown.  P2IES_bit.P2IES_7 = 0;//interrupcion en pulso de subida (low to high).  P2IE_bit.P2IE_7 = 1;//habilitamos la interrupcion del pin P2.7  P2IFG_bit.P2IFG_7 = 0;//limpiamos la bandera de interrupcion del pin P2.7

   //Segunda capa de activacion de interrupcion  __enable_interrupt();

   aux = 7;  while(1)//bucle infinito  {

   }}

 #pragma vector = PORT2_VECTOR__interrupt void InterrupcionPuerto2(void){     OUT_A = 0;      OUT_B = 0;      OUT_C = 0; 

     if((aux & 0x01) == 0x01){      OUT_A = 1;    }    if((aux & 0x02) == 0x02){      OUT_B = 1;    }    if((aux & 0x04) == 0x04){      OUT_C = 1;    }

     if(aux >= 7){      aux = 0;    }else{      aux++;    }

     P2IFG_bit.P2IFG_7 = 0;//Borro el flag de interrupcion.    }

Page 22: Tutorial básico MSP430G2553

Timer

En esta nueva entrada estudiaremos el comportamiento, configuraciones, y registros que

constituyen el Timer Block del Timer_A que posee el microcontrolador MSP430F2132. En efecto

hemos dejado atrás el MSP430F2011 y hemos cambiado al MSP430F2132 debido a su mayor

cantidad de memoria y pines. Verán que no será nada complicado navegar por este nuevo micro.

Además implementaremos en el proteus una aplicación para probar todas las configuraciones del

Timer Block.

Timer_A

Es en esencia un timer/counter de 16 bits, con registros de control y captura/comparación que en

conjunto proporcionan muchas configuraciones que servirán para alcanzar los objetivos de nuestra

aplicación. Está constituido por dos partes principales:

Timer Block (gobernado por un solo registro).

Canales de Captura/Comparación (conformado por varios registros).

Page 23: Tutorial básico MSP430G2553

Debemos mencionar que en los MSP430 pueden haber más de un modulo Timer_A, por ello para

diferenciarlos se suelen enunciar colocando el índice del módulo después de la palabra Timer y al

final la cantidad de canales que tiene implementado en dicho micro. Por ejemplo en el

MSP430F2132 tenemos dos modulo de Timer_A:

Timer0_A3: módulo Timer_A con índice 0 y con 3 canales Capture/Compare

(TA0CCR0,TA0CCR1,TA0CCR2).

Timer1_A2: módulo Timer_A con índice 1 y con 2 canales Capture/Compare

(TA1CCR0,TA1CCR1).

Ambos módulos al ser Timer_A funcionan de la misma manera, por ello en los ejemplos

trabajaremos solamente con el Timer0_A3, migrar los ejemplos al otro timer será cosa de modificar

tan sólo el índice en el nombre de los registros.

Page 24: Tutorial básico MSP430G2553

Veamos a continuación todos los registros del Timer0_A3 (sombreados en amarillo los registros

asociados del Timer Block del Timer0_A3):

En esta entrada nos enfocaremos en el estudio del Timer Block del Timer0_A3, la otra parte

principal la dejaremos para la segunda parte del estudio del Timer_A.

Timer Block del Timer0_A3

El Timer Block del Timer0_A3 está gobernado por un registro de control llamado TA0CTL el cual se

apoya en un registro timer/counter de 16 bits llamado TA0R cuyo comportamiento se puede

configurar. Se puede seleccionar la fuente del reloj y un prescaler. El Timer Block no tiene salida

directa por algun pin sin embargo genera interrupción con la bandera TAIFG cuando su contador

TA0R regresa a cero  siempre que se habilite su interrupción con el bit TAIE. Así mismo existe un

modo de operación donde se genera interrupcion cuando el valor del registro contador TA0R sea

igual al valor escrito en el registro TA0CCR0.

Page 25: Tutorial básico MSP430G2553

Si analizamos el diagrama de bloques del Timer Block empezando por la izquierda, tenemos los

clock source de donde se selecciona uno mediante los bits TASSEL (bits 9-8 del registro TA0CTL):

TACLK (0) :  señal de reloj proveniente de un pin externo, en el MSP430F2132 se ubica en el pin

P1.0.

ACLK (1) : señal de reloj previamente configurada del Basic Clock System en el MSP430F2132.

SMCLK (2) : señal de reloj previamente configurada del Basic Clock System en el MSP430F2132.

INCLK (3) : señal de reloj proveniente del pin P2.1 (TAINCLK) que permite incrementar con flanco

de bajada al registro TA0R, para los demás clock source siempre se incrementará con flanco de

subida.

A continuación nos encontramos con el bloque Input Divider o Divisor de Entrada, cuyos

valores /1,/2,/4,/8se seleccionan mediante los bits ID (bits 7-6 del registro TA0CTL), el cual dividirá

la frecuencia que nos proporcione el bloque clock source entre el valor seleccionado.

Luego aparece el registro timer de 16 bits llamado TAR. En el MSP430F2132 este registro se

llamaTA0R.

Después nos encontramos con el bloque que configura el comportamiento del registro TA0R, nos

referimos a los bits MC (bits 5-4 del registro TA0CTL) y sus opciones son las siguientes:

Stop Mode (0) : se detiene el movimiento del timer TA0R.

Up Mode (1) : el timer TA0R se incrementa hasta alcanzar el valor en el registro TA0CCR0 y luego

se reinicia desde cero.

Continuous Mode (2) : el timer TA0R se incrementa hasta ser igual a 0xFFFF y luego se reinicia

desde cero.

Up/Down Mode (3) : el timer TA0R se incrementa hasta alcanzar el valor en el registro TA0CCR0 y

luego se decrementa hasta el valor 0×0000.

Finalmente tenemos el bit TACLR (bit 2 del registro TA0CTL) el cual resetea el valor del divisor de

reloj (ID bits) y el valor del contador TA0R.

Page 26: Tutorial básico MSP430G2553

Las señales de interrupción del Timer Block (TAIE, TAIFG) del MSP430F2132 las describiremos a

continuación.

Interrupcion del Timer Block en el Timer0_A3

Las interrupciones del Timer0_A3 son otro tema, pues en la tabla de vectores de todas las

interrupciones enmascarables tiene reservado dos vectores, el #24 y el #25. El vector #24

responde a 3 banderas de interrupcion: TA0CCR1 CCIFG, TA0CCR2 CCIFG y TA0CTL TAIFG. El

vector #25 solamente refiere a la bandera TA0CCR0 CCIFG.

Page 27: Tutorial básico MSP430G2553

Para esta primera parte, vamos a enfocarnos solamente en el flag TAIFG de la interrupcion

Timer0_A3 (vector 24).

Ahora nos surge una pregunta, cómo identificamos en el vector #24 a la bandera TAIFG? Sucede

que existe un registro llamado TA0IV cuyo valor permite conocer cual de las 3 interrupciones se ha

producido.

TA0IV significa: Timer0_A3 Interrupt Vector Value, y tiene la propiedad de que por ejemplo cuando

se produce la interrupción del TAIFG (que és cuando existe un desborde del timer TA0R) se carga

en dicho registro el valor 0x0A, es decir despues de que el compilador invoque a la función de

interrupcion del vector #24 del Timer0_A3, debemos de consultar una vez dentro de la ISR al

registro TA0IV por su valor para determinar el tipo de interrupción, luego de esta lectura el registro

se resetea automáticamente.

Page 28: Tutorial básico MSP430G2553

Las interrupciones TAIFG por desborde del registro timer TA0R se configuran con los bits MC (bits

5-4 del registro TA0CTL) y tienen el siguiente comportamiento:

Up Mode: En este modo la interrupcion se produce cuando el valor del registro TA0R se reinicia en

cero justo después de que su valor haya sido igual al valor del registro TA0CCR0.

Continuous Mode: En este modo la interrupcion se produce cuando el valor del registro TA0R se

reinicia en cero justo después de que su valor haya sido igual a 0xFFFF (65535 en decimal).

Page 29: Tutorial básico MSP430G2553

Up/Down Mode: En este modo la interrupcion se produce cuando el valor del registro TA0R llega a

cero justo después de que su valor se haya decrementado desde que el valor de TA0R es igual el

valor del registro TA0CCR0.

Finalmente dicha interrupción  con flag TAIFG (bit 0 del registro TA0CTL) se activa con el

bit TAIE (bit 1 del registro TA0CTL).

Para entender y consolidar el funcionamiento del Timer Block hemos realizado un código donde

mediante 3 pulsadores se podrá seleccionar las configuraciones del source clock, del input divider,

y del mode control.

Programa de Aplicacion:12345678910111213141516171819202122

#include "io430.h"#include "intrinsics.h"#include "bsp\bsp.h"#include "lcd2x16\lcd2x16.h" char estadoCLK;char estadoDIV;char estadoMODO;char cambia;

 int main( void ){   unsigned char titulo[16] = " microembebidos ";      unsigned char linea1[16] = "CLK:      DIV:  ";      unsigned char linea2[16] = "MODO:           ";  

    unsigned char source0[5] = "TACLK";    unsigned char div0[2] = "/1";   unsigned char modo0[10] = "STOP MODE ";

    unsigned char source1[5] = "ACLK ";    unsigned char div1[2] = "/2";   unsigned char modo1[10] = "UP MODE   ";

    unsigned char source2[5] = "SMCLK";    unsigned char div2[2] = "/4";

Page 30: Tutorial básico MSP430G2553

2324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869

   unsigned char modo2[10] = "CONT.MODE ";

    unsigned char source3[5] = "INCLK";    unsigned char div3[2] = "/8";   unsigned char modo3[10] = "UP/DN MODE";

    // Stop watchdog timer to prevent time out reset   WDTCTL = WDTPW + WDTHOLD;

    BCSCTL1 = CALBC1_1MHZ;// Use 1Mhz cal data for DCO   DCOCTL = CALDCO_1MHZ;// Use 1Mhz cal data for DCO

    ACLKInit();   SMCLKInit();   TACLKInit();

    TACCR0 = 100;

    BotonesInit();

    P1DIR_bit.P1DIR_4 = 1;//salida   

    LcdInit();

    LcdStringXY(titulo,16,1,1);    __delay_cycles(500000);//500mseg

    LcdStringXY(linea1,16,1,1);    LcdStringXY(linea2,16,1,2);   

    estadoMODO = 2;   estadoDIV = 3;   estadoCLK = 2;   cambia = 1;

    __enable_interrupt();//activa todas las interrupciones enmascarables.

    while(1){

       do{      }while(cambia == 0);

       cambia = 0;     

       switch(estadoCLK){      case 0:         LcdStringXY(source0,5,5,1);          break;      case 1:         LcdStringXY(source1,5,5,1);          break;      case 2:

Page 31: Tutorial básico MSP430G2553

707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116

         LcdStringXY(source2,5,5,1);          break;      case 3:                  LcdStringXY(source3,5,5,1);          break;      }

       switch(estadoDIV){      case 0:         LcdStringXY(div0,2,15,1);          break;      case 1:         LcdStringXY(div1,2,15,1);          break;      case 2:         LcdStringXY(div2,2,15,1);          break;      case 3:                  LcdStringXY(div3,2,15,1);          break;               }     

       switch(estadoMODO){      case 0:         LcdStringXY(modo0,10,6,2);          break;      case 1:         LcdStringXY(modo1,10,6,2);          break;      case 2:         LcdStringXY(modo2,10,6,2);          break;      case 3:                  LcdStringXY(modo3,10,6,2);          break;                        }

       Setup_Timer0_A3(estadoCLK, estadoDIV, estadoMODO);   }}

 #pragma vector = TIMER0_A1_VECTOR__interrupt void InterrupcionLowPrioTimer0_A3(void){   unsigned char aux;   aux = TAIV;   if(aux == 0x0A){      P1OUT_bit.P1OUT_4 = ~P1OUT_bit.P1OUT_4;      TACTL_bit.TAIFG = 0;         }}

 #pragma vector = PORT1_VECTOR__interrupt void InterrupcionPuerto1(void){   if(BOTON1_IFG){

Page 32: Tutorial básico MSP430G2553

117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156

      estadoCLK++;      if(estadoCLK > 3){         estadoCLK = 0;      }      cambia = 1;      BOTON1_IFG = 0;   } else if(BOTON2_IFG){      estadoDIV++;      if(estadoDIV > 3){         estadoDIV = 0;      }      cambia = 1;      BOTON2_IFG = 0;   } else if(BOTON3_IFG){      estadoMODO++;      if(estadoMODO > 3){         estadoMODO = 0;      }      cambia = 1;      BOTON3_IFG = 0;   } }

Video 1_2:

Video 2_2:

Archivos:

Boxnet.

4Shared.

Estos nuevos enlaces estan compilador con la versión del software IAR 5.40 :

Page 33: Tutorial básico MSP430G2553

4Shared

 esta segunda parte del Timer_A, trataremos con los registros Capture/Compare en su

configuracion de Captura (Capture Mode). Veremos lo prácico que resulta utilizar estos registros y

sus configuraciones para detectar la duración de un pulso o para decodificar comunicaciones

donde el ancho de los pulsos sea importante para obtener los datos. Para ello hemos realizado dos

programas a manera de ejemplos para practicar.

Capture Mode del Timer0_A3

En la primera parte del post del Timer_A, mencionamos los registros que constituyen el Timer0_A3

dentro del MSP430F2132, de los cuales los que están en amarillo ya han sido estudiados

anteriormente. Lo nuevo son los tres Canales de Captura/Comparación (recordar que en el otro

Timer1_A2 sólo tiene dos de estos canales) donde cada canal tiene dos registros propios mediante

los cuales podremos configurar y generar la respectiva interrupción para el modo de captura.

Page 34: Tutorial básico MSP430G2553

Observemos que para el Canal 0 existen dos registros, lo mismo para los otros canales, todos ellos

tienen la misma estructura y función. En nuestro proyecto hemos trabajado solamente con el Canal

0, el estudio de los demás canales se deja como tarea al lector, pues verá que son idénticos al

Canal 0.

Tener en cuenta que antes de tener funcionando el Canal 0 del Timer0_A3 en Modo Captura

tenemos que configurar siempre su respectivo Timer Block, pues como veremos después, las

capturas dependen directamente del valor que tenga el registro TA0R en el preciso momento de la

captura.

Page 35: Tutorial básico MSP430G2553

TA0CCR0

En el Modo Captura este registro almacena el valor del registro TA0R cuando se cumple con la

condición de captura de flanco del Timer0_A3. Dicha condición se configura en el otro registro del

Canal 0 (TA0CCTL0).

Page 36: Tutorial básico MSP430G2553

Citamos un ejemplo, digamos que queremos medir el ancho de un pulso (Low-High-Low) entonces

en el primer flanco de subida genera interrupcion (después veremos donde está su vector de

interrupción y cómo seleccionar el flanco de captura) y leemos el valor del TA0CCR0 (que acaba

de capturar el valor del TAoR) para almacenarlo en un registro que llamaremos FS, luego se

genera otra interrupcion en el flanco de bajada y guardamos el valor del TA0CCR0 en otro registro

FB. Entonces para determinar el ancho del pulso simplemente restamos FB – FS, cuyo resultado

estará en función del source clock que tenga configurado el Timer Block del Timer0_A3.

Frecuencia TimerBlock = 125KHz (1MHz SMCLK, divisor /8)

FS = 1206; (primera captura del flanco de subida en Terminos del TA0CCR0)

FB = 1469; (segunda captura del flanco de bajada en Terminos del TA0CCR0)

Ancho de Pulso en Terminos del TA0CCR0 = FB – FS = 263

Ancho de Pulso en Segundos = 263/(125KHz) =263/125000 seg. = 2.104 mseg.

TA0CCTL0

El segundo registro del Canal 0 permite configurar el comportamiento del canal, así como la

habilitación de su interrupcion. Describiremos a continuación sus campos.

CMx (bits 15-14) : Sólo para el Modo Captura. Permite definir el flanco de captura del Canal 0.

0: Sin captura.

Page 37: Tutorial básico MSP430G2553

1: Captura en flanco de subida.

2: Captura en flanco de bajada.

3: Captura en ambos flancos.

CCISx (bits 13-12) : Sólo para el Modo Captura. Permiten definir la señal de entrada cuyos flancos

vamos a capturar.

0: CCI0A. Entrada A para el Canal 0.

1: CCI0B. Entrada B para el Canal 0.

2: GND. Pone a nivel bajo la Entrada del Canal 0.

3: VCC. Pone a nivel alto la Entrada del Canal 0.

Las entradas CCI0A y CCIoB del MSP430F2132 se ubican en los pines P1.1 (CCI0A) y en P2.2

(CCI0B):

Page 38: Tutorial básico MSP430G2553

SCS (bit 11) : Sólo para el Modo Captura. Sirve para sincronizar la captura de la señal con el timer

clock. De preferencia siempre habilitarlo.

SCCI (bit 10) : Bit de sólo lectura que sirve para monitorear el estado actual de la entrada de la

señal CCI (señal que proporciona el bloque de los bits CCISx) pero sincronizada.

CAP (bit 8) : Bit que permite definir el modo de trabajo de los Canales de Captura/Comparación.

0: Modo de Comparación.

1: Modo de Captura.

OUTMODx (bits 7-5) : Sólo para el Modo Comparación. Explicaremos estos bits en el tercer post

del Timer_A.

Page 39: Tutorial básico MSP430G2553

CCIE (bit 4) : Bit para habilitar la interrupcion del Canal de Captura/Comparación.

CCI (bit 3) : Bit de sólo lectura que sirve para monitorear el estado actual de la entrada de la señal

CCI (señal que proporciona el bloque de los bits CCISx).

OUT (bit 2) : Sólo para el Modo Comparación. Explicaremos estos bits en el tercer post del

Timer_A.

COV (bit 1) : Sólo para el Modo Captura. Indica de que se ha producido una segunda captura del

timer TA0R sin que se halla leído la primera captura almacenada aún en TA0CCR0. Se debe borrar

mediante código.

CCIFG (bit 0) : Bandera de la interrupción CCIE del Canal 0.

Page 40: Tutorial básico MSP430G2553

Interrupción del Modo Captura del Timer0_A3

La interrupcion del Canal 0 es más simple que la del Timer Block pues tiene su propio vector en la

tabla de direcciones, está ubicado en la prioridad 25.

Page 41: Tutorial básico MSP430G2553

En el código nos servimos del nombre del vector definido por “TIMER0_A0_VECTOR” para

construir la función de gestionará su interrupción de captura.

Bueno, ya expuesta la teoría tenemos que echar mano a la práctica.

Page 42: Tutorial básico MSP430G2553

Programa de Aplicación

En este primer ejemplo tenemos un programa que permite determinar el ancho de un pulso en la

entrada CCI0A del Canal 0 del Timer0_A3:

123456789101112131415161718192021222324252627282930313233343536373839404142

#include "io430.h"#include "intrinsics.h"#include "bsp\bsp.h"#include "lcd2x16\lcd2x16.h" unsigned int sampleFS;unsigned int sampleFB;unsigned char samplestate = 0;unsigned char sampleok = 0;

 unsigned char datos[4];

 int main( void ){   unsigned char titulo[16] = " microembebidos ";

    // Stop watchdog timer to prevent time out reset   WDTCTL = WDTPW + WDTHOLD;

    BCSCTL1 = CALBC1_1MHZ;// Use 1Mhz cal data for DCO   DCOCTL = CALDCO_1MHZ;// Use 1Mhz cal data for DCO

    P1DIR_bit.P1DIR_4 = 1;//salida   

    LcdInit();   LcdStringXY(titulo,16,1,1);

    ACLKInit();   SMCLKInit();   Timer0_A3_TimerBlockInit();      Timer0_A3_CaptureInputInit();  

    __enable_interrupt();

    while(1){         

       while((sampleok==0));

       if(sampleok){         unsigned int aux;           aux = sampleFB - sampleFS;         ConvertHexToString(aux, datos);         LcdStringXY(datos,4,1,2);                   sampleok = 0;       }               }}

 #pragma vector = TIMER0_A0_VECTOR

Page 43: Tutorial básico MSP430G2553

4344454647484950515253545556575859606162636465666768697071727374

__interrupt void InterrupcionHighPrioTimer0_A3(void){   if(samplestate == 0){      sampleFS = TACCR0;         samplestate++;   } else if(samplestate == 1){      sampleFB = TACCR0;               samplestate++;      sampleok = 1;   }   TACCTL0_bit.CCIFG = 0;}

 #pragma vector = TIMER0_A1_VECTOR__interrupt void InterrupcionLowPrioTimer0_A3(void){   unsigned char aux;   aux = TAIV;   if(aux == 0x02){      TACCTL1_bit.CCIFG = 0;   } else if(aux == 0x0A){      P1OUT_bit.P1OUT_4 = ~P1OUT_bit.P1OUT_4;      TACTL_bit.TAIFG = 0;         }}

En este segundo ejemplo hemos implementado la lectura de una trama de pulsos que pertenecen

a la codificación CODE39 que utlizan las tarjetas de código de barras, donde el ancho de los

pulsos determinan el digito codificado:

12345678910

#include "io430.h"#include "intrinsics.h"#include "bsp\bsp.h"#include "lcd2x16\lcd2x16.h" unsigned char samplestate = 0;unsigned char sampleok = 0;unsigned char dato;

 unsigned int barraFS;unsigned int barraFB; 

Page 44: Tutorial básico MSP430G2553

1112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657

unsigned int espacioFB;unsigned int espacioFS; unsigned int digitocode39;unsigned int lenghtcode39[9]; int main( void ){   unsigned char titulo[16] = " microembebidos ";

    // Stop watchdog timer to prevent time out reset   WDTCTL = WDTPW + WDTHOLD;

    BCSCTL1 = CALBC1_1MHZ;// Use 1Mhz cal data for DCO   DCOCTL = CALDCO_1MHZ;// Use 1Mhz cal data for DCO

    P1DIR_bit.P1DIR_4 = 1;//salida   

    LcdInit();   LcdStringXY(titulo,16,1,1);

    ACLKInit();   SMCLKInit();   Timer0_A3_TimerBlockInit();      Timer0_A3_CaptureInputInit();  

    __enable_interrupt();

    while(1){         

       while((sampleok==0));

       if(sampleok){

          unsigned int aux;           unsigned int ancho;         unsigned int peque;          //determinamos las longitudes         if(lenghtcode39[0]>lenghtcode39[1]){            ancho = lenghtcode39[0];            peque = lenghtcode39[1];         } else {            peque = lenghtcode39[0];            ancho = lenghtcode39[1];         }         //hallamos el codigo                  for(digitocode39 = 0,aux = 0; aux < 9; aux++){

             if(lenghtcode39[aux] < (peque*2)){               //colocamos un cero               digitocode39 = digitocode39 & 0xFE;            } else {               //colocamos un uno

Page 45: Tutorial básico MSP430G2553

585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104

               digitocode39 = digitocode39 | 0x01;            }                        digitocode39 = digitocode39 << 1;                     }                  digitocode39 = digitocode39 >> 1;           //imprimir el dato         //ConvertHexToString(digitocode39, datos);         if(digitocode39 == 0x0094){            dato = '*';         } else if(digitocode39 == 0x0034){            dato = '0';         } else if(digitocode39 == 0x0121){            dato = '1';         } else if(digitocode39 == 0x0061){            dato = '2';         } else {            dato = 'E';         }                  LcdStringXY(&dato,1,1,2);                   sampleok = 0;          __disable_interrupt();      }               }}

 #pragma vector = TIMER0_A0_VECTOR__interrupt void InterrupcionHighPrioTimer0_A3(void){   switch(samplestate){   case 0:      barraFS = TACCR0;      break;   case 1:      barraFB = TACCR0;       espacioFB = barraFB;      lenghtcode39[0]=barraFB-barraFS;      break;   case 2:      espacioFS = TACCR0;       barraFS = espacioFS;      lenghtcode39[1]=espacioFS-espacioFB;            break;   case 3:      barraFB = TACCR0;       espacioFB = barraFB;      lenghtcode39[2]=barraFB-barraFS;      break;   case 4:      espacioFS = TACCR0;       barraFS = espacioFS;      lenghtcode39[3]=espacioFS-espacioFB;            break;   case 5:      barraFB = TACCR0;       espacioFB = barraFB;      lenghtcode39[4]=barraFB-barraFS;      break;

Page 46: Tutorial básico MSP430G2553

105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151

   case 6:      espacioFS = TACCR0;       barraFS = espacioFS;      lenghtcode39[5]=espacioFS-espacioFB;            break;   case 7:      barraFB = TACCR0;       espacioFB = barraFB;      lenghtcode39[6]=barraFB-barraFS;      break;   case 8:      espacioFS = TACCR0;       barraFS = espacioFS;      lenghtcode39[7]=espacioFS-espacioFB;            break;   case 9:      barraFB = TACCR0;       //espacioFB = barraFB;      lenghtcode39[8]=barraFB-barraFS;      sampleok = 1;      break;                     }//   if(samplestate == 0){//      barraFS = TACCR0;   //      samplestate++;//   } else if(samplestate == 1){//      barraFB = TACCR0;         //      espacioFB = barraFB;//      samplestate++;//   }   samplestate++;   TACCTL0_bit.CCIFG = 0;}

 #pragma vector = TIMER0_A1_VECTOR__interrupt void InterrupcionLowPrioTimer0_A3(void){   unsigned char aux;   aux = TAIV;   if(aux == 0x02){      TACCTL1_bit.CCIFG = 0;   } else if(aux == 0x0A){      P1OUT_bit.P1OUT_4 = ~P1OUT_bit.P1OUT_4;      TACTL_bit.TAIFG = 0;         }}

Page 47: Tutorial básico MSP430G2553

152153154155156157158159160161162163164165166167168169Videos:

Lab 4 - Interrumpe con ensamblador y C

En esta práctica, vamos a cubrir dos temas principales:

- Interrups y rutinas de servicio de interrupción

- C programación del MSP430

Tutorial y Antecedentes

1 - Las interrupciones en la Asamblea

Las interrupciones serán discutidos en la conferencia - pero en pocas palabras - que son un mecanismo para tomar el control del procesador en función de la petición de hardware. El procesador completa con gracia la instrucción actual y luego los "servicios" de la interrupción, ejecute el código definido en una rutina de servicio de interrupción. Hay muchas fuentes de las interrupciones en el MSP430, pero en este laboratorio vamos a centrar en la entrada de propósito general en P1.3 que está unido al pulsador.

Page 48: Tutorial básico MSP430G2553

Una interrupción en P1.3 se puede activar mediante el control de varios puertos 1 registros encontrados:

P1IE es un registro que permite a las interrupciones para el puerto 1 pins.

P1IES es el opositor que determina (si las interrupciones están habilitadas para el pin correspondiente) para que el borde (ascendente o descendente) causa una interrupción.

P1IFG es el registro en el que cada bit PxIFGx es la bandera de interrupción para su correspondiente pin de E / S y se establece cuando el borde de la señal de entrada seleccionada aparece en el pin. Todos PxIFGx interrumpen banderas solicitar una interrupción cuando su correspondiente bit PXIe y el bit GIE se establecen. Cada bandera PxIFG se debe restablecer con el software. El software también puede configurar cada bandera PxIFG, proporcionando una manera de generar un programa iniciado interrupción.

Bit = 0: Sin interrupción está pendiente

Bit = 1: Una interrupción está pendiente

Sólo las transiciones, los niveles estáticos, no causan interrupciones. Si cualquier bandera PxIFGx cuaja durante la rutina de servicio de interrupción Px, o si se establece después de la instrucción RETI de una rutina de servicio de interrupción Px se ejecuta, la bandera conjunto PxIFGx genera otra interrupción. Esto asegura que se reconoce cada transición.

Finalmente, las banderas de interrupción debe ser limpiado y, finalmente, las alarmas deben estar habilitadas en todo el mundo. Estas tres líneas realizan esta función en este caso.

Cómo implementar rutinas de servicio de interrupción

Page 49: Tutorial básico MSP430G2553

Para utilizar interrumpe necesita configurar su interrupción específica (puerto 1.3 en este caso), desactive las interrupciones pendientes y habilitar las interrupciones globalmente. Este código hace esto.

bis.b # 008H, y P1IE; P1.3 Interrupción habilitada

bis.b # 008H, y P1IES; Hi P1.3 / borde inferior

bic.b # 008H, y P1IFG; IFG P1.3 Autorizado

bis.w # GIE, SR; LPM4, habilitar las interrupciones

Añadir este código de ejemplo al final de su programa de la asamblea para incluir una rutina de servicio de interrupción para el puerto 1. Usted tendrá que añadir el código del programa específico por encima de la instrucción RETI. El bic.b es necesario borrar el indicador de interrupción. Esto se conoce como "reconocer" la interrupción y evita una solicitud de interrupción siendo administrados más de una vez.

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

P1_ISR; P1.0 Toggle salida

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

; AÑADIR CÓDIGO AQUÍ PARA SERVICIO DE INTERRUPCIÓN DE RUTINA

bic.b # 008H, y P1IFG; IFG P1.3 Autorizado

retina; Regreso de ISR

;

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

; interrupción Vectores

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

. secta ". reset"; REINICIAR MSP430 Vector

. REINICIAR corto;

Page 50: Tutorial básico MSP430G2553

. secta "int02."; P1.x Vector

. P1_ISR corto;

. fin

2 - Introducción a C con el MSP430

TI tiene una amplia documentación sobre el Code Composer Studio. Usted puede encontrar todo aquí.

Para crear un proyecto de CCS, seleccione Proyecto CCS "en el nuevo menú Archivo->. Seleccione un "Proyecto vacío" con el fin de crear un proyecto de C.