HOME > 技術談話 > PIC® microcontroller > LEDの制御
はじめに テーマ 回路図 部品の配置 フローチャート プログラム説明 実験の様子
LEDはLight Emitting Diodeの略で消費電力が少なく長寿命の発光素子です。自動車のテールランプや信号機だけでなく、家電製品のパイロットランプにも多く使われています。おそらく部屋を見渡すと数十個のLEDを見つけることができると思います。 LEDは電源と抵抗(電流制限用途)を接続するだけで簡単に点灯させることができます。消費電力が少ないと言うところがミソで、PICマイコンの大電流出力ポート(「大」といっても25mA程度)に直接接続して制御できます。 本項ではLEDをPICマイコンに接続して制御する小さなプログラムを作成します。 … 探せば星の数ほど見つけることのできるプログラムですが…。スイッチ入力をいきなり始めるよりは良いかと(汗 |
▲ |
(1)基本仕様 PICマイコンにLEDを3個接続し、1秒単位で順番に点灯します(LED0 > LED1 > LED2 > LED0 > LED1 > …) (2)ハードウェア PIC12F683(8pin)を3Vで動作させます。源発振は内蔵クロックを利用します(4MHz)。 (3)ファームウェア 1秒の基準はソフトウェアタイマ(delay)を利用し、LEDの点灯はスタティック制御です。 |
▲ |
ピン数が少ないPICマイコンです。外部クロックを使用せず、また負荷を直接接続できるのでシンプルです。 電源は3Vを利用します。外部電源を持ってない場合は乾電池2個で試すことができます。PICマイコンの仕様に依存するのですが、3Vで動作させることを目標としたために内蔵クロックの発振周波数は4MHzに制限されます。 LEDと接続する抵抗に200Ωを利用していますが、LEDの種類、輝度により調整が必要です。今回使用したLEDは200Ωの抵抗を接続すると約6mAの電流が流れます(少電流ですが眩しいです)。PIC12F683では1端子あたり25mAまで電流を流せるので、今回の場合は直結することができましたが、PICマイコンによっては1端子あたりの最大電流が小さい場合、あるいは全端子の合計許容電流が小さい場合があるので注意してください。 回路図にスイッチが記載されていますが…。後で使う予定ですのでLEDだけを試したい場合には不要です。 GP3/_MCLRは_MCLR(リセット端子)として利用しています。通常はプルアップ抵抗を必要とするケースが多いのですが、今回使用するPICマイコンでは_MCLR機能を利用する場合は内蔵プルアップ(物理的な抵抗素子では無い)が有効になるので、外付けのプルアップ抵抗を接続していません。 LEDに接続する電流制限抵抗値の求め方はこちら → LEDの接続 |
▲ |
ブレッドボードを利用した場合の部品の配置例です。黒線が内部接続、赤線はジャンパ線です。 ブレッドボードの構造についてはこちらを参考にして下さい → ブレッドボード LEDが3個実装されますが、10番の列がLED0、13番がLED1、16番がLED2になります。 スイッチを使わなければ右下の部分はそっくり不要になります。 今回の配線例では、利用した抵抗を基板実装用に再利用することを目的としたために、リードの曲げ方に制限がありました。抵抗のリードを長めに折れるのであれば赤線で示すジャンパ線の一部を省略することができます。 この配置例を実際に組み込んだ状態を 実験の様子(このページの下にあります) に載せます。 |
▲ |
関数mainは自動生成されるスタートアップルーチンから呼び出されます。 関数mainは割り込み禁止状態を維持したまま呼び出されます。今回は割り込み禁止を明示していますが、これは任意です。割り込みを使用していないので不要と言えば不要です。 必要最低限の初期設定を行っています。デバイスの初期設定状態で済む内容については設定していません。思想になるかもしれませんが、デバイスの初期設定状態を再度設定する場合もあります。 以下、無限ループです。待機とポート出力を繰り返します。 |
単純待機のサブルーチンです。待機完了まで終了しません。 関数方式なのでオーバーヘッドがありますが、今回は未調整です。 __delay_ms を利用して待機しますが、単独で1秒待機を行うことができないので、10msの待機を100回実施することで1秒待機を実現しています。 パソコンの性能によりシミュレーション時間を要するので、Debugモード時は __delay_us、Releaseモードは __delay_ms を使用するよう、マクロで切り替えています。 |
当初はLEDを個別制御する方式でサンプルプログラムを作りましたが、今後紹介するタイマを利用するサンプルプログラムでも制御を流用できるよう、テーブルから表示データを取得する関数方式に変更しました。 テーブル要素は3個あり関数を呼び出される度に読み出したデータをバックアップ用の変数にセットし、注目位置を切り替えています。 バックアップ用変数は共用体、かつ、ビットで割り付けしています。宣言は面倒ですが、ビット位置の管理はコンパイラに任せることができます。 |
▲ |
(1)プログラム本体
サンプルプログラムを公開します … Test101_LED003.zip 2009.01.09 変更 HI-TECH C v9.70 で作成されたプログラムを v9.81 以降のコンパイラで再コンパイルする際の注意点 → 開発環境による修正 2011/03/09 理想を言えばハードウェア依存部を独立させたいのですが…。今回はサンプルなのでファイル1つだけとします。 プログラムには特別な記述はありません。コメントを見るだけでも大まかに理解できると思いますが、気になりそうな箇所だけをピックアップして補足説明します。 |
(2)インクルードファイル
今回のサンプルプログラムでは pic.h をインクルードします。この pic.h がプロジェクト設定で指定するPICマイコン毎の宣言を取り込む様になっています。 コンパイラのサンプル、各種ホームページに記載されているサンプルプログラムを見ると htc.h をインクルードしているプログラムがあります。実を言うと、htc.h は pic.h を参照し pic.h は htc.h を参照しています。お互いが相手の情報を自身に取り込もうとしている様です。相互参照になりますが二重定義に対する保護が施されているので、どちらを指定しても問題無いと思います。私の場合は見た目のわかりやすさ、対象を明示する意味で pic.h を使用しています。 pic.h はコンパイラをインストールしたフォルダに格納されています。標準的なインストールであれば以下のフォルダに格納されます。フォルダ名の中の「9.70」はコンパイラのバージョンにより異なる数字になります。 C:\Program Files\HI-TECH Software\PICC\9.70\include |
(3)レジスタへのアクセス
PICマイコンのレジスタアクセスは専用シンボルを利用します。PIC12F683の場合は以下のファイルにレジスタ名が宣言されています。フォルダ名の中の「9.70」はコンパイラのバージョンにより異なる数字になります。 C:\Program Files\HI-TECH Software\PICC\9.70\include\pic12f683.h 宣言されているレジスタ名はデータシートに記載されているレジスタと(ほぼ)同じです。このシンボルに対して代入や引用を行うことで必須のバンク切り替えを含めてコンパイラが自動的にアセンブラ命令を生成します。 サンプルの中では利用していませんが、LED2(GPIO、Bit2)を点灯するのであれば、 GPIO2 = 1; と記述します。バンク切り替え操作が不要なので、これだけでもC言語を利用するメリットがあると思います。 |
(4)ハードウェア上の都合:源発振の選択
PIC12F683は8MHzの内蔵クロックを利用できますが、今回の実験では4MHzで動作させます。 |
|
データシートの「Electrical Specification」の冒頭にある「電源電圧と周波数の関係グラフ」に注意してください。 今回の実験では電源電圧を3V、乾電池2個を想定しています。3Vが安定供給されるのであれば10MHzまで動作可能ですが、3Vを少しでも下回った場合は4MHzが上限になってしまいます。乾電池は使用することで徐々に電圧が下がってくるので発振周波数の選択肢としては8MHzではなく4MHzが妥当です。 |
|
電源電圧が2Vを下回った場合…。個人で利用する分には「動かない=電池交換」で良いと思いますが、ビジネス用途の場合は誤動作しない工夫が必要です。低電圧をアラーム表示する機能、低電圧でプログラムを停止する機能等が必要になると思います。 内蔵クロックを使用する場合は CONFIG で指定すると共に OSCCON レジスタに動作周波数をセットします。今回の場合は OSCCON の初期値が4MHzを選択している状態なので CONFIG で内蔵クロックを指定するだけで済みます。 |
(5)ハードウェアの都合:入力ポートのプルアップ
一般的に入力ポートはオープンで使用しない事が推奨されます。そのためスイッチ入力はプルアップし、スイッチオンでGND接続の方式が多く使われます。 左図が基本形態になりますが、スイッチの状態に応じて入力端子は H/L の何れかの状態になります。 前述の回路図ではプルアップ用の抵抗が描かれていませんが、PIC12F683が内蔵するプルアップ(物理的な抵抗素子では無い)を利用することで代用しています。 |
|
データーシートにも記述されていますが、内部プルアップ(物理的な抵抗素子では無い)用の抵抗(相当)は電流値から判断すると100K~12.5K(Typ20K)と幅があります。個人で利用する分には問題ないと思いますが、ビジネス用途の場合は定数のしっかりした抵抗素子を外付けした方が良いかと(TTL/CMOS云々の話はありますが…)。 PIC12F683に限りませんが内蔵プルアップはデバイスリセット直後は未接続になっており、プログラム起動後、直ちにプルアップ接続を行います。ですが入力ポートがオープンになった状態が短時間ですが存在します。一昔前に比べればマイコン側の耐性は強くなっていますが、ビジネス用途等で気になる場合は外付けプルアップ抵抗の利用を勧めます。 |
(6)出力ポートの操作
今回のサンプルでは出力ポートレジスタの操作にビット操作命令を使用していません。 PIC12F683では出力ポートをビット操作した場合、操作対象以外のビットに関してReadModifyWriteを行います。この時のRead対象はデバイスの端子の状態です。例えば、任意の端子に対して H を出力済みでも別のビットを操作したタイミングで端子の状態がL に変化するという現象が発生します。 今回のサンプルでは問題は有りませんでしたが…。現象が発生する可能性があるのならば対策は必須です。 サンプルプログラムでは「問題回避」と言う意味で出力データを変数上で編集し、出力ポートに対してバイト書き換えを行っています。バイト書き換えは他のビットも含めて総てのビットを書き換えるので上述の問題は発生しません。 未対策でも現象が発生しない事例は多々ありますが、出力ポートの構成がオープンドレインの場合は対策は必須です。特にIIC通信をソフトウェアで実現する場合は現象が発生します。 余談ですが、入力ポートにすべきところを出力ポートにしてしまった場合でも、端子の状態が読めてしまいます。見た目正常風ですが、入力対象の状態によってはショートしてマイコンを壊す恐れがあります。前述のスイッチであれば出力Lの場合は動作してしまいますが、出力Hの場合はスイッチオンでショートします。そう考えると保護用の抵抗を端子に対して直列に接続した方が安全と言えば安全です。 2009.01.09追記 |
(7)CONFIG
CONFIGの指定によりPIC12F683の基本動作環境を指定します。詳細についてはデータシートの「Special Features of
the CPU」の項を参照願います。ここでの指定には初期値が無く、必ず何かしらの値を設定する必要があります。 設定項目とビット位置に関してはデータシートに詳細が記述されていますが、C言語でこれを指定する場合はPICマイコン毎に用意されたヘッダファイルに宣言されているシンボルを利用すると便利です。PIC12F683の場合は以下のファイルにシンボルが宣言されています。フォルダ名の中の「9.70」はコンパイラのバージョンにより異なる数字になります。 C:\Program Files\HI-TECH Software\PICC\9.70\include\pic12f683.h このファイルの一番下に記述があります。 シンボルは対象ビットを「0」 で指定しているので、各シンボルを論理積することでCONFIGで必要なビット列を作成することができます。 設定で悩みそうな箇所だけピックアップしますが、今回のサンプルでは内部クロックだけを使用しているのでFCMEM(フェールセーフクロックモニタ)、IESO(クロックスイッチオーバー)は共に無効で構いません。 |
(8)入出力ポートの設定 2009.01.09追記
PICマイコンに限らずコントローラタイプのマイコンは沢山の機能を内蔵していますが、いかんせん端子の数が足りません。そこで1つの端子に複数の機能を割りつけ、プログラムで選択できるようになっています。時には必要な機能が1つの端子に集約されてしまうこともあり「実現不可、他のマイコンを選択、もしくは回路追加」という事態も発生します。 PICマイコンでは機能に対する端子割り当てが固定です。今回のサンプルプログラムではPIC12F683を利用しましたが、ピン数が少ないこともあり1つの端子に6種類ぐらいの機能が割りつけられています。 |
ピン番号 | 機能 | ピン番号 | 機能 | ||
1 | VDD | 8 | VSS | ||
2 | GP5/T1CKI/OSC1/CLKIN | 7 | GP0/AN0/CIN+/ICSPDAT/ULPWU | ||
3 | GP4/AN3/T1G/OSC2/CLKOUT | 6 | GP1/AN1/CIN-/VREF/ICSPCLK | ||
4 | GP3/MCLR/VPP | 5 | GP2/AN2/T0CKI/INT/COUT/CCP1 |
前述のCONFIG指定により端子の基本的な割り付けは決まりますが、幾つかの機能はマイコンの持つ初期状態に依存します。上図の中で赤色の箇所は今回のサンプルプログラムにおけるCONFIG指定後の割り付け状態です。 デジタル入出力を行う場合には初期値で有効になる機能の解除が必要です。データシートに設定サンプルが載っていますが、基本的には出力用のラッチデータをセットした後で入出力ポートへの切り替えを行います。 |
▲ |
▲ |