2011年3月27日日曜日

グレイコード化による低消費電力もどき

実験プラットフォーム

詳細は別途紹介したいと思いますが、実験プラットフォームとしてLaunchPadのベース基板を使って簡単なソフトウェアの動作テストができる箱を作成しました。

この箱には、LaunchPadのベース基板のSpyByWireとXIN, XOUTを除く全ての汎用ポートに押しボタンスイッチとLEDドライバ(74HC05×3)を接続した回路が搭載されており、LEDとスイッチを取り付けたケースに収納して色々な実験ができるようにしてあります。

スイッチ周りの回路の構成は次の通りですが、ハードウェアによるチャタリング防止機能はつけていません。これは、ソフト的なチャタリング防止の実験や検討を行うためです。

MSP430のピンと押しボタンスイッチの間には100Ωの短絡保護抵抗を直列に挿入し、スイッチの反対側をGNDに落としてあります。

100Ω抵抗と押しボタンスイッチの接点には10kΩのプルアップ抵抗を接続して、押しボタンスイッチ開放時にはHigh状態を維持し、押しボタンスイッチ短絡時にはLowレベルとなるようにしています。

但しMSP430のポートが出力に設定されていてHighが出力されているときには電流を36mAに制限するようになっていますが、元々数mAしか取り出せませんので、保護抵抗の抵抗値は再検討が必要です。

この箱から、LaunchPadで使用できる全ての汎用ポートを外部に引き出して、様々な拡張機能のテストをできるようにするのが中期的な目標ですが、当面はLEDと押しボタンスイッチを使うだけでできる実験をしてみたいと思います。

9分タイマー

汎用ポートに接続された2つの入力スイッチと、6本のLEDを使って0~9分まで1分単位で時間を設定できるタイマーのプログラムを制作しました。

先日、ステートマシンの値の変化をグレイコード化することで消費電力が減るはず、などと書きましたので、状態遷移をグレイコード化したステートマシンを用いるプログラムを組んでみました。

ただ、遷移速度が非常に遅いのであまり効果はなさそうです。むしろ、時間待ちの為のインクリメント・デクリメントの演算をストレートバイナリではなく、グレイコードで行った方が効果的であるように思います。

ちなみに、このプログラムでは待機状態のときに全てのクロックを停止させる仕様になっており、割り込み信号を受けてクロックを起動するようにしています。

以下にサンプルプログラムを元にした制御プログラムを示します。

動作させるためのハードウェア要件としてはMSP430G2シリーズの14ピンタイプの汎用ポート8本が任意に使えることと、XIN, XOUT端子に32.768kHzの水晶振動子を接続していることが条件となります。このため、LaunchPadのベース基板のTXD, RXDのジャンパストラップをオープンにする必要があります。

ソフトウェアの動作としては、以下のようになります。

  • 初期設定の後クロックを全て停止するスリープ状態になります。P1.2またはP1.3に接続されたスイッチがONにされることによる割り込みでスリープ状態を抜け出します。
  • 時刻の設定はP1.2に接続されたスイッチを繰り返し押すことにより、0→1→2→3→4→5→6→7→8→9→0…というように1分単位で行われ、P1.3に接続されたスイッチを押すことによりカウントダウンが始まります。
  • P1.3に接続されたスイッチがスイッチが押されるとカウントダウンを開始します。
  • 設定時刻を経過するとアラーム動作を行い、P1.2またはP1.3に接続されたスイッチが押されることで、アラーム動作を停止してスリープ状態になります。

各動作状態での表示については、以下のようになります。

  • スリープ状態から水晶発振器が安定するまでの期間はP1.1に接続されたLEDを点滅させます。水晶発振器が安定すると、表示に用いるLED6個全てを消灯します。
  • 時刻設定の際には、P1.4, P1.5, P1.6, P1.7 に接続されたLEDを用いて2進数で設定時刻(分)を表示します。
  • カウントダウン中は、P1.0に接続されたLEDを一秒間隔で点滅させながら、1分経過するごとに2進数表示させた設定時刻を1分ずつ減らして行き、最終的には全て消灯させます。
  • カウントダウン終了後は、P1.0に接続されたLEDを短い時間間隔で点滅させます。

以下にソースコードを示します。今回のポイントとなるグレイコード化はソースコードの先頭でステートマシンの状態を定義している箇所で行っています。

ソースコードをごらんいただけば分かるように、INITIALからSTOPまでの状態遷移においては殆どの状態遷移において1bitしか変化しません。但し、ALARMとSTOPの間は2bit変化します。これは、繰り返し処理となるHOLD→STOP→HOLDのステート数がちょうど良い数にならなかったためです。


#include  

// State Machines That Gray Coded Style
#define INITIAL 0x00 // bin 0000_0000
#define HOLD    0x01 // bin 0000_0001
#define MIN_SET 0x03 // bin 0000_0011
#define CNT_DN  0x07 // bin 0000_0111
#define ALARM   0x06 // bin 0000_0110
#define STOP    0x05 // bin 0000_0101

unsigned char state; // External Variable Used to Keep State 
int set_time;

void main (void)
{
  volatile unsigned int i;
  volatile unsigned int sec;
  
  // Initial Settings
  sec = 0x00;
  set_time = 0x00;
  state = INITIAL; // State Machine Initialize
  
  WDTCTL = WDTPW + WDTHOLD;                        // Stop watchdog timer
  BCSCTL3 |= XCAP_3;                               // Set X_CAP 12.5pF
  TACTL = TASSEL_1 + MC_1 + TACLR;                 // ACLK, up mode, Timer CLR
  CCR0 = 0x7FFF;                                   // Set TACCR0 to 16383
  P1DIR |= 0xF3;                                   // Set LED Port Output
  P1OUT &= 0x0C;                                   // LED OFF
  P1IE |= 0x0C;                                    // P1.3 Interrupt Enable
  P1IES |= 0x0C;                                   // P1.3 Fall Edge Interrupt Enable
  P1IFG &= ~0x0C;                                  // P1 Interrupt state Cleared

  // When X'tal OSC is fault, Red LED Blink
  while (BCSCTL3 & LFXT1OF) {
   P1OUT ^= 0x01;                                 // Blink Red LED
 for(i=5000;i>0;i--){;}                         // Set Blink Interval to Visible 
  }
  P1OUT = 0x00;                                    // All LED OFF

  for(;;){
   if(state == INITIAL){
    state = HOLD;             // State set as HOLD
   }
   
   if(state == HOLD){
    _BIS_SR(LPM4_bits + GIE); // All Clocks Stop and Interrupt Enable
   }
   
 if(state == HOLD){
  state = MIN_SET;
 }else if(state == CNT_DN){
  // Toggle Green LED with 1 Seconds Interval
     while(set_time > 0){
      if((TAR & 0xFFFF)==0){
         sec +=1;
          if((sec >= 60) && ((sec % 60) == 0)){
           set_time -= 1;
          }
         P1OUT = 16*set_time + (sec & 0x0001);
      }
     }
     if(set_time == 0){
      state = ALARM;
     }
 }else if(state == ALARM){
     P1OUT = 0x00;

     // Flash Red LED until Push the Button
     while(state==ALARM){
      P1OUT ^= 0x01;
        for(i=5000;i>0;i--){;}
     }

 }else if(state == STOP){
  P1OUT = 0x00;
     sec = 0;
     set_time = 0;
     TACTL |= TACLR;                 // Timer CLR
     state = HOLD;
 }
  }
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void){
  volatile unsigned int i;
  LPM4_EXIT;
  P1IE &=0xF3;
  if(P1IFG & 0x08){
   P1IFG &= ~0x08;                                // P1 Interrupt Flag Cleared
    if((state == MIN_SET) && (set_time>0)){
     state = CNT_DN;
    }else if(state == ALARM){
     state = STOP;
    }
  }else if((P1IFG & 0x04) && (state == ALARM)){
   P1IFG &= ~0x04;                                // P1 Interrupt Flag Cleared
    state = STOP;
  }else if((P1IFG & 0x04) && (state != MIN_SET)){
   P1IFG &= ~0x04;                                // P1 Interrupt Flag Cleared
    state = MIN_SET;
    P1OUT = 0x00;                                  // All LED OFF
  }else if((P1IFG & 0x04) && (state == MIN_SET)){
   P1IFG &= ~0x04;
   if((P1IN & 0x04)==0){
    if(set_time < 0x09){
     set_time += 1;
    }else if(set_time == 0x09){
     set_time = 0;
    }
   }
   P1OUT = (set_time * 16);
  }
  i=0;
  while(i<10000){
   if(P1IN & 0x0C){
    i++;
   }else{
    i=0;
   }
  }
  // When X'tal OSC is fault, LED Blink
  while (BCSCTL3 & LFXT1OF) {
   P1OUT ^= 0x02;                                 // Blink Red LED
   for(i=5000;i>0;i--){;}                         // Set Blink Interval to Visible 
 P1OUT = 0x00;
  }

  P1IE |=0x0C;
}

2011年3月20日日曜日

電力事情について

はじめに

巷では原子力発電所の損壊や、節電についての話題が流れておりますが、現在の電力事情や原子力発電所に関して有益な情報へのリンク集を作成したいと思います。

また、用語解説としては電気・電力辞典(東京電力)も有益です。

  • 有志の方々による極めて有益な情報提供
    「東西で電気の周波数が何故違うのか」
    ツイッターのまとめサイトTogetterでまとめられた、関東・東北が電力不足なのに西日本では節電をしなくて良いのか? という疑問に対する答えを分かりやすく丁寧に解説したツイートのまとめです。
    福島原発の放射能を理解する
    原子力発電所の基本から、福島第一原子力発電所で起きている出来事が過去の原子力発電所の事故事例と比較してどのように違うのかということまで、分かりやすく丁寧に解説した、カリフォルニア大学のMonreal氏による講演のスライドを物理学分野の専門家有志の皆さんが翻訳されました。(2011/3/21 一部訂正)
  • 公式情報は以下のリンク先となります
  • 資源エネルギー庁
  • 原子力保安院
  • 電力会社
    電気事業連合会
    電力会社の業界団体です。
    東北電力
    水力・火力・原子力発電と、東北地方と新潟県への電力供給を行っています。原子力発電所に関しては一部施設の損傷や停電の影響があるものの、原子炉は冷温停止状態になっています。
    東京電力
    水力発電・火力発電・原子力発電と、関東地方と山梨県・静岡県東部への電力供給を行っています。地震で損壊した福島第一原子力発電所を運営しています。
    J-POWER 電源開発
    水力発電・火力発電・地熱発電と東日本と西日本の周波数変換所(佐久間)及び本州と北海道の間の電力流通施設を運営しています。
    日本原子力発電
    地震の影響を受けた茨城県東海村に原子力発電所がありますが、事故は起きていません。

周波数変換施設等について

2011/4/1 加筆・修正

西日本と東日本では、電力会社から供給される交流電源の周波数が異なります。これは、発電事業創業当時の事情によるものですが、西日本と東日本の間の電力融通のために周波数を変換するための施設が3ヶ所。

また、津軽海峡を越えて北海道と本州の間の電力融通をするための施設が一箇所あります。

さらに、本州と四国・九州の間でも電力融通を行うための仕組みが整備されています。

また、本州内でも電力会社相互の電力融通の仕組みがあり、電力自由化に向けて平成15年末にまとめられた資料(経済産業省)に、その当時の状況がまとめられています。

西日本と東日本の間で電力をやり取りする設備
西日本は60Hz、東日本は50Hzの交流で電力が分配されています。位相や周波数の異なる交流電源同士を接続すると大事故が起こりますので、相互に電力を融通し合うためには周波数を変える必要があります。そのための施設が、静岡県と長野県に合計3ヶ所あります。
  • 佐久間周波数変換所:容量30万kW(静岡県) J-POWER 電源開発が運営
  • 東清水変換所:容量30万kW(静岡県) 中部電力が運営 ※仮運用
  • 新信濃変換所:容量60万kW(長野県) 東京電力が運営
津軽海峡を越えるための施設
本州以南の電力系統と北海道の電力系統が、津軽海峡越える海底ケーブルで接続されています。海底ケーブルでは直流送電が行われ両岸の変換設備で交流に変換されます。電力を受け取った変換設備では、直流から負荷側の系統の周波数と位相に合わせた交流への変換が行われます。海底ケーブル区間が直流である理由は、ケーブルの本数が少なくて済むことと、ケーブルの静電容量やインダクタンスの影響を回避できることなどであるそうです。<参考:直流送電のメリット・デメリット及び具体例を解説した資料(北大)>
  • 北本連系設備(北海道・青森県):容量60万kW J-POWER 電源開発が運営
本州と四国・九州の間の電力融通設備
以下の系統は交流のまま電力の受け渡しが行われます。
  • 関門連系設備(山口県・福岡県):容量30万kW(本州→九州),278万kW(九州→本州) J-POWER 電源開発が運営
  • 本四連系設備(岡山県・香川県):容量120万kW J-POWER 電源開発が運営
また、紀伊半島と四国を結ぶ電力融通施設もあり、津軽海峡を越える施設と同様に直流送電が行われます。

周波数が違うと何故だめなのか

初期位相が同じである、50Hzと60Hzの波形を同じ時間軸上にプロットすると下記の図のようになり、丸で囲んだ部分では、最大で振幅値の約2倍の電圧の差を生じます。

この状態に限らず、電圧が異なる区間がほとんどを占めますが、そのような場合には、送電線や変圧器・発電機に異常な電流・電圧を生じ、火災などの各種災害の原因になりますので、周波数の異なる交流電源同士を絶対に直接並列接続してはいけないのです。

2011年3月13日日曜日

コンシューマー機器の省エネルギー技術について

先日(2011/03/11)、日本近海で発生した地震による交通機関の麻痺で、情報収集に使っていたPHSの電池が消耗して使えなくなったり、停電により街路照明が無く歩行の安全確保の面で困りました。

結果として、非常時に備えてPHS用の予備電源や、ヘッドランプなどを携行することの重要性を痛感させられましたので、今後の開発テーマにしたいと考えておりますが、今回はコンシューマー機器類の消費電力抑制技術について述べたいと思います。

消費電力の抑制技術

ここでは、ほとんどのコンシューマー機器に搭載されている、LSIの消費電力抑制技術を取り上げたいと思います。

コンシューマー機器に搭載されている、ロジック系LSIはCMOSプロセスを用いている事と思います。

一般にCMOSプロセスのロジック回路は、状態が変化する時に電力を消費しますので、消費電力の抑制にはクロック周波数を下げたり、使用していない回路へのクロック供給を停止する方法や、状態変化の少ない回路として設計するといった方法が採られます。

特に、クロックを止めたり、周波数を下げることについて述べたいと思います。

LSIの場合

工場出荷時に内部回路が確定しているLSIに関しては、それらの開発ツールでデファクトスタンダードの地位を占めるSynopsis社Power Compiler等を使用することで、使用されていない回路へのクロック供給停止機能を自動的に製品へ付加する事ができますが、クロックスピードの低減ということに関しては自動化されておらず半導体製品開発段階から入念に考慮しなければなしません。

また、マイクロプロセッサなどを搭載したLSIでは、ソフトウェア制御によりクロックの制御を行う事が可能なものもあります。当然、クロックを制御するだけでなく例えば変数をグレイコード化するなどして、回路そのものの状態変化を減らすことでも消費電力の抑制が出来ます。

当ブログで取り上げているMSP430についても、待機時の消費電力を抑制するためにクロックの発振を完全に停止させた状態から割り込みによって起動させたり、内部オシレータのクロック周波数制御を行う事が可能です。

リコンフィギュアラブルデバイス

近年、低価格化が進み最終製品への採用も増えてきたFPGAやCPLDではクロック制御が意外と面倒です。

単純にクロックラインにゲートを挿入して、使用しないときにクロック供給を停止させたり、独自に作成したカウンタでクロックを分周した出力を低速クロックとして使うと、そのままでは論理合成ツールや配置配線ツールがそれらのクロック制御回路の出力信号をクロックとして認識してくれません。

また、仮にクロック制御回路の出力信号をクロックとして設定しても、基になるクロックとクロック制御回路の出力クロックの間のタイミング同期がきちんと取られる保障がないため、最悪の場合には回路を修正して論理合成と配置配線をやり直す度に、異なるタイミングで動作する回路が生成されるという酷い結果になることがあります。

そういった問題を回避するために、FPGAやCPLDに内蔵されているクロック制御用専用ゲートやPLLを用いて、クロック系統をきちんと設計し、各クロックの相互関係に応じた回路設計や論理合成・配置配線におけるタイミング制約の指定を行う必要があります。

簡単なまとめ

コンシューマー機器に用いられる半導体の低消費電力化に関しては、おおむね次のように言えるかと思います。

  1. CMOS回路の消費電力抑制には、クロック供給停止やクロック周波数の低減、状態変化の少ない回路方式の採用が有効
  2. 工場出荷段階で回路が固定される、マイコンなどの半導体製品では、設計段階でクロック供給停止機能を自動的に付加する事が可能だが、周波数の低減は自動化されていない
  3. マイコンやマイクロプロセッサを内蔵した半導体製品では、ソフトウェアでクロック制御できる物があり、その機能を用いる事で消費電力を抑制できる。また、回路の状態変化を減らす事によっても消費電力を抑える事ができる。
  4. FPGAやCPLDのようなリコンフィギュアラブルデバイスでは、クロック供給停止や周波数の低減が意外と面倒だが工夫次第で可能である

私の知る限りでは、以上のような方法で機器の性能や機能を活かしたまま、半導体の消費電力を抑制して消費電力を抑えることができます。

釈迦に説法とは思いますが、携帯情報端末のハードだけでなくソフトの開発者の方にも、バッテリ駆動機器の低消費電力化ということを念頭に置いて、製品開発を行って欲しいと思います。


追記(2011/03/21)

Webで検索したところ、このような記事がありました。 マルチクロックドメイン設計の落とし穴(EDN Japan)

LSIの内部で使用するクロック周波数が複数ある場合は、回路設計に細心の注意を払う必要があることを具体例を挙げて示してあり、良い参考資料といえます。

フォロワー