第1回 LEDを点灯させよう

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

[Home] [目次] [次頁]


(1) LEDを点灯させる

PIC12F509は、マイクロチップ社の低価格で高機能なフラッシュメモリ・タイプの8ビットマイコンです。PIC12F509は1024ワードのプログラムメモリと41バイトのデータメモリをもっています。I/Oピンが6つ(うち1つは入力のみ)となっています。

PIC12F509のピン配置

PIC12F509は、マイクロチップ社の12ビット・コアのベースライン・シリーズに位置付けられています。PICの命令セットは、12ビット・コアで33個、14ビット・コアで35個、16ビット・コアで58個、エンハンスド16ビット・コアで77個の命令(インストラクション)があります。プログラムが分岐するなどのプログラム・カウンタを変更する場合をのぞいて、すべての命令は1サイクルで実行されます。1命令サイクルは4クロックサイクルですから、4MHzで動作させた場合、PIC12F509は、1秒間に命令を100万回実行できるというわけです。PIC12F509は4種類のクロックモードを選択することができます(最大4MHz)。
(1) INTRC(4MHzの内蔵クロック)
(2) EXTRC(外部RC発振)
(3) XT(水晶またはセラミック発振)
(4) LP(低消費電力・低周波数の水晶発振)


LEDを1つだけ点灯させる

手始めに、PICにLEDを1つだけ点灯させてみましょう。まず、そのための回路をブレッドボードを使って組みました。電源の+5Vは、006P型の9Vの積層乾電池を使い、3端子レギュレータで供給ししています。ジャンパ線を「U」字型に曲げて、簡易スイッチにしてあります。LEDは、PIC12F509の汎用入出力ピンであるGP0ピンにつなぎます。各入出力ピンが出力できる電流は最大で25mAですが、GPIOポート全体で一度に出力できる電流は最大75mAとなっていますので、LEDの電流制限抵抗は330Ωとしました。約10mAで1つのLEDを点灯させることにしたのですが、電池駆動なので、電池を長持ちさせるために1mA程度にしてもいいでしょうね(LEDの電流制限抵抗の適切な値を求めるには「オームの法則」にしたがって、R=V/I で求めます。V は、GP0ピンが出力する電圧5VからLEDの順電圧を引いた値、I はLEDに流す順電流ですが、どちらもLEDの定格をこえてはいけません。くわしくは、LEDメーカーのデータシートを参照してください)。LEDの電流制限抵抗を計算するプログラムDropper.exe

実験ボードの組み立て

プログラムを書く

さて、こんどはプログラムの作成です。
LEDのリード線は、アノードがわが電流制限抵抗をつうじてPIC12F509の7
番ピンに配置されているGP0ピンにつながっています。LEDのカソードがわは、GNDにつながっています。このGP0が High の状態、つまりPIC12F509の電源とおなじ +5Vになると、LEDに電流が流れて点灯するというわけです。
12F509_LED_ON_GP0.asm というファイル名でマイクロチップ社のMPASMアセンブラ用のプログラム・ソースファイルをつくりました。ソースファイルの保存場所は、パス名が62文字を超えるほど
長いと、MPASMがアセンブルするときにエラーになりますので、ドライブ名から浅い位置にある簡潔な名前のフォルダに保存したほうがよいでしょう。

さて、プログラムのソースコードの書き方ですが、マイクロチップ社のアセンブラ・MPASMの様式にしたがう必要があります(見やすいように大文字で書いています)。

LABEL   Mnemonic    Operand    ;Comment  のように書きます。
 ラベル     ニーモニック      オペランド      コメント

1行目のLISTや2行目の#INCLUDE など、赤色の部分はMPASMがソースファイルをアセンブルするときに必要な指示文(ディレクティブ)です。

LISTで使用するデバイスを選択します。
#INCLUDEでLISTで選択したデバイス用の標準ヘッダーファイルを指定しています。各デバイス用の標準ヘッダーファイルは、マイクロチップ社の統合開発環境「MPLAB-IDE」をインストールしたときにつくられる、「MPASM Suite」のフォルダの中に、「PXXXX.INC」というファイル名で用意されています。
__CONFIGは、デバイスのコンフィギュレーション・ビットを設定します。指示文には下線「_」が1つではなくて「__」と2つ書かないと、アセンブル時にエラーになります。
_MCLRE_OFFで外部リセットのかわりに12F509内部のパワーオン・リセット機能をつかうようにします。下線「_」は1つです。これでMCLRピンは、入力専用のGP3として割り当てられます。
_CP_OFFでコードプロテクトをしないようにします。コードプロテクト機能は、製品などでデバイスからプログラム・コードを盗用されたくない場合はONにしますが、趣味の電子工作では不要でしょう。なお、窓付き(JW)タイプのPICでは、初期の開発されたPICをのぞいて、コードプロテクトをいったんかけてしまうと、紫外線消去してもコードプロテクトは永久に解除されませんので、注意が必要です。
_WDT_OFF ウォッチドッグタイマは使用しないのでOFFにします(猫に番犬の代わりが務まるのであれば、ウォッチキャットタイマですね!)。
_IntRC_OSC PIC12F509内蔵のクロックを使うようにします。これで、今回、LEDを点灯させるためのGP0だけでなく、PIC12F509の8本のピンのうち、VDDとVSSをのぞいた、全部で6本のピンがGPIOとしてつかえるようになります(GP3は入力のみで出力はできません!)。
ORGは、プログラム・コードが実行される番地を指定します。ここで 0x000番地、つまり、プログラム・メモリの先頭番地を指定しています。リセット後つねにゼロ番地からプログラム・コードが実行されるのであれば、ORGで指示しなくても自動的にゼロ番地から実行されるようにアセンブルされます。

1

LIST

P = 12F509

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

2

#INCLUDE

<P12F509.INC>

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

3

__CONFIG

_MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

4

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

5

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

6

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

7

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

8

ORG

0x000

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

9

MOVWF

OSCCAL

' OSCCALレジスタを更新

10

MOVLW

0x08

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

11

TRIS

0x06

' f=6

12

MOVLW

0xDF

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

13

OPTION

' OPTIONレジスタに書き込む

14

MOVLW

0x01

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

15

GP0_ON

MOVWF

GPIO

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

16

GOTO

GP0_ON

' LED点灯状態を保持する

17

END

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

9行目の MOVWF や10行目の MOVLW などは、PICの命令(インストラクション)です。

PIC12F509はリセット時に、最初にリセットベクターであるプログラムメモリの最終番地0x3FF番地(PIC12F508の場合は、0x1FF番地)からプログラムを実行します。この番地には、MOVLW 命令につづけて内蔵クロックの補正値XXが MOVLW  XX (MOVe Literal to Working register XX 、文字XXを作業用レジスタファイルに移せ)というように書き込まれています。
この補正値は、マイクロチップ社で内蔵クロックの精度を高めるために工場出荷時にあらかじめ書き込まれているものです。バルク消去するとこの値も消えてしまいます(バックアップOSCCALは消去されませんが…)ので、注意が必要です。
PIC12F509が起動すると、最初に 
MOVLW 命令を実行してこの補正値をWレジスタに格納します。つづいて、プログラム・カウンターは、プログラムメモリの0x3FF番地から0x000番地に反転し、0x000番地からプログラムを実行します。

9行目から、プログラムメモリに書き込まれて実行されるユーザープログラムがはじまります。 MOVWF OSCCAL (MOVe Working register to File OSCillator CALibration register)は、Wレジスタに格納された内蔵クロックの補正値を、 OSCCAL レジスタに移せという意味です。寒冷地などで使用する場合、ユーザーが工場出荷時の補正値をつかわずに、自分で調節することもできますが、どちらを選択するのかはまったく自由です。

つぎに、ポートの初期設定をおこないます。
10行目の 
MOVLW  0x08 でWレジスタに0x08、つまり2進数で「001000」を格納して、GP3を入力に、他は出力に設定しています。
11行目の 
TRIS 0x06 (load TRIState port  0x06)で、Wレジスタに格納された「001000」を、ポートの入出力を制御するTRIS(トライステート・ポート)レジスタに書き込みます。
12行目と13行目では、GP2をTRISレジスタで出力に設定してあっても、そのままだと、リセット時には強制的にGP2がT0CKIの入力専用ピンになってしまいますので、面倒ですが、 
OPTION レジスタでタイマ0のクロックソースをPIC12F509の内部クロックに切り替え、GP2を再度出力に設定しています。

ポートの初期設定がおわりましたので、LEDをつないでいるGP0を「1」にしてやると、PICの電源から電流が抵抗を通じて流れて、LEDは点灯するはずです。
14行目の 
MOVLW  0x01 でWレジスタに0x01、つまり2進数で「000001」を格納して、それを MOVWF  GPIO で入出力ポートのレジスタのGPIOに書き込みます。この命令は、 MOVWF  0x06 と、GPIOのあるレジスタファイルの番地を書いても結果はおなじになります。
このLEDを点灯させる命令には 
GP0_ON というラベルをつけていますので、16行目の GOTO  GP0_ON 命令で再び15行目に戻り、LEDの点灯命令をなんどもくりかえすことになります。つまり、LEDは点灯しつづけるわけです。
17行目の 
END は、このソースプログラムはここで終了というアセンブラの指示文です。

9行目から16行目までが、プログラムメモリに書き込まれて実行されます。わずか8ワードしかない、かんたんなプログラムです。

ダウンロード
12F509_LED_ON_GP0.asm


LEDを5つ点灯させる

LEDを1つ点灯させることができましたので、こんどは、5つある入出力ピンにLEDをそれぞれつないで、点灯させてみることにしました。GP0のほかに、GP1、GP2、GP4、GP5にLEDを接続します。ピン番号のならびが反時計回りですので、ややこしいですね。

プログラムの変更

上記のプログラムの15行目と16行目をすこし変更するだけでLEDを5つ点灯させることができそうです。入出力ポートレジスタ GPIO は8ビットですが、上位2ビットはつねに「0」で、下位6ビットのみが使用されます。GP0につながったLEDを点灯させるには、GPIO レジスタに「000001」を書き込みました。5つのLEDを点灯させるには、「110111」を書き込んでやればいいわけですね。

14

MOVLW

0x37

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

15

GP0_ON

MOVWF

0x06

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

ダウンロード
12F509_LED_ON_GP0_GP5.asm

[Home] [目次] [次頁]


2005年2月20日作成