前編ではLTC7000の制御用としてはMCP23S17を割り込みで使う必要はないのではないかということで終わりました。組み合わせるLTC7000の回路基板と組み合わせて検討の結果、やはり割り込みでの制御は避けた方が良いのかも?という考えに至ったので、これについて少しばかり検証します。
今回はPORTB(GPIOB)の8ビットを全て割り込み用の入力-この何れかがLowになったとき(LTC7000がfaultを出力)-に対応するLTC7000のINPへの制御出力を停止させるというシーケンスになっています。相手が1回路なら悩むことはありませんが最大で8回路あり、どのようなタイミングでfaultが入るかは未知です。
1回路からの割り込み処理中(INTがLowになり、ATmega328PBのINT0を駆動中)に他の回路からLow(fault)が入ると、先に入った割り込みに対しINTCAP(あるいはGPIO)を読んでもINTが解除できません。(←そういう仕様です)1つめの処理後、INTCAPでINTを解除する前にINTFを読んで新たな割り込みが入っていたときには、あらためてそれに対する処理を行い・・・という処理を繰り返す作りにすれば良さそうですが(←未確認です)、未知の動作への検証が複雑で見落としが出てしまいそうなので、ここは安全のために割り込み処理は中止しポーリング(一定の時間間隔での監視)でのfault監視に変更することとしました。
過電流を検知した場合、LTC7000が出力のMOSFETを自動的にオフしてくれるのでfaultに対してCPU側の処理は急ぐ必要は無いのでタイマー割り込みを使ったタイマー変数を元に500ミリ秒から1秒程度の間隔でGPIOレジスタを読んで、LowになったビットがあればINPに対する出力を落とすという単純なプログラムに変更しました。マスターとなるPC側へは当コントローラから通信で伝えるか、PC側から定期的にfaultの発生を問い合わせるかという動作で管理することができます。
If Poll_cnt = 0 Then 'カウンタがゼロになったらGPIOB読み込み Chkint = 0 '制御オン有りフラグをクリア Gosub Spiread_gpiob 'faultになったチャンネルが0 If Gpiob_data <> &HFF Then 'Lowになっているビットがある For I = 0 To 7 'bit0からbit7までを調べて0なら該当する出力を停止 Cmp = Bits(0) 'Cmpのbit0に1をセット Shift Cmp , Left , I '0から7までビットをずらしていく Temp_byte = Gpiob_data And Cmp 'マスクして該当ビットのみ取り出し If Temp_byte = 0 Then 'ビットがオンしているならオフにする Set Fault.i 'faultフラグの該当するビットをセット Set Portc.2 'fault-lamp-on portがオンでなければfault-LEDは点灯させない Reset Port_data.i 'オンしているビット(LTC7000のINP)をクリア Chkint = 1 '制御オンなのでセット End If Next If Chkint = 1 Then 'faultを検知したチャンネルはオフにする Gosub Spiout_sub 'port_dataの書き込み End If End If Poll_cnt = 10 End If