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 |
|
|