Port1割り込み
タクトスイッチと7セグLEDをつないで、タクトスイッチを押す毎に数字をカウントアップしてみた。
コードはこんな感じです。
/* p1.0 -> LED -> 抵抗 -> VCC p1.1 同上 p1.2 同上 p1.3 同上 p1.4 同上 p1.5 同上 p1.6 同上 p1.7 -> タクトSW -> VCC */ #include "msp430.h" typedef unsigned char UCHAR; void led7segNum(UCHAR aNum); UCHAR count = 0; void main ( void ) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR = 0x7f; P1IES = 0; P1OUT = 0x00; P1REN = 0x80; P1IFG = 0x00; P1IE = 0x80; led7segNum(0); _EINT(); while( 1 ) { LPM3; // enter LPM3, clock will be updated led7segNum(count % 10); _NOP(); } } // Port1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port1 (void) { P1IFG = 0x00; count ++; LPM3_EXIT; } #define DLED_A 0x40 // p1.6 #define DLED_B 0x20 // p1.5 #define DLED_C 0x10 // p1.4 #define DLED_D 0x08 // p1.3 #define DLED_E 0x04 // p1.2 #define DLED_F 0x01 // p1.0 #define DLED_G 0x02 // p1.1 #define DLED_DP // アノードコモン 7セグLED // -A- // | | // F B // | | // -G- // | | // E C // | | // -D- void led7segNum(UCHAR aNum) { UCHAR out = 0; switch (aNum) { case 0: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_E | DLED_F; break; case 1: out = DLED_B | DLED_C; break; case 2: out = DLED_A | DLED_B | DLED_D | DLED_E | DLED_G; break; case 3: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_G; break; case 4: out = DLED_B | DLED_C | DLED_F | DLED_G; break; case 5: out = DLED_A | DLED_C | DLED_D | DLED_F | DLED_G; break; case 6: out = DLED_A | DLED_C | DLED_D | DLED_E | DLED_F | DLED_G; break; case 7: out = DLED_A | DLED_B | DLED_C; break; case 8: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_E | DLED_F | DLED_G; break; case 9: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_F | DLED_G; break; } P1OUT = (P1OUT | 0x7f) & ~out; }
タイマーと組み合わせて、タクトSWを押す毎にカウントアップを停止、開始する様にしてみた。
/* p1.0 -> LED -> 抵抗 -> VCC p1.1 同上 p1.2 同上 p1.3 同上 p1.4 同上 p1.5 同上 p1.6 同上 p1.7 -> タクトSW -> VCC */ #include "msp430.h" typedef unsigned char UCHAR; void led7segNum(UCHAR aNum); enum { EINT_MODE_TIMA = 1, EINT_MODE_SW1 = 1, }; UCHAR count = 0; UCHAR intMode = 0; UCHAR countupStop = 0; void main ( void ) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer // タイマーA初期化 CCR0 = 32767 / 2 / 100; TACTL = TASSEL_1+MC_1; // ACLK, upmode CCTL0 |= CCIE; // enable CCRO interrupt // Port 1 初期化 P1DIR = 0x7f; P1IES = 0; P1OUT = 0x00; P1REN = 0x80; P1IFG = 0x00; P1IE = 0x80; led7segNum(0); _EINT(); while( 1 ) { LPM3; // enter LPM3, clock will be updated led7segNum(count); _NOP(); } } // Timer A0 interrupt service routine #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) { intMode = EINT_MODE_TIMA; if (countupStop == 0) { count = (count + 1) % 10; LPM3_EXIT; } } // Port1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port1 (void) { P1IFG = 0x00; intMode = EINT_MODE_SW1; countupStop = 1 - countupStop; LPM3_EXIT; } #define DLED_A 0x40 // p1.6 #define DLED_B 0x20 // p1.5 #define DLED_C 0x10 // p1.4 #define DLED_D 0x08 // p1.3 #define DLED_E 0x04 // p1.2 #define DLED_F 0x01 // p1.0 #define DLED_G 0x02 // p1.1 #define DLED_DP // アノードコモン 7セグLED // -A- // | | // F B // | | // -G- // | | // E C // | | // -D- void led7segNum(UCHAR aNum) { UCHAR out = 0; switch (aNum) { case 0: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_E | DLED_F; break; case 1: out = DLED_B | DLED_C; break; case 2: out = DLED_A | DLED_B | DLED_D | DLED_E | DLED_G; break; case 3: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_G; break; case 4: out = DLED_B | DLED_C | DLED_F | DLED_G; break; case 5: out = DLED_A | DLED_C | DLED_D | DLED_F | DLED_G; break; case 6: out = DLED_A | DLED_C | DLED_D | DLED_E | DLED_F | DLED_G; break; case 7: out = DLED_A | DLED_B | DLED_C; break; case 8: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_E | DLED_F | DLED_G; break; case 9: out = DLED_A | DLED_B | DLED_C | DLED_D | DLED_F | DLED_G; break; } P1OUT = (P1OUT | 0x7f) & ~out; }