LoginSignup
0
0

More than 1 year has passed since last update.

エレキ素人が何か考える(その12):シフトレジスタで7セグメントLED

Posted at

シフトレジスタで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)およびピン番号は下記のとおり。
image.png
シフトレジスタのピンアサインは下記のとおり。
シフトレジスタピン.png
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);
  }  
}

配線状況と結果

image.png
ブレッドボードの右に見えるものがシフトレジスタである。前回の写真と比べると、一目瞭然で、Arduinoと接続されているワイヤが少ない。

最後に

7セグメント用LEDドライバーICを使うともっと汎用的なことができるらしい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0