カソードコモンの8セグメントLEDへ表示する(シフトレジスタを使う)


今回はシフトレジスタを使って8セグメントLEDを表示する方法を紹介します。
使用するシフトレジスタは74HC595で す。

74HC595

以下のページで使い方が紹介されています。
http://wiringpi.com/extensions/shift-register-74x595/

結果は前回と同じとなります。

74HC595
ABCを表示

結線は以下の通りです。
シフトレジスタを2個、カスケード接続で使用しています。
1つ目のシフトレジスタはLEDのSegment用、2つ目のシフトレジスタはLEDのDigit用として使っています。
WiringPiでの番号とはsr595Setup()でのPinBaseを100としたときの番号となります。
つまりdigitalWrite(104,1)はシフトレジスタ#1の4(QE)がONになります。

シフトレジスタ#1のピン番号 WiringPiでの番号 LEDへの接続(ピン番号) Raspberryへの接続(ピン番号) シフトレジスタ#2への接続(ピン番号)
1(QB) 101 100Ωの抵抗を介してSegment b    
2(QC) 102 100Ωの抵抗を介してSegment c    
3(QD) 103 100Ωの抵抗を介してSegment d    
4(QE) 104 100Ωの抵抗を介してSegment e    
5(QF) 105 100Ωの抵抗を介してSegment f    
6(QG) 106 100Ωの抵抗を介してSegment g    
7(QH) 107 100Ωの抵抗を介してSegment D.P    
8(GND)     GND  
9(SQH)       14(A)
10(RESET)     3.3V  
11(SHIFT CLOCK)     12(GPIO18) 11(SHIFT CLOCK)
12(LATCH LOCK)     13(GPIO27) 12(LATCH LOCK)
13(OUTPUT ENABLE)     GND  
14(A)     11(GPIO17)  
15(QA) 100 100Ωの抵抗を介してSegment a    
16(VCC)     3.3V  

シフトレジスタ#2のピン番号 WiringPiでの番号 LEDへの接続(ピン番号) Raspberryへの接続(ピン番号) シフトレジスタ#1からの接続(ピン番号)
1(QB) 109      
2(QC) 110 抵抗なしでDigit1 Common    
3(QD) 111 抵抗なしでDigit2 Common    
4(QE) 112 抵抗なしでDigit3 Common    
5(QF) 113      
6(QG) 114      
7(QH) 115      
8(GND)        
9(SQH)        
10(RESET)        
11(SHIFT CLOCK)       11(SHIFT CLOCK)
12(LATCH LOCK)       12(LATCH LOCK)
13(OUTPUT ENABLE)        
14(A)       9(SQH)
15(QA) 108    
16(VCC)        

ソースコードは以下の様になります。
wiringPiライブラリはこのシフトレジスターをサポートしているので、前回か ら変えたのは赤字の箇所だけです。

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <string.h>
#include <stdint.h>
#include <sr595.h>

#define Pins    8
#define P0      100
#define Digs    3
#define D0      110

static const uint8_t segmentDigits [] =
{
// a  b  c  d  e  f  g  p       Segments
// 0  1  2  3  4  5  6  7       wiringPi pin No.
   1, 1, 1, 1, 1, 1, 0, 0,      // 0
   0, 1, 1, 0, 0, 0, 0, 0,      // 1
   1, 1, 0, 1, 1, 0, 1, 0,      // 2
   1, 1, 1, 1, 0, 0, 1, 0,      // 3
   0, 1, 1, 0, 0, 1, 1, 0,      // 4
   1, 0, 1, 1, 0, 1, 1, 0,      // 5
   1, 0, 1, 1, 1, 1, 1, 0,      // 6
   1, 1, 1, 0, 0, 0, 0, 0,      // 7
   1, 1, 1, 1, 1, 1, 1, 0,      // 8
   1, 1, 1, 1, 0, 1, 1, 0,      // 9
   1, 1, 1, 0, 1, 1, 1, 0,      // A
   0, 0, 1, 1, 1, 1, 1, 0,      // b
   1, 0, 0, 1, 1, 1, 0, 0,      // C
   0, 1, 1, 1, 1, 0, 1, 0,      // d
   1, 0, 0, 1, 1, 1, 1, 0,      // E
   1, 0, 0, 0, 1, 1, 1, 0,      // F
   0, 0, 0, 0, 0, 0, 0, 0,      // blank
} ;


DisplayDigits (char* digits)
{
    int i;
    uint8_t digit, segment ;
    uint8_t index, d, segVal ;

    for (digit = 0 ; digit < Digs; ++digit) {
      digitalWrite (D0 + digit, 0) ;
      d = toupper (digits [digit]) ;
      if ((d >= '0') && (d <= '9'))               // Digit
          index = d - '0' ;
      else if ((d >= 'A') && (d <= 'F'))        // Hex
          index = d - 'A' + 10 ;
      else
          index = 16 ;                             // Blank
      for (segment = 0 ; segment < 8 ; ++segment) {
        segVal = segmentDigits [index * 8 + segment] ;

        digitalWrite (segment+P0, segVal) ;
//delay(50)にすると動きが良く分かります
//        delay(50);
        delayMicroseconds (100) ;
        digitalWrite (segment+P0, 0) ;
      }
      digitalWrite (D0 + digit, 1) ;
    }
}


int main (void)
{
    int i;
    char digits [8] ;

    if(wiringPiSetup() == -1) return 1;
    if(sr595Setup(P0,16,0,1,2) == -1) return 2;

    for(i=0;i<Pins;i++) {
        pinMode(P0+i, OUTPUT);
        digitalWrite(P0+i, 0);
    }
    for(i=0;i<Digs;i++) {
        pinMode(D0+i, OUTPUT);
        digitalWrite(D0+i, 1);
    }

    strcpy(digits,"123");
    for(i=0;i<2000;i++) DisplayDigits(digits);

    strcpy(digits,"ABC");
    for(i=0;i<2000;i++) DisplayDigits(digits);

    for(i=0;i<Pins;i++) {
        digitalWrite(P0+i, 0);
    }
    for(i=0;i<Digs;i++) {
        digitalWrite(D0+i, 0);
    }
    exit;
}

次回はカソードコモンの8セグメントLED専用チップの使い方を紹介します。