ゆるく楽しむプログラミング

日本語フォントROM GT20L16J1Y

SPI接続の漢字ROMです。
スペックシートが中国語で読めないので (ノД`)・゜・。
販売元のスイッチサイエンスさんの解説とサンプルプログラムを参考に使用していいます。

スペック

電源 2.2~3.6V 
日本語記号 1644文字
日本語漢字 6355 文字
ASCII(半角) 128文字 
ASCII(全角)  96文字 

DIP化変換ボードでは左上に▼マークが付いているのが1番ピンです。



接続

信号レベルは3.3VなのでArduinoで使用する場合はレベル変換が必要です。

信号レベルを3.3V/5Vで切り替えられるArduinoUNO互換機
KEYESTUDIO Plus Board for Arduino UNO R3
を使う方法もあります。

レベルコンバータは秋月電子で購入した
4ビット双方向ロジックレベル変換モジュール
を使用しました。


ハードウエアSPIを使用する場合、CS以外のピンは決まっています。
複数のSPIデバイスを操作することもあるので、CSは任意のピンを使用できます。

RaspberryPi PICOの場合は、2チャンネル存在して使用するピンを変更可能・・・の筈ですが
公式(Mbedベース)のボードライブラリを使用する場合には下記の組み合わせでないと上手く動きませんでした。
信号名  ArduinoUNO  RaspberryPi PICO  GT20L16J1Y 
SLCK (SCK) 13  GP2  1
MOSI (SI) 11  GP3  6
MISO (SO) 12  GP4 
CS (SS) 10  GP5 

SLCKは16MHzまでは問題なく動きました。
それ以上は試していません。

フォントデータの読み出し手順

1バイト文字(半角文字)の場合
 ASCIIコードからアドレスを算出
if(ASCIICODE >=0x20 && ASCIICODE <=0x7F)
Address =( ASCIICODE - 0x20)*16+255968;

2バイト文字(JIS2080 区点コード)の場合
 JIS X 0208の区をMSB、点をLSBとしたときのアドレスを求めています。
 アドレスは最大18bitになるので、変数の宣言は32bitで行うほうが安全です。
if(MSB >=1 && MSB <= 15 && LSB >=1 && LSB <= 94)
Address =( (MSB - 1) * 94 + (LSB - 01))*32;
else if(MSB >=16 && MSB <= 47 && LSB >=1 && LSB <= 94)
Address =( (MSB - 16) * 94 + (LSB - 1))*32+43584;
else if(MSB >=48 && MSB <=84 && LSB >=1 && LSB <= 94)
Address = ((MSB - 48) * 94 + (LSB - 1))*32+ 138464;
else if(MSB ==85 && LSB >=0x01 && LSB <= 94)
Address = ((MSB - 85) * 94 + (LSB - 1))*32+ 246944;
else if(MSB >=88 && MSB <=89 && LSB >=1 && LSB <= 94)
Address = ((MSB - 88) * 94 + (LSB - 1))*32+ 249952;

1バイト文字は16バイト(8x2)、2バイト文字は32バイト(16x2)のビットパターンで構成されます。
ビットマップの並びがSSD1306と同じなので、このままビットパターンとして書き込めば正しく表示されます。


文字コード変換

GT20L16J1Yは区点コードからアドレスを算出します。
ArduinoIDEはUTF-8で動作しているのでUTF-8 → JIS2080への変換が必要になります。
JISx / JIS / SJIS(Shift-JIS) / EUC は 相互に変換可能
UTF-8 / UTF-16 / UTF-32 も相互に変換可能
JISx / JIS / SJIS(Shift-JIS) / EUC と UTF-8 / UTF-16 / UTF-32は
文字の並び自体が違うので、変換には変換表が必要です。
変換表は Unicode対応 文字コード表 (ash.jp) をベースに作成しました。

変換テーブルは文字コードが2バイトに固定されている UTF-16 → SJIS で作成しました。
UTF-8 →(算出)→ UTF-16 →変換テーブル→ SJIS →(算出)→ JISx区点コード
の順で変換しています。

デモプログラムは表示にSSD1306(I2C接続)を使用しています
KanjiDisp_DEMO1.zip (ArduinoUNO用) 

KanjiDisp_DEMO1.ino 漢字表示デモ 
text.h  漢字表示デモ サンプルテキスト(「吾輩は猫である」 冒頭部分) 
OLED.h  OLED SSD1306表示クラス ヘッダ 
OLED.cpp  OLED SSD1306表示クラス 
KANJIROM.h 漢字ROMアクセスクラス ヘッダ 
KANJIROM.cpp 漢字ROMアクセスクラス 
u2s.h  UTF-16 → SJIS 変換クラスヘッダ 
u2s.cpp  UTF-16 → SJIS 変換クラス 
u2sTable.h  UTF-16 → SJIS 変換テーブル 

解説動画