カソードコモンの8セグメントLEDへ表示する(MAX7219を使う)


今回はカソードコモンの8セグメントLED専用ドライバーのMAX7219を 使って8セグメントLEDを表示する方法を紹介します。
このチップはカソードコモンの8セグメントLED専用で、電流制限機能を持っていますので、電流制限用の抵抗はまったく必要ありません。
また各LEDのON/OFFはチップ内のトランジスタが高速で行いますので、チラつきも無く非常に綺麗な表示です。
表示可能な最大桁数は8桁です。
GPIOを使って8桁のLEDに表示するためには、桁制御用に8本、セグメント制御用に8本の合計16本のGPIO(TypeBの場合、ほぼ全て のGPIO)が必 要になりますが
このチップを使えば3個のGPIOで済みます。
桁数の多い8セグメントLEDや、8x8のマトリックスLED(基本的な使い方は8桁の8セグと同じ)を使うためには、
非常に便利なチップですが、国内ではあまり流通していないようです。

データシートによると定格電圧は4.0Vから5.5Vとなっていますが、Logic Low Input Voltageが3.5V以上となっており、
3.3V駆動でも動きました。


今回は4桁のLEDを使いました。結線は以下の通りです。
18番ピン(ISET)と5Vの間には、電流制限用の抵抗を挟んで使用します。
使用する抵抗値はデータシートを参照してください。
私は68KΩの抵抗を使いましたので、LEDには1.5V 10mAぐらいが流れるはずです。
MAX7219のピン番号 LEDへの接続 Raspberryへの接続(ピン番号)
1(DIN)
11(GPIO17)
2(DIG 0) Digit1 Common
3(DIG 4)

4(GND)
GND
5(DIG 6)

6(DIG 2) Digit3 Common
7(DIG 3) Digit4 Common

8(DIF 7)

9(GND)
GND
10(DIG 5)

11(DIG 1) Digit2 Common
12(LOAD)
13(GPIO27)
13(CLK)
12(GPIO18)
14(SEG A) Segment a
15(SEG F) Segment f
16(SEG B) Segment b
17(SEG G) Segment g
18(ISET)
68KΩの抵抗を介して5Vに接続
19(V+)
3.3V
20(SEG C) Segment c
21(SEG E) Segment e
22(SEG DP)
Segment D.P
23(SEG D) Segment d
24(DOUT)


ソースコードはこ ちらのページを参考にしました。
/*
 max7219.c
 Raspberry Pi driving the Max7219
 to compile : cc max7219.c -o max7219 -lwiringPi
*/

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


// define our pins :

#define DATA    0       // GPIO 17 header pin 11
#define CLOCK   1       // GPIO 18 header pin 12
#define LOAD    2       // GPIO 27 header pin 13

#define NLEDS   4       // Number of Digits

// The Max7219 Registers :

#define DECODE_MODE   0x09
#define INTENSITY     0x0a
#define SCAN_LIMIT    0x0b
#define SHUTDOWN      0x0c
#define DISPLAY_TEST  0x0f


void BitBanging (uint16_t output) {
  uint8_t i;
  for (i=16; i>0; i--)
  {
    uint16_t mask = 1 << (i - 1); // calculate bitmask
    digitalWrite(CLOCK, 0);  // set clock to 0
    // Send one bit on the data pin
    if (output & mask)
      digitalWrite(DATA, 1);
    else
      digitalWrite(DATA, 0);
    digitalWrite(CLOCK, 1);  // set clock to 1
  }
}

// Take a reg numer and data and send to the max7219
//
// reg_number : Register Address of max7219 (0x00-0x0f See datasheet)
// dataout    : Send Data
//
void MAX7219Send (uint8_t reg_number, uint8_t dataout) {
  int i;
  digitalWrite(LOAD, 1);  // set LOAD 1 to start
  BitBanging((reg_number << 8) + dataout);
  digitalWrite(LOAD, 0);  // LOAD 0 to latch
  digitalWrite(LOAD, 1);  // set LOAD 1 to finish
}


void displayNumber(int digit, uint32_t number) {
  int i;
  uint8_t data;

  uint32_t num = number;
  for(i=0;i<digit;i++) {
    data = num % 10;
//    printf("data[%d]=%d ",i,data);
    MAX7219Send(i+1 ,data);     // displays the 1 digit number
    num = num / 10;
  }
//  printf("\n");
}

int main (void)
{
  int i,j;

  printf ("\n\nRaspberry Pi Max7219 Test using WiringPi\n\n");

  if (wiringPiSetup () == -1) exit (1) ;

  //We need 3 output pins to control the Max7219: Data, Clock and Load

  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(LOAD, OUTPUT);

  MAX7219Send(SCAN_LIMIT, NLEDS-1);

/*
 BCD decode mode off
 data bits correspond to the segments (A-G and DP) of the seven segment display.

 BCD mode on
 0 to 15 =  0 to 9, -, E, H, L, P, and ' '
*/

  MAX7219Send(DECODE_MODE, 0xff); // Set BCD decode mode on
  MAX7219Send(DISPLAY_TEST, 0); // Disable test mode
  MAX7219Send(SHUTDOWN, 1);     // come out of shutdown mode(turn on the digits)

  for(i=0;i<NLEDS;i++) {
    MAX7219Send(i+1, i);
  }

  for(i=0;i<5;i++){
    MAX7219Send(INTENSITY, i);  // set brightness
    sleep(1);
  }

  for(i=0;i<16;i++) {
    for(j=0;j<NLEDS;j++) {
      MAX7219Send(j+1, i);      // displays the 4 digit number
    }
    delay(500);
  }

  for(i=0;i<1000;i++) {
    displayNumber(NLEDS, i);
    delay(100);
  }

  return 0;
}

実行すると最初に「3210」を表示し、INTENSITY(輝度)が0から4に変化します。
INTENSITY(輝度)をあまりあげすぎると、電流が増えすぎてLED側が追従できなくなります。
その後「0000」→「1111」→「2222」の様に、表示できる文字を全て表示します。
0-9以外に「-HELP」の5文字とブランクを表示することができます。
最後に、0から999の数字を表示します。




このドライバーは8桁のLEDを表示することができます。
そこで、4桁のLEDを2つ使ってみました。結線は以下の通りです。
MAX7219のピン番号 LED1への接続 LED2への接続 Raspberryへの接続(ピン番号)
1(DIN)

11(GPIO17)
2(DIG 0) Digit1 Common

3(DIG 4)
Digit1 Common
4(GND)

GND
5(DIG 6)
Digit3 Common
6(DIG 2) Digit3 Common

7(DIG 3) Digit4 Common


8(DIF 7)
Digit4 Common

9(GND)

GND
10(DIG 5)
Digit2 Common

11(DIG 1) Digit2 Common

12(LOAD)

13(GPIO27)
13(CLK)

12(GPIO18)
14(SEG A) Segment a Segment a
15(SEG F) Segment f Segment f
16(SEG B) Segment b Segment b
17(SEG G) Segment g Segment g
18(ISET)

68KΩの抵抗を介して5Vに接続
19(V+)

3.3V
20(SEG C) Segment c Segment c
21(SEG E) Segment e Segment e
22(SEG DP)
Segment D.P Segment D.P
23(SEG D) Segment d Segment d
24(DOUT)



ソースコードは以下のようになります。
/*
 max7219.c
 raspberry pi driving the max7219
 to compile : cc max7219-2led.c -o max7219-2led -lwiringpi
*/

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


// define our pins :

#define DATA    0       // GPIO 17 header pin 11
#define CLOCK   1       // GPIO 18 header pin 12
#define LOAD    2       // GPIO 27 header pin 13

#define NLEDS   8       // Number of Digits


// the max7219 registers :

#define DECODE_MODE   0x09
#define INTENSITY     0x0a
#define SCAN_LIMIT    0x0b
#define SHUTDOWN      0x0c
#define DISPLAY_TEST  0x0f

void BitBanging (uint16_t output) {
  uint8_t i;
  for (i=16; i>0; i--)
  {
    uint16_t mask = 1 << (i - 1); // calculate bitmask
    digitalWrite(CLOCK, 0);  // set clock to 0
    // Send one bit on the data pin
    if (output & mask)
      digitalWrite(DATA, 1);
    else
      digitalWrite(DATA, 0);
    digitalWrite(CLOCK, 1);  // set clock to 1
  }
}

// Take a reg numer and data and send to the max7219
//
// reg_number : Register Address of max7219 (0x00-0x0f See datasheet)
// dataout    : Send Data
//
void MAX7219Send (uint8_t reg_number, uint8_t dataout) {
  int i;
  digitalWrite(LOAD, 1);  // set LOAD 1 to start
  BitBanging((reg_number << 8) + dataout);
  digitalWrite(LOAD, 0);  // LOAD 0 to latch
  digitalWrite(LOAD, 1);  // set LOAD 1 to finish
}


void displayNumber(int digit, uint32_t number) {
  int i;
  uint8_t data;

  uint32_t num = number;
  for(i=0;i<digit;i++) {
    data = num % 10;
//    printf("data[%d]=%d ",i,data);
    MAX7219Send(i+1 ,data);     // displays the 1 digit number
    num = num / 10;
  }
//  printf("\n");
}

int main (void)
{
  int i,j;

  printf ("\n\nRaspberry Pi Max7219 Test using WiringPi\n\n");

  if (wiringPiSetup () == -1) exit (1) ;

  //We need 3 output pins to control the Max7219: Data, Clock and Load

  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(LOAD, OUTPUT);

  MAX7219Send(SCAN_LIMIT, NLEDS-1);

/*
 BCD decode mode off
 data bits correspond to the segments (A-G and DP) of the seven segment display.

 BCD mode on
 0 to 15 =  0 to 9, -, E, H, L, P, and ' '
*/

  MAX7219Send(DECODE_MODE, 0xff); // Set BCD decode mode on
  MAX7219Send(DISPLAY_TEST, 0); // Disable test mode
  MAX7219Send(SHUTDOWN, 1);     // come out of shutdown mode(turn on the digits)

  for(i=0;i<NLEDS;i++) {
    MAX7219Send(i+1, i);
  }

  for(i=0;i<5;i++){
    MAX7219Send(INTENSITY, i);  // set brightness
    sleep(1);
  }

  for(i=0;i<16;i++) {
    for(j=0;j<NLEDS;j++) {
      MAX7219Send(j+1,i);       // displays the 4 digit number
    }
    delay(500);
  }

  uint32_t number = 1;
  for(i=0;i<NLEDS;i++) {
    displayNumber(NLEDS, number);
    number = number * 10 + (i+2);
//printf("number=%d\n",number);
    delay(500);
  }

  return 0;
}



次回は同じMAXシリーズのハードウェアSPI-IFのチップを紹介します。