MSP430開発入門講座(1) ボタンでLEDをon/off(GPIO)

概要

基礎の基礎 『 ボタンを押したら緑点灯/赤消灯, 離したらその逆 』を 作ります。 大まかなポイントは次のとおり。

  1. ピンの設定をする。
  2. 入力ピン(ボタン)を読む
  3. 出力ピンに出力する

ピンの設定をする

PxSEL, P1SEL2: どのペリフェラルに割り当てるのか

多くのマイコンは1本のピンに複数の役割が割り当てられており、 使う前にプログラム中で設定する必要があります (注: MSP430は違いますが、一部のマイコンにはプログラム中からは 設定不可能で、プログラムを書き込み時に行うものもあります)。 MSP430の場合、ピン機能の設定を行うのは PxSEL, PxSEL2レジスタ(x はポート番号で1か2) です。

具体的にどのような値にするかというと (MSP430 は品種毎にピン機能が変わってきますので)、 個別品種のデータシートを見る必要があります。 例えばLaunchPad付属の MSP430G2231 を 使うなら msp430g2231.pdfです。一番最後の方の "APPLICATION INFORMATION" の表に具体的な設定例が書いてあります(Table 13〜)。

では実際の例で考えましょう。LaunchPad を見ると、シルク印刷から LED はP1.0, P1.6 (それぞれ、 ポート1の第0ビット、ポート1の第6ビット)につながっており、 タクトスイッチはP1.3につながっていることがわかります。 では、まず P1.0 を出力ポートに設定しましょう。 msp430g2231.pdf の Table 13 にはこんなふうに書いてあります。 (あ、このデバイスには PxSEL2 はないのね。)

ポートP1, bit0の機能(msp430g2231.pdfより抜粋)
PIN NAME(P1.x) x FUNCTION CONTROL BITS/SIGNALS
P1DIR.xP1SEL.x
P1.0/
TA0CLK/
ACLK
0 P1.0(I/O) I: 0; O: 1; 0
TA0CLK 0 1
ACLK 1 1

FUNCTION列とP1SEL.x列に注目してください。 今はディジタルI/Oポートとして使いたいので、 [FUNCTION]↓[P1.0(I/O)]→と目を動かすと P1SEL0 を 0 にすればいいことがわかります。 同様に もう一つの LED とタクトスイッチについても、 P1SEL.6=0, P1SEL.3=0 ということがわかります。 以上を行うには次のようなコードを書けばいいです。

  P1SEL &= ~(BIT0 + BIT6 + BIT3);

え? BIT0, BIT6, BIT3 って(想像はつくけど)何よ、ですか? これらは mspgcc の中で定義されている定数です。詳しくは /opt/msp430-gcc-4.4.3/msp430/include/を探索 してください。はい、ご想像のとおりの値です。

ところで、これらの設定(P1SEL.x = 0)は、 実はデフォルト(正しくは PUC時設定) なので、電源入れてそのまま使う分には必要ありません。

PxDIR: 入力か、出力か

これは単純。 PxDIR が 0 のビットは入力ピン。1のビットは出力ピンに なります。 デフォルト(正しくは PUC時設定) は0です。

今回は P1.0, P1.6 が LED なので出力、P1.3 がスイッチなので 入力です。だからこんなコードになります。

P1DIR |= BIT0 + BIT6;
P1DIR &= ~BIT3;       // PUC を前提とするなら不要

PxREN, PxOUT: プルアップ/ダウンもできます

ふつう、CMOSの入力ピンは未接続だと電位が安定せず 0だか1だか不定になってしまいます。そこで抵抗器を使って プルアップ/ダウンします。最近のマイコンは このプルアップ/ダウン抵抗を内蔵しているものも多く、MSP430も 例外ではありません(「プルアップだけ」というマイコンも多いの ですが、MSP430はすべてのI/Oについて両方を選択できます。うれしい)。 それを設定するのが PxREN レジスタです。 PxREN を 0にするとプルアップ/ダウン抵抗が無効に、1だと有効になります。

そして、プルアップなのかダウンなのかを決めるのが PxOUT レジスタ です。PxOUT は出力値を決めるレジスタなのですが、pullup/pulldown 選択もするんですね。 PxOUT は 0がプルダウン、1でプルアップです。

LaunchPad の場合、 回路図を見ると タクトスイッチまわりは
LaunchPad schematic (回路図より切り出した図)
のように、単にグラウンドに落ちているだけです。ですからプルアップが 必要です。こんなコードになります。

P1REN |= BIT3;    // enable pullup/pulldown
P1OUT |= BIT3;    // select pull-UP

入力ピンを読む

入力に設定されたピンの値を読むには PxIN を読むだけで ok です。 コードはこんな感じです。

if((P1IN & BIT3) == 0){
  // ボタン押された処理
}

出力ピンに出力する

出力に設定されたピンに値を出力するには PxOUT に書き込むだけで ok です。 コードはこんな感じです。

P1OUT |= BIT6;   // turn on GREEN
P1OUT &= ~BIT0;  // turn off RED

忘れちゃいけない重要な初期設定 〜ウォッチドッグタイマ〜

ウォッチドッグ(番犬)タイマとは、暴走等の監視のための仕組みで 大昔から大抵のマイコンについている機能です。タイマ犬に一定の時間以内に 餌を与え続けないとリセットがかかってしまいます。『プログラムが正常動作 しているときは餌を与え続けられるが、暴走等したら餌がなくなりリセット される(ことで強制的に正常状態に復帰できる)だろう』というロジックです。 当然のことながら リセット時にはデフォルトで動作開始します。 MSP430の Watchdog Timer+ はもう少しいろいろ高機能ですが、いずれにせよ 今回は不要なので最初に disable しておきましょう。 詳細は MSP430x2xx Family User's Guideの第10章を見てください。

WDTCTL = WDTPW + WDTHOLD;     // shut up the dog

コンパイルと実行

ボタンを押したら緑点灯/赤消灯, 離したらその逆 』 を実現するプログラム(tutorial01.c)は次のようになります。 今回は内容から自明なとおりもちろん無限ループですが、今後も基本的に 無限ループで終わります。 return 0;は単なる飾り です。だって return しようにも戻る先の OS がありませんから (逆に下手に return すると無意味なバイト列に突入して暴走します)。

// tutorial01.c  by Yagshi 2011
#include <msp430.h>

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;           // shut up the dog
  P1SEL &= ~(BIT0 + BIT6 + BIT3);
  P1DIR |= BIT0 + BIT6;
  P1DIR &= ~BIT3;
  P1REN |= BIT3;                      // enable pullup/pulldown
  P1OUT |= BIT3;                      // select pull-UP

  for (;;) {
    if ((P1IN & BIT3) == 0) {
      P1OUT &= ~BIT0;
      P1OUT |= BIT6;
    } else {
      P1OUT &= ~BIT6;
      P1OUT |= BIT0;
    }
  }
  return 0;
}

コンパイルするために Makefile を作りましょう。Makefile はこんなんで 充分です。最後の -mmcu のところでターゲットデバイスを指定します。 使いたい石そのものがなかったら /usr/msp430/include/ の中を見回して、適当に近いものを 書いておけば大抵問題ありません。

CC=msp430-gcc
CFLAGS=-Os -Wall -mmcu=msp430g2231

さあ、コンパイル〜実行しましょう。LaunchPadをUSBにつなげたら、 何とたったの2コマンド!

$ make tutorial01
msp430-gcc -Os -Wall -mmcu=msp430x2012   tutorial01.c   -o tutorial01
$ mspdebug rf2500 'prog tutorial01'
(まず赤のLEDが光ると思います。そしたらスイッチ押してみましょう。)

by Yagshi 2013
『マイコンを使った開発について』に戻る

Valid XHTML 1.0!