Download - MSP430 Examples
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 1/36
BYU CS/ECEn 124 MSP430 Examples 1
Topics to Cover«
F2013 Blinky Example
Lab 4: Blinky Lab
Example 2: Interrupts w/Timer_A
Example 3: S/W PWM w/Timer_A
Example 4: Watchdog Clock
Example 5: Watchdog PWM
Example 6: SW Switch Debounce
Example 7: Timer_B S/W PWM
Recursive Line Draw
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 2/36
BYU CS/ECEn 124 MSP430 Examples 2
F2013 Blinky Example
;*******************************************************************************; CS/ECEn 124 Lab 1 - 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 ; stop WDT bis.b #0x01,&P1DIR ; set P1.0 as output
mainloop: xor.b #0x01,&P1OUT ; toggle P1.0 mov.w #0,r15 ; use R15 as delay counter
delayloop: dec.w r15 ; delay over?jnz delayloop ; n
jmp mainloop ; y, toggle led
;------------------------------------------------------------------------------; Interrupt Vectors;------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET ; start address
.end
Systematic Decomposition
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 3/36
BYU CS/ECEn 124 MSP430 Examples 3
Add 2nd Delay Loop
;*******************************************************************************; CS/ECEn 124 Lab 1 - blinky.asm: Software Toggle P1.0;*******************************************************************************
.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013delay .set 0;------------------------------------------------------------------------------
.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
mainloop: xor.b #0x01,&P1OUT ; toggle P1.0 mov.w #delay,r15 ; use R15 as delay counter
delayloop: dec.w r15 ; delay over?jnz delayloop ; n
delay2: dec.w r15jnz delay2
jmp mainloop ; y, toggle led
;------------------------------------------------------------------------------; Interrupt Vectors;------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET ; start address
.end
Systematic Decomposition
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 4/36
BYU CS/ECEn 124 MSP430 Examples 4
LEDs
6 LED¶s on eZ430X Development Board
P1.0 Red LED eZ430-RF2500
P1.1 Green LED eZ430-RF2500
P2.6 LED #1 (Green)
P2.7 LED #2 (Orange) P3.3 LED #3 (Yellow)
P4.6 LED #4 (Red)
Port bits must be enabled for output by writing a 1 to the
port direction register
bis.b #0x03,&P1DIR ; eZ430-RF2500 LED's bic.b #0xc0,&P2SEL ; select GPIO
bis.b #0x40,&P2DIR ; LED #1 (P2.6)
bis.b #0x80,&P2DIR ; LED #2 (P2.7)
bis.b #0x08,&P3DIR ; LED #3 (P3.3)
bis.b #0x40,&P4DIR ; LED #4 (P4.6)
Device: LED
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 5/36
BYU CS/ECEn 124 MSP430 Examples 5
LEDs
Turn LED off by writing a 0 to the port pin bic.b #0x03,&P1OUT ; eZ430-RF2500 LED's bic.b #0x40,&P2OUT ; LED #1 (P2.6) bic.b #0x80,&P2OUT ; LED #2 (P2.7) bic.b #0x08,&P3OUT ; LED #3 (P3.3) bic.b #0x40,&P4OUT ; LED #4 (P4.6)
Turn LED on by writing a 1 to the port pin bis.b #0x03,&P1OUT ; eZ430-RF2500 LED's bis.b #0x40,&P2OUT ; LED #1 (P2.6) bis.b #0x80,&P2OUT ; LED #2 (P2.7) bis.b #0x08,&P3OUT ; LED #3 (P3.3) bis.b #0x40,&P4OUT ; LED #4 (P4.6)
Toggle LED by XOR¶ing a 1 to the port pin xor.b #0x03,&P1OUT ; eZ430-RF2500 LED's xor.b #0x40,&P2OUT ; LED #1 (P2.6) xor.b #0x80,&P2OUT ; LED #2 (P2.7) xor.b #0x08,&P3OUT ; LED #3 (P3.3) xor.b #0x40,&P4OUT ; LED #4 (P4.6)
Device: LED
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 6/36
BYU CS/ECEn 124 MSP430 Examples 6
Lab 4: Blinky Lab
Lab 4: Blinky
;*******************************************************************************; 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" ; MSP430F2274COUNT .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: xor.b #0x01,&P1OUT ;4 toggle P1.0 mov.w #COUNT,r15 ;1 use R15 as delay counter
delayloop: dec.w r15 ; 1 delay over?jnz delayloop ; 2 n
jmp mainloop ; 2 y, toggle led
;------------------------------------------------------------------------------; Interrupt Vectors;------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET ; start address
.end
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 7/36
BYU CS/ECEn 124 MSP430 Examples 7
.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013DELAY .equ (50/8)
.text ; beginning of codeRESET: 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 ; toggle P1.0 push.w #DELAY ; pass delay count on stack
call #delay ; call delay subroutinejmp mainloop
; 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 ; inner delay over?jne delay02 ; n
dec.w 4(SP) ; y, outer done?jne delay02 ; n
pop.w r15 ; y, restore register(s) mov.w @SP+,0(SP) ; pop input delay countret ; return from subroutine
.sect ".reset" ; MSP430 RESET Vector
.word RESET ; start address
.end
Example 1a: Activation Recor d
4(SP) = delay count2(SP) = return address0(SP) = r 15
Activation Recor d
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 8/36
BYU CS/ECEn 124 MSP430 Examples 8
.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013DELAY .equ (50/8)
.text ; beginning of codeRESET: 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 ; toggle P1.0 push.w #DELAY ; pass delay count on stackcall #delay ; call delay subroutine
jmp mainloop
; delay subroutine: stack usage 6| DELAY | \; 4| ret | subroutine frame (8 bytes); 2| r12 | /(activation record); (SP) => 0| r15 |/delay: push.w r12 ; callee-save
push.w r15 mov.w 6(SP),r12 ; get delay count mov.w #0,r15 ; use R15 as inner counter
delay02: dec.w r15 ; delay over?jne delay02 ; n
dec.w r12 ; y, done?jne delay02 ; n
pop.w r15 ; y, restore registers pop.w r12 mov.w @SP+,0(SP) ; pop input delay countret ; return from subroutine
.sect ".reset" ; MSP430 RESET Vector
.word RESET ; start address.end
Example 1b: Activation Recor d
6(SP) = delay count4(SP) = return address2(SP) = r 120(SP) = r 15
Activation Recor d
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 9/36
BYU CS/ECEn 124 MSP430 Examples 9
.cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013DELAY .equ (50/8)
.text ; beginning of codeRESET: 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 ; toggle P1.0 push.w #DELAY ; pass delay count on stackcall #delay ; call delay subroutinejmp mainloop
; 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 0(SP) ; delay over?jne delay02 ; ndec.w 4(SP) ; y, done?
jne delay02 ; nadd.w #2,SP ; y, deactivate local variable mov.w @SP+,0(SP) ; pop input delay countret ; return from subroutine
.sect ".reset" ; MSP430 RESET Vector
.word RESET ; start address
.end
Example 1c: Activation Recor d
4(SP) = delay count2(SP) = return address0(SP) = local variable
Activation Recor d
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 10/36
BYU CS/ECEn 124 MSP430 Examples 10
Example 2: Interrupts w/Timer_A
cdecls C,LIST, "msp430x20x3.h" ; MSP430F2013TA_CTL .set TASSEL_2+ID_3+MC_1+TAIE ; 000000 10 11 01 000 1 = SMCLK,/8,UP,IETA_FREQ .set 0xffff ; clocks
;------------------------------------------------------------------------------.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 ; reset timerA mov.w #TA_CTL,&TACTL ; set timerA control reg mov.w #TA_FREQ,&TACCR0 ; set interval (frequency) bis.w #LPM0+GIE,SR ; enter LPM0 w/interruptsjmp $
TA_isr: ; timer A ISR bic.w #TAIFG,&TACTL ; acknowledge interruptxor.b #0x01,&P1OUT ; toggle P1.0
reti
;------------------------------------------------------------------------------; Interrupt Vectors
.sect ".int08" ; timer A section
.word TA_isr ; timer A isr
.sect ".reset" ; MSP430 RESET Vector
.word RESET ; start address
.end
Blinky Example
TASSEL_2 = SMCLK
ID_3 = /8
MC_1 = UP Mode
Enable Interrupt
Acknowledge Interrupt(Put its hand down)
Put the processor tosleep!
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 11/36
BYU CS/ECEn 124 MSP430 Examples 11
Example 3: S /W PWM w/Timer_A
.cdecls C,LIST,"msp430x20x3.h"SMCLK .set 1200000 ; 1200000 clocks / second TA_CTL .set TASSEL_2+ID_0+MC_1+TAIE ; SMCLK, /1, UP, IETA_FREQ .set 120 ; FREQ / SMCLK = 0.0001 = 100 us
.bss cnt,2 ; counter variable
.textRESET: mov.w #0x0280,SP ; init stack pointer
mov.w #WDTPW+WDTHOLD,&WDTCTL ; stop watchdog bis.b #0x01,&P1DIR ; set P1.0 as outputclr.w &TAR ; reset timerA
mov.w #TA_CTL,&TACTL ; set timerA control reg mov.w #TA_FREQ,&TACCR0 ; set interval (frequency) bis.w #LPM0+GIE,SR ; enter LPM0 w/interruptsjmp $ ; will never get here!
TA_isr: bic.w #TAIFG,&TACTL ; acknowledge interruptinc.w &cntcmp.w #10,&cnt ; time to pulse?jlo TA_isr2 ; n
clr.w &cnt ; y, reset counter bis.b #0x01,&P1OUT ; turn on
jmp TA_isr4
TA_isr2: bic.b #0x01,&P1OUT ; turn off
TA_isr4: reti ; return from interrupt
.sect ".int08" ; timer A section
.word TA_isr ; timer A isr
.sect ".reset" ; MSP430 RESET Vector
.short RESET ; start address
.end
LED Intensity
Acknowledgeneeded
10% DutyCycle
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 12/36
BYU CS/ECEn 124 MSP430 Examples 12
Example 4: Watchdog Clock
.cdecls C,LIST,"msp430x20x3.h"SMCLK .set 1200000 ; 1.2 Mhz clock WDT_CTL .set WDT_MDLY_8 ; WDT SMCLK, 8 ms (@1 Mhz) WDT_CPS .set SMCLK/8000 ; 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: ;<< program >> jmp loop ; loop indefinitely
; Watchdog ISR ------------------------------------------------------------ WDT_ISR: dec.w &WDTSecCnt ; decrement counter, 0?
jne WDT_02 ; n
mov.w #WDT_CPS,&WDTSecCnt ; y, re-initialize counterxor.b #0x01,&P1OUT ; toggle P1.0
WDT_02: reti ; return from interrupt
; Interrupt Vectors -------------------------------------------------------.sect ".int10" ; Watchdog Vector.word WDT_ISR ; Watchdog ISR .sect ".reset" ; PUC Vector.word RESET ; RESET ISR .end
Watchdog
8 ms (@1 MHz SMCLK)
Enable WD Interrupts
No acknowledgeneeded
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 13/36
BYU CS/ECEn 124 MSP430 Examples 13
Example 5: Watchdog PWM
.cdecls C,LIST,"msp430x22x4.h" ; include c header WDT_CLK .set 500 ; 500 Mhz WD clock (@1 Mhz)STACK .set 0x0600 ; stack
.bss WDTSecCnt,2 ; WDT second counter
.bss buzzON,1 ; buzzer on flag
.text ; program sectionRESET: mov.w #STACK,SP ; initialize stack pointer
mov.w #WDT_MDLY_0_5,&WDTCTL ; set WD timer interval to 0.5 ms mov.w #WDT_CPS,&WDTSecCnt ; initialize 1 sec WD counter mov.b #WDTIE,&IE1 ; enable WDT interrupt bis.b #0x01,&P1DIR ; P1.0 output bis.b #0x20,&P4DIR ; P4.5 output (transducer)clr.b &buzzON ; turn off buzzer
bis.w #LPM0+GIE,SR ; enable interrupts / sleepjmp $ ; (should never get here!)
WDT_ISR: cmp.b #0,&buzzON ; buzzer on?jeq WDT_02 ; n
xor.b #0x20,&P4OUT ; y, use 50% PWM
WDT_02: dec.w &WDTSecCnt ; decrement counter, 0?jne WDT_04 ; n
mov.w #WDT_CPS,&WDTSecCnt ; y, re-initialize counterxor.b #0x01,&P1OUT ; toggle P1.0xor.b #0xff,&buzzON ; toggle buzzer on/off
WDT_04: reti ; return from interrupt
.sect ".int10" ; Watchdog Vector
.word WDT_ISR ; Watchdog ISR
.sect ".reset" ; PUC Vector
.word RESET ; RESET ISR
.end
Speaker (Transducer )
PWM when buzzON is
non-zero
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 14/36
BYU CS/ECEn 124 MSP430 Examples 14
;**********************************************************************; Switch debounce routine;DB_TIME .set 10 ; 10 ms debounce timeDB_CYCS .set 13 ; instruction cycles for delayDB_DELAY .set DB_TIME*myCLOCK/DB_CYCS/1000 ; delay count
debounce_switch:
push r15 ; callee save
deb02: mov.b &P2IN,r12 ; read switchesxor.b #0x0f,r12 ; SW1-4and.b #0x0f,r12 ; any switch low?jne deb02 ; y, wait until all off
deb04: mov.w #DB_DELAY,r15 ; minimum delay
deb06: mov.b &P2IN,r12 ; read switchesxor.b #0x0f,r12 ; SW1-4and.b #0x0f,r12 ; all switches high?jeq deb04 ; n, restart delay
dec.w r15 ; y, long enough delay?jne deb06 ; n, keep going
pop r15 ; y, switches debounced ret
Example 6: SW Switch Debounce
Reset timing counter if
and of theswitches
read 0
Switch Debounce
Return if
R15
countsdown to 0
Wait untilall
switches
off
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 15/36
BYU CS/ECEn 124 MSP430 Examples 15
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 ; 1200000 clocks / second TIME_A3 .set 1000000/440/2 ; A = 440 HzTB_CTL .set TBSSEL_2+ID_0+MC_1+TBIE ; SMCLK, /1, UP, IETB_FREQ .set SMCLK/TIME_A3 ; clocks / 440 Hz
reset: mov.w #0x0600,SP ; initialize SP mov.w #WDTPW+WDTHOLD,&WDTCTL ; stop WDT bis.b #0x20,&P4DIR ; P4.5 transducer outputclr.w &TBR ; reset timerB mov.w #TB_CTL,&TBCTL ; set timerB control reg mov.w #TB_FREQ,&TBCCR0 ; set interval (frequency) bis.w #LPM0+GIE,SR ; enter LPM0 w/interruptsjmp $ ; will never get here!
TB_isr: bic.w #TBIFG,&TBCTL ; acknowledge interruptxor.b #0x20,&P4OUT ; toggle (50% duty cycle)reti
.sect ".int12" ; timer B section
.word TB_isr ; timer B isr
.sect ".reset" ; reset vector section
.word reset ; reset vector ISR
.end
Timer B InterruptService Routine
Pulse Width Modulation (S /W)
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 16/36
BYU CS/ECEn 124 MSP430 Examples 16
Step 1: Start Simple
Tone Scale Example
.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 MSP430call #init_variables ; init variables
;**********************************************************************; Main event loop...loop: call #update_LEDs ; update LED's
call #goto_sleep ; go to sleepcall #adjust_volume ; awake! adjust volumecall #debounce_switch ; debounce switchesjmp loop ; go back to sleep
init_MSP430: ; init MSP430
init_variables: ; init variablesgoto_sleep: ; enter LPM0adjust_volume: ; adjust volumeupdate_LEDs: ; show volume in LEDxdebounce_switch: ; debounce switches
ret
.sect ".reset" ; reset vector section
.word reset ; reset vector ISR
.end
Working Program!
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 17/36
BYU CS/ECEn 124 MSP430 Examples 17
Step 2: Initialize MSP430
Tone Scale Example
WDT_CLK .set 8000 ; 8 khz clock (@1 Mhz) WDT_CTL .set WDT_MDLY_8 ; WDT SMCLK, 8 ms;**********************************************************************; Initialize MSP430 routineinit_MSP430:
mov.w #WDT_CTL,&WDTCTL ; configure WDT
bic.b #0x03,&P1SEL ; eZ430 LED's bis.b #0x03,&P1DIR ; P1.0-1 as output bic.b #0x01,&P1OUT ; turn off red bis.b #0x02,&P1OUT ; turn on green
bic.b #0xc0,&P2SEL ; eZ430X LED's bis.b #0xc0,&P2DIR ; LED #1 & #2 bis.b #0x08,&P3DIR ; LED #3 bis.b #0x40,&P4DIR ; LED #4
bic.b #0x0f,&P2SEL ; eZ430X push buttons
bic.b #0x0f,&P2DIR ; P2.0-3 as inputs bis.b #0x0f,&P2OUT ; P2.0-3 pull-ups bis.b #0x0f,&P2IES ; h to l bis.b #0x0f,&P2REN ; 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,&TBCTLret
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 18/36
BYU CS/ECEn 124 MSP430 Examples 18
Add WDT 1 second data variable
Add WDT ISR and interrupt vector
Tone Scale Example
;**********************************************************************; 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
; <<add scale sequence code here>>
WD10: reti ; return from interrupt
;**********************************************************************; Interrupt Vector Table Entries
.sect ".int10" ; WDT vector
.word WDT_ISR ; address of WDT ISR
.bss WDTSecCnt,2 ; WDT second counter
Step 3a: Implement Watchdog
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 19/36
BYU CS/ECEn 124 MSP430 Examples 19
Initialize 1 second data variable
Enable interrupts
Tone Scale Example
myCLOCK .set 1200000 ; 1.2 Mhz clock WDT_CLK .set 8000 ; 8 khz clock (@1 Mhz) WDT_CTL .set WDT_MDLY_8 ; WDT SMCLK, 8 ms WDT_CPS .set myCLOCK/WDT_CLK ; WD clocks / second count
;**********************************************************************; Initalize variables routineinit_variables: ; init variables
mov.w #WDT_CPS,&WDTSecCnt ; WDT counts/second bis.b #WDTIE,&IE1 ; enable WDT interruptret
Step 3b: Implement Watchdog
;**********************************************************************; Goto sleep routine (Enable interrupts and LPM0)goto_sleep: ; enter LPM0
bis.b #LPM0+GIE,SR ; enter LPM0 w/interruptsret
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 20/36
BYU CS/ECEn 124 MSP430 Examples 20
Add some tone constants equates
Create melodic array of tone values
Tone Scale Example
; 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 ; EFA .set DO*3/4 ; F
SOL .set DO*2/3 ; GLA .set DO*3/5 ; A TI .set DO*8/15 ; BDO1 .set DO*1/2 ; C
Step 4a: Create Tones
.text ; code Sectionscale .word DO, RE, MI, FA, SOL, LA, TI, DO1
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 21/36
BYU CS/ECEn 124 MSP430 Examples 21
Create tone index variable
Initialize tone variable in init variable subroutine
Use WDT ISR to sequence thru the scale
Tone Scale Example
Step 4b: Create Tones
push r4 ; save r4 mov.w &tone,r4 ; get tone
add.w #1,r4 ; next tonecmp.w #MAX_TONE,r4 ; restart scale?jlo WD02 ; n
clr.w r4 ; y
WD02: mov.w r4,&tone ; save tone; << later adjust tone & volume here >>
pop r4
.bss tone,2 ; tone number (0-8)
MAX_TONE .set 8 ; 0-8 tones mov.w #0,&tone ; 1st tone
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 22/36
BYU CS/ECEn 124 MSP430 Examples 22
Add TimerB ISR and interrupt vector
And start TimerB with 1st
tone in init variables subroutine
Tone Scale Example
;**********************************************************************; Timer B ISR TB_ISR: ; timer B ISR
bic.w #TBIFG,&TBCTL ; acknowledge interruptxor.b #0x20,&P4OUT ; pulse buzzer
TB04: reti ; return from interrupt
.sect ".int12" ; timer B section
.word TB_ISR ; timer B ISR
Step 5: Output Tone
mov.w #DO/2,&TBCCR0 ; start timer clock w/1st note bis.w #TBIE,&TBCTL ; enable timer B interrupts
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 23/36
BYU CS/ECEn 124 MSP430 Examples 23
Add Port 2 ISR to clear LPM0 and enter AM
And change to LPM0 when enabling interrupts
Tone Scale Example
Step 6: Enter LPM0
;**********************************************************************; 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 ".int03" ; P2 interrupt vector
.word P2_ISR ; address of Port 2 ISR
;**********************************************************************; Goto sleep routine (Enable interrupts and LPM0)goto_sleep: ; enter LPM0
bic.b #GIE,SR ; disable all interruptsclr.b &P2IFG ; acknowledge all bis.b #0x0f,&P2IE ; enable switch interrupts bis.b #LPM0+GIE,SR ; enter LPM0 w/interruptsret
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 24/36
BYU CS/ECEn 124 MSP430 Examples 24
Add toggle, high, and low duty cycle variables
Use Watchdog interrupt to change tone
Tone Scale Example
Step 7a: Play Scale
.bss duty_cycle_high,2 ; high part of cycle
.bss duty_cycle_low,2 ; low part of cycle
.bss duty_cycle_toggle,1 ; duty cycle flag
; << adjust timer b tone here >> push r5 ; save r5add.w r4,r4 ; (word index) mov.w scale(r4),r4 ; r4 = tone (frequency)
; << adjust volume here >>
rra.w r4 ; 50% duty cycle mov.w r4,r5
; update tone duty cycle mov.w r4,&TBCCR0 ; start clock (if necessary) mov.w r4,&duty_cycle_high ; set high duty cycle mov.w r5,&duty_cycle_low ; set low duty cycle pop r5
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 25/36
BYU CS/ECEn 124 MSP430 Examples 25
Initialize high and low duty cycle variables
And add high and low duty cycles to Timer_B ISR
Tone Scale Example
Step 7b: Play Scale
;**********************************************************************; Timer B ISR TB_ISR: ; timer B ISR
bic.w #TBIFG,&TBCTL ; acknowledge interruptxor.b #0x20,&P4OUT ; pulse buzzerxor.b #0xff,&duty_cycle_toggle ; high?
jeq TB02 ; n mov.w &duty_cycle_high,&TBCCR0 ; y, set high duty cyclejmp TB04
TB02: mov.w &duty_cycle_low,&TBCCR0 ; set low duty cycle
TB04: reti ; return from interrupt
clr.b &duty_cycle_toggle ; init toggle variable mov.w #DO/2,&duty_cycle_high ; w/1st tone mov.w #DO/2,&duty_cycle_low
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 26/36
BYU CS/ECEn 124 MSP430 Examples 26
Create volume index variable to data section
Initialize volume in init_variables
Create a PWM array of duty-cycles in text section
Tone Scale Example
Step 8a: Add Volume
MAX_VOLUME .set 4 ; 0-4 volume
mov.w #MAX_VOLUME,&volume ; init volume
; duty cycle table (shift right until duty=0)duty .word 0x7fff, 0x0020, 0x0010, 0x0004, 0x0001; off 3.125% 6.25% 12.5% 50%
.bss volume,2 ; volume (0-8)
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 27/36
BYU CS/ECEn 124 MSP430 Examples 27
Change Watchdog ISR to use duty array
Tone Scale Example
Step 8b: Add Volume
; << adjust volume here >> ; rra.w r4 ; 50% duty cycle; mov.w r4,r5
push r6
mov.w r4,r5 ; save in r5 mov.w volume,r6 ; get volumeadd.w r6,r6 ; (word index) mov.w duty(r6),r6 ; r6 = duty cycle
WD04: rra.w r4 ; 1/2 duty cycle, off?jne WD06 ; n
clr.w r5 ; y
WD06: rra.w r6 ; done?jne WD04 ; n
sub.w r4,r5 ; y, r4+r5=frequency pop r6
; update tone duty cycle
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 28/36
BYU CS/ECEn 124 MSP430 Examples 28
Use P2IFG determine which switch was pressed and
adjust volume accordingly
Tone Scale Example
Step 9: Switches Change Volume
;**********************************************************************; Adjust volume routineadjust_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, clearjmp adj04
adj02: bit.b #0x02,&P2IFG ; switch #2?
jeq adj04 ; nadd.w #1,&volume ; y, turn up volumecmp.w #MAX_VOLUME,&volume ; too high?jlo adj04 ; n
mov.w #MAX_VOLUME,&volume ; y, set to max
adj04: ret
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 29/36
BYU CS/ECEn 124 MSP430 Examples 29
Display the current volume setting using 4 LEDs
Tone Scale Example
Step 10: Volume in LEDs
;**********************************************************************; Update LEDs routineupdate_LEDs: ; show volume in LEDs
bic.b #0xc0,&P2OUT ; LED #1 & #2
bic.b #0x08,&P3OUT ; LED #3 bic.b #0x40,&P4OUT ; LED #4cmp.w #0,&volumejeq upd02
bis.b #0x40,&P2OUT ; turn on LED #1cmp.w #1,&volumejeq upd02
bis.b #0x80,&P2OUT ; turn on LED #2
cmp.w #2,&volumejeq upd02 bis.b #0x08,&P3OUT ; turn on LED #3cmp.w #3,&volumejeq upd02
bis.b #0x40,&P4OUT ; turn on LED #4
upd02: ret
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 30/36
BYU CS/ECEn 124 MSP430 Examples 30
Finally, debounce switches (1¶s (up) for 10 ms)
Tone Scale Example
Step 11: Debounce Switches
;**********************************************************************; Switch debounce routine;DB_TIME .set 10 ; 10 ms debounce timeDB_CYCS .set 12 ; instruction cycles for delayDB_DELAY .set DB_TIME*myCLOCK/DB_CYCS/1000 ; delay count
debounce_switch: push r15 ; callee save
deb02: mov.b &P2IN,r12 ; read switchesxor.b #0x0f,r12 ; SW1-4and.b #0x0f,r12 ; any switch low?
jne deb02 ; y, wait until all off
deb04: mov.w #DB_DELAY,r15 ; minimum delay
deb06: mov.b &P2IN,r12 ; read switchesxor.b #0x0f,r12 ; SW1-4and.b #0x0f,r12 ; all switches high?
jeq deb04 ; n, restart delaydec.w r15 ; y, long enough delay?
jne deb06 ; n, keep going pop r15 ; y, switches debounced ret
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 31/36
BYU CS/ECEn 124 MSP430 Examples 31
First, eliminate a lot of code!!
Step 12a: Use Timer Output PWM
.bss duty_cycle_high,2 ; high part of cycle
.bss duty_cycle_low,2 ; low part of cycle
.bss duty_cycle_toggle,1 ; duty cycle flag
mov.w #DO/2,&TBCCR0 ; 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
; << adjust volume here >> ; rra.w r4 ; 50% duty cycle; mov.w r4,r5
mov.b volume,r5 ; get volume mov.w duty(r5),r5 ; r5 = duty cyclesub.w r5,r4 ; subtract from frequencycmp.w #0,r5 ; turn off?jne WD04 ; n
mov.w #0,r4 ; y, high=low=0
WD04: mov.w r4,&TBCCR0 ; start clock (if necessary) mov.w r4,&duty_cycle_high ; set high duty cycle mov.w r5,&duty_cycle_low ; set low duty cycle
TB_isr: ; timer B ISR bic.w #TBIFG,&TBCTL ; acknowledge interruptxor.b #0x20,&P4OUT ; pulse buzzerxor.b #1,&duty_cycle_toggle ; high?jeq TB02 ; n
mov.w &duty_cycle_high,&TBCCR0 ; y, set high duty cyclejmp TB04
TB02: mov.w &duty_cycle_low,&TBCCR0 ; set low duty cycle
TB04: reti ; return from interrupt
.sect ".int12" ; timer B section
.word TB_isr ; timer B isr
Pulse Width Modulation (H /W)
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 32/36
BYU CS/ECEn 124 MSP430 Examples 32
Put transducer (P4.5) as secondary function
Change WD ISR to just put the duty cycle in TBCCR2
Step 12b: Use Timer Output PWM
bis.b #0x20,&P4SEL ; P4.5 transducer output mov.w #OUTMOD_3,&TBCCTL2 ; output mode = set/reset mov.w #DO/2,&TBCCR2 ; use TBCCR2 as volume
; << adjust timer b tone here >> push r5 ; save r5add.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 volumeadd.w r5,r5 ; (word index) mov.w duty(r5),r5 ; r5 = duty cycle mov.w r5,&TBCCR2 ; start clock (if necessary) pop r5
Pulse Width Modulation (H /W)
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 33/36
BYU CS/ECEn 124 MSP430 Examples 33
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 ; 1200000 clocks / second TIME_A3 .set 1000000/440/2/2 ; A = 440 Hz (2x)TB_CTL .set TBSSEL_2+ID_0+MC_1 ; SMCLK,/1,UP (No interrupts)TB_FREQ .set SMCLK/TIME_A3 ; 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 bis.b #0x20,&P4SEL ; P4.5 timerB outputclr.w &TBR ; reset timerB mov.w #TB_CTL,&TBCTL ; set timerB control reg mov.w #OUTMOD_3,&TBCCTL2 ; TB2 output mode = set/reset
mov.w #TB_FREQ,&TBCCR0 ; set interval (frequency) mov.w #TB_FREQ/2,&TBCCR2 ; load volume (duty cycle) bis.w #LPM0+GIE,SR ; enter LPM0 w/interruptsjmp $ ; will never get here!
.sect ".reset" ; reset vector section
.word reset ; reset vector ISR
.end
Pulse Width Modulation (H /W)
Set P4.5 asoutput from
TB2
UP mode, TB2 set/reset
50% DutyCycle
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 34/36
BYU CS/ECEn 124 MSP430 Examples 34
Example 9: H /W PWM w/Timer_A
#include "msp430x22x4.h"#include <stdio.h> #include "eZ430X.h"#include "lcd.h"#include "adc.h"
void main(void){
eZ430X_init(CALDCO_8MHZ); // init board ADC_init(); // init ADC
lcd_init(); // init LCD
P2DIR |= 0x10; // P2.4 speaker outputP2SEL |= 0x10; // P2.4 TA2 outputTAR = 0; // reset timer A TACTL = TASSEL_2 + ID_2 + MC_1; // SMCLK, /4, UP (no interrupts)TACCTL2 = OUTMOD_3; // TA2 = set/reset
while (1)
{ uint16 freq = (1023 - ADC_read(LEFT_POT)) << 6;uint16 duty = ((long)freq * (1023 - ADC_read(RIGHT_POT)) >> 10;TACCR0 = freq; // frequencyTACCR2 = duty; // duty cyclelcd_cursor(10, 4);lcd_printf("Freq:%u ", freq);lcd_cursor(10, 2);lcd_printf("Duty:%u ", duty);
}} // end main
Pulse Width Modulation (H /W)
Set P2.4 asoutput from
TA2
Freq = Left PotDuty Cycle = Right Pot
SMCLK,1 /4,
UP mode, TA2 set/reset
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 35/36
BYU CS/ECEn 124 MSP430 Examples 35
Example 9: H /W PWM w/Timer_A
#include "msp430x22x4.h"#include <stdio.h> #include "eZ430X.h"#include "lcd.h"#include "adc.h"
void main(void){
eZ430X_init(CALDCO_8MHZ); // init board ADC_init(); // init ADClcd_init(); // init LCD
P2DIR |= 0x10; // P2.4 speaker outputP2SEL |= 0x10; // P2.4 TA2 outputTAR = 0; // reset timer A TACTL = TASSEL_2 + ID_2 + MC_1; // SMCLK, /4, UP (no interrupts)TACCTL2 = OUTMOD_3; // TA2 = set/reset
while (1)
{uint16 freq = (1023 - ADC_read(LEFT_POT)) << 6;uint16 duty = ((long)freq * (1023 - ADC_read(RIGHT_POT)) >> 10;TACCR0 = freq; // frequencyTACCR2 = duty; // duty cyclelcd_cursor(10, 4);lcd_printf("Duty/Freq:%u/%u ", duty, freq);
}} // end main
Pulse Width Modulation (H /W)
Set P2.4 asoutput from
TA2
Freq = Left Pot
Duty Cycle = Right Pot
SMCLK,1 /4,
UP mode, TA2 set/reset
5/12/2018 MSP430 Examples - slidepdf.com
http://slidepdf.com/reader/full/msp430-examples 36/36
BYU CS/ECEn 124 MSP430 Examples 36
Example: Recursive Line Draw#include <math.h> #include "msp430x20x3.h"#include "eZ430X.h"#include "lcd.h"#include "graphics.h"
void lcd_draw_line(int x0, int y0, int x1, int y1){
if ((abs(x1 - x0) <= 1) && (abs(y1 - y0) <= 1)){
lcd_point(x0, y0, 1);
lcd_point(x1, y1, 1);}else{
int16 newX = ((x0 + x1) / 2);int16 newY = ((y0 + y1) / 2);lcd_draw_line(newX, newY, x1, y1, pen);lcd_draw_line(x0, y0, newX, newY, pen);
}} // end lcd_draw_line
void main(void){float a;eZ430X_init(CALDCO_8MHZ); // init board lcd_init(); // init LCDlcd_FRAM_init(); // clear lcd FRAM memoryfor (a = 0.0; a < 2 * 3.14159; a += 0.1){
lcd_draw_line(80, 50, (int)(cos(a) * 40 + 80), (int)(sin(a) * 40 + 50));}
} // end main
Recursion
Base case:2 pixel line
360r insteps of 0.1r
Draw 2 lines:
Start to mid-pointMid-point to end