wiki:KanjiROM

Version 11 (modified by kishida, 4 years ago) (diff)

--

日本語フォントROM GT20L16J1Y の使い方

日本語フォントROM GT20L16J1Y Breakoutでも販売している日本語フォントROM「GT20L16J1Y」の詳細説明と、サンプルプログラムです。
データシートもありますが、中国語でわかりにくいのと内容に若干不足があるので補足説明をします。


収録内容

1.全角文字

1文字あたり32byteの容量を持ちます。
JISXの第一水準及び第二水準の漢字に対応しています。
機種依存文字(全角1文字の「メートル」やローマ数字など)の配置はWidowsと一致しません。

番号アドレス(10進数)内容説明
00(空白)JISX 1区1点
132JISX 1区2点
136143552JISX 15区46点
126143584JISX 16区1点
7716246912JISX 84区6点
7717246944(空白)1区と同等の内容
7810249920
78112499524区と同等の内容
79052529605区と同等の内容
7998255936(空白)

2.半角文字

一文字あたり16byteの容量を持ちます。
独自の配列(?)で半角ひらがなと半角カタカナに対応しています。
メモリアドレスのオフセットは10進数で255968です。下記の表にはアドレスを通しで載せてあります。

番号アドレス(10進数)内容説明
0255968(空白)ASCIIコード準拠
95257488(空白)
02575040下記の表1を参照してください
1282595360下記の表2を参照してください
261261680)

表1

左上から順番に記録されています。「空」となっているところは空です。
全部半角サイズです。全128文字。

0123456789:;()
*#/

表2

左上から順番に記録されています。「空」となっているところは空です。
全部半角サイズです。全134文字。
こちらに記録されているアルファベットはサンセリフです。(ASCII互換の部分はセリフ体)

0123456789_:;,.
*ABCDEFGHIJKLMNO
PQRSTUVWXYZ
#abcdefghijklmno
pqrstuvwxyz@||?
&/()

通信方法

1.SPI通信で0x03を書き込みます。
2.SPI通信でデータを読みたいアドレスを8bit*3回で送ります。上位から順に送信します。右詰めです。
3.送ったデータにしたがってダミーデータ0x00を16回又は32回送ります。この時に受信されるデータがROMの内容です。

受信内容

半角または全角によって受信するデータのサイズが違います。半角は16byte、全角は32byteです。
どちらも少し変わった配列になっていますので、データシートを御覧ください。表示先によって一工夫必要になります。


サンプルプログラム

Arduino IDE のシリアルモニタから送った日本語を、 ROMから読みだしてシリアルモニタに返すプログラムです。 半角カナには対応していません。

/* GT20L16J1Y用サンプルプログラム
 * Arduinoのシリアルモニタから送信されたSJISの文字を
 * ROMから読みだしてシリアルモニタに返す
 * 半角カナまわりはデータにはあるがROM内の順とJISX規格での順が
 * 一致しないため未実装
 *
 * memo:9/30 00:00
 * memo:10/7 18:30
 */

#include <SPI.h>
unsigned char matrixdata32[32]; //16×16用表示データ
unsigned char matrixdata16[16]; //16×8用表示データ

void setup (void)
{
  pinMode (SS, OUTPUT);
  Serial.begin(115200);
  /*SPI通信の設定*/
  SPI.begin ();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(3);
  SPI.setClockDivider(SPI_CLOCK_DIV16);

  Serial.println("input word which you want to show");

}

void loop (void)
{

  if (Serial.available() > 0)
  {
    /*Arduinoのシリアルモニタから送られてくる日本語がSJISであることに注意*/
    delayMicroseconds(200);//最低でも2文字受信したい
    uint8_t msbdata = Serial.read();//1バイト目 //10/07
    /*SJISの1バイトコードか否か*/
    if ( (msbdata < 0x80) || ((0xA0 < msbdata) && (msbdata <= 0xdF)) )
    {
      showSJIS1byte(msbdata);
    } else
    {
      uint8_t lsbdata = Serial.read();//2バイト目 //10/07 
      uint16_t data =  ((msbdata << 8) + lsbdata); //2
      showSJIS2byte(data);
    }
  }
}

/*1byteのSJISを表示する*/
void showSJIS1byte(uint8_t code)
{
  readFontASCII(code);
  sendDotsToSerial16();
}

/*2byteのSJISを表示する*/
//showSJIS2byte(SJIS文字コード)
void showSJIS2byte(unsigned short code)
{
  /*Arduinoのシリアルで日本語はSJIS送信なのでSJIS->JISx0208変換をする*/
  Serial.print("SJIS, 0x"); Serial.print(code, HEX); Serial.print("\t");
  uint8_t c1 = ((code & 0xff00) >> 8);
  uint8_t c2 = (code & 0xFF);
  if (c1 >= 0xe0)
  {
    c1 = c1 - 0x40;
  }
  if (c2 >= 0x80)
  {
    c2 = c2 - 1;
  }
  if (c2 >= 0x9e)
  {
    c1 = (c1 - 0x70) * 2;
    c2 = c2 - 0x7d;
  } else
  {
    c1 = ((c1 - 0x70) * 2) - 1;
    c2 = c2 - 0x1f;
  }
  /*読み出し*/
  readFontJIS(c1, c2);
  /*表示*/
  sendDotsToSerial32();
}

/*漢字ROMとやりとり*/
//readFontJIS(JIS上位8bit,JIS下位8bit);
void readFontJIS(uint8_t c1, uint8_t c2)
{
  /*jisx変換後の表示*/
  Serial.print("jisx up8 = 0x"); Serial.print(c1, HEX); Serial.print("\t");
  Serial.print("jisx down8 = 0x"); Serial.print(c2, HEX); Serial.print("\t");
  /*jisxの区点を求める*/
  uint32_t MSB = c1 - 0x20;//区
  uint32_t LSB = c2 - 0x20;//点
  /*JISの句点番号で分類*/
  uint32_t Address = 0;
  Serial.print("MSB = d"); Serial.print(MSB, DEC); Serial.print("\t");
  Serial.print("LSB = d"); Serial.print(LSB, DEC); Serial.print("\t");
  /*各種記号・英数字・かな(一部機種依存につき注意,㍍などWindowsと互換性なし)*/
  if (MSB >= 1 && MSB <= 15 && LSB >= 1 && LSB <= 94)
  {
    Address = ( (MSB - 1) * 94 + (LSB - 1)) * 32;
  }
  /*第一水準*/
  if (MSB >= 16 && MSB <= 47 && LSB >= 1 && LSB <= 94)
  {
    Address = ( (MSB - 16) * 94 + (LSB - 1)) * 32 + 43584;
  }
  /*第二水準*/
  if (MSB >= 48 && MSB <= 84 && LSB >= 1 && LSB <= 94)
  {
    Address = ((MSB - 48) * 94 + (LSB - 1)) * 32 + 138464;
  }
  //
  /*GT20L16J1Y内部では1区と同等の内容が収録されている*/
  if (MSB == 85 && LSB >= 0x01 && LSB <= 94)
  {
    Address = ((MSB - 85) * 94 + (LSB - 1)) * 32 + 246944;
  }
  /*GT20L16J1Y内部では2区、3区と同等の内容が収録されている*/
  if (MSB >= 88 && MSB <= 89 && LSB >= 1 && LSB <= 94)
  {
    Address = ((MSB - 88) * 94 + (LSB - 1)) * 32 + 249952;
  }
  /*漢字ROMにデータを送信*/
  digitalWrite(SS, HIGH);
  Serial.print("Address = "); Serial.println(Address, HEX);
  digitalWrite(SS, LOW);  //通信開始
  SPI.transfer(0x03);
  SPI.transfer(Address >> 16  & 0xff);
  SPI.transfer(Address >> 8   & 0xff);
  SPI.transfer(Address        & 0xff);
  /*漢字ROMからデータを受信*/
  for (int i = 0; i < 32; i++)
  {
    matrixdata32[i] = SPI.transfer(0x00);
  }
  digitalWrite(SS, HIGH); //通信終了
}//spireadfont

/*漢字ROMとやりとり*/
//readFontASCII(ASCIIコード);
void readFontASCII(uint8_t ASCIICODE)
{
  Serial.print("ASCII,0x");Serial.print(ASCIICODE, HEX); //10/07
  uint32_t Address = 0;
  /*ASCII文字*/
  if (ASCIICODE >= 0x20 && ASCIICODE <= 0x7F)
  {
    Address = ( ASCIICODE - 0x20) * 16 + 255968;
  }
  /*漢字ROMにデータを送信*/
  digitalWrite(SS, HIGH);
  Serial.print("  Address = "); Serial.println(Address, HEX);
  digitalWrite(SS, LOW);  //通信開始
  SPI.transfer(0x03);
  SPI.transfer(Address >> 16  & 0xff);
  SPI.transfer(Address >> 8   & 0xff);
  SPI.transfer(Address        & 0xff);
  /*漢字ROMからデータを受信*/
  for (int i = 0; i < 16; i++)
  {
    matrixdata16[i] = SPI.transfer(0x00);
  }
  digitalWrite(SS, HIGH); //通信終了

}

/*シリアルモニタへ16*16のデータを表示する*/
void sendDotsToSerial32()
{
  /*上半分*/
  for (int i = 0; i < 8; i++)
  {
    for (int b = 0; b < 16; b++)
    {
      char byteDigit = (1 << i);
      if (matrixdata32[b] & byteDigit)
      {
        Serial.write("XX");
      } else
      {
        Serial.write("--");
      }
    }
    Serial.println();
  }
  /*下半分*/
  for (int i = 0; i < 8; i++)
  {
    for (int b = 16; b < 32 ; b++)
    {
      char byteDigit = (1 << i);
      if (matrixdata32[b] & byteDigit)
      {
        Serial.write("XX");
      } else
      {
        Serial.write("--");
      }
    }
    Serial.println();
  }
  Serial.println();
}//sendDataToSerial32


/*シリアルモニタへ16*8のデータを表示する*/
void sendDotsToSerial16()
{
  /*上半分*/
  for (int i = 0; i < 8; i++)
  {
    for (int b = 0; b < 8; b++)
    {
      char byteDigit = (1 << i);
      if (matrixdata16[b] & byteDigit)
      {
        Serial.write("XX");
      } else
      {
        Serial.write("--");
      }
    }
    Serial.println();
  }
  /*下半分*/
  for (int i = 0; i < 8; i++)
  {
    for (int b = 8; b < 16; b++)
    {
      char byteDigit = (1 << i);
      if (matrixdata16[b] & byteDigit)
      {
        Serial.write("XX");
      } else
      {
        Serial.write("--");
      }
    }
    Serial.println();
  }
  Serial.println();
}//sendDataToSerial32

動作サンプル

Sample1

「技術」と入力してEnterを押した時の動作です。
sample1

Sample2

「Ss」と入力してEnterを押した時の動作です。
sample2

Attachments (8)

Download all attachments as: .zip