この記事でわかること
・4桁7セグメントLEDの回路構成
・ダイナミック点灯制御プログラム
・7セグLEDダイナミック点灯時の動作波形
PICマイコンによる4桁7セグメントLED回路と
ダイナミック点灯制御を行うプログラムについて解説します。
本記事で使用する新居浜高専PICマイコン学習キットについては下記記事で解説しています。
キットの回路図やプログラムはキットを販売している秋月電子のHPからダウンロードできます。
秋月電子 新居浜高専PICマイコン学習キットVer.3 ACアダプタ付
また、参考書も販売されています。
※本記事はPICマイコン学習方法の一例を紹介するものであり、
ここで紹介するキットやソフトの動作を保証するものではありません。
キット等の購入については自己責任でお願いします。
(不明点等の質問にはお答えできません)
<本ソフトの利用環境と設定について>
本記事におけるMPLABの開発環境は以下の通りです。
・MPLAB X IDE v.15
・XC8 v2.46
・Device Family Pack PIC16F1xxxx_DFP(1.24.387)
※ダウンロードしたプロジェクトファイル(NNCTkit_v3.X)は、
そのままビルドするとエラーになるため、以下の変更を実施しました。
・helpstr.h 9行目
変更前:const __section(“title”) unsigned char title[224]={
変更後:const __section(“help_title“) unsigned char help_title[224]={
セクション名がtitleだとエラーになるので、別の名前にします。
ここではhelp_titleにしましたが、何でも良いです。
この時、配列名はtitleのままでも問題ありませんが、
他のデータ同様、配列名をセクション名と同じにする場合は、
この配列を使用しているソースファイルの方も直します。
・monitor.c 2093行目
変更前:TX1REG = title[i];
変更後:TX1REG = help_title[i];
MPLABの使い方については下記で解説しています。
4桁7セグメントLED回路
キットの回路は下図のような構成となっており、
7セグメントLEDは、アノードコモン型が使用されています。(以下、7セグLEDと記載)
これは、文字を構成する7つのセグメント(発光ダイオード)の内部接続が、
アノード(陽極)側が共通(COM)になっている構成のものです。
(実際のセグメント数は少数点を表すDP(デシマル・ポイント)も含めて8つです)
また、カソード(陰極)側を共通にしたカソードコモン型もあり、
各タイプによって、LEDの駆動回路は異なります。
アノードコモンの場合、マイコンの出力がLレベルの時に点灯し、
カソードコモンでは逆に、Hレベル時に点灯します。
Hレベル出力で点灯するカソードコモンの方が感覚的に分かりやすいですが、
一般的なマイコンではHレベル時にマイコンから流れ出す電流(ソース電流)よりも、
Lレベル時にマイコンに流れ込む電流(シンク電流)の方が大きいため、
アノードコモンがよく利用されます。
※PIC16F18857のデータシートを見ても、H/Lレベル出力仕様(VCC=3V時)において、
ソース電流IOH=6mAの時、Hレベル出力電圧VOH=2.3V以上、
シンク電流IOL=10mAの時、Lレベル出力電圧VOL=0.6V以下
となっており、シンク電流の方が大きいです。
ダイナミック点灯制御
7セグLED内の8個のセグメントを点灯させるには、
マイコンの出力が8本必要なので、4桁表示となると、
8本 × 4桁=32本と多くなってしまいます。
このため、各セグメントへの出力を各桁共通にし、
各桁への電源供給を切り替えることで、どの7セグを点灯させるか指定します。
この方法なら、出力信号は8本+4桁=12本で済みます。
この電源供給のON/OFFをPNPトランジスタ(TR6~9)で行っています。
ここで、一般的なNPN型にしていないのは、回路構成上、エミッタ接地にできず、
トランジスタの制御がやりにくいからです。
NPNにした場合、GNDレベルから見たベース電圧はエミッタ電圧を加えた形になるので、
7セグLEDの順方向電圧や、電流制限抵抗間の電圧が加算され、高くなります。
そのため、マイコンのHレベル出力電圧とベース電圧との電位差が小さくなる分、
ベース電流が小さくなり、Hレベル出力電圧の僅かな低下でも、
トランジスタを十分ONすることができなくなる場合があります。
PNPの場合はエミッタをVcc接続するので、Vccレベルから見たベース電圧と、
マイコンのLレベル出力電圧の差を基にベース電流が決まるので、
LEDの順方向電圧や電流制限抵抗の影響を受けず、十分なベース電流を流せます。
ちなみに、カソードコモンの場合はエミッタ接地ができるので、NPNを使います。
以上より、PNPを使用することにより、出力Hでオフ、出力Lでオンするので、
各セグメントの点灯制御と同様に、Lレベルで動作する負論理動作となります。
この回路では、各桁で異なる値を同時に点灯させることはできませんが、
各桁のみの点灯を高速で切り替えることで、人の目には同時点灯に見えます。
これをダイナミック点灯制御と呼びます。
点灯サイクルは、全ての桁を1msec~10msecで1周させるのが一般的で、
この後、説明する制御ソフトでは、各桁を400~500us毎に切り替えて、
1サイクル1.7ms程度で動作させています。
デコーダの動作
トランジスタ(TR6~9)へのベース信号はIC2の74LS138(※1)から出力しています。
このICは3 to 8デコーダで、3本の入力信号の組み合わせから、
8本の出力信号のうち、1つだけをLレベル出力します。
このキットでは7セグLED以外に、サイコロ目LEDなど、3種類のLEDが搭載されており、
これらについても、ポートC出力(RC0~7)を共通にすることで、
限られたマイコンの出力点数で制御できるようにしています。
このデコーダによって、マイコンからは3本の出力(RA3~5)で、
7種類のLEDどれを点灯させるか指定しています。
※1:一般的なロジック回路では、HCシリーズ等のCMOS ICを使う方が、低価格で低消費電力ですが、
ここでは出力電流を多く流したいため、TTL ICであるLSシリーズを使用しています。
ロジックICの選び方については下記記事で解説しています。
回路定数の選定
まず、トランジスタに流れるコレクタ電流ICを求めます。
7セグLEDのデータシートより、各セグメントの順方向電圧VF=1.8V、
PICマイコンのLレベル出力電圧VOLは0.6V以下なので、
トランジスタON時のコレクタ・エミッタ間電圧VCEを仮にゼロとすると、
各セグメントに流れる電流は、
I=(5V-VCEーVFーVOL)/330Ω
=(5Vー1.8Vー0.6V)/330Ω
≒7.9mA
各セグメントの順電流の最大定格は30mAなので、問題ありません。
7セグLEDの全セグメント点灯時がコレクタ電流の最大値となるため、
キットでは未使用のDPも使用した8セグメント分とした場合、
IC=7.9mA × 8セグメント≒63mA
となります。
トランジスタ2SA1015のコレクタ電流の最大定格は150mAなのでOKです。
次にベース電流IBですが、コレクタ電流ICが63mAの時の
ベース・エミッタ間飽和電圧VBE(sat)は特性グラフより0.9V、
LS138のレベル出力電圧VOLは0.4V以下なので、
IB=(5VーVBE(sat)ーVOL)/5.1kΩ
=(5Vー0.9Vー0.4V)/5.1kΩ
≒0.7mA
IBが決まったことで、ICーVCE特性グラフに負荷曲線を引いて、
流すことができるコレクタ電流ICと、
先程はゼロとしたコレクタ・エミッタ間電圧VCEを求めます。
負荷曲線は先程、VCE=0Vとした時の63mAの点と、
ICがゼロの時の点を結ぶ直線になります。
IC=0の時のVCEは、
IC=(5V-VCEーVFーVOL)/330Ω=0 より、
5V-VCEー1.8ー0.6V=0 から、VCE=2.6Vとなります。
IB=0.7mAの時の特性曲線は無いので、0.5Aと1Aの中間付近をとると、
VCE=0.2V、IC=58mAとなります。
これを基に再計算した結果、各セグメントに流れる電流Iは7.3mA、
トランジスタのコレクタ損失PCは11.6mWとなり、
2SA1015のコレクタ損失の最大定格は400mWなので問題ありません。
7セグLED制御ソフト設計
PICマイコンの初期設定
プログラムでは、PICマイコンの初期設定として、
動作周波数の設定や、タイマー機能を使った割込み処理の定義を行います。
(プログラムコードの詳細は、ソースファイル(nnct_kit_v3.c)を参照下さい)
コンフィグレーション設定(※1)は以下の通りです。
※1:クロックなどの動作環境設定
#pragma config FEXTOSC = HS
外部発振器モード選択:HS(水晶振動子 4MHz以上)
#pragma config RSTOSC = EXT4X
発振器の動作モード:PLL(※2)の4逓倍回路を使用
※2:Phase Locked Loop(位相同期ループ):クロック周波数を増加させる回路
PIC16F18857ではPLLにより、外部からのクロック信号の周波数を4倍に増やすことができ、
本キットでは、8MHzの水晶振動子から32MHzのシステムクロック周波数Foscを生成してます。
コンフィグレーション設定については、下記記事で解説しています。
タイマ2割込み処理
この学習キットのソフト(ソースファイル(nnct_kit_v3.c))では、
タイマ2割込みを使うことで、タイマーや時計などの正確な時間処理を行っています。
タイマ2は、タイマ2レジスタ(T2TMR)の値をカウントアップして、
T2PR(タイマ2周期レジスタ)の値に到達したらゼロに戻り、タイマ2割込みが発生します。
タイマ2の設定についても、初期設定関数SetConfigで行っています。
このプログラムでは、タイマ2のカウント速度を1MHz(1us)、
T2PRを199にセットしているので、199+1=200カウント目に割込みが発生し、
割込み処理は1us × 200=200us毎に行われます。
タイマ2割込みで行う処理内容は割込み処理関数 isrで定義しています。
このisr関数では、タイマ1割込み処理も定義されており、
ブザー音の階調(周波数)制御に用いられています。
タイマ1の動作については下記別記事で解説しています。
ダイナミック点灯制御プログラム
このプログラムは、4桁の12時間表示式デジタル時計として動作し、
2桁目と3桁目の間にある2個のΦ3mm LED(D1、D2)が1秒単位で点滅します。
時刻設定はスイッチSW4を押しながら、
SW3で時間、SW2で分(10の位)、SW1で分(1の位)が設定できます。
ここで行っている4桁のダイナミック点灯制御は
for文による256回の繰返し処理を64回毎に4分割して切替を行っているため、
各桁の点灯時間は400~500us程度と、多少ばらつきがありますが、
4桁同時点灯に見え、各桁の明るさに違いを感じることはありせん。
しかし、時刻カウント処理は精度が要求されるため、
タイマ2割込みを使った1秒経過フラグsec_flag を利用し、時刻を1秒毎にカウントしています。
秒単位で点滅するD1、D2の制御は、7セグ3桁目の点灯時に行っており、
タイマ2割込み回数 t2_icnt を利用した0.5秒の時間計測を行い、
1秒間のうち、前半0.5秒は3桁目点灯時にD1、D2も点灯させ、
後半0.5秒は点灯させない(3桁目のみ点灯)ようにしています。
また、各セグメントの点灯信号(RC0~7)ですが、
256回の繰り返し処理において、毎回最初に全消灯させることで、
LEDの点灯期間中も、高速で点灯/消灯を繰り返しています。
消灯の期間は4us程度と非常に短いため、ずっと点灯しているように見え、
消費電力を削減できます。
時刻設定処理では、SW4を押した時に、SW1~3の入力を有効にしたり、
SW1~3を押したままにしても時刻が連続増加しないようにするため、
キー入力フラグkfを使用した3種類のスイッチ入力モードを設け、
決められた操作手順を行った場合のみ、SW入力を有効にしています。
7セグLEDダイナミック点灯時の動作波形
7セグLEDの3桁目を「1」、2桁目を「2」に表示した時の動作波形を示します。
2桁目の「2」はセグメントa、b両方とも点灯し、3桁目の「1」はaが未点灯なのがわかります。
各セグメントの制御信号(RC0~7)波形を拡大すると、
周期が5~7us程度の繰り返しパルスが1桁あたり64回出力されており、
そのうち電流が流れるL期間を3~3.5usと半周期程度にすることで、消費電力を削減しています。
パルスのH/L処理は正確な時間制御を行っていないため、パルス幅にばらつきがあり、
200us周期で発生するタイマ2割込み処理の影響で、
処理に遅延が生じてパルス幅が広がっている部分があります。
デコーダの出力波形も時間制御をしていないので、各桁のL期間が多少ばらついていますが、
各桁の明るさに差は感じられません。
4桁目から1桁目まで順番に約1.7ms周期で点灯を繰り返しており、
LEDはちらつくことなく、4桁全て点灯しているように見えます。
1秒周期で点滅するD1、D2の波形を見ると、0.5秒毎に点灯期間と消灯期間が来ており、
点灯期間を拡大すると、他のセグメントと同様に1.7ms周期でダイナミック点灯を行っています。