//*************************************************************************************** // gp1 General Test Board for MSP-EXP430G2ET Launchpad // gp1-sw1.c // MSP430G2553 to make it usable by all of the programs // Test the switches // Pressing a pusbutton switch turns on the corresponding LED - no debouncing // We don't need to use interrupts // Remove the pin jumper at P1.0 on Launchpad // Uses Uses 16 MHz DCO // Requires that optimization be turned off in 'Project'. // Otherwise the compiler might remove software timers // Jed Margolin 11/18/2018. // Built with Code Composer Studio v8 //*************************************************************************************** // main.c #include #define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz #define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz #define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz #define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz void wait(unsigned int); void wait1(void); void wait2(void); void wait4(unsigned int); void Set_DCO(unsigned int Delta); void wait10ms(void); // Globals volatile unsigned int timer_flag = 0; //================================================ int main(void) { unsigned char caldata1, caldata2; // Temp. storage for MSP430 constants unsigned char count=0, save, temp; unsigned int n = 250; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer wait(150); // give the crystal 500ms to stabilize P1SEL &= ~BIT0; // In PBSW1 P1SEL2 &= ~BIT0; P1REN |= BIT0; // pullup/pulldown enabled P1OUT |= BIT0; // pullup P1DIR &= ~BIT0; // In P1SEL &= ~BIT1; // In PBSW2 P1SEL2 &= ~BIT1; P1REN |= BIT1; // pullup/pulldown enabled P1OUT |= BIT1; // pullup P1DIR &= ~BIT1; // In P1SEL &= ~BIT2; // In PBSW3 P1SEL2 &= ~BIT2; P1REN |= BIT2; // pullup/pulldown enabled P1OUT |= BIT2; // pullup P1DIR &= ~BIT2; // In P1SEL &= ~BIT3; // In PBSW4 P1SEL2 &= ~BIT3; P1REN |= BIT3; // pullup/pulldown enabled P1OUT |= BIT3; // pullup P1DIR &= ~BIT3; // In P1SEL &= ~(BIT4); // Out - LED1 P1SEL2 &= ~(BIT4); P1DIR |= BIT4; // out P1OUT &= ~(BIT4); // init to 0 P1SEL &= ~(BIT5); // Out - LED2 P1SEL2 &= ~(BIT5); P1DIR |= BIT5; // out P1OUT &= (~BIT5); // init to 0 P1SEL &= ~(BIT6); // Out - LED3 P1SEL2 &= ~(BIT6); P1DIR |= BIT6; // out P1OUT &= (~BIT6); // init to 0 P1SEL &= ~(BIT7); // Out - LED4 P1SEL2 &= ~(BIT7); P1DIR |= BIT7; // Out P1OUT &= ~BIT7; // init to 0 // Port 2 for later use of 16x2 LCD P2SEL &= ~(0x3F); // Out P2SEL2 &= ~(0x3F); P2DIR |= 0x3F; // Out P2OUT &= 0x3F; // LCD D4-7 = 0; LCD E = 0; LCD RS = 0 // Lock the DCO to the 32768 crystal - 16 MHz Set_DCO(DELTA_16MHZ); // Set DCO and obtain constants caldata1 = DCOCTL; // for debugging caldata2 = BCSCTL1; BCSCTL2 = 0x00; // DIVM0 | DIVS0 | // MCLK and SMCLK dividers // Set up timer Interrupts - 4ms CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 16000; // 4ms interrupts TACTL = TASSEL_2 | ID1 | MC_2; // SMCLK, contmode TACTL |= TACLR; // clear timer Resets TAR, clock divider, count direction __bis_SR_register(GIE); // Timer interrupts without LPM0 //=========================================== while (1) // main loop { while(!timer_flag) { } // wait for timer_flag to go high 4 ms interrupt timer_flag = 0; if(P1IN & BIT0) { P1OUT &= ~BIT4;} // switch press is '0' else { P1OUT |= BIT4;} if(P1IN & BIT1) { P1OUT &= ~BIT5;} // switch press is '0' else { P1OUT |= BIT5;} if(P1IN & BIT2) { P1OUT &= ~BIT6;} // switch press is '0' else { P1OUT |= BIT6;} if(P1IN & BIT3) { P1OUT &= ~BIT7;} // switch press is '0' else { P1OUT |= BIT7;} } // end while main loop } // end main //================================== void wait(unsigned int time) // 500 uS { volatile unsigned int i,j; for(i=time; i>0; i--) { for(j=382; j>0; j--); { } } return; } //========================================================== void wait4(unsigned int time) // 500 uS { volatile unsigned int i,j; for(i=time; i>0; i--) { for(j=20; j>0; j--); { } } return; } //========================================================== void wait2() { volatile unsigned int i; for(i=0; i<48; i++){} return; } //========================================================== void wait1() { volatile unsigned int i; i = 0; // for(i=0; i<1; i++){} return; } //======================================================== void Set_DCO(unsigned int Delta) // Set DCO to selected frequency { unsigned int Compare, Oldcapture = 0; // XT2OFF; LF Mode; DIVA_3: ACLK = LFXT1CLK/1 BCSCTL1 |= DIVA_3; // MCLK is DCOCLK; Divider /1; SIMCLK is DCOCLK; SMCLK Divider /1; DCOR // BCSCTL2 = 0; Reset = 0 anyway // Oscillator capacitor 12.5pF // BCSCTL3 |= XCAP_3; // MSP-EXP430G2ET has them on the board // Timer/Capture TACCTL0 = CM_1 + CCIS_1 + CAP; // Timer A Control TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear while (1) { while (!(CCIFG & TACCTL0)); // Wait until capture occured TACCTL0 &= ~CCIFG; // Capture occured, clear flag Compare = TACCR0; // Get current captured SMCLK Compare = Compare - Oldcapture; // SMCLK difference Oldcapture = TACCR0; // Save current captured SMCLK if (Delta == Compare) break; // If equal, leave "while(1)" else if (Delta < Compare) { DCOCTL--; // DCO is too fast, slow it down if (DCOCTL == 0xFF) // Did DCO roll under? if (BCSCTL1 & 0x0f) BCSCTL1--; // Select lower RSEL } else { DCOCTL++; // DCO is too slow, speed it up if (DCOCTL == 0x00) // Did DCO roll over? if ((BCSCTL1 & 0x0f) != 0x0f) BCSCTL1++; // Sel higher RSEL } } TACCTL0 = 0; // Stop TACCR0 TACTL = 0; // Stop Timer_A BCSCTL1 &= ~DIVA_3; // 0 = ACLK is divide by 1 } //========================================================== // wait 10 ms void wait10ms(void) { wait(41); } //========================================================== // Timer A0 interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer_A (void) #else #error Compiler not supported! #endif { CCR0 += 16000; // Add Offset to CCR0 timer_flag = 1; } //==========================================================