MSP430 Examples

April 1, 2019 | Author: Locha Paegle | Category: Digital Electronics, Computer Programming, Technology, Computing, Computer Architecture
Share Embed Donate


Short Description

Download MSP430 Examples...

Description

Topics to Cov Co ver«         

F2013 Blinky Example Lab 4: Blinky Lab Example 2: Interrupts w/Timer_A w/Timer_A Example 3: S/W PWM w/Timer_A Example 4: Watchdog W atchdog Clock Example 5: Watchdog PWM Example 6: SW Switch Debounce Example 7: Timer_B S/W PWM Recursive Line Draw

BYU CS/ECEn 124

MSP430 Examples

1

Systematic Decomposition

Blinky Example

F2013

;******************************************************************************* ; CS/ECEn 124 Lab 1 - blinky.asm: blinky.asm: Software Toggle P1.0 ;******************************************************************************* .cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013 ;-----------------------------------------------------------------------------.text ; beginning of executable code ;-----------------------------------------------------------------------------RESET: mov.w #0x0280,SP ; init stack pointer   mov.w #WDTPW+WDTHOLD,&WDTCTL #WDTPW+WDTHOLD,& WDTCTL ; stop WDT   bis.b #0x01,&P1DIR ; set P1.0 as output  

mainloop:  

delayloop:

xor.b mov.w

dec.w jnz jmp

#0x01,&P1OUT #0,r15

r15 delayloop mainloop

; toggle P1.0 ; use R15 as delay counter ; delay over? ; n ; y, toggle led 

;-----------------------------------------------------------------------------; Interrupt Vectors ;-----------------------------------------------------------------------------.sect ".reset" ; MSP430 RESET Vector .short RESET ; start address .end 

BYU CS/ECEn 124

MSP430 Examples

2

Systematic Decomposition

Add 2nd Delay Loop ;******************************************************************************* ; CS/ECEn CS/ECEn 124 Lab Lab 1 - blinky.asm: blinky.asm: Software Software Toggle Toggle P1.0 ;******************************************************************************* .cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013 delay .set 0 ;-----------------------------------------------------------------------------.text ; beginning of executable code ;-----------------------------------------------------------------------------RESET: mov.w #0x0280,SP ; init stack pointer   mov.w #WDTPW+WDTHOLD,&WDTCTL #WDTPW+WDTHOLD,& WDTCTL ; stop WDT   bis.b #0x01,&P1DIR ; set P1.0 as output  

mainloop:  

xor.b mov.w

#0x01,&P1OUT #delay,r15

; toggle P1.0 ; use R15 as delay counter

delayloop:

dec.w jnz

r15 delayloop

; delay over? ; n

delay2:

dec.w jnz jmp

r15 delay2 mainloop

; y, toggle led 

;-----------------------------------------------------------------------------; Interrupt Vectors ;-----------------------------------------------------------------------------.sect ".reset" ; MSP430 RESET Vector .short RESET ; start address .end 

BYU CS/ECEn 124

MSP430 Examples

3

Device: LED

LEDs 

6 LED¶s on eZ430X Development Board      



P1.0 P1.1 P2.6 P2.7 P3.3 P4.6

Red LED eZ430-RF2500 Green LED eZ430-RF2500 LED #1 (Green) LED #2 (Orange) LED #3 (Yellow) LED #4 (Red)

Port bits must be enabled for output by writing a 1 to the port direction register       

bis.b bic.b bis.b bis.b bis.b bis.b

BYU CS/ECEn 124

#0x03,&P1DIR #0xc0,&P2SEL #0x40,&P2DIR #0x80,&P2DIR #0x08,&P3DIR #0x40,&P4DIR

; eZ430-RF2500 LED's ; select GPIO ; LED #1 (P2.6) ; LED #2 (P2.7) ; LED #3 (P3.3) ; LED #4 (P4.6) MSP430 Examples

4

Device: LED

LEDs 

Turn LED off by writing a 0 to the port pin     



#0x03,&P1OUT #0x40,&P2OUT #0x80,&P2OUT #0x08,&P3OUT #0x40,&P4OUT

; eZ430-RF2500 LED's ; LED #1 (P2.6) ; LED #2 (P2.7) ; LED #3 (P3.3) ; LED #4 (P4.6)

Turn LED on by writing a 1 to the port pin     



bic.b bic.b bic.b bic.b bic.b bis.b bis.b bis.b bis.b bis.b

#0x03,&P1OUT #0x40,&P2OUT #0x80,&P2OUT #0x08,&P3OUT #0x40,&P4OUT

; eZ430-RF2500 LED's ; LED #1 (P2.6) ; LED #2 (P2.7) ; LED #3 (P3.3) ; LED #4 (P4.6)

Toggle LED by XOR¶ing a 1 to the port pin     

xor.b xor.b xor.b xor.b xor.b

BYU CS/ECEn 124

#0x03,&P1OUT #0x40,&P2OUT #0x80,&P2OUT #0x08,&P3OUT #0x40,&P4OUT

; eZ430-RF2500 LED's ; LED #1 (P2.6) ; LED #2 (P2.7) ; LED #3 (P3.3) ; LED #4 (P4.6) MSP430 Examples

5

Lab 4: Blinky

Lab 4: Blinky Lab ;******************************************************************************* ; CS/ECEn 124 Lab 4 - blinky.asm  ;******************************************************************************* ; cycles = --; MCLK = --- cycles / 10 seconds = --- Mhz ; CPI = MCLK / --; MIPS = MCLK / CPI / 1000000 = --- MIPS .cdecls C,LIST, "msp430x22x4.h" ; MSP430F2274 COUNT .equ 0 ; delay count ;-----------------------------------------------------------------------------.text ; beginning of executable code ;-----------------------------------------------------------------------------RESET: mov.w #0x0280,SP ; 2 init stack pointer   mov.w #WDTPW+WDTHOLD,&WDTCTL ;5 stop WDT   bis.b #0x01,&P1DIR 4 set ; P1.0 as output  

mainloop:   delayloop:

xor.b #0x01,&P1OUT mov.w #COUNT,r15

dec.w jnz jmp

r15 delayloop mainloop

4 1 ; 1 ; 2 ; 2

;toggle P1.0 use; R15 as delay counter delay over? n y, toggle led 

;-----------------------------------------------------------------------------; Interrupt Vectors ;-----------------------------------------------------------------------------.sect ".reset" ; MSP430 RESET Vector .short RESET ; start address .end 

BYU CS/ECEn 124

MSP430 Examples

6

Activation Recor d

Example 1a: Activation Recor d DELAY

.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013 4(SP) = delay count .equ (50/8) 2(SP) = return address 0(SP)

RESET:

 

= r 15

.text ; beginning of code mov.w #0x0280,SP ; init stack pointer   mov.w #WDTPW+WDTHOLD,&WDTCTL ; stop WDT   bis.b #0x01,&P1DIR ; set P1.0 as output

mainloop: xor.b #0x01,&P1OUT   push.w #DELAY call #delay jmp mainloop

; toggle P1.0 ; pass delay count on stack ; call delay subroutine

; delay subroutine: stack usage 4| DELAY | \ ; 2| ret | subroutine frame (6 bytes) ; (SP) => 0| r15 | / delay: push.w r15 ; callee-save   mov.w #0,r15 ; use R15 as inner counter delay02:

dec.w r15 jne delay02 dec.w 4(SP) jne delay02   pop.w r15   mov.w @SP+,0(SP) ret .sect .word .end 

BYU CS/ECEn 124

".reset" RESET

; ; ; ;

inner delay over? n y, outer done? n ; y, restore register(s) ; pop input delay count ; return from subroutine ; MSP430 RESET Vector ; start address

MSP430 Examples

7

Activation Recor d

Example 1b: Activation Recor d DELAY RESET:

 

.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013 .equ (50/8) .text mov.w #0x0280,SP   mov.w #WDTPW+WDTHOLD,&WDTCTL   bis.b #0x01,&P1DIR

mainloop: xor.b #0x01,&P1OUT   push.w #DELAY call #delay jmp mainloop

; delay subroutine: stack usage ; ; ; (SP) => delay: push.w r12   push.w r15   mov.w 6(SP),r12   mov.w #0,r15 delay02:

BYU CS/ECEn 124

dec.w r15 jne delay02 dec.w r12 jne delay02   pop.w r15   pop.w r12   mov.w @SP+,0(SP) ret .sect .word .end 

".reset" RESET

6(SP) = delay count 4(SP) = return address 2(SP) = r 12 ; beginning of code 0(SP) = r 15 ; init stack pointer

; stop WDT ; set P1.0 as output

; toggle P1.0 ; pass delay count on stack ; call delay subroutine

6| DELAY | \ 4| ret | subroutine frame (8 bytes) 2| r12 | /(activation record) 0| r15 |/ ; callee-save ; get delay count ; use R15 as inner counter ; ; ; ;

delay over? n y, done? n ; y, restore registers

; pop input delay count ; return from subroutine

; MSP430 RESET Vector ; start address MSP430 Examples

8

Activation Recor d

Example 1c: Activation Recor d DELAY RESET:

 

.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013 .equ (50/8)

4(SP) = delay count 2(SP) = return address 0(SP) = local variable

.text ; beginning of code mov.w #0x0280,SP ; init stack pointer   mov.w #WDTPW+WDTHOLD,&WDTCTL ; stop WDT   bis.b #0x01,&P1DIR ; set P1.0 as output

mainloop: xor.b #0x01,&P1OUT   push.w #DELAY call #delay jmp mainloop

; toggle P1.0 ; pass delay count on stack ; call delay subroutine

; delay subroutine: stack usage 4| DELAY | \ ; 2| ret | subroutine frame (6 bytes) ; (SP) => 0| counter | / delay: sub.w #2,SP ; activate local variable   mov.w #0,0(SP) ; use as inner counter delay02:

dec.w jne dec.w jne add.w   mov.w ret .sect .word .end 

BYU CS/ECEn 124

0(SP) delay02 4(SP) delay02 #2,SP @SP+,0(SP)

; ; ; ; ;

delay over? n y, done? n y, deactivate local variable ; pop input delay count ; return from subroutine

".reset" RESET

; MSP430 RESET Vector ; start address MSP430 Examples

9

Blinky Example

Example 2: Interrupts w/Timer_A TASSEL_2 = SMCLK TA_CTL TA_FREQ

cdecls C,LIST, "msp430x20x3.h" .set TASSEL_2+ID_3+MC_1+TAIE .set 0xffff

 MC_1 = UP Mode

; MSP430F2013 ; 000000 10 11 01 000 1 = SMCLK,/8,UP,IE ; clocks

ID_3 = /8 Enable Interrupt ;-----------------------------------------------------------------------------.text ; beginning of executable code RESET: mov.w #0x0280,SP ; init stack pointer   mov.w #WDTPW+WDTHOLD,&WDTCTL ; stop WDT   bis.b #0x01,&P1DIR ; set P1.0 as output clr.w &TAR   mov.w #TA_CTL,&TACTL   mov.w #TA_FREQ,&TACCR0   bis.w #LPM0+GIE,SR jmp $ TA_isr:  

bic.w #TAIFG,&TACTL xor.b #0x01,&P1OUT reti

; reset timerA  ; set timerA control reg ; set interval (frequency) ; enter LPM0 w/interrupts

Put the processor to sleep!

; timer A ISR  ; acknowledge interrupt ; toggle P1.0

Acknowledge Interrupt ;-----------------------------------------------------------------------------; Interrupt Vectors (Put its hand down) .sect ".int08" ; timer A section .word TA_isr ; timer A isr

.sect .word .end 

BYU CS/ECEn 124

".reset" RESET

; MSP430 RESET Vector ; start address

MSP430 Examples

10

LED Intensity

Example 3: S /W PWM w/Timer_A .cdecls C,LIST,"msp430x20x3.h" .set 1200000 ; 1200000 clocks / second  .set TASSEL_2+ID_0+MC_1+TAIE ; SMCLK, /1, UP, IE .set 120 ; FREQ / SMCLK = 0.0001 = 100 us

SMCLK TA_CTL TA_FREQ

RESET:

Acknowledge needed

TA_isr:

.bss cnt,2 .text mov.w #0x0280,SP   mov.w #WDTPW+WDTHOLD,&WDTCTL   bis.b #0x01,&P1DIR clr.w &TAR   mov.w #TA_CTL,&TACTL   mov.w #TA_FREQ,&TACCR0   bis.w #LPM0+GIE,SR jmp $ bic.w #TAIFG,&TACTL inc.w &cnt cmp.w #10,&cnt jlo TA_isr2 clr.w &cnt   bis.b #0x01,&P1OUT jmp TA_isr4

TA_isr2: bic.b

#0x01,&P1OUT

TA_isr4: reti .sect .word .sect .short .end 

BYU CS/ECEn 124

; counter variable ; init stack pointer ; stop watchdog ; set P1.0 as output ; reset timerA  ; set timerA control reg ; set interval (frequency) ; enter LPM0 w/interrupts ; will never get here! ; acknowledge interrupt ; time to pulse? ; n ; y, reset counter ; turn on ; turn off ; return from interrupt

".int08" TA_isr ".reset" RESET

; ; ; ;

10% Duty

Cycle

timer A section timer A isr MSP430 RESET Vector start address

MSP430 Examples

11

Watchdog

Example 4: Watchdog Clock    

SMCLK WDT_CTL WDT_CPS

.cdecls C,LIST,"msp430x20x3.h" .set 1200000 .set WDT_MDLY_8 .set SMCLK/8000

8 ms (@1 MHz SMCLK)

; 1.2 Mhz clock ; WDT SMCLK, 8 ms (@1 Mhz) ; WD clocks / second count

; Data Section -----------------------------------------------------------.bss WDTSecCnt,2 ; WDT second counter ; Code Section -----------------------------------------------------------.text RESET: mov.w #0x280,SP ; initialize stack pointer   mov.w #WDT_CTL,&WDTCTL ; set WD timer interval   mov.w #WDT_CPS,&WDTSecCnt ; initialize 1 sec WD counter   bis.b #WDTIE,&IE1 ; enable WDT interrupt   bis.b #0x01,&P1DIR ; P1.0 output   bis.w #GIE,SR ; enable interrupts loop:

 

 

;>  jmp loop

Enable WD Interrupts

; loop indefinitely

; Watchdog ISR -----------------------------------------------------------WDT_ISR: dec.w &WDTSecCnt ; decrement counter, 0? jne WDT_02 ; n   mov.w #WDT_CPS,&WDTSecCnt ; y, re-initialize counter xor.b #0x01,&P1OUT ; toggle P1.0 WDT_02:

reti

; Interrupt Vectors .sect .word .sect No acknowledge .word d d nee e .end 

BYU CS/ECEn 124

; return from interrupt

------------------------------------------------------".int10" ; Watchdog Vector WDT_ISR ; Watchdog ISR  ".reset" ; PUC Vector RESET ; RESET ISR 

MSP430 Examples

12

Speaker (Transducer )

Example 5: Watchdog PWM  

WDT_CLK STACK

.cdecls C,LIST,"msp430x22x4.h" .set 500 .set 0x0600

; include c header ; 500 Mhz WD clock (@1 Mhz) ; stack

.bss .bss

; WDT second counter ; buzzer on flag

WDTSecCnt,2 buzzON,1

.text mov.w #STACK,SP   mov.w #WDT_MDLY_0_5,&WDTCTL   mov.w #WDT_CPS,&WDTSecCnt   mov.b #WDTIE,&IE1   bis.b #0x01,&P1DIR PWM when buzzON is   bis.b #0x20,&P4DIR clr.b &buzzON non-zero   bis.w #LPM0+GIE,SR jmp $ RESET:

 

WDT_ISR:

 

WDT_02:

 

cmp.b #0,&buzzON jeq WDT_02 xor.b #0x20,&P4OUT

BYU CS/ECEn 124

; buzzer on? ; n ; y, use 50% PWM 

dec.w &WDTSecCnt jne WDT_04   mov.w #WDT_CPS,&WDTSecCnt xor.b #0x01,&P1OUT xor.b #0xff,&buzzON

WDT_04: .sect .word .sect .word .end 

; program section ; initialize stack pointer ; set WD timer interval to 0.5 ms ; initialize 1 sec WD counter ; enable WDT interrupt ; P1.0 output ; P4.5 output (transducer) ; turn off buzzer ; enable interrupts / sleep ; (should never get here!)

; decrement counter, 0? ; n ; y, re-initialize counter ; toggle P1.0 ; toggle buzzer on/off

reti ".int10" WDT_ISR ".reset" RESET

; return from interrupt ; ; ; ;

Watchdog Vector Watchdog ISR  PUC Vector RESET ISR 

MSP430 Examples

13

Switch Debounce

Example 6: SW Switch Debounce ;********************************************************************** ; Switch debounce routine ; DB_TIME .set 10 ; 10 ms debounce time DB_CYCS .set 13 ; instruction cycles for delay DB_DELAY .set DB_TIME*myCLOCK/DB_CYCS/1000 ; delay count debounce_switch:   push

r15

; callee save

deb02:

mov.b xor.b and.b jne

&P2IN,r12 #0x0f,r12 #0x0f,r12 deb02

; ; ; ;

deb04:

mov.w

#DB_DELAY,r15

; minimum delay

&P2IN,r12 #0x0f,r12 #0x0f,r12 deb04 r15 deb06 r15

; ; ; ; ; ;

deb06: Reset timing counter if  and of the switches read 0

mov.b xor.b and.b jeq dec.w jne   pop ret

BYU CS/ECEn 124

Wait until all switches off 

read switches SW1-4 any switch low? y, wait until all off

read switches SW1-4 all switches high? n, restart delay y, long enough delay? n, keep going ; y, switches debounced 

MSP430 Examples

Return if  R15 counts down to 0

14

Pulse Width Modulation (S /W)

Example 7: Timer_B S /W PWM 

Timer B interrupts used to modulate transducer at 440 Hz .cdecls C,LIST,"msp430x22x4.h" SMCLK .set 1200000 TIME_A3 .set 1000000/440/2 TB_CTL .set TBSSEL_2+ID_0+MC_1+TBIE TB_FREQ .set SMCLK/TIME_A3

; ; ; ;

1200000 clocks / second  A = 440 Hz SMCLK, /1, UP, IE clocks / 440 Hz

reset:

mov.w #0x0600,SP ; initialize SP   mov.w #WDTPW+WDTHOLD,&WDTCTL ; stop WDT   bis.b #0x20,&P4DIR ; P4.5 transducer output clr.w &TBR ; reset timerB   mov.w #TB_CTL,&TBCTL ; set timerB control reg ; set interval (frequency) Timer B Interrupt   mov.w #TB_FREQ,&TBCCR0 bis.w #LPM0+GIE,SR ; enter LPM0 w/interrupts Service Routine   jmp $ ; will never get here! TB_isr: bic.w xor.b reti .sect .word .sect .word .end  BYU CS/ECEn 124

#TBIFG,&TBCTL #0x20,&P4OUT

; acknowledge interrupt ; toggle (50% duty cycle)

".int12" TB_isr ".reset" reset

; ; ; ;

timer timer reset reset

MSP430 Examples

B section B isr vector section vector ISR  15

Tone Scale Example

Step 1: Start Simple .cdecls C,LIST,"msp430x22x4.h" STACK .set 0x0600 ; top-of-stack .text ; code Section ;********************************************************************** ; Start of program... reset: mov.w #STACK,SP ; initialize SP call #init_MSP430 ; init MSP430 call #init_variables ; init variables ;********************************************************************** ; Main event loop... loop: call #update_LEDs ; update LED's call #goto_sleep ; go to sleep call #adjust_volume ; awake! adjust volume call #debounce_switch ; debounce switches jmp loop ; go back to sleep init_MSP430: init_variables: goto_sleep: adjust_volume: update_LEDs: debounce_switch: ret .sect .word .end  BYU CS/ECEn 124

Working Program!

".reset" reset

; ; ; ; ; ;

init MSP430 init variables enter LPM0 adjust volume show volume in LEDx debounce switches

; reset vector section ; reset vector ISR  MSP430 Examples

16

Tone Scale Example

Step 2: Initialize MSP430   WDT_CLK .set 8000 ; 8 khz clock (@1 Mhz)   WDT_CTL .set WDT_MDLY_8 ; WDT SMCLK, 8 ms ;********************************************************************** ; Initialize MSP430 routine init_MSP430:   mov.w #WDT_CTL,&WDTCTL ; configure WDT        

bic.b bis.b bic.b bis.b

#0x03,&P1SEL #0x03,&P1DIR #0x01,&P1OUT #0x02,&P1OUT

; eZ430 LED's ; P1.0-1 as output ; turn off red  ; turn on green

       

bic.b bis.b bis.b bis.b

#0xc0,&P2SEL #0xc0,&P2DIR #0x08,&P3DIR #0x40,&P4DIR

; eZ430X LED's ; LED #1 & #2 ; LED #3 ; LED #4

         

bic.b bic.b bis.b bis.b bis.b

#0x0f,&P2SEL #0x0f,&P2DIR #0x0f,&P2OUT #0x0f,&P2IES #0x0f,&P2REN

; eZ430X push buttons ; P2.0-3 as inputs ; P2.0-3 pull-ups ; h to l ; enable pull-ups

 

bis.b

#0x20,&P4DIR

; P4.5 transducer output

clr.w &TBR ; Timer B SMCLK, /1, up mode   mov.w #TBSSEL_2+ID_0+MC_1,&TBCTL ret BYU CS/ECEn 124

MSP430 Examples

17

Tone Scale Example

Step 3a: Implement Watchdog 

 Add WDT 1 second data variable .bss



WDTSecCnt,2

; WDT second counter

 Add WDT ISR and interrupt vector  ;********************************************************************** ; Watchdog Timer ISR    WDT_ISR: ; WD timer ISR  dec.w &WDTSecCnt ; 1 second? jne WD10 ; n xor.b #0x03,&P1OUT ; y, toggle LEDs   mov.w #WDT_CPS,&WDTSecCnt ; reset counter ;  

  WD10:

reti

; return from interrupt

;********************************************************************** ; Interrupt Vector Table Entries .sect ".int10" ; WDT vector .word WDT_ISR ; address of WDT ISR  BYU CS/ECEn 124

MSP430 Examples

18

Tone Scale Example

Step 3b: Implement Watchdog 

Initialize 1 second data variable   myCLOCK .set   WDT_CLK .set   WDT_CTL .set   WDT_CPS .set

1200000 8000 WDT_MDLY_8 myCLOCK/WDT_CLK

; 1.2 Mhz clock ; 8 khz clock (@1 Mhz) ; WDT SMCLK, 8 ms ; WD clocks / second count

;********************************************************************** ; Initalize variables routine init_variables: ; init variables   mov.w #WDT_CPS,&WDTSecCnt ; WDT counts/second    bis.b #WDTIE,&IE1 ; enable WDT interrupt ret 

Enable interrupts ;********************************************************************** ; Goto sleep routine (Enable interrupts and LPM0) goto_sleep: ; enter LPM0   bis.b #LPM0+GIE,SR ; enter LPM0 w/interrupts ret

BYU CS/ECEn 124

MSP430 Examples

19

Tone Scale Example

Step 4a: Create Tones 

 Add some tone constants equates ; chromatic scale (12 just intonation intervals) DO .set myCLOCK*1000/261626 ; C (261.626 Hz) RE .set DO*8/9 ; D   MI .set DO*4/5 ; E FA .set DO*3/4 ; F SOL .set DO*2/3 ; G LA .set DO*3/5 ; A  TI .set DO*8/15 ; B DO1 .set DO*1/2 ; C



Create melodic array of tone values scale

.text .word

BYU CS/ECEn 124

; code Section DO, RE, MI, FA, SOL, LA, TI, DO1

MSP430 Examples

20

Tone Scale Example

Step 4b: Create Tones 

Create tone index variable .bss



; tone number (0-8)

Initialize tone variable in init variable subroutine  



tone,2

MAX_TONE   mov.w

.set 8 #0,&tone

; 0-8 tones ; 1st tone

Use WDT ISR to sequence thru the scale   push r4   mov.w &tone,r4 add.w #1,r4 cmp.w #MAX_TONE,r4 jlo WD02 clr.w r4   ;

; ; ; ;

; save r4 ; get tone next tone restart scale? n y

WD02: mov.w r4,&tone ; save tone >    pop r4

BYU CS/ECEn 124

MSP430 Examples

21

Tone Scale Example

Step 5: Output Tone 

 Add TimerB ISR and interrupt vector  ;********************************************************************** ; Timer B ISR  TB_ISR: ; timer B ISR    bic.w #TBIFG,&TBCTL ; acknowledge interrupt xor.b #0x20,&P4OUT ; pulse buzzer TB04:

reti .sect .word



; return from interrupt ".int12" TB_ISR

; timer B section ; timer B ISR 

 And start TimerB with 1st tone in init variables subroutine    

BYU CS/ECEn 124

mov.w bis.w

#DO/2,&TBCCR0 #TBIE,&TBCTL

st note ; start timer clock w/1 ; enable timer B interrupts

MSP430 Examples

22

Tone Scale Example

Step 6: Enter LPM0 

 Add Port 2 ISR to clear LPM0 and enter AM ;********************************************************************** ; Port 2 (switches) ISR  P2_ISR: ; Port 2 (switches) ISR    bic.b #0x0f,&P2IE ; disable P2 interrupts   bic.w #LPM0,0(SP) ; clear LPM0 from TOS reti ; return from interrupt .sect .word



".int03" P2_ISR

; P2 interrupt vector ; address of Port 2 ISR 

 And change to LPM0 when enabling interrupts ;********************************************************************** ; Goto sleep routine (Enable interrupts and LPM0) goto_sleep: ; enter LPM0   bic.b #GIE,SR ; disable all interrupts clr.b &P2IFG ; acknowledge all   bis.b #0x0f,&P2IE ; enable switch interrupts   bis.b #LPM0+GIE,SR ; enter LPM0 w/interrupts ret

BYU CS/ECEn 124

MSP430 Examples

23

Tone Scale Example

Step 7a: Play Scale 

 Add toggle, high, and low duty cycle variables .bss .bss .bss



duty_cycle_high,2 duty_cycle_low,2 duty_cycle_toggle,1

; high part of cycle ; low part of cycle ; duty cycle flag

Use Watchdog interrupt to change tone ;

;

;

>    push r5 add.w r4,r4   mov.w scale(r4),r4 >  rra.w r4   mov.w r4,r5 update tone duty cycle   mov.w r4,&TBCCR0   mov.w r4,&duty_cycle_high   mov.w r5,&duty_cycle_low   pop r5

BYU CS/ECEn 124

; save r5 ; (word index) ; r4 = tone (frequency)

; 50% duty cycle

; start clock (if necessary) ; set high duty cycle ; set low duty cycle

MSP430 Examples

24

Tone Scale Example

Step 7b: Play Scale 

Initialize high and low duty cycle variables clr.b &duty_cycle_toggle   mov.w #DO/2,&duty_cycle_high   mov.w #DO/2,&duty_cycle_low



; init toggle variable ; w/1st tone

 And add high and low duty cycles to Timer_B ISR ;********************************************************************** ; Timer B ISR  TB_ISR: ; timer B ISR    bic.w #TBIFG,&TBCTL ; acknowledge interrupt xor.b #0x20,&P4OUT ; pulse buzzer xor.b #0xff,&duty_cycle_toggle ; high? jeq TB02 ; n   mov.w &duty_cycle_high,&TBCCR0 ; y, set high duty cycle jmp TB04 TB02:

mov.w

TB04:

reti

BYU CS/ECEn 124

&duty_cycle_low,&TBCCR0

; set low duty cycle ; return from interrupt

MSP430 Examples

25

Tone Scale Example

Step 8a: Add Volume 

Create volume index variable to data section .bss



; volume (0-8)

Initialize volume in init_variables  

MAX_VOLUME  



volume,2

mov.w

.set

4

; 0-4 volume

#MAX_VOLUME,&volume

; init volume

Create a PWM array of duty-cycles in text section ; duty cycle table (shift right until duty=0) duty .word 0x7fff, 0x0020, 0x0010, 0x0004, 0x0001 ; off 3.125% 6.25% 12.5% 50%

BYU CS/ECEn 124

MSP430 Examples

26

Tone Scale Example

Step 8b: Add Volume 

Change Watchdog ISR to use duty array ; ; ;

>  rra.w r4 mov.w r4,r5   push r6   mov.w r4,r5   mov.w volume,r6 add.w r6,r6   mov.w duty(r6),r6

 

 

;

rra.w r4 jne WD06 clr.w r5

; 50% duty cycle

; save in r5 ; get volume ; (word index) ; r6 = duty cycle

WD04:

WD06: rra.w r6 jne WD04 sub.w r4,r5   pop r6

; 1/2 duty cycle, off? ; n ; y ; done? ; n ; y, r4+r5=frequency

update tone duty cycle

BYU CS/ECEn 124

MSP430 Examples

27

Tone Scale Example

Step 9: Switches Change Volume 

Use P2IFG determine which switch was pressed and adjust volume accordingly ;********************************************************************** ; Adjust volume routine adjust_volume: ; adjust volume   bit.b #0x01,&P2IFG ; switch #1? jeq adj02 ; n sub.w #1,&volume ; y, down volume, too low? jge adj04 ; n clr.w &volume ; y, clear jmp adj04 adj02:

adj04:

bit.b jeq add.w cmp.w jlo   mov.w

#0x02,&P2IFG adj04 #1,&volume #MAX_VOLUME,&volume adj04 #MAX_VOLUME,&volume

; ; ; ; ;

switch #2? n y, turn up volume too high? n ; y, set to max

ret

BYU CS/ECEn 124

MSP430 Examples

28

Tone Scale Example

Step 10: Volume in LEDs 

Display the current volume setting using 4 LEDs ;********************************************************************** ; Update LEDs routine update_LEDs: ; show volume in LEDs   bic.b #0xc0,&P2OUT ; LED #1 & #2   bic.b #0x08,&P3OUT ; LED #3   bic.b #0x40,&P4OUT ; LED #4 cmp.w #0,&volume jeq upd02   bis.b #0x40,&P2OUT ; turn on LED #1 cmp.w #1,&volume jeq upd02   bis.b #0x80,&P2OUT ; turn on LED #2 cmp.w #2,&volume jeq upd02   bis.b #0x08,&P3OUT ; turn on LED #3 cmp.w #3,&volume jeq upd02   bis.b #0x40,&P4OUT ; turn on LED #4 upd02:

ret

BYU CS/ECEn 124

MSP430 Examples

29

Tone Scale Example

Step 11: Debounce Switches 

Finally, debounce switches (1¶s (up) for 10 ms) ;********************************************************************** ; Switch debounce routine ; DB_TIME .set 10 ; 10 ms debounce time DB_CYCS .set 12 ; instruction cycles for delay DB_DELAY .set DB_TIME*myCLOCK/DB_CYCS/1000 ; delay count debounce_switch:   push

r15

; callee save

deb02:

mov.b xor.b and.b jne

&P2IN,r12 #0x0f,r12 #0x0f,r12 deb02

; ; ; ;

deb04:

mov.w

#DB_DELAY,r15

; minimum delay

&P2IN,r12 #0x0f,r12 #0x0f,r12 deb04 r15 deb06 r15

; ; ; ; ; ;

deb06:

mov.b xor.b and.b jeq dec.w jne   pop ret

BYU CS/ECEn 124

read switches SW1-4 any switch low? y, wait until all off

read switches SW1-4 all switches high? n, restart delay y, long enough delay? n, keep going ; y, switches debounced 

MSP430 Examples

30

Pulse Width Modulation (H /W)

Step 12a: Use Timer Output PWM 

First, eliminate a lot of code!! .bss .bss .bss

duty_cycle_high,2 duty_cycle_l ow,2 duty_cycle_t oggle,1

; high part of cycle ; low part of cycle ; duty cycle flag

  mov.w #DO/2,&TBCCR 0 ; start clock   bis.w #TBIE,&TBCTL ; enable timer B interrupts   mov.w #DO/2,&duty_ cycle_high ; set duty cycles   mov.w #DO/2,&duty_cycle_low ; >  ; rra.w r4 ; mov.w r4,r5   mov.b volume,r5   mov.w duty(r5),r5 sub.w r5,r4 cmp.w #0,r5 jne WD04   mov.w #0,r4  

WD04: mov.w r4,&TBCCR0   mov.w r4,&duty_cyc le_high   mov.w r5,&duty_cyc le_low

TB_isr:

; 50% duty cycle ; get volume ; r5 = duty cycle ; subtract from frequency ; turn off? ; n ; y, high=low=0 ; start clock (if necessary) ; set high duty cycle ; set low duty cycle

; timer B ISR    bic.w #TBIFG,&TBCT L ; acknowledge interrupt xor.b #0x20,&P4OUT ; pulse buzzer xor.b #1,&duty_cyc le_toggle ; high? jeq TB02 ; n   mov.w &duty_cycle_ high,&TBCCR0 ; y, set high duty cycle jmp TB04

TB02:

mov.w

TB04:

reti .sect .word

&duty_cycle_ low,&TBCCR0 ; set low duty cycle ; return from interrupt ".int12" TB_isr

BYU CS/ECEn 124

; timer B section ; timer B isr

MSP430 Examples

31

Pulse Width Modulation (H /W)

Step 12b: Use Timer Output PWM 

Put transducer (P4.5) as secondary function   bis.b #0x20,&P4SEL   mov.w #OUTMOD_3,&TBCCTL2   mov.w #DO/2,&TBCCR2



; P4.5 transducer output ; output mode = set/reset ; use TBCCR2 as volume

Change WD ISR to just put the duty cycle in TBCCR2 ;

>    push r5 ; save r5 add.w r4,r4 ; (word index)   mov.w scale(r4),r4 ; r4 = tone (frequency)   mov.w r4,&TBCCR0 ; start clock (if necessary)   mov.b volume,r5 ; get volume add.w r5,r5 ; (word index)   mov.w duty(r5),r5 ; r5 = duty cycle   mov.w r5,&TBCCR2 ; start clock (if necessary)   pop r5

BYU CS/ECEn 124

MSP430 Examples

32

Pulse Width Modulation (H /W)

Example 8: H /W PWM w/Timer_B 

Timer B output used to modulate transducer at 440 Hz .cdecls C,LIST,"msp430x22x4.h" SMCLK .set 1200000 ; TIME_A3 .set 1000000/440/2/2 ; TB_CTL .set TBSSEL_2+ID_0+MC_1 ; TB_FREQ .set SMCLK/TIME_A3 ; reset:

Set P4.5 as output from TB2

UP mode, TB2 set/reset 50% Duty

Cycle

mov.w #0x0600,SP   mov.w #WDTPW+WDTHOLD,&WDTCTL   bis.b #0x20,&P4DIR   bis.b #0x20,&P4SEL clr.w &TBR   mov.w #TB_CTL,&TBCTL   mov.w #OUTMOD_3,&TBCCTL2   mov.w #TB_FREQ,&TBCCR0   mov.w #TB_FREQ/2,&TBCCR2   bis.w #LPM0+GIE,SR jmp $ .sect .word .end 

BYU CS/ECEn 124

".reset" reset

1200000 clocks / second  A = 440 Hz (2x) SMCLK,/1,UP (No interrupts) clocks / 440 Hz

; initialize SP ; stop WDT ; P4.5 transducer output ; P4.5 timerB output ; reset timerB ; set timerB control reg ; TB2 output mode = set/reset ; set interval (frequency) ; load volume (duty cycle) ; enter LPM0 w/interrupts ; will never get here! ; reset vector section ; reset vector ISR 

MSP430 Examples

33

Pulse Width Modulation (H /W)

Example 9: H /W PWM w/Timer_A #include #include #include #include #include

Set P2.4 as output from TA2

SMCLK, 1 /4, UP mode, TA2 set/reset

"msp430x22x4.h"   "eZ430X.h" "lcd.h" "adc.h"

void main(void) { eZ430X_init(CALDCO_8MHZ);   ADC_init(); lcd_init();

// init board  // init ADC // init LCD

P2DIR |= 0x10; // P2SEL |= 0x10; // TAR = 0; // TACTL = TASSEL_2 + ID_2 + MC_1; // TACCTL2 = OUTMOD_3; //

P2.4 speaker output P2.4 TA2 output reset timer A  SMCLK, /4, UP (no interrupts) TA2 = set/reset

 while (1) { uint16 freq = (1023 - ADC_read(LEFT_POT)) > 10; TACCR0 = freq; // frequency TACCR2 = duty; // duty cycle lcd_cursor(10, 4); lcd_printf("Freq:%u ", freq); Freq = Left Pot lcd_cursor(10, 2); Duty Cycle = Right Pot lcd_printf("Duty:%u ", duty); } } // end main BYU CS/ECEn 124 MSP430 Examples 34

Pulse Width Modulation (H /W)

Example 9: H /W PWM w/Timer_A #include #include #include #include #include

Set P2.4 as output from TA2

SMCLK, 1 /4, UP mode, TA2 set/reset

"msp430x22x4.h"   "eZ430X.h" "lcd.h" "adc.h"

void main(void) { eZ430X_init(CALDCO_8MHZ);   ADC_init(); lcd_init();

// init board  // init ADC // init LCD

P2DIR |= 0x10; // P2SEL |= 0x10; // TAR = 0; // TACTL = TASSEL_2 + ID_2 + MC_1; // TACCTL2 = OUTMOD_3; //

P2.4 speaker output P2.4 TA2 output reset timer A  SMCLK, /4, UP (no interrupts) TA2 = set/reset

 while (1) { uint16 freq = (1023 - ADC_read(LEFT_POT)) > 10; TACCR0 = freq; // frequency TACCR2 = duty; // duty cycle Freq = Left Pot lcd_cursor(10, 4); Duty Cycle = Right Pot lcd_printf("Duty/Freq:%u/%u ", duty, freq); } } // end main BYU CS/ECEn 124

MSP430 Examples

35

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF