MSP 430

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 36

HOJA

DE EJERCICIOS (curso 2014/15)


1. Realizar un programa en ensamblador para que parpadee el bit P1.0, utilizando un bucle para realizar el retardo.

SOLUCIN:

;*************************************************************
; Plantilla que se crea automticamente
; Conviene especificar el microcontrolador usado, describir
; el programa y si fuera posible las patillas utilizadas
; Microcontrolador: MSP430G2553
; Descripcin:
;
MSP430G2553
;
----------------;
/|\|
XIN|;
| |
|
;
--|RST
XOUT|;
|
|
;
|
P1.0|-->LED
;
; Autor:
; Empresa: UA
; Fecha: 07/07/14
; Herramienta: IAR Embedded Workbench Version: 5.51
;*************************************************************
#include "msp430g2553.h"
miSP
EQU
0x400
; define el puntero de la Pila
ORG
0FC00h
; inicio del programa en memoria
;----------------------------------------------------------RESET
MOV.W
#miSP,SP
; Inicializa el SP
MOV.W
#WDTPW+WDTHOLD,&WDTCTL
; para el watchdog
BIS.B

#001h,&P1DIR

; el bit P1.0 como salida

XOR.B
MOV.W

#001h,&P1OUT
#050000,R15

DEC.W
JNZ
JMP

R15
L1
INICIO

;
;
;
;
;
;

INICIO

L1

Conmuta el bit P1.0


R15=50000 para realizar un retardo
se realiza 50000 veces el bucle L1
Decrementando R15
retardo=(1+2)*50000=150000T
vuelve a empezar

;-------------------------------------------;
VECTORES
;-------------------------------------------ORG 0FFFEh
DW
RESET
END

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


2. Realizar un programa en C para que parpadee el bit P1.0, utilizando un bucle para realizar el retardo.

SOLUCIN:
//*************************************************************
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= 0x01;

// Para el watchdog
// Configura P1.0 como salida direction

for (;;)
{
volatile unsigned int i;
P1OUT ^= 0x01;

// Conmuta P1.0 usando la XOR

i = 50000;
do (i--);
while (i != 0);
}

// Retardo


3. Realizar un programa en C que haga parpadear el bit P1.6, utilizando la funcin __delay_cicles(n ciclos)

SOLUCIN:
/*
Enciende el led verde P1.6
Utilizando __delay_cicles()
*/
#include <msp430.h>
#include <inttypes.h>
void main(){
WDTCTL= WDTPW+WDTHOLD;

//inclusiones.
//funcion principal
//Apagamos el watchdog

P1SEL= 0x00;
P1DIR|= BIT6;

//Salida el bit 6 del puerto 1

P1OUT|=BIT6;

//LED parte apagado

while(1){
//Loop infinito
P1OUT|=BIT6;
//prende el LED
__delay_cycles(100000); //espera
P1OUT&=~BIT6;
//apaga el LED
__delay_cycles(100000); //espera
}
}

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


4. Escribe un programa en lenguaje ensamblador en el cual inicialmente el bit P1.6 est apagado, cuando se pulse el

botn colocado en P1.3 se ponga a uno el bit P1.6 y si se vuelve a pulsar que se apague. Esto se debe realizar de
forma indefinida.
SOLUCIN:
;********************************************************************
#include "msp430g2553.h"
;-----------------------------------------------------ORG
0FC00h
; Definimos la direccion de inicio
;-----------------------------------------------------RESET
MOV.W
#0400h,SP
; Establecemos el SP
MOV.W
#WDTPW+WDTHOLD,&WDTCTL ; Detenemos el watchdog timer
MOV.B
#040h,&P1DIR
; Colocamos P1.6 salida resto entrada
MOV.B
#00h,&P1OUT
BIS.B
#BIT3, &P1REN
; Resistencia en la entrda P1.3
BIS.B
#BIT3, &P1OUT
; Resistencia de pull-up
SIGUE
BIT.B
#BIT3, &P1IN
; si pulsado 0000 1000 AND XXXX 0XXX
JZ
ENCIENDE
; si pulsado salta y enciende P1.6
JMP
APAGA
JMP
SIGUE
APAGA
BIC.B
#BIT6,&P1OUT
JMP SIGUE
ENCIENDE
BIS.B
#BIT6,&P1OUT
JMP SIGUE
;-----------------------------------------------------;
Vectores Interrupcin
;-----------------------------------------------------ORG
0FFFEh
; Vector RESET MSP 430
DW
RESET
;
END

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


5. Escribe un programa en lenguaje C en el cual inicialmente el bit P1.6 est apagado, cuando se pulse el botn

colocado en P1.3 se ponga a uno el bit P1.6 y si se vuelve a pulsar que se apague. Esto se debe realizar de forma
indefinida.
SOLUCIN:

#include <msp430g2553.h>
int i;
void main(void) {
WDTCTL = WDTPW + WDTHOLD;

// para el watchdog

P1OUT
P1DIR
P1DIR
P1REN
P1OUT

//
//
//
//
//

&= ~0x40;
|= 0x40;
&= ~0x08;
|= 0x08;
|= 0x08;

P1.6
P1.6
P1.3
P1.3
P1.3

a cero
(LED) como salida
(push button) como entrada
(botn) resistencia habilitada
(botn) resistencia pull-up

while (1){
if( BIT3 & ~P1IN ) {
P1OUT ^= 0x40;
}
}

// Si se pulsa botn
// led encendidO


6. Aade un antirrebotes al ejercicio 3


7. Aade un antirrebotes al ejercicio 4


8. Supongamos que la ejecucin normal del programa consiste en el desplazamiento de un bit, empezando en el

P2.0, despus se encender el P2.0 y el P2.1, despus el P2.0, P2.1 y P2.2, as sucesivamente hasta llega al P2.7,
que vuelve a empezar. Si en el bit P1.3 hay un flanco de bajada se debe atender la interrupcin ejecute el
correspondiente servicio (ISR) que deber sacar por P2 la siguiente secuencia:
secu DC8 00000001b,00000010b,00000100b,00001000b

DC8 00010000b,00100000b,01000000b,10000000b

DC8 00000000b,11111111b,00000000b,11111111b

DC8 00000000b,11111111b,00000000b,11111111b

Finsecu DC8 01010101b


Cuando se encuentre el valor 01010101b se debe salir de la interrupcin y continuar por donde iba. Escribir el
programa en ensamblador
4
Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


;----------------------------------------------------#include "msp430g2553.h"
#define
miSP 0x400
main
;-------------------------------------------------------------------------------ORG
0xFC00
;Inicio del programa
;-------------------------------------------------------------------------------RESET
MOV.W
#miSP,SP
; Inicia SP
MOV.W
#WDTPW+WDTHOLD,&WDTCTL ; Detiene WD
;----------------------esto es opcional para conseguir la frecuencia-----------MOV.B
&CALDCO_1MHZ, &DCOCTL
; calibra la f a 1MHz
MOV.B
&CALBC1_1MHZ, &BCSCTL1
; calibra la f a 1MHz
;-------------------------------------------------------------------------------BIC.B #BIT3, &P1DIR
; P1.3 IN #11110111b
BIS.B #BIT3, &P1OUT
; P1.3 Resist pullup, resto a cero 00001000b
BIS.B #BIT3, &P1REN
; P1.3 Resist pullup habilitada
BIS.B #BIT3, &P1IES
; flanco de bajada para P1.3
BIC.B #BIT3, &P1IFG
; borrar flags de interrup para P1.3
BIS.B #BIT3, &P1IE
; interrup locales habilita para P1.3
EINT
; GIE <--1
MOV.B #0xFF,&P2DIR
; P2 como salida 11111111b
;-----------------------------------------------------------------; PROGRAMA PRINCIPAL EN EJECUCIN
;-----------------------------------------------------------------MOV.B
#00h,&P2SEL
; obligatorio para que P2.6 y P2.7 sean salida
sigue
MOV.B
#00h,&P2OUT
; apagamos los diodos
MOV.W
#00010h,R14
; R14 y R15 para pasar parmetros
MOV.W
#020000,R15
; R14 y R15 para pasar parmetros
CALL
#retardo
; que se note que se apagan todos
SETC
; C <-- 1
MOV.B
#00h, R7
; R7 <-- 0000 0000
vuelta
RLC.B
R7
; rotar R7 a la izda incluido C
MOV.B
R7,&P2OUT
; P2.0 a P2.7 pone ceros, apaga,
MOV.W
#0005h,R14
; R14 y R15 para pasar parmetros
MOV.W
#025000,R15
; R14 y R15 para pasar parmetros
CALL
#retardo
MOV.B
R7,R8
; R7 --> R8 para saber si he terminado
XOR.B
#0FFh,R8
; averigua si se han apagado P2.0 a P2.7
JZ
sigue
; si es as, volvemos a empezar
JMP
vuelta
; si no, se continua rotando

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)

;--------------------------------------------------------------------P1_3_ISR;
Rutina de servicio a la interrupcin
;--------------------------------------------------------------------PUSH
R7
PUSH
R8
PUSH
R11
PUSH
R12
MOV
#secu,R5
; Asigna a la secu1 el puntero (R5)
ETQ1
MOV.B @R5+,&P2OUT
MOV.W #7,R14
; R14 y R15 para pasar parmetros
MOV.W #25000,R15
; a la subrutina retardo
CALL
#retardo
CMP
Finsecu,0(R5)
JNE
ETQ1
BIC.B #BIT3,&P1IFG
; Borra la flag de la interrupcin
POP
R12
POP
R11
POP
R8
POP
R7
RETI
;---------------------------------------------------------------------------retardo
;---------------------------------------------------------------------------MOV
R14,R11
; Valores del retardo
b2
MOV
R15,R12
; se pueden ajustar
b1
DEC.W R12
; bucle fino R12
JNZ
b1
DEC.W R11
; bucle grueso
JNZ
b2
RET
;----------------------------------------------------;
Definicion de las secuencias
;----------------------------------------------------secu
DC8
00000001b,00000010b,00000100b,00001000b
DC8
00010000b,00100000b,01000000b,10000000b
DC8
00000000b,11111111b,00000000b,11111111b
DC8
00000000b,11111111b,00000000b,11111111b
Finsecu DC8
01010101b
;--------------------------------------------------------------------;
Vectores de Interrupcin y Reset
;--------------------------------------------------------------------ORG 0FFFEh
; Vector para el reset
DW RESET
ORG 0FFE4h
; Vector para la interrupcin del P1
DW P1_3_ISR
END main

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



9. Supongamos que la ejecucin normal del programa consiste en el desplazamiento de un bit, empezando en el

P2.0, despus se encender el P2.0 y el P2.1, despus el P2.0, P2.1 y P2.2, as sucesivamente hasta llega al P2.7,
que vuelve a empezar. Si en el bit P1.3 hay un flanco de bajada se debe atender la interrupcin ejecute el
correspondiente servicio (ISR) que deber sacar por P2 la siguiente secuencia:
secu DC8 00000001b,00000010b,00000100b,00001000b

DC8 00010000b,00100000b,01000000b,10000000b

DC8 01000000b,00100000b,00010000b,00001000b

DC8 00000100b,00000010b,00000001b,00000000b

DC8 11111111b,00000000b, 11111111b,00000000b

Finsecu DC8 01010101b


Cuando se encuentre el valor 01010101b se debe salir de la interrupcin y continuar por donde iba. Esrcribir el
programa en C
SOLUCIN:

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)

#include <msp430.h>
char secu[21] = {0x01,0x02,0x04, 0x08,0x10,0x20,0x40,0x80,
0x40,0x20, 0x10, 0x08,0x04,0x02,0x01};
char secu_interrup[24] = {0x01,0x03,0x07, 0x0F,0x1F,0x3F,0x7F,0xFF,
0x7F,0x3F, 0x1F, 0x0F,0x07,0x03,0x01,0x00,0xFF,0x00,
0xFF,0x00,0xFF,0x00,0xFF,0x00};
int i,r,j;
// Rutina de Retardo
void RETARDO(void)
{r = 20000;
do (r--);
while (r != 0);
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD;
// para el watchdog
DCOCTL = CALDCO_1MHZ;
//calibra la f a 1MHz
BCSCTL1 = CALBC1_1MHZ;
// configuracin de los puertos
P2SEL &= ~0xFF;
// P2 como I/O general (GPIO)
P2DIR |= 0xFF;
// P2 como salida
P1DIR &= ~0x08;
// P1.3 (push button) como entrada
P1REN |= 0x08;
// P1.3 (botn) resistencia habilitada
P1OUT |= 0x08;
// P1.3 (botn) resistencia pull-up
// configuracin de la interrupcin de P1.3
P1IES |= 0x08;
// flanco de bajada para P1.3
P1IFG &= ~0x08;
// borrar flags de interrup para P1.3
P1IE |= 0x08;
// interrup locales habilita para P1.3
_BIS_SR(GIE);
// GIE <--1
// __enable_interrupt();
// equivalente a la anterior, se debe cambiar
// msp430.h por <io430.h>
while(1)
for (i = 0; i <15 ; i++)
{
if( BIT3 & P1IN ){
P2OUT = secu[i];
RETARDO();
}

// Si NO

se pulsa botn

}
}
//----------------------------------------------------// Rutina de atencin de interrupcin del puerto P1
//----------------------------------------------------#pragma vector=PORT1_VECTOR
__interrupt void P1_Interrupt(void)
{
for (j = 0; j <24 ; j++)
{
P2OUT = secu_interrup[j];
RETARDO();
}
P1IFG &= ~BIT3; // Reseta IFG para P1.3
}

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



10. El circuito de la figura tiene el C alimentado a 3,3V, y los displays de 7 segmentos son de ctodo comn.

Encenderemos los segmentos mediante los bits del P1 y seleccionamos el que debe encenderse mediante el
P2(P2.0 y P2.1). Calcula el valor de las resistencias R1 y R2, sabiendo que:
ILED=5mA; VLED=1,8V
VCEsat=0,2V; = 200
La corriente proporcionada por cada patilla de un puerto de salida debe estar entre 4 y 5 mA como mximo y la
corriente mxima que debe proporcionar un puerto en conjunto no debe exceder de los 25 mA.

Fig.1 circuito

SOLUCIN:
R1=300 330 ; R2=21600 22K

11. Escribir un programa en C para el circuito del problema anterior. Al pulsar el botn se iniciar la cuenta de 0 a 99

con un periodo aproximado de 1s. El pulsador solicita una interrupcin en P1.3 por flanco de bajada








9

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)




#include <msp430g2553.h>
unsigned int r, i, j;
char display[10] = {0x77,0x06,0xB3, 0x97,0xC6,0xD5,0xF5,0x07,0xF7,0xC7};
//gfedcba -> p1.7,6,5,4,2,1,0
// Rutina de Retardo
void RETARDO(void)
{r = 200;
do (r--);
while (r != 0);
}
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Paramos el WDT
BCSCTL1 = CALBC1_1MHZ;
// Y establecemos una frecuencia
DCOCTL = CALDCO_1MHZ;
// de un 1MHz
P1DIR = 0xF7;
// P1.3 como entrada, resto como salidas
P2DIR = BIT0+BIT1;
// P2.0 y P2.1 como salidas
P1OUT = BIT3;
// resitencia pull-up
P1REN = BIT3;
// P1.3 con resistencia de pullup
P1IE = BIT3;
// P1.3 con interrupcin habilitada
P1IES = BIT3;
// y activa por flanco de bajada
_BIS_SR(LPM0_bits + GIE); // Habilita interrupciones y deshabilita la CPU y MCLK
}
#pragma vector=PORT1_VECTOR
// Rutina de servicio para la interrupcin del P1
__interrupt void Port_1(void) // forma de llamar a la ISR del P1
{
i = 0;
j = 0;
for (j = 0; j < 10; j++)
{
for (i = 0; i < 10; i++)
{
int k;
for (k=0; k< 100; k++)
{
P1OUT = display[i]; // Pone el nmero en P1
P2OUT = 0x01;
// Y activa el display de las unidades
RETARDO();
P1OUT = display[j];
// Pone el otro nmero en P1
P2OUT = 0x02;
// Y activa el display de las decenas
RETARDO();
}
}
}
P2OUT = 0x03;
// deja activos los dos displays
P1IFG &= ~0x08;
// borra el flag de peticin de interrupcin
}

10

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


12. Escribir un programa en ensamblador para el circuito del problema anterior. Al pulsar el botn se iniciar la

cuenta de 0 a 99 con un periodo aproximado de 1s. El pulsador solicita una interrupcin en P1.3 por flanco de
bajada.
SOLUCIN:
#include <msp430G2553.h>
Tmux

DEFINE 300

main

;Esto viene bien por lo del "run tu main", aunque se puede quitar

;------------------------------------------------------------------------------ORG

0F800h

;------------------------------------------------------------------------------RESET
;--------------Configuracin -------------------------------------MOV

#0280h,SP

MOV

#WDTPW+WDTHOLD,&WDTCTL

MOV.B &CALBC1_1MHZ,&BCSCTL1

; Funciones de Calibracin a 1MHz

MOV.B &CALDCO_1MHZ,&DCOCTL
MOV.B

#BIT6+BIT0,&P1DIR

MOV.B

#0x0,&P1OUT

; para que estn apagados

MOV.B #0F7h,&P1DIR

; P1.3 como entrada y el resto como salidas

BIS.B #BIT3,&P1REN

; Resistencia en la entrada P1.3

BIS.B #BIT3,&P1OUT

; Decimos que sea de pull-up

BIS.B #BIT3,&P1IES

; Defino P1.3 como activo por flanco de bajada

BIS.B #BIT3,&P1IE

; Y lo habilito como entrada de interrupcin

BIS.B #BIT0+BIT1,P2DIR

; Defino P2.0 y P2.1 como salidas

MOV.B #GIE,SR

; Habilitacin global de las interrupciones

;------------------------------------------------------------------------------jmp

; Programa principal

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

11

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)

;------------------------------------------------------------------------------;
Rutina de tratamiento de la interrupcin
;------------------------------------------------------------------------------P1_ISR
MOV
#TSeg,R4
; Inicializamos los punteros de Unidades y
MOV
#TSeg,R5
; Decenas con la direccin de la tabla de segmentos
CLR
R6
; Unidades = 0
CLR
R7
; Decenas = 0
Tiempo
MOV.B
#100,R10
ETIQ1
MOV.B @R4,&P1OUT
; PUni al Puerto de Salida
MOV.B #001h,&P2OUT
; Visualiza dato en posicion de las Unidades
CALL #RETARDO
; Tiempo que est encendido el dgito
MOV.B @R5,&P1OUT
; PDcn al Puerto de Salida
MOV.B #002,&P2OUT
; Visualiza dato en posicion de las decenas
CALL #RETARDO
; Tiempo que est encendido el dgito
DEC
R10
JNZ
ETIQ1
INC
R6
; Unidades = Unidades + 1
INC
R4
; Actualiza el puntero de unidades
CMP
#10,R6
; Unidades es 9?
JNE
Tiempo
CLR
R6
; Unidades = 0
MOV
#TSeg,R4
; Restaura la direccin de la Tabla de segmentos
INC
R7
; Decenas = Decenas + 1
INC
R5
; Actualiza el puntero de decenas
CMP
#10,R7
; Decenas es 9?
JNE
Tiempo
CLR
R6
; Unidades = 0
MOV
#TSeg,R4
; Restaura la direccin de la Tabla de segmentos
INC
R7
; Decenas = Decenas + 1
INC
R5
; Actualiza el puntero de decenas
CMP
#10,R7
; Decenas es 9?
JNE
Tiempo
MOV.B #BIT3,&P1OUT
; Para apagar el display al terminar
MOV.B
#BIT0+BIT1,&P2OUT
BIC.B #BIT3,&P1IFG
; Borra el flag de interrupcion
RETI

12

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


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

Subrutina de retardo

;------------------------------------------------------------------------------RETARDO MOV #Tmux,R15


ETIQ2 DEC
JNZ

R15
ETIQ2

RET
;------------------------------------------------------------------------------;

Tabla de 7 segmentos

Estn ordenados g-f-e-d-c-b-a

;------------------------------------------------------------------------------TSeg
; 0, 1 , 2
DC8

, 3 , 4 ,

5 ,

6 ,

7 , 8 , 9

77h,06h,0B3h,97h,0C6h,0D5h,0F5h,07h,0F7h,0C7h

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

Vectores de interrupcin y reset

;------------------------------------------------------------------------------ORG

0FFFEh

DW

RESET

ORG

0FFE4h

DW

P1_ISR

END

main

; Vector de reset
; Vector de interrupcin para P1


13. Escribe un programa en C para que cuando cada vez que se pulse el P1.3, interrupcin por flanco de bajada,

cambie la frecuencia de parpadeo de los dos diodos colocados en P1.0 y P1.6


SOLUCIN:











13

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)

#include <msp430.h>
#include <inttypes.h>
int j=0;
int Tini=30000;
void main(){
WDTCTL= WDTPW+WDTHOLD;
P1SEL= 0x00;
P1DIR|= (BIT0+BIT6);
P1DIR&=~BIT3;
P1REN|=BIT3;

//resistencia en la entrada habilitada

P1OUT|=BIT3;

// de pull-up

P1IE|=BIT3;

//Habilitamos las interrupciones,


//mas informacin en la userguide.

P1IES|=BIT3;
P1IFG&=~BIT3;
P1OUT|=BIT0;
P1OUT&=~BIT6;
_BIS_SR(GIE);

//Habilitamos las interrupciones generales. IMPORTANTE!!

while(1){

//El mismo cdigo anterior

for(j=0;j<Tini;j++);
P1OUT^=BIT6;
P1OUT^=BIT0;
if(Tini<=1500){Tini=30000;}
}
}
Rutina de interrupcin.
#pragma vector= PORT1_VECTOR
__interrupt void Led_ISR (void){
P1IFG&=~BIT3;

//Al

salir de una interrupcin

//SIEMPRE es necesario limpiar la bandera.


Tini=Tini-5000;
}



14

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



14. Escribir un programa en ensamblador para que el bit P1.0 parpadee utilizando la interrupcin del Watchdog. El

periodo de parpadeo ser aproximadamente 30ms, si la fuente del reloj es por defecto DCO=SMCLK
SOLUCIN:
;***********************************************************************
#include <msp430.h>
;------------------------------------------------------------------------ORG
0FC00h
; Reset
;------------------------------------------------------------------------RESET
mov.w
#0400h,SP
; Inicializa stackpointer
SetupWDT
mov.w
#WDT_MDLY_32,&WDTCTL
; WDT~30ms intrvalo del timer
bis.b
#WDTIE,&IE1
; habilita interrupcin del WD
SetupP1
bis.b
#001h,&P1DIR
; P1.0 salida
;
Mainloop

bis.w
Jmp $

#CPUOFF+GIE,SR

; CPU off, habilita Interrup


; se para aqu
;
;----------------------------------------------------------------------WDT_ISR;
Cambia P1.0
;----------------------------------------------------------------------xor.b
#001h,&P1OUT
; cambia P1.0
reti
;
;
;----------------------------------------------------------------------;
Vectores de Interrupcin
;----------------------------------------------------------------------ORG
0FFFEh
; MSP430 RESET Vector
DW
RESET
;
ORG
0FFF4h
; WDT Vector
DW
WDT_ISR
;
END











15

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



15. Escribir un programa en ensamblador para que el bit P1.0 parpadee utilizando la interrupcin del Watchdog. El

periodo de parpadeo ser exactamente 250ms basado en el cristal de 32KHz colocado en las patillas del
microcontrolador . Teniendo en cuenta que la fuente del reloj ser ACLK=LFXT1=32768Hz, y MCLK=SMCLK=DCO. Si
dividimos los 215 / 213 obtendremos una frecuencia de 4Hz, es decir un T=250ms.
SOLUCIN:
;*********************************************************************
#include <msp430.h>
;-------------------------------------------------------------------ORG
0FC00h
; Reset
;-------------------------------------------------------------------RESET
mov.w
#0400h,SP
; Inicializa stackpointer
Setup
mov.w
#WDT_ADLY_250,&WDTCTL
; WDT 250ms
bis.b
#WDTIE,&IE1
; habiita la INT del WDT
SetupP1
bis.b
#001h,&P1DIR
; P1.0 salida
;
Mainloop
bis.w
#LPM3+GIE,SR
; Modo LPM3, INT habilitadas
Jmp
$
;------------------------------------------------------------------------WDT_ISR;
Cambia P1.0
;------------------------------------------------------------------------xor.b
#001h,&P1OUT
; Cambia P1.0
reti
;
;
;------------------------------------------------------------------------;
Interrupt Vectors
;------------------------------------------------------------------------ORG
0FFFEh
; MSP430 RESET Vector
DW
RESET
;
ORG
0FFF4h
; WDT Vector
DW
WDT_ISR
;
END










16

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



16. Escribe un programa que utilizando la interrupcin software TA_0, cambie el P1.6 cada 50.000 ciclos de SMCLK.

SMCLK proporciona la fuente de reloj para TACLK. Durante la ISR de TA_0, P1.6 se enciende y apaga cada 50.000
ciclos de reloj. La CPU est normalmente apagada y se pone en marcha slo durante el ISR de TA.
SOLUCIN:
;*************************************************************************
#include <msp430.h>
;------------------------------------------------------------------------ORG
0FC00h
; Reset
;------------------------------------------------------------------------RESET
mov.w
#0400h,SP
; Inicializa SP
StopWDT
mov.w
#WDTPW+WDTHOLD,&WDTCTL ; Stop WDT
SetupP1
bis.b
#BIT0,&P1DIR
; P1.0 salida
SetupC0
mov.w
#CCIE,&CCTL0
; habilita INT de CCR0
mov.w
#50000,&CCR0
;
SetupTA
mov.w
#TASSEL_2+MC_2,&TACTL
; SMCLK, modo cont
;
Mainloop

bis.w
#CPUOFF+GIE,SR
; CPU off, INT habilitadas
jmp
$
;------------------------------------------------------------------------TA0_ISR;
Cambia P1.0
;------------------------------------------------------------------------xor.b
#001h,&P1OUT
; Cambia P1.0
add.w
#50000,&CCR0
; AAde el Offset a CCR0
reti
;
;
;------------------------------------------------------------------------;
Interrupt Vectors
;------------------------------------------------------------------------ORG
0FFFEh
; MSP430 RESET Vector
DW
RESET
;
ORG
0FFF2h
; Timer_A0 Vector
DW
TA0_ISR
;
END







17

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


17. Escribir un programa en ensamblador que visualice ACLK en P1.0 , SMCLK en P1.4 y que en P1.1 se obtenga una

frecuencia de aproximadamente SMCLK/15.


SOLUCIN:

18. Utilizando consulta (polling), de los bits P1.4 y P1.5. Generar el programa que permita realizar lo siguiente:

a) Cuando P1.4 tengan un flanco de bajada se realizar una salida por el puerto P2 (irn apagndose los leds de
mayor a menor peso), con un tiempo de aproximadamente 500ms
b) Cuando P1.5 tengan un flanco de bajada se realizar una salida por el puerto P2 (irn apagndose los leds de
menor a mayor peso), con un tiempo de aproximadamente 1s
SOLUCIN

18

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)
























19. Qu ventaja tiene utilizar _BIS_SR(GIE)frente a __enable_interrupt()para habilitar las interrupciones
globales.

SOLUCIN:
Con _BIS_SR(GIE)se puede, adems, modificar el resto de bits del registro SR, por ejemplo establecer el modo de trabajo
LPM0, que sera, _BIS_SR(LPM0+GIE)mientras que con __enable_interrupt()solamente podemos habilitar las
interrupciones globales.



19

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



20. Escribir un programa que realice lo siguiente. Cuando se pulsa reset se est ejecutando una secuencia que

consiste en desplazar un bit a uno de izquierda a derecha y de derecha a izquierda por los 8 bits del puerto 2.
Cuando se pulsa por primera vez el pulsador S2, colocado en P1.3, se para la secuencia y cuando se vuelve a pulsar
por segunda vez se contina por donde iba la secuencia.
SOLUCIN:

#include <msp430.h>
char secuencia[15] =

{0x01,0x02,0x04, 0x08,0x10,0x20,0x40,0x80,
0x40,0x20, 0x10, 0x08,0x04,0x02,0x01};

int i,j;
int ii=0;

// variable para saber por donde va las secuencia

int parar=0;
void main(void) {
WDTCTL = WDTPW + WDTHOLD;
DCOCTL = CALDCO_1MHZ;

// para el watchdog
//calibra la f a 1MHz

BCSCTL1 = CALBC1_1MHZ;
// configuracin de los puertos
P2SEL &= ~0xFF;

// P2 como I/O general (GPIO)

P2DIR |= 0xFF;

//

P2 como salida

P1DIR &= ~0x08;

//

P1.3 (push button) como entrada

P1REN |=

0x08;

//

P1.3 (botn) resistencia habilitada

P1OUT |=

0x08;

//

P1.3 (botn) resistencia pull-up

// configuracin de la interrupcin de P1.3


P1IES |= 0x08;

// flanco de bajada para P1.3

P1IFG &= ~0x08;

// borrar flags de interrup

P1IE

|= 0x08;

//_BIS_SR(GIE);
__enable_interrupt() ;

20

para P1.3

// interrup locales habilita para P1.3


// GIE <--1
//es equivalente a la anterior

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


while(1) {
for (i = ii; i <15 ; i++)
{
P2OUT = secuencia[i];
if (parar==1) break;
//P2OUT = secu[i];
__delay_cycles(100000);
}
ii=i;

//para saber por donde va la secuencia

if (ii==15) ii=0;

// si se ha llegado al final de la secuencia


// ponerla a cero

while (parar==1){
P2OUT = secuencia[ii-1];

//se resta para que muestre el adecuado

}
}
}
//----------------------------------------------------// Rutina de atencin de interrupcin del puerto P1
//----------------------------------------------------#pragma vector=PORT1_VECTOR
__interrupt void P1_Interrupt(void)
{
__delay_cycles(250000);

//antirrebotes software este valor es el ms adecuado

parar ^= 1;
P1IFG &= ~BIT3;

// Pone a cero IFG para P1.3












21

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


21. Utilizar el Timer 1 en modo continuo con el mdulo captura/compara 0 para que el led P1.0 parpadee cada

0,1s (utilizar MCLK = 1MHz).



SOLUCIN:
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
DCOCTL = CALDCO_1MHZ;

// Paramos el WDT
//calibra la f a 1MHz

BCSCTL1 = CALBC1_1MHZ;
P1DIR |= 0x01;
TA1CCTL0 = CCIE;

// P1.0 como salida para el LED


// Habilito la interrupciones del
// Registro Captura/Compara 0 del Timer A1
TA1CCR0 = 50000;
// Y cargo este registro con el nmero de
// ciclos que quiero contar
TA1CTL = TASSEL_2 + ID_1 + MC_2; // Seleccionamos SMCLK como fuente de reloj,
//la divido por dos y modo continuo
// ***********************************************************************
// f=1000000; 1000000/2=500000 T= 2us; cuento 50000 pulsos*2us=0,1ms
// ***********************************************************************
//En registro de control del timer, para cada uno de los campos est la opcin
//elegir los bits de forma individual o directamente el modo (aparecen con
//subguin)
//Como voy a trabajar en modo comparacin no hace falta que modifique el bit CAP
_BIS_SR(LPM0_bits + GIE);

// habilitamos el modo 0 de bajo


//consumo y habilitamos las interrupciones

}
// Rutina de servicio de la interrupcin del Timer 1
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer_A0 (void)
{
P1OUT ^= 0x01;
// Hacemos cambiar al LED
TA1CCR0 += 50000;
// Se recarga el registro con 50000 valor que
//debe contar para conseguir 0,1s
}









22

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


22. Utilizar el Timer 1 en modo ascendente con el mdulo captura/compara 0 para que el led P1.0 parpadee

cada 0,1s (utilizar MCLK = 1MHz)



SOLUCIN:
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
DCOCTL = CALDCO_1MHZ;

// Paramos el WDT
//calibra la f a 1MHz

BCSCTL1 = CALBC1_1MHZ;
P1DIR |= 0x01;
TA1CCTL0 = CCIE;

// P1.0 como salida para el LED


// Habilito la interrupciones del
// Registro Captura/Compara 0 del Timer A1
TA1CCR0 = 50000;
// Y cargo este registro con el nmero de
// ciclos que quiero contar
TA1CTL = TASSEL_2 + ID_1 + MC_1; // Seleccionamos SMCLK como fuente de reloj,
//la divido por dos y modo ASCENDENTE
// ***********************************************************************
// f=1000000; 1000000/2=500000 T= 2us; cuento 50000 pulsos*2us=0,1ms
// ***********************************************************************
//En registro de control del timer, para cada uno de los campos est la opcin
//elegir los bits de forma individual o directamente el modo (aparecen con
//subguin)
//Como voy a trabajar en modo comparacin no hace falta que modifique el bit CAP
_BIS_SR(LPM0_bits + GIE);

// habilitamos el modo 0 de bajo


//consumo y habilitamos las interrupciones

}
// Rutina de servicio de la interrupcin del Timer 1
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer_A0 (void)
{
P1OUT ^= 0x01;
// Hacemos cambiar al LED
}










23

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


23. Escribir un programa para que el led P1.0 parpadee unas 8 veces por segundo (suponiendo que MCLK = 1

MHz) por desbordamiento del timer.



SOLUCIN:
Cuando se desborda el timer el flag TAIFG se activa y se produce la llamada a la interrupcin. Para saber quien ha
producido la llamada a la interrupcin bastara consultar los flags (CCIFG1, CCIFG2, TAIFG), pero habra que hacerlo
por encuesta. Para evitarlo, el MSP430 tiene el registro TAIV, que nos ayudar a identificar la fuente de interrupcin
rpidamente. Este registro contiene un valor que viene determinado por la fuente de interrupcin, 0x000A para el
overflow del Timer. Este ejemplo es interesante verlo en ensamblador.

#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;

// Paramos el WDT

P1DIR |= 0x01;

// P1.0 como salida para el LED

TA0CTL = TASSEL_2 + MC_2 + ID_1 + TAIE;

// Seleccionamos SMCLK como fuente


// de reloj, modo continuo, % por 2 y
// habilita interrupciones

_BIS_SR(LPM0_bits + GIE);

// habilitamos el modo 0 de bajo


// consumo y habilitamos
// las interrupciones globales

}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A0 (void)
{
/*

switch(TA0IV)

{
case

2: break;

case

4: break;

// Este es el caso de que se haya activado CCIFG1


// Este es el caso de que se haya activado CCIFG2

case 10: P1OUT ^= 0x01; // Y este es el timer overflow


break;
}
*/
P1OUT ^= 0x01;
}






24

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


24. Repetir el ejercicio anterior, en ensamblador.

SOLUCIN:

#include <msp430G2553.h>
;------------------------------------------------------------------------------ORG
0F800h
;------------------------------------------------------------------------------RESET
mov.w
#0400h,SP
;Incializamos el SP
mov.w
#WDTPW+WDTHOLD,&WDTCTL
;Paramos el WDT
bis.b
#001h,&P1DIR
SetupTA
mov.w #TASSEL_2+ID_1+MC_2+TAIE,&TACTL ;Seleccionamos SMCLK ;
;como fuente de reloj y se % 2
;modo ascendente
Mainloop
bis.w
#LPM0+GIE,SR
;CPU OFF e interrupciones
nop
;------------------------------------------------------------------------------; ISR genrica para CCR1 a 4 y overflow
; TA0IV contiene 2, 4, 6, 8 10 (0A). Lo que se hace es aadir su contenido al
; PC.
; si los ponemos de forma consecutiva, siempre sabremos quin ha producido la
; interrupcin y saltar a donde toque.
; Los reti tambin ocupan 2 bytes, por lo que tambin es correcto
;En este caso, como en caso de desbordamiento el contenido de TA0IV es 10 (0A)
; y es el ltimo, no hace falta poner salto.
;Eso s, hay que poner los todos los CCR1 a 4, aunque el nuestro solo tenga 3
; porque los valores son fijos.
;------------------------------------------------------------------------------TA0_ISR
add.w
&TA0IV,PC
reti
; No hay interrupcin pendiente (TA0IV = 0)
reti
; CCR1
reti
; CCR2
reti
; CCR3 - Este no existe en nuestro MSP430
reti
; CCR4 - Este no existe en nuestro MSP430
TA_over
xor.b
#001h,&P1OUT
; Desbordamiento, tambin JMP tratar_over
reti
;
;------------------------------------------------------------------------------;
Interrupt Vectors
;------------------------------------------------------------------------------ORG
0FFFEh
; MSP430 RESET Vector
DW
RESET
;
ORG
0FFF0h
; Vector del Timer0_A1
DW
TA0_ISR
;
END




25

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



25. Escribir un programa para que por la patilla P1.1 se muestre TA.0 (suponiendo que MCLK = 1 MHz) y que la

frecuencia obtenida por P1.1 sea de 1KHz. Utilizando como reloj SMCLK
SOLUCIN:
Se utiliza la patilla P1.1 como salida de TA.0. No hay llamada a interrupciones, se desconecta la CPU y queda
simplemente funcionando el Timer con el reloj.
El registro TA0CCR0 deberemos cargarlo con un valor que obtenemos de fsal = fSMCLK/TA0CCRO
cargamos el registro de comparacin con: TA0CCR0 = fSMCLK/ fsal =1000, es decir, como tenemos el tiempo a cero y el
tiempo a uno, 1000/2=500, y se empieza la cuenta en 0, TA0CCRO=499

#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;

// Paramos el WDT

BCSCTL1 = CALBC1_1MHZ;

// Ajustamos frecuencia a 1MHz

DCOCTL = CALDCO_1MHZ;

//

P1SEL |= 0x02;

// Configuramos P1.1 como salida del Timer

P1DIR |= 0x07;

// Y la habilitamos como salida

TA0CCTL0 = OUTMOD_4;

// Registro Captura/Compara del Timer A0 pongo


// modo Salida Toggle

TA0CCR0 = 499;
TA0CTL = TASSEL_2 + MC_1;

// Y en registro del control de timer


// seleccionamos SMCLK como fuente de reloj
// modo ascendente.

_BIS_SR(LPM0_bits);

// habilitamos el modo 0 de bajo consumo



26

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


26. Escribir un programa en ensamblador para que el bit P1.6 se encienda cuando la seal introducida por A1 sea

mayor de 0,5*Vcc, utilizar el convertidor ADC tomando 16 muestras por segundo


;*******************************************************************************
#include <msp430.h>
;------------------------------------------------------------------------------ORG
0FC00h
;------------------------------------------------------------------------------#define
miSP 0x400
;------------------------------------------------------------------------------RESET
mov.w
#miSP,SP
; inicializa stackpointer
mov.w
#WDTPW+WDTHOLD,&WDTCTL ; Stop WDT
mov.w
#ADC10SHT_2+ADC10ON+ADC10IE,&ADC10CTL0 ; 16x, enable int.
mov.w
#INCH_1, &ADC10CTL1
bis.b
#0x02,&ADC10AE0
; P1.1 entrada de ADC10
bis.b
#0x040,&P1DIR
; P1.6 salida
;
vuelta
bis.w
#ENC+ADC10SC,&ADC10CTL0 ; empezar muestreo y conversin
bis.w
#CPUOFF+GIE,SR
; modo LPM0, int global hab
bic.b
#0x40,&P1OUT
; P1.6 = 0
cmp.w
#01FFh,&ADC10MEM
; ADC10MEM = A1 > 0.5*Vcc
jlo
vuelta
; otra vez
bis.b
#0x40,&P1OUT
; P1.6 = 1
jmp
vuelta
; otra vez
;------------------------------------------------------------------------------ADC10_ISR; Salir de LPM0 y reti
;------------------------------------------------------------------------------bic.w
#CPUOFF,0(SP)
; sale de LPM0 y reti
reti
;
;------------------------------------------------------------------------------COMMON INTVEC
; Interrupt Vectors
;------------------------------------------------------------------------------ORG
ADC10_VECTOR
; ADC10 Vector
DW
ADC10_ISR
ORG
RESET_VECTOR
; POR, ext. Reset
DW
RESET
END






27

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


27. Escribir un programa en C para que el bit P1.6 se encienda cuando la seal introducida por A1 sea mayor de

0,5*Vcc, utilizar el convertidor ADC tomando 16 muestras por segundo.

#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Stop WDT
ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // 16x, enable int.
ADC10CTL1 = INCH_1;
// entrada A1
ADC10AE0 |= 0x02;
// PA.1 entrada a convertir
P1DIR |= 0x40;
// P1.6 salida
for (;;)
{
ADC10CTL0 |= ENC + ADC10SC;
__bis_SR_register(CPUOFF + GIE);
if (ADC10MEM < 0x1FF)
P1OUT &= ~0x40;
else
P1OUT |= 0x40;
}

// inicio de muestro y conversin


// modo LPM0 e inter. globales hab.
// apagar

P1.6

// encender P1.6

}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF);
}

// sacar de LMP0(CPUOFF)












28

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


28. Escribir un programa para que por la patilla P1.1 se muestre TA.0 (suponiendo que MCLK = 1 MHz) y que la

frecuencia obtenida por P1.1 sea de 1KHz. Utilizando como reloj ACLK
SOLUCIN: El registro TA0CCR0 deberemos cargarlo con un valor que obtenemos de fsal = fACLK/TA0CCRO
cargamos el registro de comparacin con: TA0CCR0 = fACLK/ fsal =32768/1000=32,7, es decir, como tenemos el tiempo
a cero y el tiempo a uno, 32,7/2=16,35 y se empieza la cuenta en 0, TA0CCRO=15


#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;

// Paramos el WDT

P1SEL |= 0x02;

// Configuramos P1.1 como salida del Timer

P1DIR |= 0x07;

// Y la habilitamos como salida

TA0CCTL0 = OUTMOD_4;

// Registro Captura/Compara del Timer A0 pongo


// modo Salida Toggle

TA0CCR0 = 15;
TA0CTL = TASSEL_1 + MC_1;

// Y en registro del control de timer


// seleccionamos ACLK como fuente de reloj
// modo ascendente.

_BIS_SR(LPM3_bits);

// habilitamos el modo 3 de bajo consumo













29

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


29. Generar una salida PWM en la patilla P1.2 con una frecuencia de 2KHz y un Duty Cycle del 75% y utilizando el

Timer A0 en modo ascendente y salida reset/set, utilizando SMCLK como fuente del reloj
SOLUCIN:
El valor de TA0 define el periodo del PWM y el valor en TACCR1 define el duty cycle que viene dado por
TA0CCR1/TA0CCR0. Calculamos el valor de TA0CCR0=500, para obtener un duty cycle del 75% tendremos que
poner en TA0CCR1=375, es decir, (500*0.75)=375
fSAL = fSMCLK / TA0CCR0 = 2 KHz TA0CCR0= fSMCLK/fSAL= 106/2000 = 500 499 (0 a 499) 75% de 500 =375

#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;

// Paramos el WDT

BCSCTL1 = CALBC1_1MHZ;

// f=1Mhz

DCOCTL = CALDCO_1MHZ;
P1SEL |= 0x04;

// Configuramos P1.2 como salida del Timer

P1DIR |= 0x04;

// Y la habilitamos como salida

TA0CCTL1 = OUTMOD_7;

// Registro Captura/Compara 1 del Timer A0


// el modo Salida Reset/Set
// TA0CCR0 determina el periodo
// TA0CCR1 determina el flanco

TA0CCR0 = 499;
TA0CCR1 = 375;
TA0CTL = TASSEL_2 + MC_1;
_BIS_SR(LPM0_bits);

//modo ascendente y SMCLK fuente del reloj


// habilitamos el modo 0 de bajo consumo









30

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



30. Generar una salida PWM en la patilla P1.2 con una frecuencia de 2KHz y un Duty Cycle del 75% y utilizando el

Timer A0 en modo ascendente y salida reset/set, utilizando ACLK como fuente del reloj
SOLUCIN:
El valor de TA0 define el periodo del PWM y el valor en TACCR1 define el duty cycle, que viene dado por
TA0CCR1/TA0CCR0. Calculamos el valor de TA0CCR0=16, para obtener un duty cycle del 75% tendremos que
poner en TA0CCR1=375, es decir, (500*0.75)=12

fSAL = fACLK / TA0CCR0 = 2 KHz TA0CCR0= fACLK/fSAL= 16,3 15(0 a 15) 75% de 16 =12

#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;

// Paramos el WDT

BCSCTL1 = CALBC1_1MHZ;

// f=1Mhz

DCOCTL = CALDCO_1MHZ;
P1SEL |= 0x04;

// Configuramos P1.2 como salida del Timer

P1DIR |= 0x04;

// Y la habilitamos como salida

TA0CCTL1 = OUTMOD_7;

// Registro Captura/Compara 1 del Timer A0


// el modo Salida Reset/Set
// TA0CCR0 determina el periodo
// TA0CCR1 determina el flanco

TA0CCR0 = 15;
TA0CCR1 = 12;
TA0CTL = TASSEL_1 + MC_1;
_BIS_SR(LPM0_bits);

//modo ascendente y SMCLK fuente del reloj


// habilitamos el modo 0 de bajo consumo









31

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


31. Realizar un programa para que la UART transmita el abecedario con la siguiente configuracin: 9600, 8bits,

1bit de stop, y sin paridad y que se pueda visualizara travs del USB en el hyperteminal.
SOLUCIN:
#include <msp430.h>
unsigned int contador = 97;
unsigned int i;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Stop WDT
BCSCTL1 = CALBC1_1MHZ;
// frecuencia 1MHz
DCOCTL = CALDCO_1MHZ;
P1SEL = BIT1 + BIT2 ;
// P1.1 = RXD, P1.2=TXD
P1SEL2 = BIT1 + BIT2 ;
// P1.1 = RXD, P1.2=TXD
UCA0CTL1 |= UCSSEL_2;
// SMCLK
UCA0BR0 = 104;
// 1MHz 9600
UCA0BR1 = 0;
// 1MHz 9600
UCA0MCTL = UCBRS0;
// Modulation UCBRSx = 1
UCA0CTL1 &= ~UCSWRST;
// **Inicializa mquina de estado de la USCI
IE2 |= UCA0RXIE + UCA0TXIE;
// habilita las interru`ciones de RX y TX
__bis_SR_register(LPM0_bits + GIE);
// Enter LPM0, interrupts enabled
}
// ISR de TX
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
for(i=97; i<123; i++){
while (!(IFG2&UCA0TXIFG));
// USCI_A0 TX buffer preparado?
if (contador <123)
{
UCA0TXBUF = i;
// Envo caracter i=97
delay_cycles(1500);
//tiempo para transmitir un caracter ~1,5ms
}
else if (contador==123)
{
UCA0TXBUF = 0x0D; // Retorno de carro (13 en decimal)
IE2 &= ~UCA0TXIE; //deshabilita la transmisin de caracteres
}
contador=contador+1;
}
}
// ISR de RX
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
while (!(IFG2&UCA0TXIFG));
// USCI_A0 TX buffer est preparado?
UCA0TXBUF = UCA0RXBUF;
// TX -> RXed
}


32

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


33. Utilizando la patilla P1.2 como salida TA0.1, generar dos frecuencias con un DC=50% y de 1KHz y 1,25KHz,
respectivamente, separadas ente s por un retardo de 0,5s. De esta manera colocando un Altavoz de 8 en dicha
patillas obtendremos un sonido semejante a una sirena. El reloj debe ser SMCLK. La sirena no sonar hasta que
se solicite la interrupcin por flanco de bajada mediante P1.3, en dicho momento la alarma se repetir 20 veces
Mientras se est en reposo la CPU debe estar en modo LPM2.
SOLUCIN:

33

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)



#include <msp430.h>
int PVez=0;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Paramos el WDT
BCSCTL1 = CALBC1_1MHZ;
// f=1Mhz
DCOCTL = CALDCO_1MHZ;
P1SEL = BIT2;
// Configuramos P1.2 como salida del Timer
P1DIR = BIT2;
// Y la habilitamos como salida
// CONFIGURACIN DE LA INTERRUPCIN
P1DIR &=~BIT3;
// P1.3 entrada
P1REN |=BIT3;
// P1.3 resistencia pull-up HABILITADA
P1OUT |=BIT3;
// P1.3 resistencia pull-up
P1IE |=BIT3;
//Habilitamos las interrupciones,
P1IES |=BIT3;
// FLANCO DE BAJADA
P1IFG &=~BIT3;
// flag a cero no hay INT pendiente
// CONFIGURACIN DEL TIMER
TA0CCTL1 = OUTMOD_7;
TA0CTL = TASSEL_2 + MC_1;

// Registro Captura/Compara 1 del Timer A0


// el modo Salida Reset/Set
//modo ascendente y SMCLK fuente del reloj

// Programa principal
__bis_SR_register(LPM2_bits + GIE);
__no_operation();

// Enter LPM2 y habilita INT

}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
int t;
for (t=0;t<20;t++){
//sonar 10s pues cada tono suena 0,5s
if (PVez==0){
TA0CCR0 = 999;
//f1 = fSMCLK / TA0CCR0 = 10e6/1000=1KHZ
TA0CCR1 = 500;
// DC=TA0CCR1/TA0CCR0=(500/1000)%=50%
PVez++;
__delay_cycles(500000);
//duracin de la frecuencia 1; 0,5s
}
else
{
TA0CCR0 = 799;
//f2 = fSMCLK / TA0CCR0 =
10e6/800=1,25KHZ
TA0CCR1 = 400;
// DC=TA0CCR1/TA0CCR0=(400/800)%=50%
PVez=0;
__delay_cycles(500000);
//duracin de la frecuencia 2; 0,5s
}
P1IFG &= ~0x08;
// P1.3 IFG BORRADO, permite nueva interrupcin
}
}

34

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)


34. Este problema rene los conceptos de emisin-recepcin serie entre dos microcontroladores

//******************************************************************************
//
MSP430G2553
USCI_A0, UART 9600 Full-Duplex, 32kHz ACLK
//
//
Descripcin: USCI_A0 se comunica de forma contnua en modo full-duplex
//
con otro microcontrolador. Est en modo LPM3, con actividad nicamente
//
cuando se transmiten o se reciben datos.
//
La ISR de RX transmite un carcter a 9600,8,N,1 en aproximadamente 1ms
//
La ISR de TX indica a la USCI_A0 que ha recibido un carcter.
//
ACLK = BRCLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO ~1MHz
//
Baud rate 32768Hz XTAL @9600 = 32768Hz/9600 = 3.41
//
//
MSP430G2xx3
MSP430G2xx3
//
--------------------------------//
|
XIN|/|\|
XIN|//
|
| 32kHz | |
| 32kHz
//
|
XOUT|--|RST
XOUT|//
|
| /|\
|
|
//
|
RST|--|
|
//
|
|
|
|
//
|
|
|
|
//
|
UCA0TXD/P1.2|--------->|P1.1
|
//
|
|
9600
|
|
//
|
UCA0RXD/P1.1|<---------|P1.2
|
//
|
|
|
|
//
|
|
|
|
//
|
GND|----------|GND
|
//
|
|
|
|
//
|
|
|
|
//
//******************************************************************************
#include <io430.h>
#include "LCD4bits.c"
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Stop watchdog
LCD_INI (Dos_Lineas_5x8, Derecha_NoDesplaza);
LCD_Control (CurOFF_BliOFF);
LCD_Control (ClearDisplay);
__delay_cycles(500000);
P1OUT = 0x00;
// P1.0/6 setup for LED output
P1DIR = BIT0 + BIT6;
P1SEL = BIT1 + BIT2 ;
// P1.1 = RXD, P1.2=TXD
P1SEL2 = BIT1 + BIT2;
UCA0CTL1 |= UCSSEL_1;
// CLK = ACLK
UCA0BR0 = 0x03;
// 32kHz/9600 = 3.41
UCA0BR1 = 0x00;
UCA0MCTL = UCBRS1 + UCBRS0;
// Modulation UCBRSx = 3
UCA0CTL1 &= ~UCSWRST;
// **Inicializa USCI mquina estados**

35

Sistemas Electrnicos Digitales

HOJA DE EJERCICIOS (curso 2014/15)

IE2 |= UCA0RXIE + UCA0TXIE;

// habilita interrupcin

USCI_A0 TX/RX

LCD_FilaColumna(0,1);
LCD_Cadena ("ESPERANDO...");
__delay_cycles(5000000);
__bis_SR_register(LPM3_bits + GIE);

// Modo LPM3 e interrupciones globales

}
/* En el microcontrolador que sea transmisor hay que descomentar esta rutina
USCI A0/B0 Transmisin ISR y comentar la siguiente USCI A0/B0 Recepcin ISR */
// USCI A0/B0 Transmisin ISR
//#pragma vector=USCIAB0TX_VECTOR
//__interrupt void USCI0TX_ISR(void)
//
//{
// unsigned char TxByteT=0;
//
TxByteT = 'S';
//
LCD_Control (ClearDisplay);
//
__delay_cycles(1000000);
//
LCD_FilaColumna(0,1);
//
LCD_Cadena ("TRANSMIT:");
//
LCD_FilaColumna(0,10);
//
LCD_Caracter(TxByteT);
//
__delay_cycles(500000);
//
// UCA0TXBUF = TxByteT;
//}

// Lee, y transmite

/* En el receptor cargamos con la rutina USCI A0/B0 Transmisin ISR comentada


y la rutina USCI A0/B0 Recepcin ISR descomentada */
// USCI A0/B0 Recepcin ISR
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
unsigned char TxByteR=0;
TxByteR=UCA0RXBUF;
LCD_Control (ClearDisplay);
__delay_cycles(500000);
LCD_FilaColumna(1,1);
LCD_Cadena ("RECIBIDO:");
LCD_FilaColumna(1,10);
__delay_cycles(500000);
LCD_Caracter(TxByteR);
__delay_cycles(5000000);
}


36

Sistemas Electrnicos Digitales

También podría gustarte