You are on page 1of 15

-

' 2

.038020764 .
.301563185 .
- ' 2
: ,

50193-32
'17:00 - 20:00 ,
' " 2012 -

Page 2 of 15
- ' 2
: ,

' 4 3..............................................................................................................................................Assembly

LCD 5..........................................................................................................................................................................C

B 11..................................................................................................................................................................C

Page 3 of 15
2 ' -
, :

Assembly 4 '

. " 4 ' :
, , .(4 ' 5.1 , ) ,WDT- :
, , .( ) SR- " , 2 .
. , . ,

include <msp430xG46x.h< ; Device library containing definitions, addresses,


;-------------------------------------------------------------------------------
RSEG CSTACK ; Define stack segment
; ------------------------------------------------------------------------------
RSEG CODE ; Assemble to flash memory
; ----------------------------------------------------------------------------
RESET mov.w #SFE(CSTACK),SP ; Initialize stack pointer
StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT
SetupFLL bis.b #XCAP14PF,&FLL_CTL0 ; Configure load caps

OFIFGcheck bic.b #OFIFG,&IFG1 ; Clear OFIFG


mov.w #047FFh,R15 ; Wait for OFIFG to set again if
OFIFGwait dec.w R15 ; not stable yet
jnz OFIFGwait
bit.b #OFIFG,&IFG1 ; Has it set again?
jnz OFIFGcheck ; If so, wait some more

SetupBT mov.b #027h,&BTCTL ; 2 sec Interrupt: Source=ACLK/256128Hz, 128/256=0.5Hz 2 sec


mov.b #080h,&IE2 ; Enable Basic Timer interrupt

SetupP6 bis.b #0ffh,&P6DIR ; Port 6 pins are output


bic.b #0ffh,&P6OUT ; Clearing port 6 outputs
SetupP5 bis.b #0ffh,&P5DIR ; Port 5 pins are output
bic.b #0ffh,&P5OUT ; Clearing port 5 outputs

Page 4 of 15
2 ' -
, :

SetupP4 bis.b #0ffh,&P4DIR ; Port 4 pins are output


bic.b #0ffh,&P4OUT ; Clearing port 4 outputs
SetupP3 bis.b #0ffh,&P3DIR ; Port 3 pins are output
bic.b #0ffh,&P3OUT ; Clearing port 3 outputs
SetupP2 bis.b #0ffh,&P2DIR ; Port 2 pins are output
bic.b #0ffh,&P2OUT ; Clearing port 2 outputs
SetupP1 bis.b #0ffh,&P1DIR ; Port 1 pins are output
bic.b #0ffh,&P1OUT ; Clearing port 1 outputs

Mainloop bis.w #LPM3+GIE,SR ; Enter LPM3, enable interrupts


bis.b #002h,&P5OUT ; Set P5.1 - LED4 is on
push.w #02000 ; Delay using the stack by moving 2000 to stack TOS (Top Of Stack)
Pulse dec.w 0(SP) ; Decrement Value at TOS ; 0(SP) means Contents of TOS
jnz Pulse ; Delay done?
incd.w SP ; Clean-up stack - inverse to PUSH instruction. Corrects the Stack Pointer
bic.b #002h,&P5OUT ; Reset P5.1 - LED4 is off
jmp Mainloop ; Infinite loop back to sleep until interrupt occur.
;------------------------------------------------------------------------------
BT_ISR ; Basic Timer interrupt Service Routine (ISR)
bic.w #LPM3,0(SP) ; Exit LPM3 Status Register (SR) is stored at Top Of Stack (TOS)
reti ; Return from interrupt
;-----------------------------------------------------------------------------
COMMON INTVEC ; Interrupt Vectors
ORG RESET_VECTOR ; RESET Vector
DW RESET
ORG BASICTIMER_VECTOR ; Basic Timer Vector
DW BT_ISR
END

Page 5 of 15
2 ' -
, :

C LCD

. LCD :
, . LCD- LCD 5 ,WDT- :
,( ) , . 2- 1
, .LCD- 1- , .
. ,

#include <msp430xG46x.h> // Device library containing definitions, addresses,


#include "LCD_defs.h" // Definitions used for LCD operating.

unsigned char hour, min, sec; // Global parameters Hours, Minutes & Seconds.

//******************************************************************
// Write hours in LCD
//******************************************************************
void LCD_hour() // This function handles Hours parameter and updates the LCD accordingly.
{
unsigned char hour1,hour2; // Local parameters used to separate the number to two digits
hour1 = hour / 10; // Left digit of hour - most significant digit
hour2 = hour % 10; // Right digit of hour - least significant digit

switch (hour1) // Updating LCD left digit of hour according to "hour1" value.
{
case 1: P7_A1; break; case 2: P7_A2; break;
case 3: P7_A3; break; case 4: P7_A4; break;
case 5: P7_A5; break; case 6: P7_A6; break;
case 7: P7_A7; break; case 8: P7_A8; break;
case 9: P7_A9; break; case 0: P7_A0; break;
}

Page 6 of 15
2 ' -
, :

switch (hour2) // Updating LCD right digit of hour according to "hour2" value.
{
case 1: P6_A1; break; case 2: P6_A2; break;
case 3: P6_A3; break; case 4: P6_A4; break;
case 5: P6_A5; break; case 6: P6_A6; break;
case 7: P6_A7; break; case 8: P6_A8; break;
case 9: P6_A9; break; case 0: P6_A0; break;
}
}
//******************************************************************
// Write minutes in LCD
//******************************************************************
void LCD_min() // This function handles Minutes parameter and updates the LCD accordingly.
{
unsigned char min1,min2; // Local parameters used to separate the number to two digits
min1 = min / 10; // Left digit of minutes - most significant digit
min2 = min % 10; // Right digit of minutes - least significant digit

switch (min1) // Updating LCD left digit of min according to "min1" value.
{
case 1: P5_A1; break; case 2: P5_A2; break;
case 3: P5_A3; break; case 4: P5_A4; break;
case 5: P5_A5; break; case 6: P5_A6; break;
case 7: P5_A7; break; case 8: P5_A8; break;
case 9: P5_A9; break; case 0: P5_A0; break;
}
switch (min2) // Updating LCD right digit of min according to "min2" value.
{
case 1: P4_A1; break; case 2: P4_A2; break;
case 3: P4_A3; break; case 4: P4_A4; break;
case 5: P4_A5; break; case 6: P4_A6; break;

Page 7 of 15
2 ' -
, :

case 7: P4_A7; break; case 8: P4_A8; break;


case 9: P4_A9; break; case 0: P4_A0; break;
}
}
//******************************************************************
// Write seconds in LCD
//******************************************************************
void LCD_sec() // This function handles Seconds parameter and updates the LCD accordingly.
{
unsigned char sec1,sec2; // Local parameters used to separate the number to two digits
sec1 = sec / 10; // Left digit of seconds - most significant digit
sec2 = sec % 10; // Right digit of seconds - least significant digit

switch (sec1) // Updating LCD left digit of sec according to "sec1" value.
{
case 1:P3_A1; break; case 2:P3_A2; break;
case 3:P3_A3; break; case 4:P3_A4; break;
case 5:P3_A5; break; case 6:P3_A6; break;
case 7:P3_A7; break; case 8:P3_A8; break;
case 9:P3_A9; break; case 0:P3_A0; break;
}
switch (sec2) // Updating LCD right digit of sec according to "sec2" value
{
case 1: P2_A1; break; case 2: P2_A2; break;
case 3: P2_A3; break; case 4: P2_A4; break;
case 5: P2_A5; break; case 6: P2_A6; break;
case 7: P2_A7; break; case 8: P2_A8; break;
case 9: P2_A9; break; case 0: P2_A0; break;
}
}
//******************************************************************

Page 8 of 15
2 ' -
, :

//LCD clean. All segments are turned off


//******************************************************************
void LCD_all_off (void)
{
LCDM2 = 0x00; LCDM3 = 0x00; LCDM4 = 0x00; LCDM5 = 0x00;
LCDM6 = 0x00; LCDM7 = 0x00; LCDM8 = 0x00; LCDM9 = 0x00;
LCDM10 = 0x00; LCDM11 = 0x00; LCDM12 = 0x00; LCDM13 = 0x00;
}
//*****************************************************************
// BAsic Timer Interrupt Service Routine. Run with 1 sec period
//*****************************************************************
#pragma vector=BASICTIMER_VECTOR
__interrupt void basic_timer_ISR(void)
{
P2OUT |= 0x04; // LED1 turn on
P2OUT ^= 0x02; // LED2 toggle

sec++; // increment seconds


LCD_sec(); // refresh seconds field in LCD

if (sec == 60) // one minute was pass


{
sec = 0; // reset seconds counter
min++; // increment minutes
LCD_min(); // refresh minutes field in LCD
if (min == 60) // one hour was pass
{
min = 0; // reset minutes counter
hour++; // increment hours
LCD_min(); // refresh hours field in LCD
if (hour == 24) // one day was pass

Page 9 of 15
2 ' -
, :

{
hour = 0; // reset hours counter
}
}
}

if (sec & 0x01) // toggle clock dots


{
P3_DOT_ON; P5_DOT_ON;
}
else
{
P3_DOT_OFF; P5_DOT_OFF;
}

P2OUT &= ~0x04; // LED1 turn off


}
//*****************************************************************
// Main routine
//*****************************************************************
void main(void)
{
WDTCTL = WDTPW | WDTHOLD;// Stop WDT
FLL_CTL0 |= XCAP18PF; // Set load cap for 32k xtal

// LCD COM0-COM1-COM2-COM3 configuration


P5DIR |= 0x1c; // Ports P5.2, P5.3 and P5.4 as outputs
P5SEL |= 0x1c; // Ports P5.2, P5.3 and P5.4 as special function (COM1, COM2 and COM3)

// LCD_A Port Control Register 0


// LCD segment 24 to 27 enable // LCD segment 20 to 23 enable // LCD segment 16 to 19 enable

Page 10 of 15
2 ' -
, :

// LCD segment 12 to 15 enable // LCD segment 8 to 11 enable // LCD segment 4 to 7 enable


LCDAPCTL0 = LCDS24 | LCDS20 | LCDS16 | LCDS12 | LCDS8 | LCDS4;

// LCD_A configuration
LCDACTL = LCDFREQ_192 | LCD4MUX | LCDSON | LCDON; // (ACLK = 32768)/192, 4-mux LCD, LCD_A on, Segments on
LCDAVCTL0 = LCDCPEN; // Charge pump enable
// Charge pump voltage select
LCDAVCTL1 = VLCD_3_44; // VLCD = 3,44 V

LCD_all_off(); // Clean LCD

// Set memory clock variables


sec = 0; min = 0; hour = 0;

// Write time in LCD


LCD_sec(); // Updating seconds on LCD
LCD_min(); // Updating minutes on LCD
LCD_hour(); // Updating hours on LCD

// LED1 & LED2 configuration


P2DIR |=0x06; // P2.2 and P2.1 as digital output
P2OUT |=0x04; P2OUT &= ~0x02; // LED1 on and LED2 off

// Basic Timer 1 Configuration


// Basic Timer1 clock divide & Basic Timer1 interrupt interval, fCLK2/128

BTCTL = BT_fCLK2_DIV128 + BTDIV; // 1 sec Interrupt: Source=ACLK/256128Hz, 128/128=1Hz 1 sec


IE2 |= BTIE; // Enable Basic Timer 1 interrupt

_BIS_SR (LPM3_bits + GIE); // Enter LPM3 with all interrupts enabled


}

Page 11 of 15
- ' 2
: ,

B C

: B 1) 2-(.
: , WDT- B : ,SMCLK ) 1 ( ,
. , , 1 2- 1 .
, 1 2- .B , .
, " . 3.5
) B (4 .

>#include <msp430xG46x.h // Device library containing definitions, addresses,

#define notas 10 // Defining notes


#define SI0 15895 #define DO 15258 #define RE 13620 #define MI 12077
#define FA 11405 #define SOL 10159 #define LA 9106 #define SI 7963
#define DO2 7629 #define MUTE 0

******************************************************************//
// Global data
******************************************************************//
;}unsigned int scale[notas] = {SI0, DO, RE, MI, FA, SOL, LA, SI, DO2, MUTE
;}unsigned int space[notas] = {RE, MI, DO2, DO, SOL, MUTE, MUTE, MUTE, MUTE, MUTE
;unsigned int index_notas = 0
;char volume = 2
******************************************************************//
// Port1 Interrupt Service Routine
******************************************************************//
#pragma vector=PORT1_VECTOR
)__interrupt void PORT1_ISR (void
{
;if (P1IFG & 0x01) volume = volume - 1 // If SW1 was pushed volume down
;if (P1IFG & 0x02) volume = volume + 1 // If SW2 was pushed volume up

Page 12 of 15
2 ' -
, :

if (volume == 6) volume = 5; // Maximum value of volume is 5


if (volume == 0) volume = 1; // Minimum value of volume is 1

TBCCR4 = space[index_notas]/volume; // Updating Timer B duty cycle

P1IFG = 0x00; // Clearing port 1 interrupt flags.


}
//*****************************************************************
// Basic Timer Interrupt Service Routine. Run with 1 sec period
//*****************************************************************
#pragma vector=BASICTIMER_VECTOR
__interrupt void basic_timer_ISR(void)
{
P2OUT ^= 0x06; // Toogle LED1 and LED2
TBCCR0 = space[index_notas]; // get next note
TBCCR4 = space[index_notas]/volume; // set duty-cycle

index_notas++; // manage note point


if (index_notas == notas) // Maximum value of index_notas is limited to notas (defined as 10)
index_notas = 0;
}
//******************************************************************
// Main routine
//******************************************************************
void main (void)
{
WDTCTL = WDTPW | WDTHOLD;//Stop WatchDog

FLL_CTL0 |= DCOPLUS + XCAP18PF; //FLL+ configuration, ACLK = 32.768 kHz (DCO+ set)
// fDCOCLK = 3.2-25Mhz

Page 13 of 15
2 ' -
, :

SCFI0 |= FN_4; // x2 DCO freq, 8MHz nominal DCO


// freq = xtal x D x N+1
SCFQCTL = 121; // (121+1) x 32768 x 2 = 7.99 MHz

// TimerB configuration
TBCCR0 = space[0]; // load first tone from sequence
TBR = 0; // Clearing TBR (Timer B Register)
// SMCLK
// 16-bit, TBR(max) = 0FFFFh
// Each TBCLx latch loads independently
// Up mode: the timer counts up to TBCL0
// Input divider. These bits select the divider for the input clock.(/1)
TBCTL = TBSSEL_2+MC_1+ID_0; // Timer B clock source select SMCLK, Input divider = /1, Mode control = Up Mode
TBCCTL4 = OUTMOD_3; // Output mode - Set/reset
TBCCR4 = space[0]/2;

// Basic Timer 1 Configuration


// Basic Timer1 clock divide
// Basic Timer1 interrupt interval, fCLK2/128
BTCTL = BT_fCLK2_DIV128 + BTDIV; // 1 sec Interrupt: Source=ACLK/256128Hz, 128/128=1Hz 1 sec
IE2 |= BTIE; // Enable Basic Timer 1 interrupt

// SW1 and SW2 configuration (Port1)


P1SEL &= ~0x03; // P1.0 (SW1) and P1.1 (SW2) as digital I/O
P1DIR &= ~0x03; // P1.0 and P1.1 inputs
P1IFG &= ~0x03; // clear P1 flags
P1IES |= 0x03; // high-to-low transition interrupts
P1IE |= 0x03; // Enable port1 interrupts

Page 14 of 15
2 ' -
, :

// LED1 and LED2 configuration (Port2)


P2DIR |= 0x06; // P2.2 (LED1) and P2.1 (LED2) as digital output
P2OUT |=0x04; P2OUT &= ~0x02; // LED1 on and LED2 off

// Buzzer port configuration (Port3)


P3SEL |= 0x20; // P3.5 as special function TB4
P3DIR |= 0x20; // P3.5 as output

_BIS_SR (LPM0_bits + GIE); //Low Power Mode with interrupts enabled


}

Page 15 of 15

You might also like