MSP430G2553 - 温湿度センサ

提供: MochiuWiki : SUSE, EC, PCB

概要

MSP430G2553の特徴である低消費電力、高速起動、豊富なペリフェラルを活用することで、バッテリー駆動の温湿度センサシステムを構築できる。

DHT11 / DHT21はサーミスタと異なり、温度と湿度のキャリブレーション済みの状態で出荷されているセンサ (デジタル信号) である。

DHT11では温度は2[℃]程度の誤差、湿度は5[%]程度の誤差で測定できる。
DHT21 (AM2301) は高精度であり、温度は0.5[℃]程度、湿度は3[%]程度の誤差で測定可能である。

ピンの割り当ては、下図の通りである。
4本のピンは左から順に、VDD、DATA、NC (非接続)、GNDである。


VDDへの供給電圧は、DHT11が3.0[V]〜5.5[V]の範囲、DHT21が3.3[V]〜5.5[V]の範囲である。
VDDとGNDの間にパワーフィルタリングとして0.1[uF]のセラミックコンデンサを配置することが推奨される。

データはシングル・バス・データフォーマットで伝送される。
データのサンプリング間隔は最短で1[s]なので、ソフトウェア側でデータを取得する時に待機する必要がある。

2番ピンであるDATAピンはプルアップして使用する。
プルアップ抵抗は、ワイヤが20[m]以下の場合は、4.7[kΩ]〜10[kΩ]程度が推奨される。

MSP430G2553の内部プルアップ抵抗は約35[kΩ]であるため、外部にプルアップ抵抗を追加することが推奨される。
ただし、短い配線であれば内部プルアップのみでも動作する可能性がある。

DHT11 / DHT21は1線式通信プロトコルを使用するため、タイミングの正確な制御が必要である。
また、高度な機能として、以下に示すような拡張が可能である。

  • Timer_Aを使用した高精度タイミング制御
  • UART / I2C / SPI経由でのデータ送信
  • 低電力モード (LPM3) を活用した省電力動作
  • 複数のDHTセンサからのデータ収集
  • LCDディスプレイへのデータ表示
  • ADC10を併用した他のセンサとの統合



MSP430G2553の基本仕様

主要スペック

  • CPU
    16ビット RISCアーキテクチャ、最大16[MHz]動作
  • フラッシュROM
    16[KB]
  • RAM
    512[B]
  • GPIO
    24ピン (Port P1, P2, P3)
  • タイマ
    16ビット Timer_A (2個、Timer0_A3、Timer1_A3)
  • 通信インターフェース
    USCI_A0 (UART/SPI)、USCI_B0 (I2C/SPI)
  • ADC
    10ビット SAR型 ADC、8チャンネル
  • 動作電圧
    1.8[V]〜3.6[V]
  • 低消費電流
    アクティブモード 約230[uA/MHz]、スタンバイモード(LPM3) 約0.7[uA]
  • パッケージ
    PDIP20、TSSOP28、VQFN32


クロックシステム

MSP430G2553は、Basic Clock Module+を搭載しており、以下に示すクロックソースを提供する。

  • MCLK (Main Clock)
    CPUクロック、最大16[MHz]
    デフォルト設定 : DCO 約1[MHz]
  • SMCLK (Sub-Main Clock)
    ペリフェラルクロック
    デフォルト設定 : DCO 約1[MHz]
  • ACLK (Auxiliary Clock)
    低速クロック、32768[Hz]の水晶発振器
    デフォルト設定 : VLO 約12[kHz] (水晶未実装時)


DCO (Digitally Controlled Oscillator) は内蔵の高速クロック源であり、起動時間が1[us]未満と非常に高速である。

低電力モード

MSP430G2553は、6種類の動作モードを持つ。

  • Active Mode (AM)
    全てのクロックが動作
  • LPM0
    CPUが停止、ACLK、SMCLKが動作
  • LPM1
    CPUが停止、ACLK、SMCLKが動作、DCOのDC生成器が停止
  • LPM2
    CPUが停止、MCLKとSMCLKが停止、ACLKが動作
  • LPM3
    CPUが停止、MCLKとSMCLKが停止、ACLKが動作、DCOが完全停止
  • LPM4
    全てのクロックが停止、最低消費電力モード


GPIO設定レジスタ

MSP430G2553のGPIOは、以下に示すレジスタで制御される。
以下は、Port P1の例である。(Port 2 / 3も同様である)

  • P1IN (0x0020)
    入力レジスタ (読み取り専用)
  • P1OUT (0x0021)
    出力レジスタ
  • P1DIR (0x0022)
    方向制御レジスタ (0 : 入力、1 : 出力)
  • P1IFG (0x0023)
    割り込みフラグレジスタ
  • P1IES (0x0024)
    割り込みエッジ選択 (0 : 立ち上がり、1 : 立ち下がり)
  • P1IE (0x0025)
    割り込み許可レジスタ
  • P1SEL (0x0026)
    機能選択レジスタ
  • P1REN (0x0027)
    プルアップ / プルダウン抵抗有効化レジスタ
  • P1SEL2 (0x0041)
    第2機能選択レジスタ



MSP430G2553 と DHT11/DHT21の接続

ハードウェア接続

MSP430G2553 と DHT11 / DHT21の接続
DHT11 / DHT21 MSP430G2553 備考
VDD VCC (Pin 1) 3.3[V]または5[V]供給
DATA P1.6 (Pin 14) プルアップ抵抗必要
NC 未接続 -
GND VSS (Pin 20) グランド


外部プルアップ抵抗 (4.7[kΩ]〜10[kΩ]) をDATAピンとVDDの間に接続することが推奨される。
また、VDDとGNDの間には0.1[uF]のセラミックコンデンサを配置してノイズ対策を行う。

推奨回路図

MSP430G2553           DHT11/DHT21
Pin 1 (VCC) ---+-------- VDD
               |
              [0.1uF]
               |
Pin 20 (VSS) --+-------- GND

Pin 14 (P1.6) --[4.7k]-- VDD
        |
        +--------------- DATA
        
※注意
[4.7k]はプルアップ抵抗
[0.1uF]はパスコン



DHT11 / DHT21の通信プロトコル

データフォーマット

DHT11 / DHT21は1線式通信を使用し、5[byte] (40[bit]) のデータを送信する。

  • 1[byte]
    湿度の整数部 (DHT11) または 湿度上位バイト (DHT21)
  • 2[byte]
    湿度の小数部 (DHT11では常に0) または 湿度下位バイト (DHT21)
  • 3[byte]
    温度の整数部 (DHT11) または 温度上位バイト (DHT21)
  • 4[byte]
    温度の小数部 (DHT11では常に0) または 温度下位バイト (DHT21)
  • 5[byte]
    チェックサム (1[byte]〜4[byte]の合計の下位8ビット)


通信シーケンス

1. スタート信号

MSP430G2553がDATAラインをLOWに18[ms]以上保持後、20〜40[us]の間HIGHにする。

2. 応答信号

センサがDATAラインを80[us]間LOWにした後、80[us]間HIGHにする。

3. データ送信

各ビットは以下のタイミングで送信される。

  • ビット開始
    センサがDATAラインを50[μs]間LOWにする
  • データビット0
    26〜28[us]間HIGHを保持
  • データビット1
    70[us]間HIGHを保持


タイミングチャート

下図に、DHT11 / DHT21のタイミングチャートを示す。

  1. MSP430G2553からセンサへの開始信号
    18[ms] LOW + 40[us] HIGH
  2. センサからの応答信号
    80[us] LOW + 80[us] HIGH
  3. データビット "0" の送信
    50[us] LOW + 26〜28[us] HIGH
  4. データビット "1" の送信
    50[us] LOW + 70[us] HIGH




サンプルコード

基本

以下の例では、MSP430G2553を使用してDHT11 / DHT21から温度と湿度を取得している。

 /*
  * MSP430G2553とDHT11/DHT21温湿度センサのサンプルプログラム
  * 
  * 接続:
  *   P1.6 - DHT11/DHT21 DATA pin (4.7kΩプルアップ推奨)
  *   VCC  - DHT11/DHT21 VDD (3.3Vまたは5V)
  *   GND  - DHT11/DHT21 GND
  * 
  * データシート参照:
  *   MSP430G2x13/MSP430G2x53 Datasheet (SLAS735)
  *   - GPIO設定: Section 8.2 Digital I/O
  *   - Timer_A: Section 12 Timer_A
  *   - Clock System: Section 5 Basic Clock Module+
  */
 
 #include <msp430g2553.h>
 #include <stdint.h>
 
 // DHTセンサのデータピン定義
 #define DHT_PIN         BIT6        // P1.6をDATAピンとして使用
 #define DHT_DIR         P1DIR       // P1.6の方向制御レジスタ
 #define DHT_OUT         P1OUT       // P1.6の出力レジスタ
 #define DHT_IN          P1IN        // P1.6の入力レジスタ
 #define DHT_REN         P1REN       // P1.6のプルアップ/ダウン制御レジスタ
 
 // DHT11とDHT21の選択
 #define USE_DHT11       1           // DHT11使用時は1、DHT21使用時は0
 
 // データ構造体
 typedef struct {
    uint16_t humidity;              // 湿度 (10倍値、DHT11: 整数値のみ、DHT21: 0.1%単位)
    uint16_t temperature;           // 温度 (10倍値、DHT11: 整数値のみ、DHT21: 0.1℃単位)
    uint8_t  checksum_ok;           // チェックサムが正しければ1
 } DHT_Data;
 
 // 関数プロトタイプ
 void init_clock(void);
 void init_gpio(void);
 void delay_ms(uint16_t ms);
 void delay_us(uint16_t us);
 void dht_set_output(void);
 void dht_set_input(void);
 uint8_t dht_read_bit(void);
 uint8_t dht_read_byte(void);
 uint8_t dht_start(void);
 uint8_t dht_read_data(DHT_Data *data);
 
 /*
  * メイン関数
  */
 int main(void)
 {
    DHT_Data dht_data;
    uint8_t result;
 
    WDTCTL = WDTPW | WDTHOLD;      // ウォッチドッグタイマを停止
                                   // WDTPW (0x5A00) : パスワード
                                   // WDTHOLD : タイマ停止ビット
 
    init_clock();                  // クロックシステムの初期化
    init_gpio();                   // GPIOの初期化
 
    __enable_interrupt();          // グローバル割り込み許可
 
    while(1)
    {
       // DHTセンサからデータを読み取り
       result = dht_read_data(&dht_data);
 
       if(result && dht_data.checksum_ok)
       {
          // データ読み取り成功
          // ここで温度と湿度のデータを使用
          // 例: UART経由で送信、LCD表示等
 
          // 温度と湿度は10倍値で格納されている
          // 実際の値 = dht_data.temperature / 10.0
          //           dht_data.humidity / 10.0
       }
       else
       {
          // データ読み取り失敗
          // エラー処理
       }
 
       // 次の測定まで最低2秒待機 (DHT11/DHT21の仕様)
       delay_ms(2000);
 
       // 低電力モードに移行 (オプション)
       // __bis_SR_register(LPM0_bits + GIE);
    }
 
    return 0;
 }
 
 /*
  * クロックシステムの初期化
  * 
  * MCLK = SMCLK = DCO 約1[MHz] (デフォルト設定)
  * ACLK = VLO 約12[kHz]
  * 
  * データシート参照: Section 5.2 (Basic Clock Module+ Registers)
  * レジスタ:
  *   DCOCTL  (0x0056): DCO制御レジスタ
  *   BCSCTL1 (0x0057): 基本クロック制御1
  *   BCSCTL2 (0x0058): 基本クロック制御2
  *   BCSCTL3 (0x0053): 基本クロック制御3
  */
 void init_clock(void)
 {
    // DCOを1[MHz]に設定 (キャリブレーション値を使用)
    // キャリブレーション値はInfoメモリSegment Aに保存されている
    if (CALBC1_1MHZ != 0xFF)        // キャリブレーション値が有効かチェック
    {
       DCOCTL = 0;                 // DCO制御レジスタをクリア
       BCSCTL1 = CALBC1_1MHZ;      // 基本クロック制御1にキャリブレーション値設定
       DCOCTL = CALDCO_1MHZ;       // DCO制御にキャリブレーション値設定
    }
 
    // MCLK = DCO, SMCLK = DCO (デフォルト)
    BCSCTL2 = 0;                    // BCSCTL2レジスタ
                                    // SELM_0: MCLK = DCOCLK
                                    // DIVM_0: MCLK分周なし
                                    // SELS: SMCLK = DCOCLK
                                    // DIVS_0: SMCLK分周なし
 
    // ACLK = VLO (~12kHz)
    BCSCTL3 = LFXT1S_2;             // LFXT1S_2: VLOを選択
                                    // 外部水晶がない場合はVLOを使用
 }
 
 /*
  * GPIOの初期化
  * 
  * P1.6をDHTセンサのDATAピンとして設定
  * 
  * データシート参照: Section 8.2 (Digital I/O)
  * レジスタアドレス:
  *   P1DIR  (0x0022): ポート1方向レジスタ
  *   P1OUT  (0x0021): ポート1出力レジスタ
  *   P1SEL  (0x0026): ポート1機能選択レジスタ
  *   P1SEL2 (0x0041): ポート1機能選択レジスタ2
  *   P1REN  (0x0027): ポート1プルアップ/ダウン有効化
  */
 void init_gpio(void)
 {
    // P1.6をGPIOとして設定
    P1SEL &= ~DHT_PIN;              // P1SEL.6 = 0: GPIO機能を選択
    P1SEL2 &= ~DHT_PIN;             // P1SEL2.6 = 0: GPIO機能を選択
 
    // 初期状態は入力に設定
    DHT_DIR &= ~DHT_PIN;            // P1DIR.6 = 0: 入力モード
 
    // 内部プルアップを有効化 (オプション、外部プルアップ推奨)
    DHT_REN |= DHT_PIN;             // P1REN.6 = 1: プルアップ/ダウン有効
    DHT_OUT |= DHT_PIN;             // P1OUT.6 = 1: プルアップを選択
                                    // (P1OUT=0でプルダウン、P1OUT=1でプルアップ)
 }
 
 /*
  * ミリ秒単位の遅延関数
  * 
  * MCLK = 1[MHz]を前提とした簡易的な遅延
  * より正確な遅延が必要な場合はTimer_Aを使用
  */
 void delay_ms(uint16_t ms)
 {
    volatile uint16_t i;
    while(ms--)
    {
       for(i = 0; i < 1000; i++)
       {
          __delay_cycles(1);      // 1サイクル遅延 (1[MHz]時は1[us])
       }
    }
 }
 
 /*
  * マイクロ秒単位の遅延関数
  * 
  * MCLK = 1[MHz]を前提
  * __delay_cycles()はコンパイラ組み込み関数
  */
 void delay_us(uint16_t us)
 {
    while(us--)
    {
       __delay_cycles(1);          // 1[MHz]時 : 1サイクル = 1[us]
    }
 }
 
 /*
  * DHTピンを出力モードに設定
  */
 void dht_set_output(void)
 {
    DHT_DIR |= DHT_PIN;             // P1DIR.6 = 1: 出力モード
 }
 
 /*
  * DHTピンを入力モードに設定
  */
 void dht_set_input(void)
 {
    DHT_DIR &= ~DHT_PIN;            // P1DIR.6 = 0: 入力モード
 }
 
 /*
  * DHTセンサから1ビット読み取り
  * 
  * 戻り値 : 0または1
  */
 uint8_t dht_read_bit(void)
 {
    uint8_t count = 0;
 
    // DATAラインがLOWになるまで待機 (タイムアウト付き)
    while(DHT_IN & DHT_PIN)
    {
       delay_us(1);
       if(++count > 100) return 0;
    }
 
    // DATAラインがLOWの間待機 (約50μs)
    count = 0;
    while(!(DHT_IN & DHT_PIN))
    {
       delay_us(1);
       if(++count > 100) return 0;
    }
 
    // DATAラインがHIGHの期間を測定
    // HIGHの期間が26〜28[us]ならビット0、70[us]ならビット1
    delay_us(35);                   // 35[us]待機
 
    if(DHT_IN & DHT_PIN)            // まだHIGHならビット1
    {
       return 1;
    }
    else                            // LOWに戻っていればビット0
    {
       return 0;
    }
 }
 
 /*
  * DHTセンサから1バイト(8ビット)読み取り
  * 
  * 戻り値: 読み取った8ビットデータ
  */
 uint8_t dht_read_byte(void)
 {
    uint8_t i, byte = 0;
 
    for(i = 0; i < 8; i++)
    {
       byte <<= 1;                 // 左シフト
       byte |= dht_read_bit();     // ビットを読み取って追加
    }
 
    return byte;
 }
 
 /*
  * DHTセンサへ開始信号を送信
  * 
  * 戻り値 : 応答があれば1、なければ0
  */
 uint8_t dht_start(void)
 {
    uint8_t count = 0;
 
    // 1. MCUが開始信号を送信
    dht_set_output();               // 出力モードに設定
    DHT_OUT &= ~DHT_PIN;            // DATAラインをLOWに
    delay_ms(20);                   // 20[ms]間LOWを保持
 
    DHT_OUT |= DHT_PIN;             // DATAラインをHIGHに
    delay_us(30);                   // 30[us]待機
 
    // 2. 入力モードに切り替えてセンサの応答を待つ
    dht_set_input();                // 入力モードに設定
 
    // センサがDATAラインをLOWにするまで待機
    while(DHT_IN & DHT_PIN)
    {
       delay_us(1);
       if(++count > 100) return 0; // タイムアウト
    }
 
    // センサがDATAラインを約80μs間LOWに保持
    count = 0;
    while(!(DHT_IN & DHT_PIN))
    {
       delay_us(1);
       if(++count > 100) return 0; // タイムアウト
    }
 
    // センサがDATAラインを約80[us]間HIGHに保持
    count = 0;
    while(DHT_IN & DHT_PIN)
    {
       delay_us(1);
       if(++count > 100) return 0; // タイムアウト
    }
 
    // 応答成功
    return 1;
 }
 
 /*
  * DHTセンサからデータを読み取り
  * 
  * 引数 : data - データを格納する構造体へのポインタ
  * 戻り値 : 成功時1、失敗時0
  */
 uint8_t dht_read_data(DHT_Data *data)
 {
    uint8_t i;
    uint8_t raw_data[5];            // 5バイトの生データ
    uint8_t checksum;
 
    // 開始信号を送信
    if(!dht_start())
    {
       return 0;                   // 開始失敗
    }
 
    // 5バイト (40ビット) のデータを読み取り
    for(i = 0; i < 5; i++)
    {
       raw_data[i] = dht_read_byte();
    }
 
    // チェックサムの検証
    checksum = raw_data[0] + raw_data[1] + raw_data[2] + raw_data[3];
    data->checksum_ok = (checksum == raw_data[4]);
 
 #if USE_DHT11
    // DHT11の場合
    data->humidity = raw_data[0] * 10;      // 湿度は整数部のみ
    data->temperature = raw_data[2] * 10;   // 温度は整数部のみ
 #else
    // DHT21 (AM2301) の場合
    data->humidity = ((uint16_t)raw_data[0] << 8) | raw_data[1];
    data->temperature = ((uint16_t)raw_data[2] << 8) | raw_data[3];
 
    // 温度の符号処理 (DHT21は負の温度に対応)
    if(data->temperature & 0x8000)
    {
       data->temperature = -(data->temperature & 0x7FFF);
    }
 #endif
 
    return 1;                       // 読み取り成功
 }


外部デバイスとの連携

以下の例では、温度と湿度をUART経由でPC等の外部デバイスに出力している。

 /*
  * MSP430G2553とDHT11/DHT21温湿度センサ
  * 
  * 追加接続:
  *   P1.1 - UART TXD (PC等と接続)
  *   P1.2 - UART RXD (PC等と接続)
  * 
  * UART設定: 9600bps, 8bit, No Parity, 1 Stop bit
  */
 
 #include <msp430g2553.h>
 #include <stdint.h>
 #include <stdio.h>
 
 // 前述のDHT関連定義と関数をここに含める
 // ...
 
 // UART関連の関数プロトタイプ
 void init_uart(void);
 void uart_send_char(char c);
 void uart_send_string(const char *str);
 void uart_send_number(int16_t num);
 
 /*
  * UART初期化 (USCI_A0を使用)
  * 
  * ボーレート: 9600[bps]
  * MCLK = SMCLK = 1MHz
  * 
  * データシート参照: Section 15 (USCI_A)
  * レジスタ:
  *   UCA0CTL1 (0x0061) : USCI_A0 制御レジスタ1
  *   UCA0CTL0 (0x0060) : USCI_A0 制御レジスタ0
  *   UCA0BR0  (0x0062) : ボーレート制御レジスタ0
  *   UCA0BR1  (0x0063) : ボーレート制御レジスタ1
  *   UCA0MCTL (0x0064) : モジュレーション制御レジスタ
  */
 void init_uart(void)
 {
    // UARTピンの機能を有効化
    P1SEL |= BIT1 + BIT2;           // P1.1 = RXD, P1.2 = TXD
    P1SEL2 |= BIT1 + BIT2;          // P1SEL2も設定
 
    // USCI_A0をUARTモードで初期化
    UCA0CTL1 |= UCSSEL_2;           // SMCLK (1MHz) を選択
 
    // ボーレート設定: 9600[bps] @ 1[MHz]
    // N = 1000000 / 9600 = 104.166
    UCA0BR0 = 104;                  // 下位バイト
    UCA0BR1 = 0;                    // 上位バイト
    UCA0MCTL = UCBRS0;              // モジュレーション UCBRSx = 1
 
    UCA0CTL1 &= ~UCSWRST;           // USCI状態マシンを初期化
 }
 
 /*
  * UART経由で1文字送信
  */
 void uart_send_char(char c)
 {
    while (!(IFG2 & UCA0TXIFG));    // 送信バッファが空になるまで待機
    UCA0TXBUF = c;                  // 文字を送信バッファに書き込み
 }
 
 /*
  * UART経由で文字列送信
  */
 void uart_send_string(const char *str)
 {
    while(*str)
    {
       uart_send_char(*str++);
    }
 }
 
 /*
  * UART経由で数値送信 (符号付き整数)
  */
 void uart_send_number(int16_t num)
 {
    char buffer[8];
    sprintf(buffer, "%d", num);
    uart_send_string(buffer);
 }
 
 /*
  * メイン関数
  */
 int main(void)
 {
    DHT_Data dht_data;
    uint8_t result;
 
    WDTCTL = WDTPW | WDTHOLD;      // ウォッチドッグタイマを停止
 
    init_clock();                   // クロックシステムの初期化
    init_gpio();                    // GPIOの初期化
    init_uart();                    // UARTの初期化
 
    __enable_interrupt();           // グローバル割り込み許可
 
    // 起動メッセージ
    uart_send_string("\r\n=== MSP430G2553 DHT11/DHT21 Test ===\r\n");
 
    while(1)
    {
       // DHTセンサからデータを読み取り
       result = dht_read_data(&dht_data);
 
       if(result && dht_data.checksum_ok)
       {
          // データ読み取り成功
          uart_send_string("Temp: ");
          uart_send_number(dht_data.temperature / 10);
          uart_send_char('.');
          uart_send_number(dht_data.temperature % 10);
          uart_send_string(" C, Humidity: ");
          uart_send_number(dht_data.humidity / 10);
          uart_send_char('.');
          uart_send_number(dht_data.humidity % 10);
          uart_send_string(" %\r\n");
       }
       else
       {
          // データ読み取り失敗
          uart_send_string("ERROR: Failed to read DHT sensor\r\n");
       }
 
       // 次の測定まで2秒待機
       delay_ms(2000);
    }
 
    return 0;
 }



トラブルシューティング

タイミングの調整

  • DHTセンサの通信プロトコルはタイミングに敏感なため、待機時間の精度が重要となる。
  • MSP430G2553のクロック周波数が変更された場合は、delay_us関数 と delay_ms関数を調整する必要がある。
  • 正確なタイミングが必要な場合は、Timer_Aモジュールを使用することを推奨する。


プルアップ抵抗

  • 外部プルアップ抵抗 (4.7[kΩ]〜10[kΩ]) を使用することが推奨される。
  • 内部プルアップ抵抗のみでも動作する場合があるが、信号品質が低下する可能性がある。
  • 配線が長い場合 (20[m]以上) は、プルアップ抵抗値を小さくする (5[kΩ]程度) 必要がある。


電源とノイズ対策

  • VDDとGNDの間には必ず0.1[uF]のセラミックコンデンサを配置する。
  • センサとMCUの間の配線は可能な限り短くする。
  • ノイズの多い環境では、追加のフィルタリングが必要な場合がある。


データ取得間隔

  • DHT11 / DHT21は連続測定には対応していない。
  • 最低でも1秒、推奨では2秒以上の間隔を空けてデータを取得する。
  • 連続して読み取ると、センサが応答しなくなる場合がある。


低消費電力動作

MSP430G2553の低電力モードを活用することで、バッテリー駆動時間を延ばすことができる。

 // 測定間隔の待機時にLPM3モードに移行
 // Timer_Aの割り込みで復帰
 
 void main(void)
 {
    // ... 初期化処理 ...
 
    while(1)
    {
       // データ取得処理
       result = dht_read_data(&dht_data);
 
       // データ処理
       // ...
 
       // Timer_Aを設定して2秒後に割り込み発生
       TA0CCR0 = 32768 * 2;        // ACLK = 32768[Hz]の場合
       TA0CTL = TASSEL_1 + MC_1;   // ACLK, Up mode
       TA0CCTL0 = CCIE;            // 割り込み許可
 
       // LPM3モードに移行 (ACLKのみ動作)
       __bis_SR_register(LPM3_bits + GIE);
    }
 }
 
 // Timer_A0割り込みサービスルーチン
 #pragma vector=TIMER0_A0_VECTOR
 __interrupt void Timer_A0_ISR(void)
 {
    TA0CTL = 0;                     // Timer停止
    __bic_SR_register_on_exit(LPM3_bits); // LPM3から復帰
 }



エラッタ情報

MSP430G2553には既知のエラッタ (不具合) が存在する。

BCL12 : DCOクロック切り替え時の問題

RSELxビットを切り替える時、DCOが停止する可能性がある。
回避策として、RSELx > 13 から RSELx < 12に切り替える時は、中間値 (RSEL=13) を経由する。

TA12: Timer_A割り込み消失

ACLK等の低速クロックを使用する場合、割り込みが消失する可能性がある。
回避策として、CCRxレジスタを更新する前に、TARレジスタとCCRxレジスタの差を確認する。

詳細は、MSP430G2553のエラッタ情報を参照すること。