送信機からのシリアルパルスをそれぞれのチャンネルに分離してそれぞれのポートに出力する。それにはシリアルパルスの先頭をきちんと判別するルーチンが必要になる。
PIC Learning で何度も出てきたが、一般に送信機のシリアルパルスは 20msec から 24msec ほどの周期で繰り返されている。各チャンネルのとりうるパルス幅は 1msec から 2msec ほど。送信機によってチャンネル数に違いがあるが、すべてのパルス幅が最大幅になったとしてもチャンネル最後のパルスから次のシリアルパルスの先頭までは 3msec 以上のギャップがある。このギャップを検出できればシリアルパルスの先頭をきちんと見極められる。
PIC12F629 の 4MHz 内部発振回路を使って 3msec の時間をカウントするには、プログラムで 3000 ステップ必要になる。一方 8 ビットのカウンタでは 256 までしかカウントできない。 8 ビット 2 桁なら 65536 までカウントできる。ギャップの検出ループのステップ数にもよるが、 3msec のギャップをカウントするには 8 ビットのカウンタが 2 桁必要になる。今回は 2 桁のカウンタを使って新たにギャップを検出するプログラムを考えてみた。
今回のギャップ検出ループは 7 ステップになる。 1 桁目がオーバーフローするステップ数は 7 x 256 = 1792 となり、 1.792msec までカウントできる。 2 回オーバーフローすると 3.584msec カウントしたことになるので、2 桁目のカウンターが 2 になったらギャップを検出したと判断するようにした。
;-- ギャップ検出 ---------------- loop btfsc GPIO, 3 ;入力がゼロなら次をスキップ (1step/2steps) goto out_h ;入力が1ならout_hへ (2steps) movlw d'2' ;wレジスタに2をセット (1step) subwf gapcnt2, w ;w = gapcnt2 - w (1step) btfss STATUS, C ;STATUSレジスタのキャリビットが1なら次をスキップ goto lp1 ;gapcnt2 < 2 ならlp1へ call clr_cnt ;ギャップカウンタクリア goto output ;ギャップが検出されたのでoutputへ lp1 call clr_cnt ;ギャップカウンタクリア goto loop out_h incf gapcnt1, f ;gapcnt1をインクリメント (1step) btfss STATUS, Z ;桁上げが発生したら次をスキップして goto loop incf gapcnt2 ;gapcnt2をインクリメント goto loopギャップが検出された時点ですでにチャンネル 1 の立ち下がりパルスを検出したことになるので、次のステップでチャンネル 1 の GP0 を ON にする。あとは立ち下がりパルスを検出した都度、現在 ON になっているチャンネルを OFF にして次のチャンネルを ON にするという操作を必要チャンネル数だけ繰り返せばいい。
では出力プログラムを見てみよう。
;-- 出力 ------------------------ output ;-- ch1 -- o1 bsf GPIO, 0 ;GP0 ON (1step) btfss GPIO, 3 ;入力が1なら次をスキップ goto o1 o2 btfsc GPIO, 3 ;入力がゼロなら次をスキップ goto o2 bcf GPIO, 0 ;GP0 OFF (1step) ;-- ch2 -- o3 bsf GPIO, 1 ;GP1 ON btfss GPIO, 3 ;入力が1なら次をスキップ goto o3 o4 btfsc GPIO, 3 ;入力がゼロなら次をスキップ goto o4 bcf GPIO, 1 ;GP1 OFF ;-- ch3 -- o5 bsf GPIO, 2 ;GP2 ON btfss GPIO, 3 ;入力が1なら次をスキップ goto o5 o6 btfsc GPIO, 3 ;入力がゼロなら次をスキップ goto o6 bcf GPIO, 2 ;GP2 OFF立ち下がりパルスでポート出力を ON にし、途中立ち上がりパルスを確認したあと次の立ち下がりパルスで ON にしたポートを OFF にする。これで 1 チャンネル分の出力処理が完了する。この処理を必要なチャンネル数だけ繰り返す。
今回は 3 チャンネルのデコーダをプログラミングしたが、使用する送信機が 3 チャンネル以上でも、それ以降のパルスは、ギャップ検出ルーチンに戻してその中で消化している。 PIC12F629 ではあと GP4 と GP5 が余っているので、プログラム次第で 5 チャンネルまで簡単に追加できる。
AVR 超入門 NO.7 に ATtiny15L を使った同じデコーダプログラムを掲載している。また、入力と出力の関係をオシロで観測した波形も掲載している。 AVR とのプログラムの違いを比較してみるのもおもしろい。
2003/09/16