ハイサイドスイッチ回路用コントローラ

 前回のブログではハイサイドスイッチ回路について書きました。今回はこのハイサイドスイッチボードを最大で8枚接続できる制御用ボードについてです。ステンシルを使ってペーストハンダを塗り、部品を置いてからオーブントースターでリフロー。今回は試作検討用なので1枚だけ。

 ATmega328PBとRS-232C通信用のトランシーバ、I/Oエキスパンダ(MCP23S17)とトランジスタアレーが載っています。マイコンの発振回路は水晶は使わず16MHzのクロックオシレータです。(今後はこの組み合わせが基本になる予定。)リフロー終了後はプログラム書き込み用に最低限必要なDCジャックと5Vレギュレータ、プログラム書き込み用のピンヘッダだけを実装。プログラムは無事に書き込めたので、次にRS-232C用のDsubコネクタを実装。これでデバッグの準備が整いました。

 色々とつなげてデバッグ開始。写真ではプログラマとRS-232C、ロジックアナライザ、ブレッドボード上のLEDとプッシュスイッチをつなげてあります。I/Oエキスパンダ(MCP23S17)を出力/入力の混在で使うのはおそらく今回が初めて。出力はさほど悩むことなく動くのですが、今回は入力の割り込み処理もあって確認が少し手間です。そこでロジックアナライザが登場するのですが初期設定からして何かおかしい。今回はSPIが2系統使えるATmega328PBなので、プログラム書き込み用のSPI0とは独立させたSPI1をハードウエアとして使用することにしましたが。動かすたびにMCP23S17のチップセレクト(イネーブル)が関係ないところでhigh-lowしたりする現象が発生。そのためか動作もおかしく悩むこと数時間。コンパイラのBASCOM-AVRのバグなのか。

 万策尽きて?ハードSPIからソフトSPIに変更し、チップセレクトもSPIOUT/SPIINとは別に制御。(これならあえてSPIが2系統ある必要などなかったですね。)

 上はロジックアナライザで見た初期設定の様子。上からMOSI、MISO、SCK、チップセレクト、そして入力ポートから発生させる割り込み信号のINTB。

 これ(上)は初期設定の初めの部分を少し大きくしたもの。

 ハイサイドスイッチ回路から過電流検出のfault信号が入ってくると、上の写真の一番下(Channel4)のINTBがLowに落ち、これをマイコンで割り込み信号として検出。次にChannel3のチップセレクトをLow(有効)にしてINTCAPBを読み込むとINTBはクリアされHighに戻る。次に出力ポートの制御ビットをLowに落としてハイサイドスイッチを切断するために制御信号をオフするためOLATAにAポートの出力データを書き込みというのが上の写真。ここも悩んだところで、はじめの構想ではプルアップされた入力ポートが過電流でLowに落ちる=比較用としてDEFVALBをHighに設定してあるので、ここで不一致となり割り込みが入る=というものだったのですが、割り込みは入るもののINTCAPB(あるいはGPIOB)を読み込んでもINTBがクリアされないというデータシートとは違う謎の現象。そこで比較一致はあきらめて状態変化割り込みで対応することに。これであると入力がLowになったときとLowからHighになったとき、どちらも割り込みが入ってしまいます。必要なのはLowに落ちたときだけなので割り込み検知後にINTCAPBを読み、その値がHighであれば処理しないという流れにして対応することにしました。(文章だけだとよくわかりませんね。)

 そんなこんなでデバッグに丸一日程度かかりましたが、構想通りに動くようになりました。ハイサイドスイッチボードの改良版が届いたらこのボードとつなげて実機検討を再度行うことにします。今回はエキスパンダでこんなに悩むとは思いませんでした。まあ、これで入力/出力とも使えるというソフトウエア資産ができたので「めでたしめでたし」ということで。でも、データシート通りに設定しているはずなのに動かないのはなぜでしょうか。どこか理解していないところがあるのかも。

(以下翌朝追記)

 目が覚めてから気になったことがあったのでデータシートを読み直してソフトを修正し再度検証したところ原因がわかりました。DEFVALBに1をセットしておいて入力がLowになったときにINTBがLowになる–>マイコンはそれを割り込み(INT0)で受け付けて割り込み処理に入ります。最初に8ビットの入力のうち、どのビットが割り込みの原因であるかを判別するためINTCAPBを読みにいきます。ここでINTBがクリアされるはずがされない。なぜか? INTCAPBを読みにいった時点で入力はまだLowのままなのでクリアできない。–>入力をHighに戻してからもう一度INTCAPBを読みにいくとINTBはクリアされる。こういうことでした。要はワンショット(短いパルス)での入力ではなく今回のようにこちらが処理を終えるまで入力がLowのままであると「(本来割り込みがクリアされる)INTCAPBを読んでも割り込みの条件が続いている」ことによりINTBは割り込みの結果であるLowのまま・・・ということですね。このボードと合わせて使うハイサイドスイッチ(制御はLTC7000)では過電流を検出してfault信号をオン–>これをMCP23S17に入力してマイコン(ATmega328PB)へ割り込み信号発出–>マイコンはLTC7000の駆動信号(INP)をオフ–>fault信号解除 というフローなので、それまではINTCAPBを読み込んでもINTBは解除されません。結局、DEFVALBとの比較による割り込み発生の方法では解除されないために具合が悪いということがわかりました。この割り込み検知が立ち下がり/立ち上がりという条件を設定できれば、fault信号によるネガティブエッジで割り込みを発生させられるので何も悩まずにすんだということです。(MCP23S17での割り込みの設定はDEFVALとの比較か状態変化 High–>Low あるいはLow–>High のみ。) 

 ハイサイドスイッチのMOSFETをドライブするLTC7000側では過電流検出をして自動的に出力を切ってくれるのでマイコン側から急いでINPをオフする必要はありません。今回は割り込みを使って即時切断という設計をしましたが、10m秒なり100m秒毎の時間割込みでMCP23S17のPORTBを読んで、「faultが発生している場合にはINPをオフ」というフローにしても全く問題はありません。いちどMCP23S17での入力と割り込み処理を試してみたかったため余計に時間がかかってしまいました・・。