Está en la página 1de 49

Realizar un proyecto en CODE COMPOSER STUDIO V4 1.

Primero nos pedir que seleccionemos una carpeta en la cual se guardarn todos los proyectos que realizamos.

2. Ahora pasamos a realizar un nuevo proyecto

3. Escribimos el nombre del proyecto que queramos darle y seleccionamos el botn next

4. Ahora dejamos las opciones como se ven en la siguiente figura y seleccionamos next

5. Para esta ventana, dejamos todo como esta y seleccionamos al botn next

6. Seleccionamos el microcontrolador MSP430F2013

7. Y finalmente seleccionamos Finish

Incluyendo archivos .c y .h en CCS Para poder incluir archivos en nuestro proyecto, es muy sencillo, solo tenemos que seleccionar nuestra carpeta, y presionar el botn secundario del ratn.

Seleccionamos Source file para crear nuestro archivo main.c, cabe mencionar que cuando queramos incluir archivos de cabecera solo tenemos que seleccionar header file.

A partir de aqu, solo tenemos que empezar a escribir nuestro programa. Cmo compilar mi proyecto? Para compilar nuestro proyecto, solo tenemos que seleccionar Project->Build Project

Cmo programar el microcontrolador una vez que ya haya terminado mi programa? Solamente tenemos que presionar el botn que aparece encerrado en el crculo rojo en la figura:

A continuacin nos aparece un cambio de opciones en la pantalla, que nos permitirn hacer un debug en tiempo real, checando valores de variables, memoria, registros y lnea del programa.

En la pantalla podemos ver varios iconos que nos demuestran cuales son las herramientas que nos ofrece este excelente compilador:

Run: Este botn es para arrancar el programa Pause: para pausar el programa en tiempo real Terminate: para terminar el debug Step Into: Una vez que hemos seleccionado Pause, podemos ir recorriendo nuestro programa lnea por lnea, entrar a funciones, etc. Step Into (ensamblador): estos botones sirven para cuando queremos hacer un step para a un nivel de instruccin en ensamblador. Step Return: Este comando sirve, para cuando queremos salir de alguna funcin en la cual est el compilador corriendo en steps.

Ejercicios con MSP430F2013 EJERCICIO #1 (SALIDA DIGITAL)


#include <msp430f2013.h>

void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR |= 0x01; for (;;) { volatile unsigned int i; P1OUT ^= 0x01; i = 50000; do (i--); while (i != 0); } }

// Stop watchdog timer // Set P1.0 to output direction

// Toggle P1.0 using exclusive-OR // Delay

Explicacin Aqu podemos ver un sencillo ejemplo, en el cual el objetivo en encender y apagar un led, el puerto P1.0

El primer registro que vemos es

WDTCTL

Explique la ejecucin de esta lnea de programacin.

WDTCTL = WDTPW + WDTHOLD; _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________

Puertos de entrada y salida digitales

PXDIR
Este registro, sirve para determinar si queremos el puerto como entrada o salida:

P1DIR |= 0x01;

// Set P1.0 to output direction

Con esta orden, lo que hacemos es poner el pin 0 del Puerto 1 como salida, al escribir en el registro el valor hexadecimal 0x01.

PXOUT1
Este registro sirve para poner el estado lgico en el puerto como salida:

P1OUT ^= 0x01;
Que se realiza con esta orden? _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________ Existe alguna otra forma de realizar la misma orden? _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________

EJERCICIO #2 (ENTRADAS DIGITALES)


#include <msp430f2013.h>

void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR |= 0x01;

// Stop watchdog timer // Set P1.0 to output direction // Test P1.4 // if P1.4 set, set P1.0 // else reset

while (1) { if ((0x10 & P1IN)) P1OUT |= 0x01; else P1OUT &= ~0x01; } }

En la condicin:
if ((0x10 & P1IN)) P1OUT |= 0x01; // if P1.4 set, set P1.0 else P1OUT &= ~0x01; // else reset

Qu se desea hacer? _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________ _________________________________________________________________________

Con la condicin: if(P1IN==0x10) P1OUT=0x01; else P1OUT=0x00; Se hace lo mismo que en la anterior condicin y por qu?

_______________________________________________________________ _______________________________________________________________ _______________________________________________________________ _______________________________________________________________ Ejercicio #3 (Interrupciones de entradas)


#include <msp430f2013.h>

void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR = 0x01; P1OUT = 0x10; P1REN |= 0x10; P1IE |= 0x10; P1IES |= 0x10; P1IFG &= ~0x10; _BIS_SR(LPM4_bits + GIE); } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { P1OUT ^= 0x01; P1IFG &= ~0x10; }

// Stop watchdog timer // P1.0 output, else input // P1.4 set, else reset // P1.4 pullup // P1.4 interrupt enabled // P1.4 Hi/lo edge // P1.4 IFG cleared // Enter LPM4 w/interrupt

// P1.0 = toggle // P1.4 IFG cleared

El circuito, es el mismo que se uso en la practica anterior. En este ejemplo, utilizamos por primera vez la interrupcin para detectar la entrada de una seal positiva. Para esto utilizamos la directiva:
// Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void)

{ P1OUT ^= 0x01; P1IFG &= ~0x10; } // P1.0 = toggle // P1.4 IFG cleared

Al declarar #pragma vector= PORT1_VECTOR direccionamos la funcin _interrupt void Port_1(void) para que cada vez que detecte un pulso en la entrad 1.4 el led se encienda o apague segn sea el caso. En el registro P1IFG limpiamos la bandera para que se salga de la interrupcin, de lo contrario jams saldramos de la funcin, ocasionando un ciclo infinito en la funcin de interrupcin.
P1IFG &= ~0x10;

Cada puerto P1 y P2 tienen interrupciones, configuradas con los registros PxIFG. PxIE, y PxIES. Todos los pines P1 llaman a un solo vector de interrupcin, y todos los pines del puerto P2 tienen otro vector de interrupcin. El registro PxIFG puede ser verificado para saber el estado de la interrupcin.

Arquitectura de pin P1.0

Practicas a realizar para terminar unidad IO Registro de corrimiento para leds

#include

<msp430f2013.h>

void delay(void){ volatile unsigned int i; for(i=0;i<80000;i++); } void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR |= 0x0F; direction for (;;) { P1OUT = 0x00; delay(); P1OUT = 0x01; delay(); P1OUT = 0x02; delay(); P1OUT = 0x04; delay();

// Stop watchdog timer // Set P1.0 to P1.3 to output

} }

Escribe un programa que realice la misma secuencia, con diferentes sentencias:

Realiza un programa que despliegue una secuencia en leds dependiendo del valor de dos botones:

#include

<msp430f2013.h>

unsigned char flag_secuencia1, flag_secuencia2; void delay(void){ volatile unsigned int i; for(i=0;i<80000;i++); } void secuence(unsigned char value){ if(!value){ P1OUT = 0x00; delay(); P1OUT = 0x01; delay(); P1OUT = 0x02; delay(); P1OUT = 0x04; delay(); }else{ P1OUT = 0x04; delay(); P1OUT = 0x02; delay(); P1OUT = 0x01; delay(); P1OUT = 0x00; delay(); } }

void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR |= 0x0F; P1REN |= 0x30; P1IE |= 0x30; P1IES |= 0x30; P1IFG &= ~0x30; flag_secuencia1=0; flag_secuencia2=0; for (;;) { if(flag_secuencia1){ secuence(0); flag_secuencia1=0; } if(flag_secuencia2){ secuence(1); flag_secuencia2=0; } } }

// Stop watchdog timer // Set P1.0 to P1.3 to output direction // P1.4 P1.5 pullup // P1.4 P1.5 interrupt enabled // P1.4 P1.5 Hi/lo edge

// Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { if(!(0x10 & P1IN)){ flag_secuencia1=1; } if(!(0x20 & P1IN)){ flag_secuencia2=1; } P1IFG &= ~0x30; } // P1.4 IFG cleared

Realiza un programa que utilice un display de 7 segmentos e incremente cada determinado tiempo automticamente.

El display de 7 segmentos se conforma de 7 leds que conforman un nmero del 1 al 9, se usan frecuentemente en dispositivos de medicin.

La tabla de valores que debemos de tener para desplegar en nuestro puerto 1 es el siguiente: Nmero Codificacin 1 2 B,C A,B,G,E,D Valor Hexadecimal (ctodo Comn) 0x06 0x5b Valor Hexadecimal (nodo Comn) 0xf9 0xa4

3 4 5 6 7 8 9 0

A,B,G,C,D F,G,B,C A,F,G,C,D A,F,G,E,C,D A,B,C A,B,C,D,E,F,G A,F,G,B,C,D A,B,C,D,E,F

0x4f 0x66 0x6d 0x7d 0x07 0x7f 0x6f 0x3f

0xb0 0x99 0x92 0x82 0xf8 0x00 0x90 0x40

Entonces, como ya sabemos los valores que tenemos que imprimir para que se despliegue el nmero deseado, pasamos a la programacin:
#include <msp430f2013.h>

int valor=0; const unsigned char display[10]={0x40,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void delay(void){ volatile unsigned int i; for(i=0;i<40000;i++); } void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR = 0xFF; for(;;){ P1OUT=display[valor]; valor++; if(valor>9)valor=0; delay(); } }

// Stop watchdog timer

Realice un programa que incremente el contador en el display de 7 segmentos cuando no se est presionando el botn, cuando se mantenga presionado, se decrementar el contador.

Respuesta:

CAPITULO 2 MODOS DE OPERACIN Y BAJO CONSUMO

OSCILADOR Y SISTEMA DE RELOJ

Como nos explica este articulo, existen tres fuentes de reloj que necesitamos alimentar, ACLK, MCLK y SMCLK. La primera es para obtener la frecuencia de un cristal de 32.768 KHz, la segunda es la frecuencia que alimentar las ejecuciones de reloj del CPU y por ltimo, la frecuencia que suministrar de pulsos a los perifricos del microcontrolador como son ADC, IO, SPI, etc.

El microcontrolador MSP430 est diseado para aplicaciones de ultrabajo consumo, y se puede utilizar en diferentes tipos de operacin de bajo consumo.

Los registros para configurar el reloj, son:

BCSCTL3

BCSCTL2

IFG1

REGISTER SR

EJERCICIO #2 (VLO)

#include

<msp430x20x3.h>

void main(void) { volatile unsigned int i; WDTCTL = WDTPW + WDTHOLD; BCSCTL3 |= LFXT1S_2; IFG1 &= ~OFIFG; __bis_SR_register(SCG1 + SCG0); BCSCTL2 |= SELM_3 + DIVM_3; P1DIR = 0xFF; P1OUT = 0; P2DIR = 0xFF; P2OUT = 0; for (;;) { P1OUT |= for (i = P1OUT &= for (i = } }

// // // // // // // // // //

Volatile to prevent removal Stop watchdog timer LFXT1 = VLO Clear OSCFault flag Stop DCO MCLK = LFXT1/8 All P1.x outputs All P1.x reset All P2.x outputs All P2.x reset

0x01; 10; i > 0; i--); ~0x01; 1000; i > 0; i--);

// // // //

P1.0 set Delay 1x P1.0 reset Delay 100x

Para poder configurar el reloj en bajo consumo, en el programa se escriben los siguientes registros:
BCSCTL3 |= LFXT1S_2; IFG1 &= ~OFIFG; __bis_SR_register(SCG1 + SCG0); BCSCTL2 |= SELM_3 + DIVM_3; // LFXT1 = VLO // Clear OSCFault flag // Stop DCO // MCLK = LFXT1/8

Recordemos que el registro BCSCTL3 sirve para configurar la velocidad de reloj, as que al poner una operacin OR de lo que contiene, ms lo que se define como LFXT1S_2, seleccionamos:

La opcin VLO en el microcontrolador MSP430 es el oscilador interno, con una frecuencia normal de 12KHz, aqu podemos ver algunas de sus especificaciones:

En la siguiente lnea, se configura el registro IFG1, lo cual la nica tarea que hace, es limpiar la bandera de la interrupcin del oscilador interno. En la lnea: __bis_SR_register(SCG1 + SCG0); Configuramos el registro SR para que pongamos a 1 los bits SCG1 y SCG2 para poder apagar el DCO (digitally controlled oscillator) que permite despertar al microcontrolador de un estado de sueo en tan solo 1us.

Por ltimo se configura el registro BCSCTL2, con valores 3 respectivamente

Es as, como se elige en SELM_3 trabajar con el oscilador interno y con DIVM_3 tenemos una frecuencia de 12KHz dividida entre 8, que es igual a 1.5KHz de frecuencia de trabajo. En qu modo de operacin se encuentra el microcontrolador con los registros SELM_3 y DIVM_2? ___________________________________________________________________

EJERCICIO #3 (DCO)
#include <msp430f2013.h>

void main(void) { WDTCTL = WDTPW +WDTHOLD; // Stop Watchdog Timer if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) { while(1); // If calibration constants erased // do not load, trap CPU!! } //1Mhz BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation */ /* //8Mhz BCSCTL1 = CALBC1_8MHZ; DCOCTL = CALDCO_8MHZ; modulation */ /* //12Mhz BCSCTL1 = CALBC1_12MHZ; DCOCTL = CALDCO_12MHZ; modulation*/ /* //16Mhz BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; modulation*/ P1DIR |= 0x13; P1SEL |= 0x11; while(1) { P1OUT |= 0x01; P1OUT &= ~0x01; } }

// Set range // Set DCO step +

// Set range // Set DCO step +

// Set range // Set DCO step +

// P1.0,1 and P1.4 outputs // P1.0,4 ACLK, SMCLK output

// P1.1 = 1 // P1.1 = 0

EJERCICIO #3 (LFxTAL)
#include <msp430x20x3.h> volatile unsigned int i; void main(void) { WDTCTL = WDT_ADLY_1000; IE1 |= WDTIE; P1DIR = 0xFF; P1OUT = 0; P2DIR = 0xFF; P2OUT = 0; // An immedate Osc Fault will occur next IE1 |= OFIE; while(1) { P1OUT ^= 0x01; _BIS_SR(LPM3_bits + GIE); } } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer (void) { _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) } #pragma vector=NMI_VECTOR __interrupt void nmi_ (void) { do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0xFFF; i > 0; i--); // Time for flag to set P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR } while (IFG1 & OFIFG); // OSCFault flag still set? IE1 |= OFIE; // Enable Osc Fault }

// // // // // //

WDT 1s interval timer Enable WDT interrupt All P1.x outputs All P1.x reset All P2.x outputs All P2.x reset

// Enable Osc Fault

// Toggle P1.0 using exclusive-OR // Enter LPM3 w/interrupt

En este ejercicio podemos notar que por primera vez utilizamos el watchdog, y habilitamos una interrupcin en el registro IE1.

IE1

En la informacin aparece que debemos de utilizar una forma especial para cargar informacin en el registro, mencionan como hacerlo para ensamblador, en c se hace con una operacin OR.
IE1 |= WDTIE;

Esto quiere decir que estamos cargando el registro IE1 con el estado del bit de la interrupcin de watchdog para poder habilitar la interrupcin.

En la parte de:
WDTCTL = WDT_ADLY_1000;

Configuramos la interrupcin del watchdog cada segundo, recordemos el registro WDTCTL

Con la sentencia _BIS_SR(LPM3_bits + GIE); Entramos al modo de bajo consumo LPM3, con esta accin, el microcontrolador entrar en un modo de suspensin y bajo consumo, y solo se despertar cuando suceda alguna interrupcin. Como puede ser la interrupcin de cada 1 segundo del watchdog. En las siguientes sentencias, vemos varias interrupciones, estas se declaran de esta forma: #pragma vector=WDT_VECTOR __interrupt void watchdog_timer (void) { _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) } Cada vez que se cumple el segundo, se repite esta funcin, la cual limpia la bandera del modo LPM3 y as el CPU vuelva a despertar, lo cual har que parpadee el led que est conectado al pin de salida. Esto lo hacemos con una operacin en ensamblador: _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)

EJERCICIO #4 (OPERACIN EN MODO LPM3)


#include <msp430f2013.h> void main(void) { BCSCTL1 |= DIVA_2; WDTCTL = WDT_ADLY_1000; IE1 |= WDTIE; P1DIR = 0xFF; P1OUT = 0; P2DIR = 0xFF; P2OUT = 0; while(1) { int i; P1OUT |= 0x01; for (i = 5000; i>0; i--); P1OUT &= ~0x01; _BIS_SR(LPM3_bits + GIE); } } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer (void) { _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) }

// ACLK/4 // WDT 1s/4 interval timer // Enable WDT interrupt // All P1.x outputs // All P1.x reset // All P2.x outputs // All P2.x reset

// // // //

Set P1.0 LED on Delay Reset P1.0 LED off Enter LPM3

CAPITULO 3 ADC (SD16)

El periferico SD16 es un convertidor analogico digital de 16 bits. Este modulo de conversin tipo sigma delta con alta impedancia a la entrada.

Diagrama a bloques del SD16

Ejercicio #1 ADC Realizar la lectura del canal A1

#include

<msp430f2013.h>

void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= 0x01; // Set P1.0 to output direction SD16CTL = SD16REFON + SD16SSEL_1; // 1.2V ref, SMCLK SD16INCTL0 = SD16INCH_1; // A1+/SD16CCTL0 = SD16UNI + SD16IE; // 256OSR, unipolar, interrupt enable SD16AE = SD16AE2; // P1.1 A1+, A1- = VSS SD16CCTL0 |= SD16SC; // Set bit to start conversion _BIS_SR(LPM0_bits + GIE); } #pragma vector = SD16_VECTOR __interrupt void SD16ISR(void) { if (SD16MEM0 < 0x7FFF) P1OUT &= ~0x01; else P1OUT |= 0x01; }

// SD16MEM0 > 0.3V?, clears IFG

También podría gustarte