PIC16F84電子遊戯(16)
最終更新日:2001年3月31日
ミラクルライト(1ページ)へ (2ページ) (3ページ)へ (4ページ)へ

ミラクルライトのLED制御
各LEDは約200usecの割り込みを基準クロックにしてON/OFFすることによって、輝度を変化させます。
各LEDはそれぞれ3つのパターンで点灯させます。
200usecの割り込みを何回カウントするかで、時間を決定します。
モード LED全灯 LED半灯 LED消灯
点灯時間 70h 20h 0h
消灯時間 0h 50h 70h
(3パターンの割り込みカウント設定値)
モード LED全灯 LED半灯 LED消灯
点灯時間 21.5msec 6.1msec 0sec
消灯時間 0msec 15.4msec 21.5msec
(3パターンの設定時間)
全灯、消灯の他に半灯を用意しました。
半灯のデューティは1/3程度ですが、これくらいのほうが全灯との区別がつきます。
まずLEDごとにON時間とOFF時間が書き込まれているRAMを用意します。
消灯から点灯に変化したときはON時間のRAMよりデータを読み出し、ワークRAMにデータを設定します。点灯から消灯に変化したときはOFF時間のRAMよりデータを読み出しワークRAMにデータを設定します。
red_on 赤色LEDON時間
red_off 赤色LEDOFF時間
green_on 緑色LEDON時間
green_off 緑色LEDOFF時間
blue_on 青色LEDON時間
blue_off 青色LEDOFF時間
(LED設定時間RAM)
red_count green_count blue_count
赤色LEDワーク用 緑色LEDワーク用 青色LEDワーク用
(時間ワークRAM)
割り込みごとにこのワークRAMのデータをデクリメントして、「0」になれば点灯状態を変更します。このとき次の状態の時間を読み出しワークRAMにセットします。
これを順次繰り返して、LEDをコントロールします。
特別処理として、次の状態の時間が「0」の時は、さらにその次の時間をセットします。
注意することはON時間、OFF時間の設定を両方とも「0」にすると確実に無限ループに入ることです。(まあ両方ともそんな数値を設定することはないでしょう。)
以上の説明について赤色LEDのみのソースを掲載します。
200usecの割り込み処理の部分
		;----------------------- RED
red_leds	decfsz	red_count,1
		goto	green_leds
		btfsc	led_data,0	;RED OFF?
		goto	red_leds_2
red_leds_3	bsf	led_data,0	;RED ON
		movf	red_on,0
		movwf	red_count
		movf	red_count,0
		btfsc	STATUS,2
		goto	red_leds_2
		goto	green_leds
red_leds_2	bcf	led_data,0	;RED OFF
		movf	red_off,0
		movwf	red_count
		movf	red_count,0
		btfsc	STATUS,2
		goto	red_leds_3
green_leds		
1)ワークRAM(red_count)をデクリメントして、「0」でないときは次のLED処理(green_leds)へ飛ぶ。
2)「0」のときは今が消灯か調べる。消灯でないときは消灯処理(red_leds_2)へ飛ぶ。
3)点灯処理:LEDを点灯にする。ON時間RAM(red_on)からデータを読み出し、ワークRAM(red_count)にセットする。
4)ワークRAM(red_count)からデータを読み出し「0」でないときは次のLED処理(green_leds)へ飛ぶ。
5)「0」のときは消灯処理(red_leds_2)へ飛ぶ。
6)消灯処理:LEDを消灯にする。OFF時間RAM(red_off)からデータを読み出し、ワークRAM(red_count)にセットする。
7)ワークRAM(red_count)からデータを読み出し「0」でないときは次のLED処理(green_leds)へ飛ぶ。
8)「0」の時は点灯処理(red_leds_3)へ飛ぶ。
これがひとつのLEDに対するコントロール処理です。
ON時間とOFF時間をこのルーチンの外側からコントロールすれば簡単に輝度を変化することが出来ます。
LEDの点灯・点滅は一度RAMに設定してから、別ルーチンで出力ポートに設定しています。従ってこのルーチンではLEDに対するRAMを設定しているだけです。
各LEDに対するRAMは次の通りです。
led_data
7 6 5 4 3 2 1 0
-- -- -- -- -- BLUE LED GREEN LED RED LED
(LED出力イメージRAM)
ミラクルライトの点灯仕様
ミラクルライトはふたつの点灯モードを持ちます。
1)マニュアル色切り換えモード(マニュアルモード)
2)オート色切り換えモード(オートモード)
初期設定はマニュアルモードに設定しています。
マニュアルとオートの切り換えには次のRAMを使用します。
led_mode
7 6 5 4 3 2 1 0
-- -- -- -- -- -- -- manual/auto select
led_mode.0 が「0」=マニュアルモード、「1」=オートモードとします。
ミラクルライトのSW1の操作仕様
SW1には次のふたつの機能を割り当てます。
1)マニュアルモード時にはスイッチを押すごとに色を16色変化させます。
2)オートモード時には色を切り換える時間を4種類切り換えます。
SW1のキースキャン
sw1_key	btfsc   PORTA,3
		goto	sw2_key
		call	wait_1
		btfsc	PORTA,3
		goto	sw2_key
					;sw1 on
		btfsc	led_mode,0
		call	auto_time
		bcf	INTCON,GIE
		call	led_change	
		call	led_set
		bsf	INTCON,GIE
		
sw1_end		movf	led_data,0
		movwf	PORTB
		btfss	PORTA,3
		goto	sw1_end
;-------------------------------------
sw2_key
1)SW1の入力ポートが「0」でないときは次のSW処理(sw2_key)へ飛びます。
2)「0」のときは一定時間待ちます。(チャタリング防止のため)
3)再びSW1の入力ポートを調べて「0」でないときは次のSW処理(sw2_key)へ飛びます。
4)マニュアルモードでないときは時間変更ルーチン(auto_time)処理をします。
5)割り込みを禁止して色変更ルーチン(led_change/led_set)処理をします。処理後は割り込みを許可します。
6)LEDの表示データを出力ポートに出力します。
7)SW1が離されるまで待ちます。
時間変更ルーチン(auto_time)、色変更ルーチン(led_change/led_set)は後で詳しく説明します。
ミラクルライトのSW2の操作仕様
SW2はマニュアルモードとオートモードの切り換えに使用します。
SW2のキースキャン
sw2_key	 btfsc   PORTA,4
		goto	next_key
		call	wait_1
		btfsc	PORTA,4
		goto	next_key
					;sw2 on
		btfsc	led_mode,0
		goto	sw2_key2
		bsf	led_mode,0	;LED mode=auto
		call	auto_clear
		goto	sw2_key3
sw2_key2	bcf	led_mode,0	;LED mode=manual
sw2_key3	btfss	PORTA,4
		goto	sw2_key3
;--------------------------------------
next_key
1)SW2の入力ポートが「0」でないときは次のSW処理(next_key)へ飛びます。
2)「0」の時は一定時間待ちます。(チャタリング防止のため)
3)再びSW2の入力ポートを調べて「0」でないときは次のSW処理(next_key)へ飛びます。
4)モードを変更します。オートモードにしたときは時間クリアルーチン(auto_clear)処理をします。
5)SW2が離されるまで待ちます。
時間クリアルーチン(auto_clear)は後で詳しく説明します。
ミラクルライトの色変更処理
ミラクルライトの色は一応16色用意しました。
16色を切り換えるには4bit分のカウンタがあれば16通りに切り換えることが可能ですが、PICでは任意の数値の比較が苦手なので、ちょっと贅沢ですが、2バイト分のRAMを用意してそのうちの9bit分を使用して16通りの切り換えを行います。
PICはビット判断が得意ですので、それを使用します。
まず1バイト目の8bitを使用してビットの立っている位置で8通りを切り換えます。
次に2バイト目の下位1bitを使用して2通りを切り換えます。
合計8x2=16通りとなります。
key_count
7 6 5 4 3 2 1 0
色(8) 色(7) 色(6) 色(5) 色(4) 色(3) 色(2) 色(1)
(色切り換えRAM)
key_sub
7 6 5 4 3 2 1 0
-- -- -- -- -- -- -- 色切り換え
(色切り換えサブRAM)
色変更ルーチン
led_change	movf    key_count,0
		btfsc	STATUS,2
		goto	led_change1
		btfss	key_count,7
		goto	led_change2
		incf	key_sub,1
led_change1	movlw	01h
		movwf	key_count
		return
led_change2	rlf	key_count,1
		bcf	key_count,0	
		return
1)色切り換えRAM(key_count)が「0」のときは「1」=色(1)指定にして戻ります。
2)「0」でないときは7bit目が「1」か調べて、そのときは色切り換えサブRAM(key_sub)をインクリメントします。(本当はkey_subの0bit目を反転すれば良いのだが、簡単に処理するためにインクリメントしている。)
その後色切り換えRAM(key_count)を「1」=色(1)指定にして戻ります。
3)7bit目が「1」でないときは色切り換えRAM(key_count)を左回転します。このとき0bit目には「0」を入れます。(そうしないとキャリーフラグの内容が0bit目に入ってしまうため。)
これで16色の切り換えが出来ることになります。
もっと沢山の色を切り換えることも出来ますが、人間の目にはそれ以上の色の種類を区別出来ないようです。16色が妥当なところではないでしょうか。
まだまだ説明したいところはありますが、このページはこの辺で終了します。
この続きは次ページへ、よろしくお願いいたします。
この続きは(3ページ)へ

不明点などあればメールお願いいたします。nonchansoft@nifty.com