実験・調査

【IC紹介】7セグメントドライバー TC4511BP の使い方を紹介する

直近の工作で7セグメントLEDを使うことになりました。

今回は制御ICを使った点灯制御を行ってみます。

7セグメントLEDの制御はいろいろ

7セグメントLEDやその制御用ICなどについて、概要をざっくりまとめてみます。

7セグメントICについて

7セグメントLEDは、デジタルの数字を表せるように各LEDが配置されており、光り方によって数字に見せることができる表示器です。

7セグメントLEDは見た目は変わっていますが、基本的にはLEDと変わりません。

アノード・コモン、カソード・コモン、各端子バラバラのタイプ等、いろいろなものがあります。

回路としてはLEDのアノード、カソードのどちらが共通になっているか、またはどれも共通になっていない、といった違いがあります。

カソード・コモン タイプ
アノード・コモン タイプ

7セグメントLEDは見た目が数字ですが、LEDが複数組み合わさっただけなので、単純な構成です。

それぞれのどのLEDをどの組み合わせで点灯させるかにより、表示される数字が変化します。

制御ICを使った7セグメントLEDの制御について

前述の通り、7セグメントLEDはただのLEDなので電流を流せば点灯でき、数字を表すことができます。

カソード・コモン タイプを使用した場合、どのアノードに電圧を加えるかによって制御が可能です。

上記の7セグメントLEDなら、8本の入力があれば数値を制御可能です。

ただマイコンによってはピン数が限られており、1桁表示させるためだけに8本もポートを使えない場合があります。

そこで制御ICの出番、といった感じです。

制御ICにもいろいろあり、I2CやSPI通信などで制御するもの、特定の入力を加えて制御するものなどがあります。

今回は「特定の入力を加えると数値を表示できる」タイプのICについて紹介してみます。

今回使用する 7セグメントドライバIC 「TC4511BP」について

今回使用する7セグメントLEDの制御ICは下記のものです。

「カソード・コモン」タイプの7セグメントLEDに対応した制御用ICです。

このICは「BCDコード」(後述) を4本の入力端子へ入力することで、0~9までの数字を表示させることができます。

またBCDコードは4本の入力で行えるため、制御に必要なピン数を7➡4本まで減らすことができます。
(※このICは小数点の"ドット"の制御には対応していないため、上の文では制御に必要なピン数を"7"と書いています。)

ICのピン配置

TC4511BPのピン配置は以下のようになっています。

a~gまでの出力を、それぞれカソード・コモンタイプの7セグメントLEDへ接続して使用します。

A、B、C、Dの4つがBCDコードの入力に対応します。

nLTやnBI、LEなど、その他の制御ピンがありますが、これらは出力の強制全ON、強制全OFFなどに使用します。
(これらの特殊ピンについての説明は割愛します。)

BCDコードについて

この制御ICは、入力としてBCDコードを受け付けています。

BCDコードは、「10進数表記の各桁ごとに、2進数の数値を割り当てたもの」になります。

数値の1~20まで、ざっくり表にしてみると以下のようになります。

このBCDコードのメリット、特徴は、

「"10進数"における情報としての数値」と、「"16進数"における表記としての数値」が同じになります。

データのフォーマットがBCDコードです、と言われたら、特に変換せずに日常で目にする通常の数値(10進数)で値を読めるわけです。

注意点としては、BCDコードで示された数値をそのまま2進数や16進数に変換しても、「同じ情報としての値」にはならないことです。

例えば上の表の一番下、「数値の20」の場合、BCDコードにおいては10進数の桁ごとの数である「2」「0」に対して、
それぞれ2進数で「0010」と「0000」を割り当てています。

「0010 0000」は、16進数では「20」、10進数の数値なら「32」です。

変換には若干注意が必要です。

と、ここまでこのICを使うためにBCDコードについて説明したのですが、
7セグメントLED1桁で表現できる数値は9までなので、実質2進数と同じです。。。。。

ICの出力対応

このICの入力に対する出力は以下のようになります。

赤枠の範囲が、BCDコードをA~Bのポートに入力した場合の、a~gポートの出力の対応表です。

赤枠外はほかのピンへ信号を入力した場合の特殊出力などです。

回路の作成

実際に使用する準備をしていきます。

実験に使用する部品(まとめ)

今回実験に使用した部品を以下にまとめました。

・7セグメント制御用IC:TC4511BP

・カソードコモン 7セグメントLED:C-551SRD

・TC4511BPへBCDコードを送るマイコン:PIC16F1827

・7セグメントLED 電流制限用抵抗:数個

・ユニバーサル基板

制御ICの電源電圧の決定

まずは7セグメントLED制御用ICの電源電圧から決めていきます。

TC4511BPは下記のような仕様となっています。

基本的には広い電源条件に対応した使いやすい ICかな~と思います。

7セグメントLEDへの出力電圧はTC4511BPへ入力した電源電圧より少し低い値ぐらいになるようです。

高い電源電圧で使用する場合、各ポートの出力電圧も電源電圧レベルまで上がるので、順方向電圧が小さい7セグメントLEDを使う場合は注意が必要です。
(電流制限抵抗の値が大きくなる、電流大きいと消費電力大きいので定格注意)

今回はマイコンの電源電圧が5Vのため、5Vを使用することにしました。

出力電流の確認

TC4511BPの絶対最大定格は以下のようになっています。

出力電流は50mAまで対応しているようです。

絶対最大定格なので50mAで使った時点で壊れます。今回は余裕をもって30mAのカソード・コモンタイプのLEDを使用することにします。

よって7セグメントLEDとTC4511BPは直結、間には電源供給用の回路を挟まない構成とします。

多分大丈夫だと思いますが、I_OHって"各ピンごとの"出力電流なのか?という点が気になりました。

さすがにIC全体で50mAだったらしょぼすぎるのでないと思いますが・・・

今回は1つのセグメントで20mA程度消費する下記の7セグメントLEDを選択しました。

制限抵抗の値決定

次に7セグメントLEDとTC4511BPの間の制限抵抗を決めていきます。

制限抵抗は7セグメントLEDに流したい電流と電源電圧の2つから決めていきます。

今回使用する7セグメントLEDは、1つのセグメント(数字表示のバー1つ)のLEDが、順方向電圧降下 1.8V(平均)、順方向電流30mA(最大)となっています。

今回は順方向電流 20mA、電源電圧5Vで使用したいので、制限抵抗は下記の値とします。

全体の回路構成

全体の回路構成は下記のようになりました。

ICが入った分ごちゃごちゃして見えますが、マイコン周りの制御線は4本のみでシンプルな構成です。

BCDコードの入力にはPICマイコンの PIC16F1827 を使用します。

TC4511BPの a ~ g ピンは、7セグメントLEDの A ~ G ピンへそれぞれ接続します。

プログラム

今回はPICマイコンを使用して点灯テストをしてみます。

PICマイコンへのプログラムの書き込み方法、MPLABの使用方法などは下記の記事を参考にしてください。

開発環境
【PIC】開発環境整備:MPLABで作成したプログラムをPICKIT3で書き込む方法を紹介する

あまり新しい情報がなかったのでまとめてみました。 開発環境(ソフト)->開発環境(ハード)->プロジェクトの作成->実際に書き込みの順で書いてあります。 多少参考になるかもしれん。 ...

続きを見る

ソースコードの例は以下になります。

数値を入力したらそのパターンのBCDコード (2進数) の各ビットを調べ、出力するようにしています。

/*
 * File:   interrupt.c
 * Author: ICE__MEGANE
 * Mid-Range 8-bit MCUs PIC16F1827
 * Created on 2024/03/27, 23:38
 */

/* PIC16F1827 Configuration Bit Settings */
/* 'C' source line config statements */

/* CONFIG1 */
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

/* CONFIG2 */
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

/* #pragma config statements should precede project file includes. */
/* Use project enums instead of #define for ON and OFF. */


#include <xc.h>

/* ========================== Macro define =========================== */
#define     SET     1
#define     CLEAR   0

#define _XTAL_FREQ  32000000     /* 32MHz */


typedef unsigned char UCHAR;
typedef unsigned short USHORT;


/* ============= TRISA bit-field type definition =========================== */
/* The PORTA bit field definitions are also available in the standard header,*/
/* but as soon as they are used, the port state changes, so they are provided as buffers. */
typedef union
{
    UCHAR PORTA_ALL_1BYTE;           /* 1byte */

    struct
    {
        /* Memory sharing with "TRISA_USER". */
        UCHAR BIT_RA0 : 1;      /* 0 */     /* The 1st element defined is the LSB */
        UCHAR BIT_RA1 : 1;      /* 1 */
        UCHAR BIT_RA2 : 1;      /* 2 */
        UCHAR BIT_RA3 : 1;      /* 3 */

        UCHAR BIT_RA4 : 1;      /* 4 */
        UCHAR BIT_RA5 : 1;      /* 5 */
        UCHAR BIT_RA6 : 1;      /* 6 */
        UCHAR BIT_RA7 : 1;      /* 7 */
    };
}PORTA_USER_BF_t;

PORTA_USER_BF_t PORTA_USER_BF;


/* ========================== Function Prototype== =========================== */
static void main_init( void );
static void tc4511bp_data_set( UCHAR disp_num );


/**************************************************************/
/*  Function:                                                 */
/*  main task                                                 */
/*                                                            */
/**************************************************************/
void main(void) {

    main_init();                /* initialize before loop task. */

    while(1)
    {
        tc4511bp_data_set(9);
    }

}

/**************************************************************/
/*  Function:                                                 */
/*  variable initialize                                       */
/*                                                            */
/**************************************************************/
static void main_init(void)
{
    /* functional initialize */
    INTCON      =  0x00;
    OSCCON      =  0xF0;
    OSCTUNE     =  0x00;
    OPTION_REG  =  0xC7;    
    APFCON0     =  0x08;
    APFCON1     =  0x00;

    /* port initialize */
    TRISA = 0x00;
    PORTA_USER_BF.PORTA_ALL_1BYTE = 0x00;
}

/**************************************************************/
/*  Function:                                                 */
/*  7seg data exchange                                        */
/*                                                            */
/**************************************************************/
static void tc4511bp_data_set( const UCHAR disp_num )
{

    /* ==== BCD bit check ==== */
    if( ( disp_num & (UCHAR)0x01 ) == (UCHAR)0x01 )
    {
        PORTA_USER_BF.BIT_RA6 = SET;
    }

    if( ( disp_num & (UCHAR)0x02 ) == (UCHAR)0x02 )
    {
        PORTA_USER_BF.BIT_RA7 = SET;
    }

    //disp_num_buff = disp_num;
    if( ( disp_num & (UCHAR)0x04 ) == (UCHAR)0x04 )
    {
        PORTA_USER_BF.BIT_RA0 = SET;
    }

    //disp_num_buff = disp_num;
    if( ( disp_num & (UCHAR)0x08 ) == (UCHAR)0x08 )
    {
        PORTA_USER_BF.BIT_RA1 = SET;
    }

    /* ==== port setup ==== */
    PORTA = PORTA_USER_BF.PORTA_ALL_1BYTE;
}

若干長くなってしまいましたが、以下の関数以外は初期設定です。

tc4511bp_data_set(9);

PORTAレジスタは標準ヘッダファイルである「pic16F1827.h」に定義がありますが、これを使って1ビット操作をすると出力がバグることがあります。

レジスタのビット長(PORTAは8bit)で一気に書くと問題がないので、まとめて書き換えできるように以下の共用体を1つ用意しています。

typedef union
{
    UCHAR PORTA_ALL_1BYTE;           /* 1byte */

    struct
    {
        /* Memory sharing with "TRISA_USER". */
        UCHAR BIT_RA0 : 1;      /* 0 */     /* The 1st element defined is the LSB */
        UCHAR BIT_RA1 : 1;      /* 1 */
        UCHAR BIT_RA2 : 1;      /* 2 */
        UCHAR BIT_RA3 : 1;      /* 3 */

        UCHAR BIT_RA4 : 1;      /* 4 */
        UCHAR BIT_RA5 : 1;      /* 5 */
        UCHAR BIT_RA6 : 1;      /* 6 */
        UCHAR BIT_RA7 : 1;      /* 7 */
    };
}PORTA_USER_BF_t;
参考
【PICマイコン】RA1ポートの電圧が正しく出力されない(パルスになる)場合 -1ビット操作使用時の注意点-

今回はPICマイコンのコンパイラ仕様で沼ったので注意点をメモしておきます。 データシートにそれっぽいことは書いてありますが、原因ははっきりわかってないので参考程度にお願いします。 備忘録。 発生した問 ...

続きを見る

動作確認

前述したプログラムについて、引数の数字を0~9に実行し、7セグメントLEDの表示を確認してみます。

tc4511bp_data_set(0);
/*                ↑:0 ~ 9 を入力*/

結果は以下の通り。

正常に動作しました。

個人的に6、9は上下にバーがあるタイプが好みだったんですが、今回のICはないタイプでした。

データシートに記載のあるフォーマットで数字が表示されていることが確認できました。

まとめ

今回は7セグメントLEDを制御するICである「TC4511BP」を使用してみました。

マイコンのGPIOで制御でき、シンプルで使いやすいICかな~と思います。

今回は1桁のみだったので、入力の信号線が7本から4本になったところで・・・感がありますが、2桁、3桁になると効果は大きいかなと思います。

ダイナミック点灯制御に対応しているため、その辺も後々試してプログラムを追記します。

それでは、また。

-実験・調査
-, , ,