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;
}

タイマー

タイマーを使ってみましょう。まずは、レジスター一覧はこちら。

TIのホームページのサンプルコードが動きませんね。んー。ググっても参考になる記事が見つからない。
長引きそう。。。

こっちのサンプルだと動きますね。でも、2秒周期に点滅を繰り返す。1秒周期じゃないのかな?

#include "msp430.h"
#include  "RTC.h"
#include  "RTC_TA.h"
void main ( void )
{
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  setTime( 0x12, 0, 0, 0);              // initialize time to 12:00:00 AM
  P1DIR |= 0x01;                        // Set P1.0 to output direction
  CCR0 = 32768-1;
  TACTL = TASSEL_1+MC_1;                // ACLK, upmode
  CCTL0 |= CCIE;                        // enable CCRO interrupt
  _EINT();

  while( 1 )
  {
    LPM3;                               // enter LPM3, clock will be updated
    P1OUT ^= 0x01;                      // do any other needed items in loop
    _NOP();                             // set breakpoint here to see 1 second interrupt
  }
}


// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  incrementSeconds();
  LPM3_EXIT;
}

ケーブル自作

MSP430-F2013、前に知り合いからDIPタイプのをもらってた。もらった時は、ICだけ有っても使えないよなー、とか思ったんだけど、道具箱の肥やしにもらってた。これを活用出来れば、高いターゲットボードを買わなくてもすむので、ググってみた。
同じ事を考える人はいますね。
実は先日購入した部品にケーブルの材料が入ってたのでした。(;^_^A
DF13ハウジング04P
DF13コンタクトピン
QIコネクタ04P

で完成したケーブルがこれ。

部品が小さく、四苦八苦しましたが、とりあえず使えそう。
こんな感じでつなぐとDIPタイプのF2013でサンプルプログラムが動きました。\(^_^ )( ^_^)/


#include "msp430.h"

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  P1DIR |= 0x01;                        // Set P1.0 to output direction

  for (;;)
  {
    volatile unsigned int i;            // volatile to prevent optimization

    P1OUT ^= 0x01;                      // Toggle P1.0 using exclusive-OR

    i = 10000;                          // SW Delay
    do i--;
    while (i != 0);
  }
}

eZ430-F2013

あ、これも有った。これが一番高かったのよね。。。

これは、TIのeZ430-F2013で、MSP430-F2013マイコンの開発キット。USBメモリーサイズの機器で、なんとこれだけでプログラムのダウンロードからデバッグまでが出来てしまうと言う優れもの。2006年に発売されたものなので、新しくは無いんだけど、遅ればせながら手を付けようかと。
前から扱いやすい自分として標準的なマイコンを探していて、使い慣れたM16Cや流行のArduinoやPICなんかも気になりつつ、14Pinで小型なのと、低消費電力で開発キットが\3,381と安いので、このマイコンから始めようかと。