PIC12F629 入門 NO.4

[Previous] [Next] [Index]
PIC12F629 を使った最も簡単な 3 チャンネルデコーダプログラム
 AVR でプログラミングしたデコーダプログラムを PIC12F629 でも組んでみることにした。赤外線受光素子と組み合わせるだけで立派な 3 チャンネル受信機になる。スピードコントローラとサーボをつなげばそのまま受信機として飛行機に搭載することも可能だ。

 送信機からのシリアルパルスをそれぞれのチャンネルに分離してそれぞれのポートに出力する。それにはシリアルパルスの先頭をきちんと判別するルーチンが必要になる。

 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 になったらギャップを検出したと判断するようにした。

3 チャンネルデコーダプログラム(テキスト形式)

 ではギャップの検出プログラムを見てみよう。

;-- ギャップ検出 ----------------
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 とのプログラムの違いを比較してみるのもおもしろい。


[Previous] [Next] [Index]
2003/09/16