ナゾテックの名前で模型・ジオラマ用のLED電飾コントローラーや配線済みチップLEDの販売などを行っている者です。
その1の記事
7セグメントLEDシリアルドライバーをPICマイコンでSPIを使って制御する(その1)
想定読者
その1からの続きの方。
PICマイコンを使った7セグメントLEDの制御でダイナミック点灯はいろいろ面倒だから何か簡単に出来るもの無いかなぁって方へ。
PICマイコンの開発環境や電子工作の基本に付いては下記をご参照ください。
Microchip MPLAB X IDEのインストールと使い方の基礎
ブレッドボードの使い方の基本
MicrochipのPICマイコンとMPLAB Snap インサーキット デバッガを繋ぐ
MPLAB X IDE+MCCでLチカやってみる
目次
7セグメントLEDシリアルドライバーの複数接続
プログラムの実行
もっと桁数を増やす
もうちょっと実用的な物
7セグメントLEDシリアルドライバーの複数接続
前回の記事で示したシリアルドライバーの端子の意味を再掲します。
この中で"SCK"は制御用のクロック信号、"SDI"は信号の入り口で、ここまでは前回で使用しました。この記事では"SDO"が登場します。
"SDO"は信号の出口になります。前回記事で書いたようにシリアルドライバーは新しいデータを受け取ったら、自分の次に繋がっているシリアルドライバーに今自分が持っているデータを送り出します。そのための端子が"SDO"になります。
つまり、"SDO"と次のシリアルドライバーの"SDI"を接続してやることで順にデータを送る事ができると言う訳です。

その他の端子は全て共通のものなので、それぞれを一本の線で接続しても構いません。

ブレッドボードのスペースが少ないので部品の下に配線を行います。

7セグメントLEDシリアルドライバーをこのように配置します。

部品を少しずらした写真です。

反対側です。

実際の外観です。

マイコンとの接続はその1と同じです。複数接続した場合でも最初の一つに接続します。

プログラムの実行
その1の最後に書いたプログラムをそのまま実行して見てください。左から右の7セグメントLEDへ順に数字が写っていく様子が見られると思います。
もっと桁数を増やす
ではもっと桁数を増やして見ましょう。
やることは先ほどと同じことの繰り返しです。ただし、先ほどは配線などを分かりやすくするために7セグメントLEDの間隔を広げて配置しましたが、大体の場合は隣同士くっついた状態にするので、その形で配線しています。

LEDを乗せた状態。

マイコンからの配線。もちろん電源+ーも接続してください。

プログラムは同じものが使えます。実行した時の様子。

もうちょっと実用的な物
実際に多数桁の7セグメントLEDを使う場合は桁数分の配列を用意して表示したい数値が変わる毎に全桁の表示データを送信するのがセオリーかと思います。
そこで、6桁の7セグメントLEDを使うとして各桁の数値を持つ配列を宣言します。
#define NUM_SIZE 6
uint8_t numArray[NUM_SIZE];
次にこの6桁を一度に送信する関数を記述します。
void sendNumArray(uint8_t numArray[]){
IO_RB6_SetLow();
for(int i=0;i<NUM_SIZE;i++){
sendSPI1Data(NumPatternData[numArray[i]]);
}
IO_RB6_SetHigh();
}
この"numArray"の各要素に数値の各桁の一桁分の値を入れます。
たとえば"123"の場合、
numArray[0] = 3;
numArray[1] = 2;
numArray[2] = 1;
また6桁の内の残り3桁は"0"表示でも良いのですが何も表示しないのが一般的かと思うので、全部を消灯する"0b00000000"を入れておきます。これは"NumPatternData"の18番目の要素にありますので、下記のようにしておきます。
numArray[3] = 18;
numArray[4] = 18;
numArray[5] = 18;
ただ、このやり方ですと自由に数値を表示するには面倒すぎるので、好きな数値を配列の各要素に格納する関数を作成します。
void makeNumArray(int32_t displayNum, uint8_t numArray[]){
for(int i=0;i<NUM_SIZE;i++){
numArray[i] = 18; //一旦表示無しに設定
}
int32_t wkDisplayNum = displayNum;
for(int i=0;i<NUM_SIZE;i++){
int num = wkDisplayNum % 10;
wkDisplayNum = wkDisplayNum / 10;
if(num == 0 && wkDisplayNum == 0){
break;
}else{
numArray[i] = num;
}
}
}
一旦全桁表示無しに設定します。
各桁の一桁を算出するために、まず受け取った数値を10で割った余りを取得("num"に格納)します。これは数値に一桁目に当たります。
次の桁を得るために受け取った数値を10で割っておきます。
この時、"num"も"wkDisplayNum"も0の場合はもうそれ以上数値表示がないと言うことなので、ループを抜けます。
10で割ったあまりを配列に格納します。
これで簡単に好きな数値を7セグメントLEDの6桁に表示できます。
とりあえず、1からカウントアップしていく様子を表示してみましょう。
uint32_t count = 1;
while (1)
{
makeNumArray(count++, numArray);
sendNumArray(numArray);
DELAY_milliseconds(1);
}
これで順にカウントアップされる様子がLEDに表示されます。

