49
Realizar un proyecto en CODE COMPOSER STUDIO V4 1. Primero nos pedirá que seleccionemos una carpeta en la cual se guardarán todos los proyectos que realizamos. 2. Ahora pasamos a realizar un nuevo proyecto

Ejercicios Con MSP430F2013

Embed Size (px)

Citation preview

Page 1: Ejercicios Con MSP430F2013

Realizar un proyecto en CODE COMPOSER STUDIO V4

1. Primero nos pedirá que seleccionemos una carpeta en la cual se guardarán todos los proyectos que realizamos.

2. Ahora pasamos a realizar un nuevo proyecto

Page 2: Ejercicios Con MSP430F2013

3. Escribimos el nombre del proyecto que queramos darle y seleccionamos el botón 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 botón next

Page 3: Ejercicios Con MSP430F2013

6. Seleccionamos el microcontrolador MSP430F2013

7. Y finalmente seleccionamos Finish

Page 4: Ejercicios Con MSP430F2013

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 botón secundario del ratón.

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

Page 5: Ejercicios Con MSP430F2013

A partir de aquí, solo tenemos que empezar a escribir nuestro programa.

¿Cómo compilar mi proyecto?

Para compilar nuestro proyecto, solo tenemos que seleccionar Project->Build Project

Page 6: Ejercicios Con MSP430F2013

¿Cómo programar el microcontrolador una vez que ya haya terminado mi programa?

Solamente tenemos que presionar el botón que aparece encerrado en el círculo rojo en la figura:

A continuación nos aparece un cambio de opciones en la pantalla, que nos permitirán hacer un debug en tiempo real, checando valores de variables, memoria, registros y línea del programa.

Page 7: Ejercicios Con MSP430F2013

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

Run: Este botón 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 línea por línea, entrar a funciones, etc.

Step Into (ensamblador): estos botones sirven para cuando queremos hacer un step para a un nivel de instrucción en ensamblador.

Step Return: Este comando sirve, para cuando queremos salir de alguna función en la cual está el compilador corriendo en steps.

Page 8: Ejercicios Con MSP430F2013

Ejercicios con MSP430F2013

EJERCICIO #1 (SALIDA DIGITAL)

Explicación

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

#include <msp430f2013.h> void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= 0x01; // Set P1.0 to output direction for (;;) { volatile unsigned int i; P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR i = 50000; // Delay do (i--); while (i != 0); } }

Page 9: Ejercicios Con MSP430F2013

El primer registro que vemos es

WDTCTL

Page 10: Ejercicios Con MSP430F2013

Explique la ejecución de esta línea de programación.

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 lógico en el puerto como salida:

P1OUT ^= 0x01;

¿Que se realiza con esta orden?

___________________________________________________________________________________________________________________________________________________________________________________________________________________________

¿Existe alguna otra forma de realizar la misma orden?

____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Page 11: Ejercicios Con MSP430F2013

EJERCICIO #2 (ENTRADAS DIGITALES)

En la condición:

if ((0x10 & P1IN)) P1OUT |= 0x01; // if P1.4 set, set P1.0 else P1OUT &= ~0x01; // else reset ¿Qué se desea hacer?

____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

#include <msp430f2013.h> void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= 0x01; // Set P1.0 to output direction while (1) // Test P1.4 { if ((0x10 & P1IN)) P1OUT |= 0x01; // if P1.4 set, set P1.0 else P1OUT &= ~0x01; // else reset } }

Page 12: Ejercicios Con MSP430F2013

Con la condición:

if(P1IN==0x10) P1OUT=0x01; else P1OUT=0x00; ¿Se hace lo mismo que en la anterior condición y por qué? ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Ejercicio #3 (Interrupciones de entradas)

El circuito, es el mismo que se uso en la practica anterior.

En este ejemplo, utilizamos por primera vez la interrupción para detectar la entrada de una señal positiva. Para esto utilizamos la directiva:

// Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void)

#include <msp430f2013.h> void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR = 0x01; // P1.0 output, else input P1OUT = 0x10; // P1.4 set, else reset P1REN |= 0x10; // P1.4 pullup P1IE |= 0x10; // P1.4 interrupt enabled P1IES |= 0x10; // P1.4 Hi/lo edge P1IFG &= ~0x10; // P1.4 IFG cleared _BIS_SR(LPM4_bits + GIE); // Enter LPM4 w/interrupt } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { P1OUT ^= 0x01; // P1.0 = toggle P1IFG &= ~0x10; // P1.4 IFG cleared }

Page 13: Ejercicios Con MSP430F2013

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

Al declarar #pragma vector= PORT1_VECTOR direccionamos la función _interrupt void Port_1(void) para que cada vez que detecte un pulso en la entrad 1.4 el led se encienda o apague según sea el caso. En el registro P1IFG limpiamos la bandera para que se salga de la interrupción, de lo contrario jamás saldríamos de la función, ocasionando un ciclo infinito en la función de interrupción.

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 interrupción, y todos los pines del puerto P2 tienen otro vector de interrupción. El registro PxIFG puede ser verificado para saber el estado de la interrupción.

Page 14: Ejercicios Con MSP430F2013
Page 15: Ejercicios Con MSP430F2013

Arquitectura de pin P1.0

Page 16: Ejercicios Con MSP430F2013

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; // Stop watchdog timer P1DIR |= 0x0F; // Set P1.0 to P1.3 to output direction for (;;) { P1OUT = 0x00; delay(); P1OUT = 0x01; delay(); P1OUT = 0x02; delay(); P1OUT = 0x04; delay(); } }

Page 17: Ejercicios Con MSP430F2013

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

Page 18: Ejercicios Con MSP430F2013

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(); } }

Page 19: Ejercicios Con MSP430F2013

void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR |= 0x0F; // Set P1.0 to P1.3 to output direction P1REN |= 0x30; // P1.4 P1.5 pullup P1IE |= 0x30; // P1.4 P1.5 interrupt enabled P1IES |= 0x30; // P1.4 P1.5 Hi/lo edge 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; } } } // 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 }

Page 20: Ejercicios Con MSP430F2013

Realiza un programa que utilice un display de 7 segmentos e incremente cada determinado tiempo automáticamente.

El display de 7 segmentos se conforma de 7 leds que conforman un número del 1 al 9, se usan frecuentemente en dispositivos de medición.

La tabla de valores que debemos de tener para desplegar en nuestro puerto 1 es el siguiente:

Número Codificación Valor Hexadecimal (cátodo Común)

Valor Hexadecimal (ánodo Común)

1 B,C 0x06 0xf9 2 A,B,G,E,D 0x5b 0xa4

Page 21: Ejercicios Con MSP430F2013

3 A,B,G,C,D 0x4f 0xb0 4 F,G,B,C 0x66 0x99 5 A,F,G,C,D 0x6d 0x92 6 A,F,G,E,C,D 0x7d 0x82 7 A,B,C 0x07 0xf8 8 A,B,C,D,E,F,G 0x7f 0x00 9 A,F,G,B,C,D 0x6f 0x90 0 A,B,C,D,E,F 0x3f 0x40

Entonces, como ya sabemos los valores que tenemos que imprimir para que se despliegue el número deseado, pasamos a la programación:

#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; // Stop watchdog timer P1DIR = 0xFF;

for(;;){ P1OUT=display[valor]; valor++; if(valor>9)valor=0; delay(); } }

Page 22: Ejercicios Con MSP430F2013

Realice un programa que incremente el contador en el display de 7 segmentos cuando no se esté presionando el botón, cuando se mantenga presionado, se decrementará el contador.

Page 23: Ejercicios Con MSP430F2013

Respuesta:

Page 24: Ejercicios Con MSP430F2013

CAPITULO 2

MODOS DE OPERACIÓN Y BAJO CONSUMO

Page 25: Ejercicios Con MSP430F2013

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 periféricos del microcontrolador como son ADC, IO, SPI, etc.

Page 26: Ejercicios Con MSP430F2013
Page 27: Ejercicios Con MSP430F2013
Page 28: Ejercicios Con MSP430F2013

El microcontrolador MSP430 está diseñado para aplicaciones de ultrabajo consumo, y se puede utilizar en diferentes tipos de operación de bajo consumo.

Page 29: Ejercicios Con MSP430F2013
Page 30: Ejercicios Con MSP430F2013

Los registros para configurar el reloj, son:

Page 31: Ejercicios Con MSP430F2013

BCSCTL3

Page 32: Ejercicios Con MSP430F2013

BCSCTL2

IFG1

Page 33: Ejercicios Con MSP430F2013

REGISTER SR

Page 34: Ejercicios Con MSP430F2013

EJERCICIO #2 (VLO)

Para poder configurar el reloj en bajo consumo, en el programa se escriben los siguientes registros:

Recordemos que el registro BCSCTL3 sirve para configurar la velocidad de reloj, así que al poner una operación OR de lo que contiene, más lo que se define como LFXT1S_2, seleccionamos:

#include <msp430x20x3.h> void main(void) { volatile unsigned int i; // Volatile to prevent removal WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO IFG1 &= ~OFIFG; // Clear OSCFault flag __bis_SR_register(SCG1 + SCG0); // Stop DCO BCSCTL2 |= SELM_3 + DIVM_3; // MCLK = LFXT1/8 P1DIR = 0xFF; // All P1.x outputs P1OUT = 0; // All P1.x reset P2DIR = 0xFF; // All P2.x outputs P2OUT = 0; // All P2.x reset for (;;) { P1OUT |= 0x01; // P1.0 set for (i = 10; i > 0; i--); // Delay 1x P1OUT &= ~0x01; // P1.0 reset for (i = 1000; i > 0; i--); // Delay 100x } }

BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO IFG1 &= ~OFIFG; // Clear OSCFault flag __bis_SR_register(SCG1 + SCG0); // Stop DCO BCSCTL2 |= SELM_3 + DIVM_3; // MCLK = LFXT1/8

Page 35: Ejercicios Con MSP430F2013

La opción 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 línea, se configura el registro IFG1, lo cual la única tarea que hace, es limpiar la bandera de la interrupción del oscilador interno.

En la línea:

__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 “sueño” en tan solo 1us.

Page 36: Ejercicios Con MSP430F2013

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 operación se encuentra el microcontrolador con los registros SELM_3 y DIVM_2?

___________________________________________________________________

Page 37: Ejercicios Con MSP430F2013
Page 38: Ejercicios Con MSP430F2013

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; // Set range DCOCTL = CALDCO_8MHZ; // Set DCO step + modulation */ /* //12Mhz BCSCTL1 = CALBC1_12MHZ; // Set range DCOCTL = CALDCO_12MHZ; // Set DCO step + modulation*/ /* //16Mhz BCSCTL1 = CALBC1_16MHZ; // Set range DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation*/ P1DIR |= 0x13; // P1.0,1 and P1.4 outputs P1SEL |= 0x11; // P1.0,4 ACLK, SMCLK output while(1) { P1OUT |= 0x01; // P1.1 = 1 P1OUT &= ~0x01; // P1.1 = 0 } }

Page 39: Ejercicios Con MSP430F2013

EJERCICIO #3 (LFxTAL)

#include <msp430x20x3.h> volatile unsigned int i; void main(void) { WDTCTL = WDT_ADLY_1000; // WDT 1s interval timer IE1 |= WDTIE; // Enable WDT interrupt P1DIR = 0xFF; // All P1.x outputs P1OUT = 0; // All P1.x reset P2DIR = 0xFF; // All P2.x outputs P2OUT = 0; // All P2.x reset // An immedate Osc Fault will occur next IE1 |= OFIE; // Enable Osc Fault while(1) { P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrupt } } #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 }

Page 40: Ejercicios Con MSP430F2013

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

IE1

En la información aparece que debemos de utilizar una forma especial para cargar información en el registro, mencionan como hacerlo para ensamblador, en c se hace con una operación OR.

IE1 |= WDTIE;

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

Page 41: Ejercicios Con MSP430F2013

En la parte de:

WDTCTL = WDT_ADLY_1000;

Configuramos la interrupción del watchdog cada segundo, recordemos el registro WDTCTL

Page 42: Ejercicios Con MSP430F2013

Con la sentencia

_BIS_SR(LPM3_bits + GIE);

Entramos al modo de bajo consumo LPM3, con esta acción, el microcontrolador entrará en un modo de suspensión y bajo consumo, y solo se despertará cuando suceda alguna interrupción. Como puede ser la interrupción 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 función, 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 operación en ensamblador: _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)

Page 43: Ejercicios Con MSP430F2013

EJERCICIO #4 (OPERACIÓN EN MODO LPM3)

#include <msp430f2013.h> void main(void) { BCSCTL1 |= DIVA_2; // ACLK/4 WDTCTL = WDT_ADLY_1000; // WDT 1s/4 interval timer IE1 |= WDTIE; // Enable WDT interrupt P1DIR = 0xFF; // All P1.x outputs P1OUT = 0; // All P1.x reset P2DIR = 0xFF; // All P2.x outputs P2OUT = 0; // All P2.x reset while(1) { int i; P1OUT |= 0x01; // Set P1.0 LED on for (i = 5000; i>0; i--); // Delay P1OUT &= ~0x01; // Reset P1.0 LED off _BIS_SR(LPM3_bits + GIE); // Enter LPM3 } } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer (void) { _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) }

Page 44: Ejercicios Con MSP430F2013

CAPITULO 3

ADC

(SD16)

Page 45: Ejercicios Con MSP430F2013

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

Page 46: Ejercicios Con MSP430F2013

Diagrama a bloques del SD16

Page 47: Ejercicios Con MSP430F2013
Page 48: Ejercicios Con MSP430F2013
Page 49: Ejercicios Con MSP430F2013

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) // SD16MEM0 > 0.3V?, clears IFG P1OUT &= ~0x01; else P1OUT |= 0x01; }