かふぇルネに投稿しました。
今回はリセット信号に関連する組み込み機器ならではの処理です。
組み込み機器に限らず、電気製品はいつ電源が切られるか分かりませんよね。しかし、次に電源やスイッチを入れたときに「電源が切れる直前の状態」であったり、「編集中のデータが失われていない」などが求められます。
ここはパソコンとは違う所ですね。パソコンなら電源を強制的に落とすと、次回の起動時に異常終了したことを表示し、使用者にどう対応するか求めてきます。
ではどうやって電源が落ちたことを検出するのか、ですが、一般的にはリセットICと呼ばれるものや低電圧検知IC、もしくはマイコンに内蔵される低電圧検知機能を利用します。バッテリー駆動で低電圧を検知するのであれば、マイコン内蔵の低電圧検知でもいいのですが、電源遮断(スイッチoff)や瞬停(一瞬だけ電源が落ちる現象)にはリセットICや遮断検出回路を外付けしたほうが安心です。
接続する方法は様々あると思いますが、NMI(ノンマルカブルインタラプト)やIRQ(インタラプトリクエスト)に繋ぐのが一般的ではないでしょうか。
図1. 接続例
もちろん、マイコンのRES端子に繋ぐことも考えられますが、あまり推奨しません。RES端子に接続してしまうとマイコン内部ではリセットがかかってしまい、電源が落ちる直前にデータを保存したいなどに対応できなくなるからです。
上図は電圧降下と時間の関係を示しています。電圧は落ちる時にはシステム負荷に応じて一気に落ちますから、ある程度時間を稼ぐために(数ms持つくらいの)コンデンサが必要かもしれません。
図1.ではNMIやIRQ0に繋いでいましたが、これも訳があります。
電源が落ちてきたことを検知するといち早くデータ保存を行わなくてはならないのですが、他の割込みを処理していては割込み処理完了待ちが発生してしまいます。折角かせいだ時間が無駄になってしまうので、割込み優先順位が最優先であるNMIや、外部割込み要求の中で最優先のIRQ0を割り付けるのです。
肝心の処理ですが、このようなイメージでしょうか
void Interrupt_IRQ0(void){ /* data saving */ /* watch dog start */ }
こちらは電源低下を検知した時に、データ保存のみ行うタイプです。システムが再起動したとき用にウォッチドッグタイマを設定していますが、再起動を検討しなくていい場合は、この処理は不要です。
void Interrupt_IRQ0(void){ /* data saving */ /* output initialize */ for( ;port; ){ /* waiting restart power */ ; } /* watch dog start */ }
一方で、こちらは電源復旧を織り込んだタイプです。データ保存処理後に一時的な待機状態に備えるために、出力を全てoffしてから電源復旧をポート監視しながら待ちます。復旧が検知できたらウォッチドッグや他の内部リセット機能を用いて再起動します。
何が最適か?というベストアンサーはありません。ケースバイケースがほとんどです。最低限の機能は満たさなくてはいけませんし、品質過多も問題でしょう。こんなケースはどうしたらいい?というご質問がございましたら、お気軽にお問い合わせください。