Hoja_ejercicios_soluciones.pdf

  • Uploaded by: Roberto Reyes
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Hoja_ejercicios_soluciones.pdf as PDF for free.

More details

  • Words: 6,518
  • Pages: 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.  

SOLUCIÓN:  

;************************************************************* ; Plantilla que se crea automáticamente ; Conviene especificar el microcontrolador usado, describir ; el programa y si fuera posible las patillas utilizadas ; Microcontrolador: MSP430G2553 ; Descripción: ; 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

 

 

            1  

Sistemas  Electrónicos  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.  

SOLUCIÓN:   //************************************************************* #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  función  __delay_cicles(nº  ciclos)  

SOLUCIÓN:   /* Enciende el led verde P1.6 Utilizando __delay_cicles() */ #include <msp430.h> #include 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 } }

    2  

Sistemas  Electrónicos  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  

botón  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.   SOLUCIÓN:   ;******************************************************************** #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 Interrupción ;-----------------------------------------------------ORG 0FFFEh ; Vector RESET MSP 430 DW RESET ; END  

 

3  

Sistemas  Electrónicos  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   botón  

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.   SOLUCIÓN:  

#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 (botón) resistencia habilitada (botón) resistencia pull-up

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

// Si se pulsa botón // led encendidO

}

  6. Añade  un  antirrebotes  al  ejercicio  3  

  7. Añade  un  antirrebotes  al  ejercicio  4  

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

P2.0,  después  se  encenderá  el  P2.0  y  el  P2.1,  después  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   interrupción   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   interrupción   y   continuar   por   donde   iba.   Escribir   el   programa  en  ensamblador   4   Sistemas  Electrónicos  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 EJECUCIÓN ;-----------------------------------------------------------------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 parámetros MOV.W #020000,R15 ; R14 y R15 para pasar parámetros 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 parámetros MOV.W #025000,R15 ; R14 y R15 para pasar parámetros 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

   

5  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)  

;--------------------------------------------------------------------P1_3_ISR; Rutina de servicio a la interrupción ;--------------------------------------------------------------------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 parámetros 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 interrupción 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 Interrupción y Reset ;--------------------------------------------------------------------ORG 0FFFEh ; Vector para el reset DW RESET ORG 0FFE4h ; Vector para la interrupción del P1 DW P1_3_ISR END main

    6  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)     9. Supongamos   que   la   ejecución   normal   del   programa   consiste   en   el   desplazamiento   de   un   bit,   empezando   en   el  

P2.0,  después  se  encenderá  el  P2.0  y  el  P2.1,  después  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   interrupción   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   interrupción   y   continuar   por   donde   iba.   Esrcribir   el   programa  en  C   SOLUCIÓN:  

7  

Sistemas  Electrónicos  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; // configuración 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 (botón) resistencia habilitada P1OUT |= 0x08; // P1.3 (botón) resistencia pull-up // configuración de la interrupción 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 while(1) for (i = 0; i <15 ; i++) { if( BIT3 & P1IN ){ P2OUT = secu[i]; RETARDO(); }

// Si NO

se pulsa botón

} } //----------------------------------------------------// Rutina de atención de interrupción 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 }

 8  

Sistemas  Electrónicos  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   cátodo   común.  

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   máximo   y     la   corriente  máxima  que  debe  proporcionar  un  puerto  en  conjunto  no  debe  exceder  de  los  25  mA.    

Fig.1  circuito       SOLUCIÓN:   R1=300Ω  ≅330Ω    ;  R2=21600Ω  ≅22KΩ       11. Escribir  un  programa  en  C  para  el  circuito  del  problema  anterior.  Al  pulsar  el  botón  se  iniciará  la  cuenta  de  0  a  99  

con  un  periodo  aproximado  de  1s.  El  pulsador  solicita  una  interrupción  en  P1.3  por  flanco  de  bajada                   9  

Sistemas  Electrónicos  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 interrupción 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 interrupción 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 número en P1 P2OUT = 0x01; // Y activa el display de las unidades RETARDO(); P1OUT = display[j]; // Pone el otro número 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 petición de interrupción }  

 

10  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   12. Escribir   un   programa   en   ensamblador   para   el   circuito   del   problema   anterior.   Al   pulsar   el   botón   se   iniciará   la  

cuenta   de   0   a   99   con   un   periodo   aproximado   de   1s.   El   pulsador   solicita   una   interrupción   en   P1.3   por   flanco   de   bajada.   SOLUCIÓN:   #include <msp430G2553.h> Tmux

DEFINE 300

main

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

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

0F800h

;------------------------------------------------------------------------------RESET ;--------------Configuración -------------------------------------MOV

#0280h,SP

MOV

#WDTPW+WDTHOLD,&WDTCTL

MOV.B &CALBC1_1MHZ,&BCSCTL1

; Funciones de Calibración a 1MHz

MOV.B &CALDCO_1MHZ,&DCOCTL MOV.B

#BIT6+BIT0,&P1DIR

MOV.B

#0x0,&P1OUT

; para que estén 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 interrupción

BIS.B #BIT0+BIT1,P2DIR

; Defino P2.0 y P2.1 como salidas

MOV.B #GIE,SR

; Habilitación global de las interrupciones

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

$

; Programa principal

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

 

11  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)  

;------------------------------------------------------------------------------; Rutina de tratamiento de la interrupción ;------------------------------------------------------------------------------P1_ISR MOV #TSeg,R4 ; Inicializamos los punteros de Unidades y MOV #TSeg,R5 ; Decenas con la dirección 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 dígito 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 dígito 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 dirección 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 dirección 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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   ;------------------------------------------------------------------------------;

Subrutina de retardo

;------------------------------------------------------------------------------RETARDO MOV #Tmux,R15 ETIQ2 DEC JNZ

R15 ETIQ2

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

Tabla de 7 segmentos

;

Están 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 interrupción y reset

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

0FFFEh

DW

RESET

ORG

0FFE4h

DW

P1_ISR

END

main

; Vector de reset ; Vector de interrupción para P1

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

cambie  la  frecuencia  de  parpadeo    de  los  dos  diodos  colocados  en  P1.0  y  P1.6   SOLUCIÓN:                         13  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)  

#include <msp430.h> #include 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 información en la userguide.

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

//Habilitamos las interrupciones generales. IMPORTANTE!!

while(1){

//El mismo código anterior

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

//Al

salir de una interrupción

//SIEMPRE es necesario limpiar la bandera. Tini=Tini-5000; }

    14  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)     14.  Escribir  un  programa  en  ensamblador  para  que  el  bit  P1.0  parpadee  utilizando  la  interrupción  del  Watchdog.  El  

periodo  de  parpadeo  será  aproximadamente  30ms,  si  la  fuente  del  reloj  es  por  defecto  DCO=SMCLK     SOLUCIÓN:   ;*********************************************************************** #include <msp430.h> ;------------------------------------------------------------------------ORG 0FC00h ; Reset ;------------------------------------------------------------------------RESET mov.w #0400h,SP ; Inicializa stackpointer SetupWDT mov.w #WDT_MDLY_32,&WDTCTL ; WDT~30ms intérvalo del timer bis.b #WDTIE,&IE1 ; habilita interrupción 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 Interrupción ;----------------------------------------------------------------------ORG 0FFFEh ; MSP430 RESET Vector DW RESET ; ORG 0FFF4h ; WDT Vector DW WDT_ISR ; END                       15  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)     15. Escribir   un   programa   en   ensamblador   para   que   el   bit   P1.0   parpadee   utilizando   la   interrupción   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.   SOLUCIÓN:   ;********************************************************************* #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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)     16. Escribe  un  programa  que  utilizando  la  interrupción  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  sólo  durante  el  ISR  de  TA.   SOLUCIÓN:   ;************************************************************************* #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 ; AñAde 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  Electrónicos  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.   SOLUCIÓN:     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  (irán  apagándose  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  (irán  apagándose  los  leds  de   menor  a  mayor  peso),  con  un  tiempo  de  aproximadamente  1s   SOLUCIÓN  

18  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)                                               19. ¿Qué   ventaja   tiene   utilizar     _BIS_SR(GIE)frente   a __enable_interrupt()para   habilitar   las   interrupciones   globales.  

SOLUCIÓN:   Con   _BIS_SR(GIE)se  puede,  además,  modificar  el  resto  de  bits  del  registro  SR,  por  ejemplo  establecer  el  modo  de  trabajo   LPM0,   que   sería,   _BIS_SR(LPM0+GIE)mientras   que   con   __enable_interrupt()solamente   podemos   habilitar   las   interrupciones  globales.    

    19  

Sistemas  Electrónicos  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  continúa  por  donde  iba  la  secuencia.   SOLUCIÓN:  

#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; // configuración 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 (botón) resistencia habilitada

P1OUT |=

0x08;

//

P1.3 (botón) resistencia pull-up

// configuración de la interrupción 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  Electrónicos  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 atención de interrupción del puerto P1 //----------------------------------------------------#pragma vector=PORT1_VECTOR __interrupt void P1_Interrupt(void) { __delay_cycles(250000);

//antirrebotes software este valor es el más adecuado

parar ^= 1; P1IFG &= ~BIT3;

// Pone a cero IFG para P1.3

}

                      21  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   21. Utilizar  el  Timer    1  en  modo  continuo  con  el  módulo  captura/compara  0  para  que  el  led  P1.0  parpadee  cada  

0,1s  (utilizar  MCLK  =  1MHz).     SOLUCIÓN:   #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 número 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 opción //elegir los bits de forma individual o directamente el modo (aparecen con //subguión) //Como voy a trabajar en modo comparación 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 interrupción 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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   22. Utilizar   el   Timer     1   en   modo   ascendente   con   el   módulo   captura/compara   0   para   que   el   led   P1.0   parpadee  

cada  0,1s  (utilizar  MCLK  =  1MHz)     SOLUCIÓN:   #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 número 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 opción //elegir los bits de forma individual o directamente el modo (aparecen con //subguión) //Como voy a trabajar en modo comparación 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 interrupción del Timer 1 #pragma vector=TIMER1_A0_VECTOR __interrupt void Timer_A0 (void) { P1OUT ^= 0x01; // Hacemos cambiar al LED }

                  23  

Sistemas  Electrónicos  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.       SOLUCIÓN:   Cuando   se   desborda   el   timer   el   flag   TAIFG   se   activa   y   se   produce   la   llamada   a   la   interrupción.   Para   saber   quien   ha   producido  la  llamada  a  la  interrupción  bastaría  consultar  los  flags  (CCIFG1,  CCIFG2,  TAIFG),  pero  habría  que  hacerlo   por  encuesta.  Para  evitarlo,  el  MSP430  tiene  el  registro  TAIV,  que  nos  ayudará  a  identificar  la  fuente  de  interrupción   rápidamente.   Este   registro   contiene   un   valor   que   viene   determinado   por   la   fuente   de   interrupción,   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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   24. Repetir  el  ejercicio  anterior,  en  ensamblador.  

SOLUCIÓN:  

#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 genérica para CCR1 a 4 y overflow ; TA0IV contiene 2, 4, 6, 8 ó 10 (0A). Lo que se hace es añadir su contenido al ; PC. ; si los ponemos de forma consecutiva, siempre sabremos quién ha producido la ; interrupción y saltar a donde toque. ; Los reti también ocupan 2 bytes, por lo que también 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 interrupción 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, también 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  Electrónicos  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   SOLUCIÓN:   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  comparación  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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   26. Escribir  un  programa  en  ensamblador  para  que  el  bit  P1.6  se  encienda  cuando  la  señal  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 conversión 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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   27. Escribir  un  programa  en  C  para  que  el  bit  P1.6  se  encienda  cuando  la  señal  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 conversión // 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  Electrónicos  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   SOLUCIÓN:  El  registro  TA0CCR0  deberemos  cargarlo  con  un  valor    que  obtenemos  de  fsal  =  fACLK/TA0CCRO   cargamos  el  registro  de  comparación  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  Electrónicos  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   SOLUCIÓN:   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  Electrónicos  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   SOLUCIÓN:   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  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   31. Realizar  un  programa  para  que  la  UART  transmita  el  abecedario  con  la  siguiente  configuración:  9600,  8bits,  

1bit  de  stop,  y  sin  paridad    y  que  se  pueda  visualizara  través  del  USB  en  el  hyperteminal.   SOLUCIÓN:   #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 máquina 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; // Envío 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 transmisión 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  Electrónicos  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   interrupción   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.   SOLUCIÓN:    

33  

Sistemas  Electrónicos  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 // CONFIGURACIÓN DE LA INTERRUPCIÓN 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 // CONFIGURACIÓN 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); //duración 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); //duración de la frecuencia 2; 0,5s } P1IFG &= ~0x08; // P1.3 IFG BORRADO, permite nueva interrupción } }

34  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)   34. Este  problema  reúne  los  conceptos  de  emisión-­‐recepción  serie  entre  dos  microcontroladores    

//****************************************************************************** // MSP430G2553 USCI_A0, UART 9600 Full-Duplex, 32kHz ACLK // // Descripción: USCI_A0 se comunica de forma contínua 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 carácter a 9600,8,N,1 en aproximadamente 1ms // La ISR de TX indica a la USCI_A0 que ha recibido un carácter. // 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 #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 máquina estados**

35  

Sistemas  Electrónicos  Digitales    

HOJA  DE  EJERCICIOS  (curso  2014/15)  

IE2 |= UCA0RXIE + UCA0TXIE;

// habilita interrupción

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 Transmisión ISR y comentar la siguiente USCI A0/B0 Recepción ISR */ // USCI A0/B0 Transmisión 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 Transmisión ISR comentada y la rutina USCI A0/B0 Recepción ISR descomentada */ // USCI A0/B0 Recepción 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  Electrónicos  Digitales    

More Documents from "Roberto Reyes"