Vol.918 16.May.2025

Google_Gemini フォントROM文字も表示

G Google Gemini

by fjk

 Gemini(ジェミニ)は、Googleが開発・提供する高機能なAIチャットサービスで、文章や画像、音声などさまざまな情報を組み合わせた、高度な判断ができるマルチモーダル型のAIです。テキストや音声入力によるチャットに対応しているだけでなく、画像を基にした質問にも回答できます。
 Geminiは、対話形式で質問や依頼が可能で、ChatGPTやClaudeと同様に大規模な言語モデル(LLM)を採用していて、以下のことなどが実現できる。

<参考>
google
ai-review

 スマホでGemini を使うには、デフォルトで搭載されている「Google アシスタント」を Gemini に切り替える必要がありますが、切替後は、電源ボタンの長押しや、「OK Google」の呼びかけで使えます。
 アプリの切替は、「設定」を開き、「Google」→「すべてのサービス」→「Google アプリの設定」→ 「検索、アシスタントと音声」→「Google アシスタント」→「Google の デジタル アシスタント」から「Gemini」をタップし、画面の指示に従って操作。
 そこで、電源ボタンの長押しでGeminiを起動し、「今日の天気は?」と尋ねると、チャンと現在地の今の天気予想を音声で答えてくれました。もし、答えが日本語で無い場合は。「今日の天気は?日本語で」と訪ねると、チャンと日本語で答えてくれました。
 なお、Geminiには無料版と有料版があり、無料版では使える機能に制限があり、主な機能を比較すると、

Gemini 無料版 有料版 (2,900円/月)
文書生成・編集 日常的な文書 より高度で洗練された文書作成
質疑応答 Web検索連携した回答より深い推論に基づく回答
アイデア 一般的なアイデア より専門的で複雑なアイデア
翻訳・画像認識 対 応 対 応
データ分析・コード生成限定的 より高度な分析、コード生成

 便利な機能ですが、Gemini出力データは正しく無い場合もあり、最終的にユーザが判断すること!


P PICでSDカードを使う(5)  〜フォントROM文字も表示

by fjk

 abc917で画像に文字表示も可能となったが、全ての文字(漢字)も使えるようフォントROMも追加した。用いたROMは4Mビット(512kバイト)のIS25LP040で、フォントマップはROM_MAP2とした。なお、spi_Mem0.cにはフォントROMライター機能が無いので、フォントデータのROMへの書込は、abc910のBDF_Edita4.xlsmabc913のカラー文字表示回路を利用した。

【ハード】
abc917にSPI接続フォントROM(IS25LP040)を追加した。

回路図(必要に応じて0.1μF程度のパスコンを追加)

ブレッドボード
【ソフト】
基本的にはabc917にメモリアクセス関数(spi_Mem0.c)と、漢字フォントの表示関数を(QT095B.cに)追加しただけだが、全半角文字表示関数は同様の記述をまとめて、より簡潔にした。
<ターミナルコマンド> [ ]はオプション
K[H][aaaa]
フォントデータ表示
 
H:半角指示
 
aaaa:アドレス(hex)
L[jisCode]
文字データ表示
C:
画面クリア
G[n]
グラフィックテスト
P[str]
文字表示テスト
 
str:表示文字
F[name]
ファイル名[name]をセット
U[aaaa]
メモリデータのダンプ表示
 
aaaa:アドレス(hex)
V:
メモリの画像データを表示
D:
SDからメモリにダウンロード

画像に漢字フォントの表示例(拡大)

 当初、SDカードから画像データを読み出しながら直接OLEDに表示しようとしたが、何故がデータ化けが発生。そこで、一端読込データをROMに(40000Hから)書込「D」、その後OLEDに表示「V」するようにしたが、それでもSDから読み出し後にSPIのフリーズが発生することがあった。しかし、ROMにはデータがチャンと書き込まれていたので、再起動後に画像データをOLEDに表示することができた(宿題)

【QT095B.cに変更・追加したところ】  QT095B.c/h+Font_5x7.h(zip)


・・・<ここまで省略>・・・

void gPset8X(uint8_t x, uint8_t y, uint8_t b,uint8_t col,uint8_t bcl){
    uint8_t i,bc;
    uint8_t m = 1;
    bc = bcl;
    if(bc == 1) bc = 0;
    for (i=0; i<8;i++){
        if(b & m)    gPsetX(x,y+i,col);
        else if(bcl) gPsetX(x,y+i,bc);
        m <<= 1;
    }
}

・・・<途中省略>・・・

//----  8x16ドット文字を1文字表示
uint8_t gOLED_HptnX(uint8_t x, uint8_t y, char *hp, uint8_t col, uint8_t bcl){
    char i, ptn;
    gSetMode(COLOR256,1);               // アドレス増分を縦に
    for(i=0; i<8; i++) {
        ptn = *hp++;
        gPset8X(x+i,y,ptn,col,bcl);     // 8ドット描画(透明付)
    }
    for(i=0; i<8; i++) {
        ptn = *hp++;
        gPset8X(x+i,y+8,ptn,col,bcl);   // 8ドット描画(透明付)
    }
    gSetMode(COLOR256,0);               // アドレス増分を横に
    gRstArea();                         // 書込エリア指定クリア
    return x+i;
}

#ifdef USE_FONT_ROM
//---- 半角(8x16dot)文字表示(次xpos位置を返す)
uint8_t gOLED_HchrX(uint8_t xpos,uint8_t ypos,uint8_t chCode,uint8_t col,uint8_t bcl){
    uint32_t adr;
    char  ptn[16];
    adr = HfntAdr(chCode);
    if(adr > 0){
        SPI_Mem_NRead(adr,(uint8_t *)ptn,16);
        xpos = gOLED_HptnX(xpos,ypos,ptn,col,bcl);
    }
    return xpos;
}

//---- 半角(8x16dot)文字列表示(次xpos位置を返す)
uint8_t gOLED_HstrX(uint8_t xpos,uint8_t ypos,char *str,uint8_t col,uint8_t bcl){
    while(*str)  xpos = gOLED_HchrX(xpos, ypos, *str++,col,bcl);
    return xpos;                    //次表示位置を返す
}
#endif


//---- 16x16ドット文字を1文字表示(次xpos位置を返す)
uint8_t gOLED_KptnX(uint8_t x, uint8_t y, char *kp, uint8_t col, uint8_t bcl){
    char i, ptn;
    gSetMode(COLOR256,1);               // アドレス増分を縦に
    for(i=0; i<16; i++) {
        ptn = *kp++;
        gPset8X(x+i,y,ptn,col,bcl);     // 16ドット描画(透明付)
    }
    for(i=0; i<16; i++) {
        ptn = *kp++;
        gPset8X(x+i,y+8,ptn,col,bcl);   // 16ドット描画(透明付)
    }
    gSetMode(COLOR256,0);               // アドレス増分を横に
    gRstArea();                         // 書込エリア指定クリア
    return x+i;
}

#ifdef USE_FONT_ROM
//---- 全角(漢字)を1文字表示(次xpos位置を返す)
uint8_t gOLED_ZchrX(uint8_t xpos,uint8_t ypos,uint16_t kCd,uint8_t col,uint8_t ed,uint8_t bcl){
    uint32_t adr;
    uint16_t kk;
    uint8_t h,l;
    char ptn[32];

    if(ed & 0x01){
        h = (uint8_t)(kCd>>8);
        l = (uint8_t)kCd;
        kCd = l*256 + h;
    }
    if(ed < 2)  kk = SJis2Jis(kCd);
    else        kk = kCd;
    adr = KfntAdr(kCd);
    SPI_Mem_NRead(adr,(uint8_t *)ptn,32);
    if(adr)	return gOLED_KptnX(xpos,ypos,ptn,col,bcl);
    return xpos;                    //次表示位置を返す
}

//---- 全角(漢字)文字列表示(次xpos位置を返す)
uint8_t gOLED_ZstrX(uint8_t xpos,uint8_t ypos,char *str,uint8_t col,uint8_t ed,uint8_t bcl){
    uint16_t cd, *kjP;
    kjP = (uint16_t *)str;
    while(*kjP & 0xFF){
        xpos = gOLED_ZchrX(xpos,ypos,*kjP,col,ed,bcl);
        kjP++;
    }
    return xpos;
}
#endif

・・・<以下省略>・・・


【SPIメモリアクセス関数】 spi_Mem0.c/h(zip)


/******************************(spi_Mem0.c)*************
 *  SPI接続メモリの読み・書き関数ライブラリ            *
 *     (SPI接続フォントROMが必要です)                 *
 *******************************************************/

#include "mcc_generated_files/mcc.h"
#include "myProject.h"
#include "QT095B.h"
#include "spi_Mem0.h"

#define SPI_RBLK(a,c)  (SPI2_ReadBlock(a,c))
#define SPI_WBLK(a,c)  (SPI2_WriteBlock(a,c))

#define MCS_SEL()       mCS_SetLow()
#define MCS_UNSEL()     mCS_SetHigh()

#define CMD_LINE    0
#define DATA_LINE   12
#define LIST_LINE   24

#define CMD_COLOR   0xFC
#define DATA_COLOR  0xFF
#define LIST_COLOR  0x1F
#define LIST_COLOR2 0xE3

//=== グローバル変数 ============
char     Dlm[] = ",";                       // 文字列区切りデリミタ
char     SBuf[20];                          // 文字列処理用バッファー

//--- SPIメモリー用
//static uint8_t  BlkNum = 0;               // メモリブロック番号
static uint32_t CrtAdr = 0;                 // カレントアドレス
static uint8_t  DBuf[120];                  // ページメモリ用バッファー
static uint8_t  SqMode = 0;                 // シーケンスモードフラグ
static char     LstCmd;                     // 最終コマンド
static uint8_t  spiRom = 1;                 // spiRomかどうか
static uint16_t LstChr = 0;                 // 最終表示文字

//---- ROMステータスの読み出し
uint8_t SPI_Rom_RdStat(void){               // ROMのみ使用
    uint8_t stat;
    MCS_SEL();
    SPI_EXCHG(SPIROM_RD_STATS);
    stat = SPI_EXCHG(0xAA);                 // 0xAAはダミー
    MCS_UNSEL();
    return stat;
}

//---- コマンドと24ビットアドレスを送信
void sendAdr(uint8_t cmd, uint32_t adr){
    MCS_SEL();
    SPI_EXCHG(cmd);                         // send Command
    SPI_EXCHG((uint8_t)(adr>>16));
    SPI_EXCHG((uint8_t)(adr>>8));
    SPI_EXCHG((uint8_t)adr);
} 

//-----  アドレスadrから、1バイトを読み出す
uint8_t SPI_Mem_Read(uint32_t adr){
    uint8_t dat;
    sendAdr(SPIMEM_READcmd,adr);            // send Read_CMD & Address
    dat = SPI_EXCHG(0xAA);
    MCS_UNSEL();
    return dat;
}

//-----  アドレスadrに、1バイトdtを書き込む
uint8_t SPI_Mem_Write(uint32_t adr, uint8_t dat){
    MCS_SEL();
    SPI_EXCHG(SPIROM_WR_ENABL);             // Set Write Enable Bit
    MCS_UNSEL();
    sendAdr(SPIMEM_WRITEcmd,adr);           // send Write_CMD & Address
    SPI_EXCHG(dat);
    MCS_UNSEL();
    __delay_ms(20);
    return dat;
}

//-----  アドレスadrからnバイトをary[]に読み出す
void SPI_Mem_NRead(uint32_t adr,uint8_t *ary,uint16_t cnt){
    sendAdr(SPIMEM_READcmd,adr);            // send Read_CMD & Address
    SPI_RBLK(ary,cnt);                      // block read
    MCS_SEL();
    while(SPI_Rom_RdStat() & 1);
}

//-----  アドレスadrからary[]のnバイトを書き込む
void SPI_Mem_NWrite(uint32_t adr,uint8_t *ary,uint16_t cnt){
    MCS_SEL();
    SPI_EXCHG(SPIROM_WR_ENABL);             // Set Write Enable Bit
    MCS_UNSEL();
    sendAdr(SPIMEM_WRITEcmd,adr);           // send Write_CMD & Address
    SPI_WBLK(ary,cnt);                      //  block write
    MCS_UNSEL();
    while(SPI_Rom_RdStat() & 1);
}

//----  半角フォントアドレス取得
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;
}

//---- シフトJISー>JIS変換
uint16_t SJis2Jis(uint16_t sCd){
    uint8_t hi,lo;
    hi = sCd >> 8;
    lo = (uint8_t)sCd;
    if(hi <= 0x9F){
        if(lo < 0x9F)   hi = hi * 2 - 0xE1;
        else            hi = hi * 2 - 0xE0;
    }else{
        if(lo < 0x9F)   hi = (hi - 0xB0) * 2 - 1;
        else            hi = (hi - 0xB0) * 2;
    }
    if(lo < 0x7F)       lo = lo - 0x1F;
    else{
        if(lo < 0x9F)   lo = lo - 0x20;
        else            lo = lo - 0x7E;
    }
    return (uint16_t)(hi * 256 + lo);
}

//--- JIS−>シフトJIS変換
uint16_t Jis2SJis(uint16_t jCd){
    uint8_t hi,lo;
    hi = jCd >> 8;
    lo = (uint8_t)jCd;
    if(hi && 1){
        if(lo < 0x60)   lo = lo + 0x1F;
        else            lo = lo + 0x20;
    }else{              lo = lo + 0x7E;
    }
    if(hi < 0x5F)       hi = (hi + 0xE1) >> 1;
    else                hi = (hi + 0x161) >> 1;
    return (hi * 256 + lo);
}

//--- 全角(漢字)フォントアドレス取得)
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<0x50){                     // 漢字(第1水準)
        if(lsb>=0x21 & lsb<=0x7E) 
                return F_KAN0 + (lmsb-0x30)*3008+(llsb-0x21)*32;
        else    return NO_FONT;
  #else

・・・<途中省略>・・・

  #endif
    }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;
}

/****** 汎用サブルーチン ********************/
//---- ページバッファープリント
void prt_PBf(void){
    uint8_t i,x,y;
    for(i = 0; i < 64; i++){                // 16x4文字表示
        if(i % 16 == 0) printf("\r");
        sprintf(SBuf,"%02X",DBuf[i]);
        printf(" %s",SBuf);
        if(i<32){
          x = i % 8;
          y = i / 8;
          if(i % 2){
            gOLED_strX(12*x,LIST_LINE+10*y,SBuf,LIST_COLOR,0);
          }else{
            gOLED_strX(12*x,LIST_LINE+10*y,SBuf,LIST_COLOR2,0);
          }
      }
    }
    puts("\r");
}

//---- K(漢字)表示コマンド  K[H][aaaa] 
int spiMem_cmd_K(char *str){
    char *sp;
    uint8_t  cn;                            // コラムドット数
    uint8_t  ofs;                           // 文字列解読オフセット
    uint8_t  i,n,x,y;                       // ループ変数
    int32_t  res;                           // 取得アドレス

    LstCmd = str[0];
    if((strlen(str)>1)&(str[1]=='H')){
		ofs = 2; cn = 8;
    }else{
		ofs = 1; cn = 16;
	}
    sp = strtok(str+ofs,Dlm);
    if(sp != NULL){
        res = my_xtoi(sp) & 0xFFFF0;        // 16バイト単位
        if(res>0) CrtAdr = (uint32_t)res;
    }

    sprintf(SBuf,"%05lX - %05lX",CrtAdr,CrtAdr+127);
   	printf("%s\r",SBuf);
    gOLED_strX(0,DATA_LINE,SBuf,DATA_COLOR,0);
    if(ofs==1){                             // 全角
        for(y=0;y<2;y++){
          for(x=0;x<4;x++){
            SPI_Mem_NRead(CrtAdr,(uint8_t *)DBuf,2*cn); 
            gOLED_KptnX(x*24,y*24+LIST_LINE,(char *)DBuf,255,0);
            CrtAdr += 2*cn; 
          }
        }
    }else{
        for(y=0;y<2;y++){
          for(x=0;x<8;x++){
            SPI_Mem_NRead(CrtAdr,(uint8_t *)DBuf,2*cn); 
            gOLED_HptnX(x*12,y*24+LIST_LINE,(char *)DBuf,255,0);
            CrtAdr += 2*cn;            
          }
        }        
    }
    return i;
}

//---- L(文字)表示コマンド  L[code] (文字コード)
void spiMem_cmd_L(char *str){
    char     *pt;                           // 文字列操作用ポインタ
    uint32_t res;                           // Hex文字数値変換結果
    uint16_t ftCd = 0;                      // フォントコード
    uint32_t fAdr;
    
    LstCmd = str[0];
    if(strlen(str)==1){                     // アドレス無し
        LstChr += 1;                        // 次文字
    }else{
        pt = strtok(str+1,Dlm);
        if(pt != NULL){                     // アドレス有り?
            res = (uint32_t)my_xtoi(pt);
            if(res>0)   LstChr = (uint16_t)res;
        }
    }
    if(LstChr < 256){
        fAdr = HfntAdr((uint8_t)LstChr);
        sprintf(SBuf,"%02X-%05lX",LstChr,fAdr);
        printf("%s",SBuf);
        gOLED_strX(0,DATA_LINE,SBuf,DATA_COLOR,0);   
        gOLED_HchrX(80,0,(uint8_t)LstChr,255,0);
        SPI_Mem_NRead(HfntAdr((uint8_t)LstChr),DBuf,16);
        prt_PBf();
    }else{
        fAdr = KfntAdr(LstChr);
        sprintf(SBuf,"%04X-%05lX",LstChr,fAdr);
        printf("%s",SBuf);
        gOLED_strX(0,DATA_LINE,SBuf,DATA_COLOR,0);
        gOLED_ZchrX(80,0,LstChr,255,2,0);
        SPI_Mem_NRead(KfntAdr(LstChr),DBuf,32);
        prt_PBf();
    }
}
/******* End of File ********/


【abc918-18857.c】 abc918-18857.c + myFunction.c + myProject.h(zip)


/*******************(abc918-18857.c)[秋月slot版]***
 *  SDカードの読み書きと文字表示                  *
 **************************************************/

#include "mcc_generated_files/mcc.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "myProject.h"
#include "QT095B.h"
#include "spi_Mem0.h"

#define  OLED_BF_SIZE  80

enum { NON = 0, TXT, CSV, BIN = 8, BMP };

//--- File Systme 用変数
FRESULT  result;                            // FatFs処理結果
FATFS    drive;                             // FatFsオブジェクトへのポインタ
FIL      file;                              // ドライブ番号、ex: "0:"

//--- Fileアプリ用変数
char     FilNam[16] = "FLOWER.BMP";
uint8_t  F_ext = BMP;                       // 1:TXT, 2:CSV, 8:BIN, 9:BMP
uint16_t Length[2];                         // 送受信用文字数格納配列
char     Buffer[192];                       // データ受信用バッファー
char     Msg[40];                           // コメント等送信用文字列
char     msg2[]="=== SD Test ===";

//--- タイマーカウンター用変数
uint8_t  tMode = 1;                         // タイマカウンタ表示モードフラグ
uint8_t  tFlag;                             // タイマーフラグ
uint16_t Counter;                           // タイマーカウンタ

//---- EUSART用変数
char    RBuf[EU_BFSIZE];
uint8_t SFlg;

//---- OLED用変数
uint8_t CrtLn = 0;                          // 現在行(ページ)位置
uint8_t gBf[OLED_BF_SIZE];                  // グラフィック表示用
char msg1[] = "Test QT095B";

/***************************************
 *  タイマ0 Callback関数 (1秒周期割り込み)
 ***************************************/
void TMR0_Process(void){
    tFlag = 1;                              // フラグセット
}

/***************************************
 *  SDカード用汎用関数
 ***************************************/
//--- SDカードのマウント
FRESULT SD_Mount(void){
    uint8_t ct = 10;
    FRESULT res;
    do{
        res = f_mount(&drive,"0:",1);     
        EUSART_Write('.');
    }while((res != FR_OK) && ct--);         // 10回まで試みる
    
    if(res != FR_OK){                       // マウント失敗なら
        EU_Puts("** SD Not Mounted !!");
    }else{
        EU_Puts("SD Mount OK!");
        LED_SetHigh();
    }
    return res;	
}

//--- SDカードのクローズとアンマウント
void SD_All_Close(void){
    f_close(&file);                         // ファイルクローズ
    f_mount(0, "0:", 0);                    // アンマウント
    EU_Puts("closed & Un_Mounted"); 
    LED_SetLow();	
}

/***************************************
 *  コマンド処理
 ***************************************/
//--- SDカードテストコマンド (兼テンプレート)
void SD_cmd_T(void){
    EU_Puts("Start Command T");
    gCS_SetHigh();
    if(SD_Mount() == FR_OK){                // SDマウント
        __delay_ms(2000);
        f_mount(0, "0:", 0);                // アンマウント
        EU_Puts("Un_Mounted");
    }
    LED_SetLow();
}

//--- SDカードから読込コマンド
void SD_cmd_R(void){
    FRESULT res;
    if(F_ext != TXT){                       // テキストファイルでないなら
        sprintf(Msg,"%s is not Text File!",FilNam);
        EU_Puts(Msg);
        return;   
    }
    EU_Puts("Start Command R");
    if(SD_Mount() == FR_OK){
        res = f_open(&file, FilNam, FA_READ);  // ファイルオープン
        if(res == FR_OK){
            sprintf(Msg,"Open %s",FilNam);
            EU_Puts(Msg);
            do{
                f_read(&file, Buffer, 64, (UINT *)Length); // SDから読込む
                Buffer[Length[0]] = 0;
                EU_Puts(Buffer);
            }while(Length[0]!=0);
        }else{
            sprintf(Msg,"** Can't open %s !!",FilNam);
            EU_Puts(Msg);
        }
        SD_All_Close();                     // ファイルクローズ&アンマウント
    }
}

//--- SDカードへデータ書込コマンド
void SD_cmd_W(void){
    FRESULT res;
    EU_Puts("Start Command W");
    if(SD_Mount() == FR_OK){
        res = f_open(&file, FilNam, FA_WRITE | FA_OPEN_APPEND); // ファイルオープン
        if(res == FR_OK){
            sprintf(Msg,"Open %s",FilNam);
            EU_Puts(Msg);
            sprintf(Msg, "%07d,", Counter);
            f_write(&file, Msg, 8, (UINT *)Length);   // SDへ書込
            EU_Puts(Msg);
        }else{
            sprintf(Msg,"** Can't open %s !!",FilNam);
            EU_Puts(Msg);
        }
        SD_All_Close();                     // ファイルクローズ&アンマウント
    }
}

//--- ファイル名セットコマンド
void SD_cmd_F(char *str){
    size_t i,n;
    char *p;
    n = strlen(str);
    if(n > 1){
        if(n > 12) n = 12;
        for(i = 0; i < n; i++)
            FilNam[i] = (char)toupper(str[i+1]);
        FilNam[n]=0;
    } 
    p = strchr(FilNam,'.');
    if     (strncmp(p+1,"TXT",3)==0) F_ext = TXT;
    else if(strncmp(p+1,"CSV",3)==0) F_ext = CSV;
    else if(strncmp(p+1,"BIN",3)==0) F_ext = BIN;
    else if(strncmp(p+1,"BMP",3)==0) F_ext = BMP;
    else                             F_ext = NON;

    sprintf(Msg,"NewFileName = %s: %d\n",FilNam,F_ext);
    EU_Puts(Msg);
}

//--- SDカードから読込コマンド
void SD_cmd_D(void){
    FRESULT res;
    uint8_t i, n;
    uint32_t  adr = 0x40000;
    
    EU_Puts("Start Command D");
    if(SD_Mount() == FR_OK){
        res = f_open(&file, FilNam, FA_READ);       // ファイルオープン
        if(res == FR_OK){
            sprintf(Msg,"Open %s",FilNam);
            EU_Puts(Msg);
            do{
                f_read(&file, Buffer, 192, (UINT *)Length); // SDから読込む
                n = (uint8_t)Length[0]; 
                SSPEN_ON();
                for(i = 0; i < n; i++){
                    SPI_Mem_Write(adr++, Buffer[i]);    // ROMに書き込む
                }
//              SPI_Mem_NWrite(adr,Buffer,n);
//              adr += n;
                EUSART_Write('.');          // 書込中を表示
                SSPEN_OFF();
            }while(Length[0]!=0);
            EU_Write_CR();
        }else{
            sprintf(Msg,"** Can't open %s !!",FilNam);
            EU_Puts(Msg);
        }
        SD_All_Close();                     // ファイルクローズ&アンマウント
    }
}

//--- メモリからBMPファイル読込んで表示コマンド
void SD_cmd_V(void){
    uint8_t c[2];
    uint16_t j;
    uint32_t adr = 0x40000 + 138;           // ヘッダー部をオフセット
    
    SSPEN_ON();
    gSetMode(COLOR64K2,0);                  // 64k(16ビット)カラーに
    gRstArea();
    gDC_SetHigh();                          // Select Data
    // 全画面を対象に
    for(j=0; j<6144; j++){
        c[0]= SPI_Mem_Read(adr++);          // ROMから読込
        c[1]= SPI_Mem_Read(adr++);
        gCS_SetLow();                       // Select gCS 
        SPI_EXCHG(c[1]);                    // OLEDに書込
        SPI_EXCHG(c[0]);
        gCS_SetHigh();
    }
    SSPEN_OFF();
}

//---  文字表示コマンド
void SD_cmd_P(char *str){
    uint8_t xpos;
    SSPEN_ON();
    gSetMode(COLOR256,0);                   // 256(8ビット)カラーに
    if(strlen(str)==1){
        gOLED_ZchrX( 2,2,0x692C,gRGB256(7,7,0),2,0);   // '薔'
        gOLED_ZchrX(78,2,0x692F,gRGB256(7,7,0),2,0);   // '薇'
    }else{
        xpos = gOLED_strX(20,54,str+1,gRGB256(0,7,7),0);
    }
    gSetMode(COLOR256,0);                   // アドレス増分を横に
    gRstArea();                             // 全画面を対象に
    SSPEN_OFF();
}

//---  画像表示テストコマンド
void QT_cmd_G(char *str){
    SSPEN_ON();	
    if(strlen(str) > 1){
        switch(str[1]){
            case '1': QT095B_Test1(); break;
            case '2': QT095B_Test2(); break;
            case '3': QT095B_Test3(); break;
        }
    }else{
        QT095B_Test1();
    }
    SSPEN_OFF();    
}

//---  画面表示消去コマンド
void QT_cmd_C(void){
    SSPEN_ON();
    gOLED_Clr(0,0,95,63);
    SSPEN_OFF();
}

//---  (全半角)漢字表示コマンド
void sM_cmd_K(char *str){
    SSPEN_ON();
    gOLED_strX(0,0,str,gRGB256(7,7,0),0);
    spiMem_cmd_K(str); 
    SSPEN_OFF();
}

//---  Jisコード漢字表示コマンド
void sM_cmd_L(char *str){
    SSPEN_ON();
    gOLED_strX(0,0,str,gRGB256(7,7,0),0);
    spiMem_cmd_L(str); 
    SSPEN_OFF();
}

//---  メモリデータダンプ表示コマンド
void sM_cmd_U(char *str){
    SSPEN_ON();
    gOLED_strX(0,0,str,gRGB256(7,7,0),0);
    spiMem_cmd_U(str); 
    SSPEN_OFF();
}

//---   SSPステータス表示
void ck_SSP(void){
    uint8_t a,b,c;
    a = SSP2STAT;
    b = SSP2CON1;
    c = SSP2CON3;
    sprintf(Msg,"%02X %02X %02X",a,b,c);
    EU_Puts(Msg); 
}

/***************************************
 *  メイン関数
 ***************************************/
void main(void){
    char   cmd;                                     // 受信コマンド文字
    
    SYSTEM_Initialize();

    SSPEN_ON();
    SSD1331_Init();                                 // OLED初期化
    SSPEN_OFF();
 
  // タイマ0 Callback関数定義
    TMR0_SetInterruptHandler(TMR0_Process);
 
  // 割り込み許可
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    
    EU_Puts(msg2);
    SSPEN_ON();
    gOLED_strX(0,0,msg2,gRGB256(7,7,7),1);
    SSPEN_OFF();
 
  //======= メインループ =========
    while(1){
      // 1秒周期の処理
        if(tFlag == 1){                             // フラグオンの場合
             LED_Toggle();
            tFlag = 0;                              // フラグリセット
            if(tMode == 0){
                sprintf(Msg,"Counter = %05d",Counter++);
                EU_Puts(Msg);                       // 送信
            }
        }
      // コマンド処理
        if(SFlg){                                   // 受信ありの場合
            cmd = RBuf[0];  
            sprintf(Msg,"Input = %s\n",RBuf);
            EU_Puts(Msg);

            switch(cmd){
                case 'X':  tMode ^= 1;      break;  // カウンタ表示ON/OFF
                case 'C':  QT_cmd_C();      break;  // 画面消去
                case 'G':  QT_cmd_G(RBuf);  break;  // グラフィックテスト 
                case 'T':  SD_cmd_T();      break;  // SDマウントテスト
                case 'R':  SD_cmd_R();      break;  // SDからデータ読出し
                case 'W':  SD_cmd_W();      break;  // SDにデータを書込む
                case 'F':  SD_cmd_F(RBuf);  break;  // ファイル名セット
                case 'D':  SD_cmd_D();      break;  // データダウンロード
                case 'V':  SD_cmd_V();      break;  // グラフィック描画
                case 'P':  SD_cmd_P(RBuf);  break;  // 文字表示テスト
                case 'U':  sM_cmd_U(RBuf);  break;  // 16進数でダンプ
                case 'K':  sM_cmd_K(RBuf);  break;  // 漢字表示(アドレズ)
                case 'L':  sM_cmd_L(RBuf);  break;  // 漢字表示(コード)

                default:    EU_Puts("???"); break;  // 無効なコマンド
            }
            SFlg = 0;
        }
    }
}

/******  End of File ******/


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


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


Google_Gemini フォントROM文字も表示