【16】リセットとウォッチドッグタイマー・・・
リセットという言葉はパソコンやゲーム機、携帯機器などで頻繁に使用するようになり一般的な言葉になりつつありますが、クリア操作と混同してきているような気がします。
本来、リセットとは突発的なことが起きて、マシンがにっちもさっちも行かなくなったときに行うプログラムの初期化のコトだと私は思っています。クリア操作は記憶したデータを消して最初に戻すことで、プログラムは初期化されないはずです。
▽ リセット △
PICでいうリセットという処置はプログラムの初期化をすること、と簡単に片付けられない重い意味があります。PICはパソコンと異なり非常に気軽に電源を切られます。さらに、電源の再投入もとうぜん気軽に行われます。電源の入り切りを頻繁にできるパソコンなんて見たことありませんね。(昔のは別ですが…)PICはそれで当たり前なのです。PICは非常にハードウエアと密接しています。そのためPICに書き込むプログラムをソフトウエアと呼ばずに中間的な意味であるファームウエアと呼ばれることがあります。
最近のPICは電源を入れ直せばそれ自身はリセットするようにできますが、古いタイプのPICや他の機器と連動した使い方をする場合は、PIC内部のリセットだけではカバーしきれなくなり外部リセット回路が必要になります。
ひとくちでリセットといってもPICにはいろいろなリセットがあります。
① 電源が入ったとき(パワーオン)リセット
② 電源が切れたとき(ブラウンアウト)リセット
③ マニュアルリセット。手動で MCLR端子を L にしてから H にする。
④ 異常時に(ウォッチドッグタイムアウト)リセット
⑤ ソフトウエア リセット
⑤のソフトウエア リセットはプログラマーの都合(仕様)で、プログラムを強制的にもとに戻すことですので今回は省きます。
それ以外のリセットはどれもPICの内部ロジックを使える状態に戻してプログラムアドレスの 0000番地から走りだすようになります。
PICの内部ロジックがどのリセットでも同じようにクリアされるかというとそうではなく、リセットの種類によってフラグの一部が異なった設定になります。その違いをプログラムの先頭で判断して分岐させることになります。
(その話は次回で・・・)
リセットをひとことで書くと、プログラムの流れを振り出しに戻すということです。PICがどのような状態になって迷走しようが、あるいは無茶苦茶に暴走しようが、リセットが掛かるとプログラムの流れが最初に戻ります。ということは、すべて初めからやり直すということになりますが、どのリセットが掛かったかを判別することで暴走する前の状態に戻せることもできます。
PICが無茶苦茶に動き出すことを"暴走"と呼んでいますが、ほとんどの場合はプログラムが間違っていることが原因しています。これは製作者の責任ですのでどうしようもありません。プログラマーが間違いを修正すれば暴走は収まります。ここでいう暴走とはプログラマーが予期できないような暴走です。予期できないのでプログラムでは対処のしようがありません。
一番多いのが、電源の入り切り(パワーオン時とパワーダウン時)や、電源ラインの揺らぎ、瞬断、また強いノイズの進入によるPIC内部のロジックが暴走してRAMの内容が書き換えられてプログラムが暴走します。ただ私はノイズによるRAMの書き換え現象には遭遇したことがありません。5年以上電源を入れられたまま、一度も不具合を出さずに正常動作しているPICを数多く見ています。
▽ パワーオンリセット △
電源ONの瞬間の電源ラインを図にするとこのような感じです。
単純に電源がONになるといっても、規定の5Vへ瞬時に上がっているのでありません。バッテリーを電源とするシステムと、レギュレータを使用したり、スイッチング電源を使用した外部電源を使用したシステムと比べると、立ち上がりの速度に図のような差がありますが、問題は赤色の不安定期間がどちらにもあるということです。
PICのメーカーはこの期間の正常動作を保障していません。そこで、その間はMCLR端子をLにしておく必要があります。これがパワーオンリセットです。最近のPICはパワーオンリセット回路が内蔵されていますので、MCLR端子を電源の5Vに直結しておき、デバイス設定で"POR(パワーオンリセット)"を使用するにセットしておけば、PIC内部で電源が規定値になるまで待ってから自動的に立ち上がります。
しかし、PIC以外にもリセット信号が欲しいということもあります。そのようなときは外部にリセット回路を作り、PICのMCLR端子やその他の回路に接続します。下記が超簡単リセット回路ですが・・・。
そうです。これはやってはいけない悪い例です。たしかにコンデンサーに充電されていく期間 MCLR端子の部分は L になります。その時間以内に電源が立ち上がれば、このリセット信号は有効です。しかし電源がOFFになったときは、コンデンサーに溜まった電流が放電するまでMCLR端子は H を維持します。そこでダイオードを使って、コンデンサの充電電流を電源に向って放電させていますが、結果は下記のようなグラフになり不安定期間が消えることはありません。
▽ ブラウンアウトリセット △
電源が規定値以下になったとき、瞬時にMCLR端子をLに落とさなければいけません。そうでないとその不安定期間にPICはどのような動作をするか想像もできません。
電源電圧の揺らぎと、それに対する MCLR端子に掛ける電圧の理想的な波形は以下のようになります。
電源の不安定期間はMCLR端子がすべてLに落ちています。MCLR端子がLに落ちている期間がリセットです。この間PICは停止して内臓されているロジック部分を最初の状態に戻します。そしてMCLR端子がHになるとPICはアドレス0000番地から走り出します。
(古いPICではプログラムエリアの最終アドレスからスタートするものもあります)
特に電源がOFFあるいは瞬断した部分をご覧ください。PICが正常に走れると保障している規定値、4.5V以下になったとき、MCLR端子が瞬時Lに落ちています。これをブラウンアウトと呼んでいます。このブラウンアウト機能が搭載されているPICもありますので、先のパワーオンリセットと合わせて "BOR"(ブラウンアウトリセット)も機能させるようにします。これで特別なことを行わなくても電源の揺らぎからプログラムの暴走を防ぐことができます。
電源の揺らぎはテスターではほとんど見えません。でもオシロスコープなどで見るとはっきりと見えてきます。
例えばモーターが回転すると大電流が流ます。その瞬間に電源電圧が下がることもありますし、貧弱なGNDの配線が原因で大きく変動することもあります。
5Vラインは電源ラインだと意識しているのでしっかり配線させますが、実はGNDラインが最も重要な電源ラインだということを覚えておきましょう。PICを利用したシステムには、PICの電源になる5V以外にもモータやLEDを点灯させる別の電圧の電源があると思います。GNDラインはそれらすべての基準になる点で、この点を基準に5Vや12V、24Vという電圧が決まります。そしてこれらすべての電源から電流がGNDへ流れ込んできます。このGNDが接触不良を起こしていたり細い電線で配線されていたりすると、それが電源の揺らぎとなって返ってきます。
GNDは太く広く短くが基本だとしっかり肝に命じてください。
そしてそれとともに重要なのがパスコンと呼ばれる、電源ラインに取り付ける小さなコンデンサーです。これは正式名称バイパスコンデンサーと呼ばれるもので、IC1個に対して1個は付けたいです。0.01μF~1μFのセラミックコンデンサーを使います。一般的には0.1μ50V程の積層セラミックを使用します。このコンデンサの役目は高速パルスによる過電流を補い、電源の揺らぎを和らげる働きをします。
昔、大陸のお国が日本のゲーム機をコピーしたモノがありましたが、それにはパスコンがほとんど省略されていました。当然ですが、まともに動くものは皆無でした。最初はちゃんと動くのですが、しばらくするとリセットを繰り返して使い物になりませんでした。
パスコンは1個2個なくてもそうそうの問題は出ませんが、全部なくなると暴走を繰返します。
パスコンはICの電源供給ポイントに極限まで近くに取り付けるが基本です。
PICによっては電源供給ポイントが2ヶ所あるものがありますが、その2ヶ所ともに付けましょう。
ところで外部リセット回路の場合、先ほどの中途半端な外部リセットではブラウンアウトリセットができませんので、専用のICを使用します。最近は部品点数も少なく簡単に実現できます。
下記はミツミ電機製のPST37シリーズです。
外付けのコンデンサーと抵抗を付けると、遅延とチャタリング対策つきのマニュアルリセット回路もできます。こんな簡単な回路で外部パワーオンリセットとブラウンアウトリセットができます。
▽ ウォッチドッグタイムアウトリセット △
電源電圧の揺らぎによる暴走からプログラムを守るには、パワーオンリセットとブラウンアウトリセットで解決ですが、PICのような自立型のコンピュータシステムをさらに安全に確実に動かし続けるには、まだ取るべき方法があります。それがウォッチドッグタイムアウトリセットです。
ウォッチドッグをインターネットで調べますと「番犬」のことと出てきます。なかには「番犬を撫でる動作」というのもありました。私は「番犬を撫でる動作」のほうが的確に云い得ていると思います。
簡単に説明しますと、ウォッチドッグタイマーもタイマー0のようなカウンターです。タイマー0はオーバーフローすると割り込みを掛けることができます。同じようにウォッチドッグタイマーは、オーバーフローするとリセットを掛ける特別なタイマーです。
オーバーフローするとリセットするので、オーバーフローする前に "0" にクリアすればよいのです。プログラムの途中であろうが何であろうが、オーバーフローする前にクリアしなければ、無条件にリセットされてしまいます。
番犬が吠え出す前に撫でてご機嫌を取っているみたいです。これがウォッチドッグタイマーが「番犬を撫でる動作」だと思う理由です。
この番犬ですが、使い方を間違うと何の役にも立たない、ただの駄犬になってしまいます。
まず、ウォッチドッグタイマーをクリアさせる方法ですが、これは " clrwdt " というひとつの命令です。コレをプログラムの要所に記序するだけですが、場所が悪いとすぐにオーバーフローを起こします。
何のためにこのようなモノがあるかを考えたら、どこに記序するべきかがすぐに解るとおもいます。
なぜオーバーフローするのか・・・。
それは、タイマーをクリアしないから・・・。
なぜタイマーをクリアできなかったか・・・。
それは、暴走していてそれどころではなかったから・・・。
じゃ、リセットされてもしょうがない・・・となります。
私はメインループにひとつだけ " clrwdt " 記序しています。メインループは正常である限り常に回り続けていますし、割り込み処理との兼ね合いで、それほどゆっくりとは廻っていません。そこで正常に動いている限り、そこにある " clrwdt " 命令はウォッチドッグタイマーがオーバーフローする前に確実にクリアします。
もし、時間内にメイン処理に戻って来なかったときは暴走状態か異常状態ですので、ウォッチドッグタイマーがオーバーフローしてリセットが掛かかるという仕組みです。
周期的に動いている場所と書きましたが、間違っても割り込み処理の中に記序してはダメです。暴走中でも割り込みが掛かることがあります、そんなとこに " clrwdt " が記序されていると、暴走していてもウォッチドッグタイマーがオーバーフローしませんので、飼い犬に手を噛まれることになります。
_______________________________________________________
次回は "リセットの使い方" です。
2011.01.16
Copyright(C) 2004. D-Space Keyoss. All rights reserved