LEDで漢字表示

#include <16f648A.h>
#fuses HS,NOWDT,PROTECT
#use delay(CLOCK =4000000)
void main()
   {                           //font配列
    int data2[16] ={0x8c,0xcc,0x6c,0x2d,0x2d,0x2d,0x2c,0x0f,
           0x00,0x20,0x4f,0x81,0x01,0x17,0x21,0x41}; //満left
    int data1[16] ={0x07,0x03,0x03,0xfb,0x6b,0x6b,0x63,0xff,
           0x60,0x60,0xff,0x98,0x98,0xfe,0x98,0x98}; //満right
    int data4[16]={0xff,0x01,0x01,0x01,0x01,0x3f,0x00,0x60,
           0x30,0x18,0x18,0xcc,0xcc,0xff,0x01,0x01};  //空left
    int data3[16] ={0xff,0x80,0x80,0x80,0x80,0xfc,0x00,0x00,
           0x3e,0x66,0x60,0x63,0x63,0xff,0x80,0x80}; //空right
    int data6[16] = {0xce,0x43,0x62,0x22,0x33,0x12,0x12,0x00,
           0x23,0x62,0xc2,0x03,0x12,0x32,0x63,0x00}; //混left
    int data5[16] = {0x0e,0xd3,0x11,0x10,0xdc,0x16,0x10,0x00,
           0xfc,0x04,0x04,0xfc,0x04,0x04,0xfc,0x00}; //混right
    int *ptr1,*ptr2,*ptr3,*ptr4,*ptr5,*ptr6;
    int i, j, y;
    int a1,a2;
   while(1)
    {
     switch((input_b())& 0x07)
      {
       case 6:case 0:case 2:case 4:             //満
        output_Low(pin_b7);               
        output_Low(pin_b6);             // inhibit Low
        ptr1=data1;         //data1 のアドレスをポインタに渡す
        ptr2=data2;         //data2 のアドレスをポインタに渡す
        for (i=0 ; i<16; i++)
         {output_b(0x00);     
          a1=*ptr1;        //ポインタアドレスのデータをa1 に
          a2=*ptr2;
         for (j=0; j<8; j++)
           {y=a1;         //adressiのdata8個を順次出力
           y&=0x01;              //LSB を取り出し
           output_low(pin_b3);            //clkをlow
           output_bit(pin_b5,y);           //Data出力
           output_high(pin_b3);           //clkをhigh
           output_low(pin_b5);
           a1>>=1; }           //a1を1ビット右シフト
         for (j=8; j<16; j++)
           {y=a2;         //adressiのdata8個を順次出力
           y&=0x01;              //LSB を取り出し
           output_low(pin_b3);        //clkをlowからhigh
           output_bit(pin_b5,y);
           output_high(pin_b3);
           output_low(pin_b5);
           a2>>=1; }
        j=0;       //ループ脱後j=0x10となるのでクリアしておく
        output_high(pin_b6);             // inhibit high
        output_high(pin_b4);             // latch high
        output_a(i);          // i で A0,A1,A2,A3を設定
        output_Low(pin_b4);            // latch = Low
        ptr1++ ;
        ptr2++ ; }
        break;
       case 5:case 1:                    //空
        output_Low(pin_b6);             // inhibit Low
        ptr3=data3;         //data1 のアドレスをポインタに渡す
        ptr4=data4;         //data2のアドレスをポインタに渡す
        for (i=0 ; i<16; i++)
         { output_b(0x00);
          a1=*ptr3;       //ポインタアドレスのデータを a1 に
          a2=*ptr4;
         for (j=0; j<8; j++)
           {y=a1;         //adressiのdata8個を順次出力
           y&=0x01;              //LSB を取り出し
           output_low(pin_b3);          // clk を low
           output_bit(pin_b7,y);           //data出力
           output_high(pin_b3);
           output_low(pin_b5);
           a1>>=1; }           //a1を1ビット右シフト
          for (j=8; j<16; j++)
           {y=a2;         //adressiのdata8個を順次出力
           y&=0x01;              //LSBを取り出し
           output_low(pin_b3);        //clkをlowからhigh
           output_bit(pin_b7,y);
           output_high(pin_b3);
           output_low(pin_b5);
           a2>>=1; }
           output_high(pin_b6);          // inhibit high
           output_high(pin_b4);          // latch high
           output_a(i);         //iでA0,A1,A2,A3を設定
           output_Low(pin_b4);         // latch = Low
           ptr3++ ;  
           ptr4++ ; }
           break;
       case 3:                       //混
        output_Low(pin_b6);             // inhibit Low
        ptr5=data5;         //data1 のアドレスをポインタに渡す
        ptr6=data6;         //data2のアドレスをポインタに渡す
        for (i=0 ; i<16; i++)
         {output_b(0x00);
          a1=*ptr5;        //ポインタアドレスのデータをa1 に           a2=*ptr6;
         for (j=0; j<8; j++)
          {y=a1;          //adressiのdata8個を順次出力
          y&=0x01;               //LSBを取り出し
          output_low(pin_b3);
          output_bit(pin_b5,y);
          output_bit(pin_b7,y);
          output_high(pin_b3);
          output_low(pin_b5);
          a1>>=1; }
         for (j=8; j<16; j++)
          {y=a2;          //adressiのdata8個を順次出力
          y&=0x01;               //LSB を取り出し
          output_low(pin_b3);
          output_bit(pin_b5,y);
          output_bit(pin_b7,y);
          output_high(pin_b3);
          output_low(pin_b5);
          a2>>=1; }
          output_high(pin_b6);           // inhibit high
          output_high(pin_b4);           // latch high
          output_a(i);          //iでA0,A1,A2,A3を設定
          output_Low(pin_b4);          // latch = Low
          ptr5++ ;
          ptr6++ ;}
          break;
       default:
       break;
      }
    }
   }

 LED表示で縦・横各々16ドットあれば、JIS第一水準の漢字を大部分を表現できます。1文字あたりのエリアは、16×16=256ドットということになります。文字を表現するには、各ドットを点灯(オン)又は消灯(オフ)します。各ドットのオン・オフを直接制御すればわかりやすいですが、ドット分の配線が必要だし、制御回路も複雑になります。文字を変える必要のない固定文字表示の場合は、必要な部分だけLEDを配置するLED固定文字(パーシャル)表示機もありますが、これについてはこのサイトのリンク先で触れています。LED表示機は大きくいえば制御回路・ドライブ回路・LEDマトリクス回路で構成されます。ここでは、16ビットのシフトレジスタの各ビットにドライバを通じてLEDにつなぎ、PIC16F648Aを使って、3文字を切換えて表現できる表示機について説明します。PICは表示機に必要な信号を生成・送出します。クロックは4Mのセラロックかクリスタルを使用します。静止表示ですのでこれで十分です。ランニング表示には耐えられないと思います。セラコン内臓のセラロックを使用すればクロック回路の配線がシンプルになります。

ハードウエアの説明
トップページに戻る

スイッチの切換で満、空、混を表示します。フォントの色は満が赤、空が緑、混が橙です。橙は赤と緑の混色です。

ソースリスト

製作した表示機の写真です。スイッチで表示内容を切換えます。

16×16のドットマトリクス上で表現するとこのようになります。PIC16F648Aの扱えるのは8ビットですので、このマトリクスを縦に2等分し、8ビットで扱えるようにします。

このようにカラムとローが連動して文字を表示するわけですが、ここでは"
満"を表示するためのプログラムについて説明します。

 シフトレジスターの各ビットに接続された駆動用トランジスタのコレクタにLEDマトリクス回路のロー(行)のLEDが接続されています。PICから送られてきたシリアルデータはクロックによりシフトレジスタで順次おくられ16個入った時点でラッチ信号でラッチされます。これがドライバトランジスタのベースに入るのでコレクタにつながったLEDを動かします。
一方、ロー(行)アドレスを指定するためにPICからA0〜A3のスキャン信号がきています。これが4 to 16 LINE DECORDER で4ビットのバイナリー値を0から15の数値に変換します。ICはC−MOSでいえば74HC154でTTLでいえば74LS154です。

 ドライブ回路はPICからの各信号を受け、16ビットシフトレジスタ、ラッチ、ドライバーによりLEDマトリクス回路を制御します。

 文字データはプログラミング時に入れておきます。回路図の左側は文字を切換える回路で、フォトカプラは切換えスイッチからの配線と、PICとのアイソレーションをとるためです。後述する満空表示機では、車の出入りを管理する場所と、表示機間は結構距離があるので、誘導雷による高圧が乗ってくることがあるためです。又、思わぬ廻りこみがあったりするのを防止するためです。PICのVcc1、GND1とフォトカプラのダイオードのVcc2、GND2が分離されているのはこのためです。距離が短い場合は同じでも問題ありません。
PICは文字データのメモリ、行・列のアドレス指定(A0,A1,A2,A3)、文字データのシリアル出力(SD_R,SD_G)、シフトレジスタのためのラッチ信号(LT)、LEDの点灯・不灯を指示するインヒビット(INH)、クロック(CLK)の出力を行います。

同様に右半分です。

これが左半分です。行アドレス毎にみれば8ビットです。この図の左に記載してある数字は8ビットをHEX表示した数字です。