シフトレジスタで7セグメントLEDを操作
前回では、ArduinoのGPIOピン7つを7セグメントLEDにアサインしていた。通常、マイコンのGPIO数は限られており、潤沢には存在しない。7セグメントLED制御には、通常、専用のチップを使い、マイコンの使用GPIO数を減らすらしい。ここでは、シフトレジスタを用いて、それを試みる。
シフトレジスタ
シフトレジスタの説明は、Wikiなどにおまかせしたい。ここでは、Arduinoで使用するGPIOの数を減らすという目的で利用している。秋月電子で入手した8ビットシフトレジスタ U74HC595AG-Dを用いる。データシートはこちらにある。
結論としては、3つのGPIOを利用して、7セグメントLEDの8個のLEDを制御している。
ソースコード
実現することは、前回と同じ。キーボード(シリアル)入力した数値を表示するのみ。次のサイトを参照した。
準備(面倒)
7セグメントLEDの配線は適当に行ったが、前回と同じ。LSBFirstで8ビットを1ビットずつ出力、LEDへの配線を考慮して、0から9までの数値をビット列化する。7セグメントLEDの各LEDの位置(AからG)およびピン番号は下記のとおり。
シフトレジスタのピンアサインは下記のとおり。
LSBFirstではb0からb7の順番に、ピンアサインではQh->Qg->Qf->Qe->Qd->Qc->Qb->Qaの順番に出力される。適当に行った配線では、下記の対応となった。(配線を行っていない人にはわかりにくいのは容赦。)
// b1:E b2:D b3:C b4:B b5:A b6:F b7:G (b0:DP)
// Qa:10 Qb:9 Qc:7 Qd:6 Qe:4 Qf:2 Qg:1 wired connection
// G F A B C D E
//
// A B C D E F G
// bit 5 4 3 2 1 6 7
これらをもとに、各数値に対応するビット列を作成。
/*
uint8_t disp_ary[][sizeof(ary)/sizeof(uint8_t)] = {
// A B C D E F G
{LOW, LOW, LOW, LOW, LOW, LOW, HIGH}, // 0 B10000000
{HIGH, LOW, LOW, HIGH, HIGH, HIGH, HIGH}, // 1 B11100110
{LOW, LOW, HIGH, LOW, LOW, HIGH, LOW}, // 2 B01001000
{LOW, LOW, LOW, LOW, HIGH, HIGH, LOW}, // 3 B01000010
{HIGH, LOW, LOW, HIGH, HIGH, LOW, LOW}, // 4 B00100110
{LOW, HIGH, LOW, LOW, HIGH, LOW, LOW}, // 5 B00010010
{HIGH, HIGH, LOW, LOW, LOW, LOW, LOW}, // 6 B00110000
{LOW, LOW, LOW, HIGH, HIGH, HIGH, HIGH}, // 7 B11000110
{LOW, LOW, LOW, LOW, LOW, LOW, LOW}, // 8 B00000000
{LOW, LOW, LOW, HIGH, HIGH, LOW, LOW} // 9 B00000110
};
*/
実際のコード
準備に時間はかかったが、前回と比べて、コード量は激減(GPIO削減だけの効果ではなく)。
#define SER 5
#define RCLK 6
#define SRCLK 7
uint8_t num_disp[] = {
B10000000, B11100110, B01001000, B01000010, B00100110,
B00010010, B00110000, B11000110, B00000000, B00000110};
void setup() {
Serial.begin(9600);
pinMode(SER, OUTPUT);
pinMode(RCLK, OUTPUT);
pinMode(SRCLK, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n');
uint8_t val = data.toInt();
Serial.println(val);
digitalWrite(RCLK, LOW);
shiftOut(SER, SRCLK, LSBFIRST, num_disp[val]);
digitalWrite(RCLK, HIGH);
}
}
配線状況と結果
ブレッドボードの右に見えるものがシフトレジスタである。前回の写真と比べると、一目瞭然で、Arduinoと接続されているワイヤが少ない。
最後に
7セグメント用LEDドライバーICを使うともっと汎用的なことができるらしい。