Vol.909 27.dec.2024

BDFフォントパターンエディッタ ジグソーパズル I2C接続RAM(47C16)を使う

F EXCELで作るBDFフォントパターンエディッタ

by fjk

 abc905でフォントデータを連続的にROMに書き込むことができたが、BDFファイルに無いフォントパターンの作成が面倒だった。
 そこで、フォントパターンをマウスのダブルクリックで作成し、そのパターンをROMやファイルに書き込めるフォントエディタを作成した(16x16、8x16 dotフォントのみ対応)。
 なお、Excelでマウスのダブルクリックで文字や記号を入力する方法として、「ごぶろぐさんのページ」を参考にさせていただいた。

1.フォントコピー
左画面のフォントパターンを右画面のエディッタ画面に条件(Set、Or、And、Xor)付きでコピー。
 
2.CSVファイルからフォントパターンを取り込む
@ abc905等で作成したCSVファイルを「ファイル読込」で読み込む(FileNameが変わることあり)
A Code Hex(B23セル)[赤枠]に文字コード(16進数)を入力
B「読み込んで表示」をクリック(読込後、不要になったらシートを削除可[右端のシートが有効])
[ファイル内に同じコードが複数あった場合、最初に見つかったデータを取得します]
 
3.シリアル通信で読み込んだフォントデータをプロット(U:ダンプコマンドに対応)
開始行(受信セル枠内で)、ColSize(C2セル)を確認・セットし、「パターン読込」をクリック
 
※パターン編集後、「BDFコピー」を押すと、左のパターンにコピーされるので、保存や書込ができる
※エディタでは、パターンの(条件付き)コピー、移動、ビット反転、一時保存、保存データ読出し、消去、が可能

BDFフォントビュアー・エディタ画面例
(赤枠内のセルでダブルクリックすると、ドットのOn/Offができる)

★ BDFフォントパターンエディッタ使用例
  @ 丸文字の作成例  BDF_Edita.xlsm(zip)使用
  A 組文字の作成例  BDF_Edita3.xlsm(zip)(強化版)使用
ExcleVBAのソースリスト(主に追加関数)


J ジグソーパズル

by fjk

 我が家の正月行事として、「ジグソーパズル」があります。毎年、年末年始に、炬燵の上でパズルを組み上げています。ジグソーパズルの組合せは、目と頭と手先を使うので、ボケ防止になると思います。
 パズルの組み合わせ方法はいくつかあると思いますが、我が家では、

1.パズルの完成サイズに合うパネル・フレームを準備する
(組立途中でバラバラにならいように・・。あると、チョット移動させるときも便利)
パネルはジグソーパズルを扱っている店舗で入手できます(色やデザインがいろいろあります)
 
2.パネルの透明シートの上でパズルを組み合わせていきます(詳細は以下を参考に)
パズルの下にシートがあると、糊付け時などで、完成パズルを移動させるのに便利です。
@ コーナーと外枠のピース(ピースの辺がまっすぐ)を選別する。その他のピースは特徴(色、模様)を決めて一緒に選別。
A 選別したピースをパズルの空き箱などに綺麗に並べる(これが大切)。異形(変型ピース、ピースの辺の凸と凹が順でないもの)は基本ピースとは別に分けておく。
 箱はサイズが異なるものを利用すると、並べたピースセットを重ねて収納できる。
B ピースの特徴(色、形、模様、色や模様の境界線)からピースを組合わせてみる。
(正しく組み合っているかは、2カ所以上で隙間がなく、幅、模様なども合っているか確認)
C 最初に、コーナーと辺の周辺部からピースを組み合わせていく。
D 周辺部が出来たら、特徴があり判りやすいピースで島(複数のピースが組合ったもの)をつくる。一方から順に組合せるのでは無く、組合わせやすいピース同士から・・。
E 島の回りに組合うピースを探し、外枠までどんどん広げて行く(他の島に組合う場合もある)。
 
これが基本ですが、ピースを探す時は、組合せたいピースを持って、箱の中のピースに合わせてみる。サーチは2段階で行います。この時、外したピースが、どの場所のピースか判るように、おはじき等をピースを取り外した場所に置いておいておきます。
 
@ ピースを空中に持ち、色や形で合いそうな候補ピースを素早く探す[1段階目]。
A @で見つからない場合は、ピースを1個1個はめ込んでみる[2段階目]。
B それでも見つからない場合はあきらめる(ピースが少なくなってから再トライ)。
C どうしても手がかりが無い場合は、全てのピースを対象に、組み合うか捜してゆきます。
  ★ abc690 も参考にして下さい
 
3.組合せ完成後、ジグソーパズルに付属の糊でピースを固定し、乾燥後、再びパネルにはめ込みます
(糊付け時、糊がピースの下に染み出るので、糊がくっつかないシートを下に敷くと良い)
パネルにはめる時、糊で固定したジグソーパズルは透明シートの下にする。


作成途中(ピースの島が点在)

まもなく完成(秋深まる瑠璃光院)

※ ここも参考になります「ジグソークラブ


P PICミニBBシリーズ(19)  〜I2C接続RAM(47C16)を使う

by fjk

・I2C接続で利用できるRAMは少なく、Microchip社の16kbitの47C16(8pin)を使ってみた。
・47C16はVcc=5Vで動作するEERAMで、EEPROMへのバックアップ機能を備えている。
・シャットダウン時にSRAM⇒EEPROM、電源投入時にEEPROM⇒SRAMへのコピーが行われる。
・コピー機能を有効にするには、Vcap端子(1番ピン)に10μFのコンデンサを接続しておく必要がある。
   47C16データシート(日本語)

【ハード】 (abc907から、PICをPIC16F18326に、47C16廻りの配線を変更)

回路図 (A2、HSは内部でGndにプルダウン)

書込んだRAMデータの表示例
【ソフト】
これまでに使用したI2C接続外部メモリのアクセス方法を纏めてみると、以下の様になり、最初のバイト(コマンド)のみ考慮すれば、ROMもRAMも、ほぼ同じシーケンスでアクセスすることができる。
 


 
・ROMとRAMの両方に対応するので、ファイル名をi2c_MEM.cに変更
・abc908からメモリ読み書き関数名をROMからMemに変更し、if(adr<0x80000)文も削除した。
・47C16の読み書きは正常に行えた。
※ 何故か47C16のASEビット(Default=0)を1にできず、ROMへの自動保存ができなかった(今後の課題)。

  ★ PICプログラムのソースリスト


【フォントエディッタ使用例(1)】 (丸数字文字の作成例。なおAA-AG列は非表示にしています)

@左画面に数字を読み出す
A右画面に上書きモードでコピー
B左画面に丸文字を読み出す
CORモードで右画面にコピー
Dマウスでパターンを修正
EBDFコピーで左画面にコピー
F左画面にコピー後、文字コードを設定しファイルに保存、またはROMに書込を行う。

【フォントエディッタ使用例(2)】  BDF_Edita3.xlsm(zip)(強化版)使用
 BDF_Edita.xlsmに「BDFを追加保存」と「横縮小」ボタンを追加したので、組文字フォント「令和」を作成してみる。

@ "和"を左画面に読み込み、右画面にコピー(set)
A「横縮小」で8x16ドットに、「M+」で一時保存
B 同様に"令"を読出し右画面にコピー、横縮小
C パターン移動で左に7ドット移動後、BDF転送
D「RM」で縮小した「和」フォントを読み戻す
E ORモードで「令」をコピー。マウスで修正
F「BDF転送」で左画面にコピー後、Codeに登録したい新しい漢字コード(例えば2D5E)を入力。
それから、「Hexデータ記録」や「BDFを追加保存」、さらに「ROM書込」を実行
G 変更したBDFファイルまたはCSVファイルを再度読み込み、code(B23セル)に指定したコードを入力後、
「パターン表示」(BDF)または「パターン読込」(CSV)で作成したフォントが表示されれば成功です。
(サーチするフォントデータは一番右にあるシートのデータです。不要なシートは削除してもOK)
※ 保存したCSVファイルは、C言語のソースとしてそのまま使用できる書式にしています。
  ファイルはPIC接続ROM以外の、他のライター・プログラムでも使用できると思います。

(注)「BDFファイルの追加」は、オリジナルの”ENDFONT”以降にビットマップデータを追加します。
すなわち、正式のBDFファイルにするには、途中の”ENDFONT”をテキストエディッタ等で削除して下さい
(本BDFエディッタではENDFONTをチェックしていないので、追加フォントはエラー無く読み出せますが・・)。
 
(注)ファイルの保存は「カレントフォルダー」のファイルになります。保存時には以下に注意
・カレントフォルダーは「カレントフォルダーの変更」で確認できます
・ファイル名が正しいか?(複数のファイルを読み込むと変わる場合がある。C1セルで変更)
・フォントのドットサイズ(特にCorSize)が正しいか?(正しくなければC2セルで変更)
・保存する漢字コードが正しいか?(正しくなければB23セルで変更)
・CSVファイルで行末に追加される文字はD23セルの文字です(丸数字などは表示しておく)
・CSVファイルには左画面データ、BDFファイルには右画面データが保存されます。
 
(注)作成したフォントをROMへ書き込むには
@ 書き込みたいROMアドレスをAD2セルに16進数で入力
A ColSize(=16/8)をC2で確認。正しくなければ変更
B「送信データ作成」をクリック
C「送信」をクリックすると、ROMにデータが転送され、フォントデータが書き込まれる
 
(注)半角フォントをROMに書き込むには、C2セル(CorSize)を 8 にすること
   (その後、全角フォントを読み込むと16に再セットされます)。
 
(注)マクロ等でセルを直接指定しているので、列や行の削除・追加は行わないこと!!(表示/非表示の設定はOK)


【BDFフォントエディッタのVBAプログラム】
  abc905に追加した関数のみ紹介(詳細は 16dot_sheets.bas[zip]DBFEdita.bas[zip]DBFEdita3.bas[zip] を参照)
 ※また、一部のセルの数式・値を(関数で値をセットするように)変更しています。

【16dot_sheet.bas】 (マウスアクションなど)

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    If Intersect(Target, Range("AI5:AX20")) Is Nothing Then Exit Sub
    With Target
        Select Case .Value
            Case ""
                .Value = "●"
            Case "●"
                .Value = ""
        End Select
    End With
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim c As Variant
    If Not Intersect(Target, Range("D23")) Is Nothing Then
        Range("B23") = WorksheetFunction.Dec2Hex(Range("b24"), 4)
    End If
End Sub

 
【Module1】に、以下の記述を追加して下さい
  @(General)(Declaration)に
    Dim Bdf(16) As Integer

  A「BDFEdita3.bas」 (BDFEdita.basにsaveBDF()とHorShurink()を追加したもの)

Sub Pattern_Copy()
   Dim row As Integer
   Dim col As Integer
    Dim md As Integer
    md = Worksheets("16dot").Range("AI28").Value
   For row = 0 To 15
     For col = 0 To 15
       If Cells(5 + row, 10 + col) = " " Then
            Select Case md
                Case 0, 2
                    Cells(5 + row, 35 + col) = ""
            End Select
       Else
            Select Case md
                Case 0, 1
                    Cells(5 + row, 35 + col) = "●"
                Case 3
                    If Cells(5 + row, 35 + col) = "" Then
                         Cells(5 + row, 35 + col) = "●"
                    Else
                         Cells(5 + row, 35 + col) = ""
                    End If
            End Select
       End If
     Next col
    Next row
End Sub

Sub BDF_Copy()
    Dim row As Integer
    For row = 0 To 15
        Cells(5 + row, 2) = Cells(5 + row, 51)
    Next
End Sub

Sub findPtn()
    Dim ws As Worksheet
    Set ws = Worksheets(Worksheets.Count)
    Dim code As Variant
    code = Worksheets("16dot").Range("B23").Value
    RowSize = Worksheets("16dot").Range("E2")
    CorSize = Worksheets("16dot").Range("C2")
    Dim i As Integer
    Dim j As Integer
    Dim m As Integer
    Dim b As Integer
    Dim r As Range
    Dim c As Variant
    Dim h As Variant
    Dim rOfs As Integer
    Dim rStr As Variant
    If CorSize = 16 Then        ' 16dot
        rStr = "AH:AH"
        rOfs = -33
    ElseIf CorSize = 8 Then
        rStr = "R:R"
        rOfs = -18
    Else
        rStr = "A:A"
        rOfs = 0
    End If
    With ws.Range(rStr)
        Worksheets("16dot").Range("C1").Value = ws.Name
        Set r = .Find(what:=code, LookAt:=xlWhole)
        Do
            If r Is Nothing Then
                MsgBox (code & "該当無し")
                Exit Do
            Else
              For j = 0 To 1
                For i = 0 To 15
                  h = r.Offset(0, rOfs + i + j * 16)
                  c = Val(Replace(h, "0x", "&H"))
                  For b = 0 To 7
                    m = 2 ^ b
                     If c And m Then
                        Worksheets("16dot").Range("AI5").Offset(b + j * 8, i) = "●"
                     Else
                        Worksheets("16dot").Range("AI5").Offset(b + j * 8, i) = ""
                     End If
                  Next
                Next
              Next
              Exit Sub
            End If
        Loop While Not r Is Nothing
    End With
End Sub

Sub PlotSRdat()
    Dim i, j, b, c, m, ofs, col, row, dot As Integer
    Dim arr() As String     ' 格納する文字列配列
    col = 28        ' Range("AB10")
    row = Worksheets("16dot").Range("AL39") + 7
    If Worksheets("16dot").Range("C2") = 8 Then
        dot = 7
        ofs = 8
    Else
        dot = 15
        ofs = 0
    End If
    For j = 0 To 1
      arr = Split(Cells(row, col), " ")
      For i = 0 To 15
        c = Val("&H" + arr(i))
        For b = 0 To 7
          m = 2 ^ b
          If c And m Then
            Worksheets("16dot").Range("AI5").Offset(b + j * 8, i + ofs) = "●"
          Else
            Worksheets("16dot").Range("AI5").Offset(b + j * 8, i + ofs) = ""
          End If
        Next
      Next i
      row = row + 1
    Next j
End Sub

Sub PatternClear()
    Dim rtn As Integer
    rtn = MsgBox("パターンを消去して良いですか?", vbYesNo + vbQuestion, "確認")
    If rtn = vbYes Then
        Range("Ai5:AX20").Clear
    End If
End Sub

Sub MoveLeft()
    Dim i, j As Integer
    For j = 0 To 15
        For i = 0 To 14
            Range("AI5").Offset(j, i) = Range("AI5").Offset(j, i + 1)
        Next
    Next
    Range("AX5:AX20").Clear
End Sub

Sub MoveRight()
    Dim i, j As Integer
    For j = 0 To 15
        For i = 15 To 1 Step -1
            Range("AI5").Offset(j, i) = Range("AI5").Offset(j, i - 1)
        Next
    Next
    Range("AI5:AI20").Clear
End Sub

Sub MoveUp()
    Dim i, j As Integer
    For j = 0 To 14
        For i = 0 To 15
            Range("AI5").Offset(j, i) = Range("AI5").Offset(j + 1, i)
        Next
    Next
    Range("AI20:AX20").Clear
End Sub

Sub MoveDown()
    Dim i, j As Integer
    For j = 15 To 1 Step -1
        For i = 0 To 15
            Range("AI5").Offset(j, i) = Range("AI5").Offset(j - 1, i)
        Next
    Next
    Range("AI5:AX5").Clear
End Sub

Sub SaveMemory()
    Dim i As Integer
    For i = 0 To 15
        Bdf(i) = Val("&H" + Range("AY5").Offset(i, 0))
    Next
End Sub

Sub RecallMemory()
    Dim i, b As Integer
    Dim m As Long
    Dim rtn As Integer
    rtn = MsgBox("パターンを置き換えて良いですか?", vbYesNo + vbQuestion, "確認")
    If rtn = vbYes Then
        For i = 0 To 15
            For b = 0 To 15
                m = 2 ^ b
                If Bdf(i) And m Then
                    Worksheets("16dot").Range("AI5").Offset(i, 15 - b) = "●"
                Else
                    Worksheets("16dot").Range("AI5").Offset(i, 15 - b) = ""
                End If
            Next
        Next
    End If
End Sub

Sub RevPattern()
    Dim i, j As Integer
    For j = 0 To 15
        For i = 0 To 15
            If Worksheets("16dot").Range("AI5").Offset(i, j) = "" Then
                Worksheets("16dot").Range("AI5").Offset(i, j) = "●"
            Else
                Worksheets("16dot").Range("AI5").Offset(i, j) = ""
            End If
        Next
    Next
End Sub

Sub saveBDF()
    Dim fso         As Object
    Dim tso         As Object
    Dim hData(24)   As String
    Dim i           As Integer
    Dim c As Integer
    Dim rtn As Integer
    rtn = MsgBox(Range("c1") & "に追加して良いですか?", vbYesNo + vbQuestion, "確認")
    If rtn = vbNo Then
        Exit Sub
    End If
    Set fso = CreateObject("Scripting.FileSystemObject")
    strPath = Worksheets("16dot").Range("C1") & ".bdf"
    Set tso = fso.OpenTextFile(strPath, 8, True)
    RowSize = Worksheets("16dot").Range("E2")
    CorSize = Worksheets("16dot").Range("C2")
    c = WorksheetFunction.Hex2Dec(Range("B23"))
    hData(0) = "STARTCHAR " & Range("B23")
    hData(1) = "ENCODING" & Str(c)
    hData(2) = "SWIDTH" & Str(CorSize * 60) & " 0"
    hData(3) = "DWIDTH" & Str(CorSize) & " 0"
    hData(4) = "BBX" & Str(CorSize) & " 16 0 -2"
    hData(5) = "BITMAP"
    For i = 0 To 15
        hData(6 + i) = Range("AY5").Offset(i, 0)
    Next
    hData(22) = "ENDCHAR"
    hData(23) = "ENDFONT"
    With tso
        .WriteLine Text:=Join(hData, vbLf)
        .Close  'ファイルのクローズ
    End With
    Set fso = Nothing
    Set tso = Nothing
    MsgBox CurDir() & "\" & strPath & " にデータを追加しました"
End Sub

Sub HorShurink()
    Dim col, row As Integer
    For row = 0 To 15
        For col = 0 To 7
            If Range("AX5").Offset(row, -col * 2) = "" And Range("AX5").Offset(row, -col * 2 - 1) = "" Then
                Range("AX5").Offset(row, -col) = ""
            Else
                Range("AX5").Offset(row, -col) = "●"
            End If
        Next
    Next
    For row = 0 To 15
        For col = 0 To 7
            Range("AI5").Offset(row, col) = ""
        Next
    Next
End Sub


【OLEDと47C16を使ったPIC用プログラム】
  abc908でメモリがギリギリだったので、PICはメモリに余裕があるPIC16F18326を使用した

・abc909-18326.cファイル
abc909-18326.c + myProject.h(zip)、(abc908と同じ)
 
・i2c_SSD1306.c/hファイル
i2c_SSD1306.c/h + Font_5x7.h (zip)、(abc908と同じ)
 
・i2c_MEM.cファイル
i2c-MEM.c/h(zip)、i2cMEM.hはabc908と同じでファイル名のみ変更

/*******************************(i2c-MEM.c)**************
 *	I2C接続メモリ利用ライブラリ(M24M02/24FC1025 + 47C16)
 ***********************************************************/

#define ROM_24FC1025 0      // 値を0にするとdefinが無効となる
#define ROM_M24M02   2      // 値を0にするとdefinが無効となる

#define ROM_ADR	0x50
#define RAM_ADR 0x52        // M24M02 & 47C16の場合

#define MBFSIZE	64          // メモリ操作用バッファーサイズ

#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#include "i2c_SSD1306.h"
#include "ctype.h"          // isxdigit()
#include "stdio.h"          // puts(),..
#include "stdlib.h"         // atoi()...
#include "string.h"         // strtok()...
#include "myProject.h"

//=== グローバル変数 ========================
static char     Dlm[] = ",";        // 文字列区切りデリミタ

//--- I2Cメモリー用
static uint8_t  Device = 0;         // デバイス・ブロック番号
static uint32_t CrtAdr = 0;         // カレントアドレス
static uint8_t  DBuf[MBFSIZE+2];    // ページメモリ用バッファー
static uint8_t  SqMode;             // 連続モード(=1)か?
static char     SBuf[31];           // 表示用(1行最大30文字)
static uint8_t  LstCmd;             // 現在(最終)のコマンド
static uint16_t LstChr = 0;         // 最終表示文字

/*********************************************
 *  I2C Memory function
 **********************************************/

//----  デバイスのアドレス&ブロック計算
uint8_t calcDev(uint32_t adr){
    uint8_t dv;
    if(adr < 0x80000){
#if  ROM_24FC1025
        dv = ROM_ADR + (uint8_t)(adr >> 17);
        if(adr & 0x10000) dv += 0x04;
#elif ROM_M24M02
        dv = ROM_ADR + (uint8_t)(adr >> 16);
        dv += 0x04;            // E = high
#endif
    }else{
        dv = RAM_ADR;
    }
    return dv;
}

//-----  アドレスadrから、1バイトを読み出す
uint8_t I2C_Mem_Read(uint32_t adr){
    uint8_t bf[2];
    Device = calcDev(adr);
    bf[0] = (uint8_t)((adr & 0x1FFFF) >> 8);
    bf[1] = (uint8_t)adr;               // アドレスセット
    I2C1_WriteNBytes(Device, bf, 2);    // アドレス送信
    I2C1_ReadNBytes(Device, bf, 1);     // データ読込み
    return bf[0];
}

//-----  アドレスadrに、1バイトdtを書き込む
void I2C_Mem_Write(uint32_t adr, uint8_t dt){
    uint8_t bf[3];
    Device = calcDev(adr);
    bf[0] = (uint8_t)((adr & 0x1FFFF) >> 8);
    bf[1] = (uint8_t)adr;               // アドレスセット
    bf[2] = dt;                         // データセット
    I2C1_WriteNBytes(Device, bf, 3);    //書き込む
    __delay_ms(5);
}

//-----  アドレスadrからnバイトをary[]に読み出す
void I2C_Mem_NRead(uint32_t adr, uint8_t *ary, uint8_t n){
    uint8_t bf[2];
    Device = calcDev(adr);
    bf[0] = (uint8_t)((adr & 0x1FFFF) >> 8);
    bf[1] = (uint8_t)adr;               // アドレスセット
    if(n > MBFSIZE) n = MBFSIZE;
    I2C1_WriteNBytes(Device, bf, 2);    // アドレス送信
    I2C1_ReadNBytes(Device, ary, n);    // nバイト読込み
}

//-----  アドレスadrからary[]のnバイトを書き込む
void I2C_Mem_NWrite(uint32_t adr, uint8_t  *ary, uint8_t n){
    uint8_t bf[MBFSIZE + 2];
    Device = calcDev(adr);
    bf[0] = (uint8_t)((adr & 0x1FFFF) >> 8);
    bf[1] = (uint8_t)adr;               // ページ境界に注意!
    if(n > MBFSIZE) n = MBFSIZE;
    memcpy(bf+2,ary,n);                 // ary[]をbf[]にコピー
    I2C1_WriteNBytes(Device, bf, n+2);  // nバイト書込み
    __delay_ms(5);
}

/****** 汎用サブルーチン ********************

//---   以下はabc908と同じなので省略 ----(詳細は添付ファイル参照)

※添付ファイルには、47C16の制御レジスタの読み(Get)書き(seT)コマンドも追加しています。


【PICプログラムのおまけ】
 フォントの作成が容易になったので、JIS第1・2水準の全フォントと機種依存文字の表示を行うため、空きエリアを含めた文字コード順に、M24M02メモリへ格納した。
   フォントの格納アドレスマップ: FontRom3.xlsx(zip) (漢字フォントは0x8000から、半角も変更)
 この変更により、フォントアドレスの計算が簡単になり、プログラムメモリ使用量が7,839バイトと、PIC16F18325(ROM:8Kb)でも使用可能となった。
 フォントパターンをROMに書込後、OLEDの文字表示を確認し、更に細かな修正を何度か加えた。


丸数字(2D21-2D28)の表示例

組文字「令和」(2D5Eとした)の表示例

 DLしたファイル名は"i2C_SSD1306B.zip"ですが、解凍したファイル名は"i2c_SSD1306.c"と同じなので、強化前のファイルに上書きして下さい。
 なお、#define ROM_MAP2 を無効にすると、強化前のファイルと同じになります(この場合、PIC16F18326が必要)。

<i2c_SSD1306に追加・変更した部分> i2c_SSD1306.c(zip)

/************************(i2c_SSD1306.c) ****
 *      OLED library                        *
 *      use for 0.96OLED  ,....             *
 ********************************************/

#include "myProject.h"
#include "Font_5x7.h"

#define I2COLED_ADR     0x3C    // 0x3Dもある
#define OLED_BF_SIZE    80

#define ROM_MAP2

//---  フォントデータアドレス)
#define F_H_ASC     0x00200     // 半角ASCII(20-7E)
#define F_H_KANA    0x00800     // 半角カナ(A1-DF)
#define F_SYM1      0x01000     // 記号1(2121-217E)
#define F_SYM2      0x01BC0     // 記号2(2221-222E)
#define F_SYM3      0x01D80     // 記号3(223A-2241)
#define F_SYM4      0x01E80     // 記号4(224A-2250)
#define F_SYM5      0x01F60     // 記号5(225C-226A)
#define F_SYM6      0x02140     // 記号6(2272-2279)
#define F_SYM7      0x02240     // 記号7(227E)
#define F_NUM       0x02260     // 数字(2330-2339)
#define F_ASC       0x023A0     // ASCii[大](2341-235A)
#define F_ASC2      0x026E0     // ASCii[小](2361-237A)
#define F_HIRA      0x02A20     // ひらかな(2421-2473)
#define F_KATA      0x03480     // カタカナ(2521-2576)
#define F_PCDEF     0x06800     // 機種依存文字(2Dxx)
#define F_GRK1      0x1B2A0     // ギリシャ[大](2621-2638)
#define F_GRK2      0x1B5A0     // ギリシャ[小](2641-2668)
#define F_CRL1      0x1B8A0     // キリル[大](2721-2741)
#define F_CRL2      0x1BCC0     // キリル[小](2751-2771)
#define F_RULE      0x1C0E0     // 罫線 (2821-2840)
#define F_KAN1      0x04000     // 漢字1水準(3021-4F53)
#define F_KAN0      0x08000     // 漢字1水準(新アドレス)
#define F_KAN2      0x20000     // 漢字2水準(5021-7426)
#define F_SYM_A     0x3A800     // 全記号(2121-2D7C)

//--- 途中省略

uint32_t HfntAdr(uint8_t chCode){
  #ifdef ROM_MAP2
        return (chCode - 0x20) * 16 + F_H_ASC; 
  #else
    if((chCode >= 0x20) & (chCode < 0x7F)){
        return (chCode - 0x20) * 16 + F_H_ASC;
    }else if((chCode > 0xA0) & (chCode <= 0xDF)){
        return  (chCode - 0xA0) * 16 + F_H_KANA;        
    }
  #endif
    return 0;
}

//--- 途中省略

//--- 全角(漢字)フォントアドレス取得)
uint32_t KfntAdr(uint16_t kCode){
    uint8_t msb, lsb;
    uint32_t lmsb, llsb;
    msb = kCode >> 8;
    lsb = (uint8_t)kCode & 0x000FF;
    lmsb = (uint32_t)msb;
    llsb = (uint32_t)lsb;
  #ifdef ROM_MAP2
    if(msb>=0x21 & msb<=0x28){                      // 全角記号・英字・かな文字
        if(lsb>=0x21 & lsb<=0x7E) return F_SYM1 + (lmsb-0x21)*3008+(llsb-0x21)*32;
        else                      return NO_FONT;
    }else if(msb==0x2d){                            // 機種依存文字
        if(lsb>=0x21 & lsb<=0x7E) return F_PCDEF + (lmsb-0x2d)*3008+(llsb-0x21)*32;
        else                      return NO_FONT;
  
  #else
    if(msb>=0x21 & msb<0x30){
        if(msb==0x21){                              // 記号1
            if(lsb>=0x21 & lsb<=0x7E) return F_SYM1+(lsb-0x21)*32;
            else                        return NO_FONT;
        }else if(msb==0x22){                        // 記号2
            if(lsb>=0x21 & lsb<=0x2E) return F_SYM2 + (lsb-0x21)*32;
            else                      return NO_FONT;
        }else if(msb==0x23){                        // ASCII
            if(lsb>=0x30 & lsb<=0x39) return F_NUM + (lsb-0x30)*32;
            if(lsb>=0x41 & lsb<=0x5A) return F_ASC + (lsb-0x41)*32;
            if(lsb>=0x61 & lsb<=0x7A) return F_ASC2 + (lsb-0x61)*32;
            else                      return NO_FONT;;
        }else if(msb==0x24){                        // ひらかな
            if(lsb>=0x21 & lsb<=0x73) return F_HIRA + (lsb-0x21)*32;
            else                      return NO_FONT;
        }else if(msb==0x25){                        // カタカナ
            if(lsb>=0x21 & lsb<=0x76) return F_KATA + (lsb-0x21)*32;
            else                      return NO_FONT;
        }else if(msb==0x26){                        // ギリシャ
            if(lsb>=0x21 & lsb<=0x38) return F_GRK1 + (lsb-0x21)*32;
            if(lsb>=0x41 & lsb<=0x58) return F_GRK2 + (lsb-0x41)*32;
            else                      return NO_FONT;;
        }else if(msb==0x27){                        // キリル
            if(lsb>=0x21 & lsb<=0x41) return F_CRL1 + (lsb-0x21)*32;
            if(lsb>=0x51 & lsb<=0x71) return F_CRL2 + (lsb-0x51)*32;
            else                      return NO_FONT;;
        }else if(msb==0x28){                        // 罫線
            if(lsb>=0x21 & lsb<=0x40) return F_RULE + (lsb-0x21)*32;
            else                      return NO_FONT;
        }

  #endif
    }else if(msb<0x50){                             // 漢字(第1水準)
        if(lsb>=0x21 & lsb<=0x7E) return F_KAN0 + (lmsb-0x30)*3008+(llsb-0x21)*32;
        else                      return NO_FONT;
    }else if(msb<0x75){                             // 漢字(第2水準)
        if(lsb>=0x21 & lsb<=0x7E) return F_KAN2 + (lmsb-0x50)*3008+(llsb-0x21)*32;
        else                      return NO_FONT;
    }
	return NO_FONT;
}
//---  以下省略


※プログラムのリストをハイライト付きのスタイルで見る場合はここをクリック


※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。


BDFフォントパターンエディッタ ジグソーパズル I2C接続RAM(47C16)を使う