MSP 430
MSP 430
MSP 430
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
XOR.B
MOV.W
#001h,&P1OUT
#050000,R15
DEC.W
JNZ
JMP
R15
L1
INICIO
;
;
;
;
;
;
INICIO
L1
;-------------------------------------------;
VECTORES
;-------------------------------------------ORG 0FFFEh
DW
RESET
END
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;
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;
P1OUT|=BIT6;
while(1){
//Loop infinito
P1OUT|=BIT6;
//prende el LED
__delay_cycles(100000); //espera
P1OUT&=~BIT6;
//apaga el LED
__delay_cycles(100000); //espera
}
}
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
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
;--------------------------------------------------------------------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
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
#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
}
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
10
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
MOV.B &CALDCO_1MHZ,&DCOCTL
MOV.B
#BIT6+BIT0,&P1DIR
MOV.B
#0x0,&P1OUT
MOV.B #0F7h,&P1DIR
BIS.B #BIT3,&P1REN
BIS.B #BIT3,&P1OUT
BIS.B #BIT3,&P1IES
BIS.B #BIT3,&P1IE
BIS.B #BIT0+BIT1,P2DIR
MOV.B #GIE,SR
;------------------------------------------------------------------------------jmp
; Programa principal
;-------------------------------------------------------------------------------
11
;------------------------------------------------------------------------------;
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
Subrutina de retardo
R15
ETIQ2
RET
;------------------------------------------------------------------------------;
Tabla de 7 segmentos
;------------------------------------------------------------------------------TSeg
; 0, 1 , 2
DC8
, 3 , 4 ,
5 ,
6 ,
7 , 8 , 9
77h,06h,0B3h,97h,0C6h,0D5h,0F5h,07h,0F7h,0C7h
;------------------------------------------------------------------------------;
;------------------------------------------------------------------------------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,
#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;
P1OUT|=BIT3;
// de pull-up
P1IE|=BIT3;
P1IES|=BIT3;
P1IFG&=~BIT3;
P1OUT|=BIT0;
P1OUT&=~BIT6;
_BIS_SR(GIE);
while(1){
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
14
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
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
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
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
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
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;
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;
P2DIR |= 0xFF;
//
P2 como salida
//
P1REN |=
0x08;
//
P1OUT |=
0x08;
//
P1IE
|= 0x08;
//_BIS_SR(GIE);
__enable_interrupt() ;
20
para P1.3
while(1) {
for (i = ii; i <15 ; i++)
{
P2OUT = secuencia[i];
if (parar==1) break;
//P2OUT = secu[i];
__delay_cycles(100000);
}
ii=i;
if (ii==15) ii=0;
while (parar==1){
P2OUT = secuencia[ii-1];
}
}
}
//----------------------------------------------------// Rutina de atencin de interrupcin del puerto P1
//----------------------------------------------------#pragma vector=PORT1_VECTOR
__interrupt void P1_Interrupt(void)
{
__delay_cycles(250000);
parar ^= 1;
P1IFG &= ~BIT3;
21
// Paramos el WDT
//calibra la f a 1MHz
BCSCTL1 = CALBC1_1MHZ;
P1DIR |= 0x01;
TA1CCTL0 = CCIE;
}
// 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
// Paramos el WDT
//calibra la f a 1MHz
BCSCTL1 = CALBC1_1MHZ;
P1DIR |= 0x01;
TA1CCTL0 = CCIE;
}
// 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
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Paramos el WDT
P1DIR |= 0x01;
_BIS_SR(LPM0_bits + GIE);
}
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A0 (void)
{
/*
switch(TA0IV)
{
case
2: break;
case
4: break;
24
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
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;
DCOCTL = CALDCO_1MHZ;
//
P1SEL |= 0x02;
P1DIR |= 0x07;
TA0CCTL0 = OUTMOD_4;
TA0CCR0 = 499;
TA0CTL = TASSEL_2 + MC_1;
_BIS_SR(LPM0_bits);
26
;*******************************************************************************
#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
#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;
}
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
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;
P1DIR |= 0x07;
TA0CCTL0 = OUTMOD_4;
TA0CCR0 = 15;
TA0CTL = TASSEL_1 + MC_1;
_BIS_SR(LPM3_bits);
29
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;
P1DIR |= 0x04;
TA0CCTL1 = OUTMOD_7;
TA0CCR0 = 499;
TA0CCR1 = 375;
TA0CTL = TASSEL_2 + MC_1;
_BIS_SR(LPM0_bits);
30
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;
P1DIR |= 0x04;
TA0CCTL1 = OUTMOD_7;
TA0CCR0 = 15;
TA0CCR1 = 12;
TA0CTL = TASSEL_1 + MC_1;
_BIS_SR(LPM0_bits);
31
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
33
// Programa principal
__bis_SR_register(LPM2_bits + GIE);
__no_operation();
}
#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
//******************************************************************************
//
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
// habilita interrupcin
USCI_A0 TX/RX
LCD_FilaColumna(0,1);
LCD_Cadena ("ESPERANDO...");
__delay_cycles(5000000);
__bis_SR_register(LPM3_bits + GIE);
}
/* 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
36