0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

エレキ素人が何か考える(その18):7セグメントLEDドライバ

Posted at

7セグメントLEDドライバで7セグメントLEDを操作

エレキ素人が何か考える(その12):シフトレジスタで7セグメントLEDの続編。7セグメントLEDドライバを用いて、7セグメントLEDを制御する。マイコンの使用GPIO数を減らすことについては、シフトレジスタと同じである。

7セグメントLEDドライバ

7セグメント用LEDドライバーIC TM1630を利用。本ICは、カソードコモン専用となるため、カソードコモン用LEDであるC-551SRDを対象とした。いずれも、秋月電子で購入。

LEDのピン配置

image.pngimage.png

TM1630のデータシート

データシートは中国語で書かれている。Googleで英訳したものを適宜PickUp。なお、次のサイトの説明が参考になる。

ピンアサイン、LEDとの接続


TM1630datasheet-Pin1.png
TM1630datasheet-Pin2.png

ここは説明割愛(ほぼ自明であろう)。

コマンドやデータの書き込みシーケンス

固定アドレスモード(後述)のコマンドシーケンスは下記となる。(小さな字でゴメンナサイ)
TM1630datasheet-FixedAddr1.png
TM1630datasheet-FixedAddr2.png

  1. Display Mode(5桁7セグメント or 4桁8セグメント)
  2. Data Setting(固定アドレスモード)
  3. Display Address(GRID1-4のいずれか選択)
  4. Data(AddressへのLED表示データのセット)
    (3,4の繰り返し)
  5. Display Control(ON or OFF)

となっており、上記の1-5までのそれぞれのコマンド実行前にSTBをLowに、実行後にSTBをHighにする。コマンド実行(データ転送)中に、8ビット分のクロックを発生させるため、shiftOut()を利用する。ソースコード的には下記となる。

  1. STB Low: digitalWrite(pin, LOW)
  2. コマンド: shiftOut(DIO, CLK, LSBFIRST, データ) (必要に応じて繰り返す)
  3. STB High: digitalWrite(pin, HIGH)

データシートにはこのシーケンスとなっているが、実はこのとおりでなくても動作する。詳細は後述するソースコードを参照してほしいが、最初に
 1(Display Mode) -> 2(Data Setting) -> 5(Display Control)
を実施し、その後
 3(Display Address) -> 4(Data)
を繰り返しても問題ないようだ。また、途中で
 5(Display Control)
により、LED Off/Onを単独で行っても動作した。

Display Mode

TM1630datasheet-DisplayModeSetting.png
5桁7セグメントまたは4桁8セグメントの設定。ここでは後者を選択(0b00xxxx01)。

Data Setting

TM1630datasheet-DataSetting.png
データ書き込み、固定アドレスモードの選択(0b01xx0100)。

Display Address

TM1630datasheet-DisplayRegisterAddress.png
TM1630datasheet-AddressCommand.png
自動翻訳後の内容が見えづらくなっているが、SEG2-8へのデータを書き込む場合、各Gridに対して次のデータをアドレスとして用いる。

  • Grid1: 0b11xx0000 (00H)
  • Grid2: 0b11xx0010 (02H)
  • Grid3: 0b11xx0100 (04H)
  • Grid4: 0b11xx0110 (06H)

Data

LEDの各セグメント(A-G)を用いて、数字の0-9を作る。ソースコードのほうがわかりやすい。

uint8_t digit[] = {0b01111110, 0b00001100, 0b10110110, 0b10011110, 0b11001100,
                    0b11011010, 0b11111010, 0b01001110, 0b11111110, 0b11011110};

shiftOut()にて、LSB1stでデータを送出するので、bit7がセグメントGに、bit1がセグメントAに相当するようだ。

Display Control

TM1630datasheet-DisplayControl.png
ここでは、PWM-13/16を選択(2番目に明るい)。

  • Display ON: 0b10xx1110
  • Display OFF: 0b10xx0000

ソースコード

1秒毎に0から9までを表示させる単純なもの。動作中でも、LEDのOFF/ON制御、テスト用のGRID選択をPCから行いたかったため、タスクを設けて制御(FreeRTOS利用)。

#include <Arduino_FreeRTOS.h>

// TM1630
#define DISP_MODE 0b00000001 // 5-digit 7-segments
#define FIX_MODE  0b01000100 // Increased Fixed Write Mode
#define DISP_ON   0b10001110 // Display ON & PWM-13/16
#define DISP_OFF  0b10000000 // Display OFF
#define GRID1     0b11000000 // 00H
#define GRID2     0b11000010 // 02H
#define GRID3     0b11000100 // 04H
#define GRID4     0b11000110 // 06H

// Arduino
#define DIO 5
#define CLK 6
#define STB 7
  • データシートにそった各種コマンドなどの定義
  • Arduino GPIO番号
boolean tgl;
uint8_t addr;
uint8_t grid[] = {GRID1, GRID2, GRID3, GRID4};
uint8_t digit[] = {0b01111110, 0b00001100, 0b10110110, 0b10011110, 0b11001100,
                    0b11011010, 0b11111010, 0b01001110, 0b11111110, 0b11011110};

TaskHandle_t xKbd, xDisp;
  • Display On/OFF用変数:tgl
  • GRID用変数:addr
  • GRID定義
  • 0-9までの数値の定義
  • FreeRTOS用タスクハンドラ
void configure(uint8_t arg) {
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, arg);
  digitalWrite(STB, HIGH);  
}

void disp_num(uint8_t num) {
  digitalWrite(STB, LOW);
  shiftOut(DIO, CLK, LSBFIRST, addr);
  shiftOut(DIO, CLK, LSBFIRST, digit[num]);
  digitalWrite(STB, HIGH);  
}
  • コマンド制御関数:configure()
  • 数値データ関数:disp_num()
TaskHandle_t xKeyboard() {
  for (;;) {
    if (Serial.available() > 0) {
      String data = Serial.readStringUntil('\n');
      uint8_t val = data.toInt();
      val = val%5;  // Avoid exception
      Serial.println(val);
      if (val == 0) {
        tgl = !tgl;
        configure((tgl? DISP_ON: DISP_OFF));
      } else {
        addr = grid[val-1];
      }
    }
    vTaskDelay(1);  
  }
}
  • PCからのシリアル入力タスク
    • 入力値0:Display ON/OFF切り替え
    • 入力値1-4:GRID選択
      (今回はLEDが1つだけだが、配線を変えてGRID1-4が機能することを確認するため、選択できるようにしている。)
TaskHandle_t xDisplay() {
  for (;;) {
    for (int i=0; i<10; i++) {
      disp_num(i);
      vTaskDelay(1000/portTICK_PERIOD_MS);
    } 
  }
}
  • LED表示タスク(1秒毎に0-9までの数値を表示)
void setup() {
  Serial.begin(9600);
  pinMode(DIO, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(STB, OUTPUT);
  digitalWrite(DIO, LOW);
  digitalWrite(CLK, LOW);
  digitalWrite(STB, HIGH);
  tgl = true;
  addr = GRID1;
  delay(1);

  // Command Display
  configure(DISP_MODE);
  // Address Incremental
  configure(FIX_MODE);
  // Setting Display Control
  configure((tgl? DISP_ON: DISP_OFF));
  // Task
  xTaskCreate(xKeyboard, "Keyboard", 128, NULL, 1, &xKbd);
  xTaskCreate(xDisplay, "Display", 128, NULL, 1, &xDisp);
  vTaskStartScheduler();
}

void loop() {
  // nothing
}
  • シリアル初期化
  • GPIO初期値設定
  • 各種変数初期化
  • TM1630初期値設定
  • タスク起動およびスケジューリング

検証

特に説明は不要かと。中央下にあるICが、TM1630である。
IMG_20221120_090028.jpg
なお、ここでは、Arduino Uno互換ボードを利用した。

EOF

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?