先に、バグの原因をレポートしたが、実際に、どのような状況で不具合が発生していたのか確認しておこうと思う。
つまりは、“CMCON=0b00000111”とすべきところを“CMCON=0x00000111”とするとPICはどのような挙動を示すのか。
CMCONレジスタは8ビットで構成されている。よって”0b00000111″であれば、それぞれのビットに値が設定されることとなる。それでは”0x00000111″だとどうなるか。
16進数だから、2進数に変換すると以下のようになる。(空欄は見やすくするため便宜的に入れてある)
“0b 0000 0000 0000 0000 0000 0001 0001 0001”
上位の24ビット分はレジスタサイズからあふれるので無視されるとして、下8桁(赤字部分)がレジスタに設定されることとなる。レジスタには、本来”0000 0111″と設定するところが”0001 0001″を設定してしまうこととなる。
レジスタのビットの意味は、図右上に示した。CMCONレジスタは、コンパレータの動作を設定するためのものであり、”0000 0111″は、コンパレータ機能は利用せず、コンパレータ機能に設定されているICのピンは、汎用入出力に利用するという設定だ。
しかし、”0001 0001″ではまったく違った意味になる。下3桁がコンパレータの動作モードを設定する部分で、”001″は図左上のように利用する設定となる。
つまりは、以下のようになっている。
GP0(ICの7番ピン):アナログ入力:コンパレータで比較する入力0
GP1(6番ピン):アナログ入力:コンパレータで比較する入力1
GP2(5番ピン):デジタル出力:入力の大小比較結果を出力
ここで、人感センサライトの回路図(図下)を見ると、以下のようになっている。
GP0:未使用
GP1:デジタル出力:照明のON/OFFを司るリレーの制御に利用
GP2:デジタル入力:人感センサの検知信号を読取ることに利用
GP1は、PIC内ではアナログ入力として利用するように設定されているのに、回路ではデジタル出力として利用されており、GP2は、デジタル出力として利用するように設定されているのに、回路ではデジタル入力として利用されている。これは、まずい。人感センサの検知状態をきちんと読むことができないばかりか、照明のON/OFFを制御する部分もきちんと動作することは困難なようだ。
こんな状態で、プログラム通りの正常にみえる動作を行う場合もあったのはなぜか。
PICでは、内部の回路の接続/切断を数多くの特殊レジスタで設定する。設定が矛盾を起した場合、本来行うべきではない複数の内部回路に同時に接続されると想定される。その結果、片方の接続が、もう片方の接続と干渉するような状態に陥る。
結果、運が良ければ、プログラムの通りに動作するが、運が悪ければ、想定外の挙動を示すことになる。想定外の挙動が、具体的にどういう場合にどういう事が起るかというのは、PICの内部構造が分らないと解明できない。データシートには、論理構成までは出ているが、物理構成は分らない。そこまで解明しようとすると、半導体の物性に関わることとなるので、素人には、ここまでの理解が限界か。
いずれにせよ、正常な動作が行えない状態に陥るであろう事までは、理解できた。と言うことで、今回の解析はここまでとする。