第1回 LEDを点灯させよう

このページは、わたしの備忘録として作成しました。

[Home] [目次] [前頁] [次頁]


(2) LEDを点滅させる

LEDを点灯させることができましたので、つぎはLEDをぴかぴかと点滅させてみたいとおもいます。

LEDを点滅させるには、LEDをつけたり消したりすればいいわけですね。では、前回のプログラムの16行目以降をつぎのように変更して、LEDを消してまたLEDを点灯させるようにしてみましょう。

16

GP0_OFF

MOVLW

0x00

; Wにb'000000'を格納して、それを

17

MOVWF

0x06

; GPIOレジスタ(0x06番地)に書き込んで消灯させる

18

GOTO

GP0_ON

; LEDをふたたび点灯させる

18

END

; プログラムはここで終了

ダウンロード
12F509_LED_BLINK_GP0_1.asm

でも、これだと、LEDが点滅する間隔が数マイクロ秒しかないので、人間の目にはLEDがずっと点灯したままのようにみえます。家庭で照明につかわれているる蛍光灯も、高速で点滅していますが、人間の目にはずっと点灯しているようにみえます。映画やアニメ、そしてパソコンの画面もこの人間の網膜の残像を利用したものですね。LEDが点滅していることが人間の目にもわかるようにするには、LEDが点灯している時間と消灯している時間をおおくとる必要がありそうです。

では、LEDが人間の目でみて点滅していると感じるようにするためには、点灯と消灯の時間をどれぐらいに設定すればいいのでしょうか。LEDの色や明るさ、周囲の明るさ、個人差などがありますので、厳密ではありませんが、実験ボードで使用している3ミリ径の赤色LED(800mcd)が光るのを自分の目でみて確認してみました。点灯と消灯の時間が1ミリ秒だと、LEDは点灯したままでした。10ミリ秒だと、まだLEDは点灯したままでした。15ミリ秒前後だと、LEDがちらつきだしたのがわかりました。20ミリ秒にすると、LEDが点滅していると感じられるようになりましたが、点滅が速すぎて、いらいらしてきます。それで、今回は200ミリ秒の間隔でLEDを点滅させてみることにしました。


遅延させる方法

PICで遅延をつくる方法は、PICに関する解説書やおおくのウェブサイトでとりあげられていますが、なかなか複雑で、理解しにくいものです。遅延のテクニックについては、マイクロチップ社の『Tips ‘n Tricks』で簡潔に紹介されています(『Tips ‘n Tricks』の最新版は、マイクロチップ社のサイトで検索して探してください)。


    NOP        ; NOP(No OPeration)は、何もしない命令
    
NOP        ; NOP2個で2命令サイクル


    GOTO    $+1 ; 1命令で2サイクル。$は現在のプログラムカウンタの値。


    CALL    Rtrn ; 1命令で4サイクル。
     -----------------------------

Rtrn RETURN


これらのほかに、DECFSZDECrement File, Skip if Zero) や INCFSZINCrement File, Skip if Zero)などの命令を組み合わせて遅延時間をつくっていきます。1命令につきメモリロケーションを1つ使いますので、NOP だけで長い遅延時間をつくると、メモリサイズの小さいPIC12F509ではすぐにいっぱいになってしまいます。ですから、NOPと分岐命令のCALLGOTODECFSZINCFSZ(今回は使用しません) を使ったサブルーチンをつくって遅延させます。内側のループカウンタがゼロになったら、GOTO命令はスキップされて次の番地の命令、すなわち外側のループカウンタが実行されます。

下記は、ミリ秒単位で遅延時間をつくるサブルーチンです。数学の苦手な私は、このルーチンをつくるのになんと2週間もかかってしまいました。しかし、苦労しただけあって、正確に1000命令サイクルの遅延をメインルーチンの変数 i で指定した回数だけ実行します(注:このルーチンをよびだすための命令などが数サイクルくわわります)。変数のレジスタは8ビットですので、1〜256の値を指定します。0を指定すると、i は256になります。257以上を指定すると、9ビット目は無視され、下位8ビットが有効になりますので、i は1になります。4MHzでPICを動かした場合は、このサブルーチンを1回よびだすことで1ミリ秒から256ミリ秒まで遅延させることができるというわけです。このサブルーチンは、インクルードファイルにして、他のプログラムでも流用できるようにしました。プログラム本体から i に200をセットし、LEDが点灯してからの保持時間、消灯してからの保持時間として DELAYms をよびだせば、0.2秒間隔でLEDは点滅するようになるはずです。なお、12ビットコアのPICの命令セットには RETURN はありませんので、RETLW 0 で代用します(RETURN と記述しても、MPASM は自動的に RETLW 0 に置き換えてくれます)。

delayms.inc

1

DELAYms:

; i x1000命令サイクル、i はメインルーチンで指定

2

CLRW

; W をクリアする

3

ADDWF

i,W

; ループカウンタ j の値を i にする

4

MOVWF

j

5

DELAY1k:

; 1000命令サイクルの遅延ループ

6

MOVLW

0xF9

; ループカウンタ k に249(0xF9)をセットする

7

MOVWF

k

8

LOOP1k

9

NOP

10

DECFSZ

k,f

11

GOTO

LOOP1k

; 2+4x249-1

12

DECFSZ

j,f

13

GOTO

DELAY1k

; 3xj+997xj=1,000xj

14

RETLW

0

; RETURNの代用

GP0につないだLEDを0.2秒間隔で点滅させるプログラムの本体です。

12F509_LED_BLINK_GP0_2.asm

1

LIST

P = 12F509

; プロセッサの種類を指定

2

#INCLUDE

<P12F509.INC>

; プロセッサのインクルードファイルを指定

3

__CONFIG

0x0A

; このように記述することもできます

4

; 外部リセットを使用しない

5

; コードプロテクトしない

6

; ウォッチドッグタイマを使用しない

7

; 内蔵クロックを使用する

8

i

EQU

0x07

; ループカウンタの変数の定義

9

j

EQU

0x08

; ループカウンタの変数の定義

10

k

EQU

0x09

; ループカウンタの変数の定義

11

ORG

0x000

; プログラム実行開始番地

12

MOVWF

OSCCAL

; OSCCALレジスタを更新

13

MOVLW

0x08

; GP3を入力ポート、他は出力ポートに設定

14

TRIS

0x06

; f=6

15

MOVLW

0xDF

; T0CSはゼロ、GP2を出力ポートに

16

OPTION

; OPTIONレジスタに書き込む

17

MOVLW

0xC8

; 200ミリ秒の遅延時間を設定

18

MOVWF

i

; カウンタの初期値は200(0xC8)

19

GP0_ON

MOVLW

0x01

; Wにb'000001'を格納して、それを

20

MOVWF

GPIO

; GPIOレジスタ(0x06番地)に書き込む

21

CALL

DELAYms

; LED点灯状態を200ミリ秒保持する

22

GP0_OFF

MOVLW

0x00

; Wにb'000000'を格納して、それを

23

MOVWF

GPIO

; GPIOレジスタ(0x06番地)に書き込む

24

CALL

DELAYms

; LED消灯状態を200ミリ秒保持する

25

GOTO

GP0_ON

; これを電源が切られるまでくりかえす

26

INCLUDE

delayms.inc

; 遅延ルーチンのインクルードファイルを指定

27

END

; プログラムはここで終了

ダウンロード
12F509_LED_BLINK_GP0_2.asm
delayms.inc

このプログラムを実行させてみると、LEDが期待通りの間隔で点滅してくれました。なお、i の値を10〜20の間で変化させると、このページのはじめに網膜の残像について紹介したように、何ミリ秒間隔だとLEDの点滅が目で見てわかるようになるのか、ためすことができます(ひょっとすると、1ミリ秒でもわかる人がいるかも……。注:LEDの光を長時間みつめてはいけません。目を痛めます)。

LEDの点滅

応用

おさらいをかねて、『ナイトライダー』の「ナイト2000」についているフラッシャーもどきをつくりました。
GP0、GP1、GP2、GP4、GP5にLEDをつなぎ、そのLEDを一列に配置して、順番に点灯、消灯させていきます。一度にひとつのLEDしか点灯しませんので、各LEDのカソードがわをたばねて、そこにLEDの電流制限抵抗を1本つけるだけでだいじょうぶです。

「ナイト2000」もどき

ダウンロード
12F509_LED_BLINK_GP0_2.asm
delayms.inc

PIC10F206を使った「ナイト2000」もどきもつくってみました。ここです(2005年7月3日)

[Home] [目次] [前頁] [次頁]


2005年7月3日更新

2005年2月20日作成