Vol.916 11.Apr.2025

BMPファイル カラー画像表示

B BMPファイル  〜任意の画像サイズのBMPファイルを作る

by fjk

 BMP(Bitmap)はビットマップ形式の画像ファイルで、非圧縮、高品質の画像を得られるが、ファイルサイズは大きい。フォーマットの詳細はマイクロソフトを参照。

【BMPファイルのフォーマット例】(リトルエンディアン)
≪FILEヘッダー≫
00:41,4D     'B','M'  // ファイルタイプ(通常"BM")
02:0000308A 12,426 // ファイルサイズ(byte)
06:0000 0 // 予約(常に0)
08:0000 0 // 予約(常に0)
0A:0000008A 138 // データまでのオフセット
 
≪INFOヘッダー≫
0E:0000007C 124 // ヘッダーサイズ(V5ヘッダー)
12:00000060 96 // 画像の幅
16:00000040 64 // 画像の高さ
1A:0001 1 // プレーン数(常に1)
1C:0010 16 // 1画素のビット数
1E:00000003 3 // 圧縮形式(BI_BITFIELDS)
22:00003000 12,288 // 画像データのサイズ
26:00002E23 11,811 // 横方向の解像度
2A:00002E23 11,811 // 縦方向の解像度
2E:00000003 3 // 使用色(パレット)数
32:00000000 0 // 重要パレットのインデックス
36:0000F800 - // 赤のカラーマスク
3A:000007E0 - // 緑のカラーマスク
3E:0000001F - // 青のカラーマスク
42:00000000 0 // αのカラーマスク
46:73524742 - // 色空間
4A:(36byte) - // 論理色空間のRGBの端点
6E:00000000 0 // 赤成分のガンマ値
72:00000000 0 // 緑成分のガンマ値
76:00000000 0 // 青成分のガンマ値
7A:00000002 2 // レンダリングインデント
7E:00000000 0 // プロファイルへのオフセット
82:00000000 0 // プロファイルデータサイズ
86:00000000 0 // 予約(常に0)
 
≪DATA≫
8A:0821 // 0000100000100001
(R=00001,G=000001,B=00001)、黒
  ・・・
840:2D61 // 0010110101100001
(R=00101,G=101011,B=00001)、緑
  ・・・
1A40:E021// 1110000000100001
(R=11100,G=000001,B=00001)、赤

※ アドレス0x16(bV5Width)の画像高さが正値なので、
 画像データは画面左下隅から右、さらに上へと並ぶ
   
テスト画像(TEST.BMP)
 
   
TEST.BMPファイルのダンプリスト(1)
 
   
TEST.BMPファイルのダンプリスト(2)
 
   
TEST.BMPファイルのダンプリスト(3)

【任意サイズ・色のBMPファイルを作る】
 カメラで撮影した写真を元に、大きさが任意のBMPファイルを作るには、abc867で紹介した無料のラスター画像編集ソフトのGIMPが便利。GIMPには画像編集機能の他に描画機能もあるので、新規のデータも作ることもできる。(最新版は3.0だが、ここでは2.10を使用)
 以下の手順でカラーOLEDの16ビットモード(5-6-5)の書式でBMPファイルを作ることができる。


@ GIMPに写真データを取り込む−>範囲を選択

A「画像/画像の拡大・縮小」−>希望サイズ入力

B 画像が希望サイズに縮小される−>拡大表示

C「ファイル/名前をつけてエクスポート」

D「ファイル形式の選択」で「windowsBMP形式」
「ファイル名」も入力後 −>エクスポート
 

 
E「詳細設定」で「16ビットR5G6B5」
 を選択後   −>エクスポート

※ 縦横比が異なる画像や、画像の一部を使う場合は、以下の手順を参考に。
 ・例えば、QT095Bの96x64ピクセルの16ビットカラー画像を作成するには、

  1. 「ファイル/開く」でファイルを指定(又はマウスでドラッグ&ドロップ)し、画像を表示
  2. 矩形選択ツールで、縦横比に「96:64」と入力し、「固定」にチェック
    ・ マウスで使いたい画像エリアを選択
  3. 「画像/キャンパスを選択範囲に合わせる」でトリミング
  4. 「画像/画像の拡大・縮小」で、画像サイズをW96xE64(px)、「拡大縮小」を実行
  5. 「ファイル/名前を付けてエクスポート」
    ・「ファイル形式の選択/Windows BMP画像」
    ・「フォルダー」、「ファイル名」 を入力
    ・「エクスポート」
    ・ 詳細設定で「16ビットR5G6B5」を選び「エクスポート」


P PICでSDカードを使う(3) 〜カラー画像を表示

by fjk

 前項の方法で、デジカメで撮影した花の写真を、96x64ドット(R5G6B5カラー)画像のFLOWER.BMPとしてSDカードに書込み、このBMPファイルをPICでSDカードから読み取り、カラーOLED(QT095B)に16ビットモードで表示した。
 
【ハード】
 abc915abc913で紹介したQT095Bを追加した。QT095BのCSはPIC16F18857のB5、D/CはB6、ResはB4に接続。なお、SDのCSはB0に変更した。


回 路 図

ブレッドボードの配線状況

【ソフト】
 MCC設定はQT095Bのピン以外は、abc915とほぼ同じ。なお、各CSは初期値をHighに設定。
 パソコン端末との通信用のEUSARTの設定はabc915を参照。
 BMPファイルの画像データはリトルエンディアンだが、QT095Bの16ビット画像データはビッグエンディアン。


MCCのPIN設定

 ・ターミナルコマンド(abc915に以下を追加)
U
ファイルデータを読込み
・ダンプリスト表示
 
V
BMPファイルデータ読込み
・画像を表示
(ファイル拡張子がBMP時のみ実行)
 
R
テキストファイルの読込み(修正)
・データ表示
(ファイル拡張子がTXT時のみ実行)
 

SDカードからFLOWER.BMPを読出し・表示

【トラブル】

@ abc915にabc912のQT095Bの関数を追加し、初期化を実行するとフリーズした。
A そこで、SSP2CON1bits.SSPEN = 1; とするとQT095Bの初期化が実行でき、デモ画像も表示できた。
B しかし、続けて、SDカードをアクセスすると、こんどはマウントできない。
C そこで、SSP2CON1bits.SSPEN = 0; とするとSDカードにはアクセスできる。
D しかし、この状態ではQT095Bにアクセスできない。
E そこで、QT095B使用時にSSPEN=1にし、その後=0にすると、どちらもアクセスできた
    どうも、FatFs使用時には、 SSP2CON1bits.SSPEN = 0
       QT095B使用時には、  SSP2CON1bits.SSPEN = 1 にしておく必要がありそう。−>宿題1
F これで、何とか画像の表示ができたが、それでもQT095Bの表示が不安定になったり、
   SDのマウントもできないことがある。
G 各チップセレクト信号や、SPIクロックをオシロスコープで見ると、配線が長くなったためか、
   ノイズで波形が綺麗で無く、SPI通信がうまくできていないようだ。        −>宿題2
H そこで、メモリ追加用に配線していた未接続のワイヤーを全て取り外したところ、かなり安定した。
 
★Eの宿題1については、mcc_generated_files/docs/spi_basic.dox に、
  「既に開いているSPIがあると、open時にfalesが返される」、さらに、「SPIを使用する時は
  component_name_open を実行し、使用後は component_name_close を使用すること」とある。
  また、「スレーブ選択ピンの制御は行わない」となっているが、今回、選択ピンの制御を行わなくても、
  アクセスできているようだ(正しくは選択ピンの制御を行った方がよさそう・・・かな?)。


【SDカードからBMP画像データを読込・表示】 abc916-18857.c+myProject.h(zip)


/*******************(abc916-18857.c)***************
 *  SDカードから画像データの読込・表示
 ****************************************************/
#include "mcc_generated_files/mcc.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "myProject.h"

#define  SSP2_ON()  SSP2CON1bits.SSPEN = 1
#define  SSP2_OFF() SSP2CON1bits.SSPEN = 0

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

//--- File Systme 変数
FRESULT  result;                    // FatFs処理結果
FATFS    drive;                     // FatFsオブジェクトへのポインタ
FIL      file;                      // ドライブ番号、ex: "0:"
		
//--- アプリ変数
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];                   // コメント等送信用文字列
uint8_t  tFlag;                     // タイマーフラグ
uint16_t Counter;                   // タイマーカウンタ

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

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

/***************************************
 *  文字列バッファ出力関数
 ***************************************/
void StrWrite(char * str){
    while(*str != 0){               // '\0'(文字列終り)まで繰り返し
        EUSART_Write(*str++);       // 1文字バッファに出力(送信)
    }
}

void EU_Write_CR(void){
        EUSART_Write('\n');
}

//--- EUSARTへ文字列送信(改行付)
void EU_Puts(char * str){
    StrWrite(str);
    EU_Write_CR();
}

/*******************************************************
  *	有機ELカラーグラフィック 	QT095B(SSD1331)
 ********************************************************/
//---  SSD1331 初期化
void SSD1331_Init(void){
    RES_SetLow();                   // Reset OLED (SSD1331))
    __delay_ms(100);                // 最終的にOLCDリセットは省略可
    RES_SetHigh();

    __delay_ms(500);
    gCS_SetLow();                   //  Select gCS
    gDC_SetLow();                   //  Select Command

    SPI2_ExchangeByte(0xAE);        //  Set Display Off
    SPI2_ExchangeByte(0xA0);        //  Remap & Color Depth setting
      SPI2_ExchangeByte(0x20);      // =20H [40],(0b00100000); 
                                    //   A[7:6] = 00; 256 color
                                    //   A[5] = 1; Enable COM Sprit
                                    //   A[4] = 0; Scan from 0-COMn
                                    //   A[3] = 0; Disable Swaping
                                    //   A[2] = 0; Norma Order (RGB)
                                    //   A[1] = 0; RAM Colum Seg:95-0
                                    //   A[0] = 0; Horizontal Address Incriment
    SPI2_ExchangeByte(0xA1);        //  Set Display Start Line
      SPI2_ExchangeByte(0);         // = 0 [00]
    SPI2_ExchangeByte(0xA2);        //  Set Display Offset
      SPI2_ExchangeByte(0);         // = 0 [00]
    SPI2_ExchangeByte(0xA4);        //  Set Display Mode (Normal)
    SPI2_ExchangeByte(0xA8);        //  Set Multiplex Ratio
      SPI2_ExchangeByte(63);        // = 63 [63]
    SPI2_ExchangeByte(0xAD);        //  Set Master Configration
      SPI2_ExchangeByte(0x8E);      // =8E [8F],a[0]=0 Select external Vcc supply
    SPI2_ExchangeByte(0xB0);        //  Power Save Mode
      SPI2_ExchangeByte(0x1A);      // = 1AH [1A},Enable power save mode
    SPI2_ExchangeByte(0xB1);        //  Phase 1 and 2 period adjustment
      SPI2_ExchangeByte(0x74);      // = 74H [74]
    SPI2_ExchangeByte(0xB3);        //  Display Clock DIV
      SPI2_ExchangeByte(0xF0);      // = F0H [D0]
    SPI2_ExchangeByte(0x8A);        //  Pre Charge A
      SPI2_ExchangeByte(0x81);      // = 81H [81]
    SPI2_ExchangeByte(0x8B);        //  Pre Charge B
      SPI2_ExchangeByte(0x82);      // = 82H [82]
    SPI2_ExchangeByte(0x8C);        //  Pre Charge C
      SPI2_ExchangeByte(0x83);      // = 83H [83]
    SPI2_ExchangeByte(0xBB);        //  Set Pre-charge level
      SPI2_ExchangeByte(0x3A);      // = 3AH [3E]
    SPI2_ExchangeByte(0xBE);        //  Set VcomH
      SPI2_ExchangeByte(0x3E);      // = 3EH [3E]
    SPI2_ExchangeByte(0x87);        //  Set Master Current Control
      SPI2_ExchangeByte(0x06);      // = 06H [0F]
    SPI2_ExchangeByte(0x15);        //  Set Column Address
      SPI2_ExchangeByte(0);         // = 00 [00]
      SPI2_ExchangeByte(95);        // = 95 [95]
    SPI2_ExchangeByte(0x75);        //  Set Row Address
      SPI2_ExchangeByte(0);         // = 00 [00]
      SPI2_ExchangeByte(63);        // = 63 [63]
    SPI2_ExchangeByte(0x81);        //  Set Contrast for Color A
      SPI2_ExchangeByte(255);       // = 255 [80]
    SPI2_ExchangeByte(0x82);        //  Set Contrast for Color B
      SPI2_ExchangeByte(255);       // = 255 [80]
    SPI2_ExchangeByte(0x83);        //  Set Contrast for Color C
      SPI2_ExchangeByte(255);       // = 255 [80]
    SPI2_ExchangeByte(0xAF);        //  Set Display On
    __delay_ms(110);                //  0xAFコマンド後最低100ms必要
    gCS_SetHigh();                  //  DeSelect gCS
}

void gOLED_Set256Md(void){
    gCS_SetLow();                   //  Select gCS
    gDC_SetLow();                   //  Select Command
    SPI2_ExchangeByte(0xA0);        //  Remap & Color Depth setting
      SPI2_ExchangeByte(0x20);      // = 20H (0b00100000)
    gCS_SetHigh();                  //  DeSelect gCS
	__delay_ms(50);
}

void gOLED_Set64kMd(void){
    gCS_SetLow();                   //  Select gCS
    gDC_SetLow();                   //  Select Command
    SPI2_ExchangeByte(0xA0);        //  Remap & Color Depth setting
      SPI2_ExchangeByte(0x62);      // = 62H (0b01100010)
    gCS_SetHigh();                  //  DeSelect gCS
    __delay_ms(50);
}

//----- 表示エリアの設定
void setArea(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1){
    gCS_SetLow();                   // Select gCs
    gDC_SetLow();                   // Select Comand
    SPI2_ExchangeByte(0x15);        // Set Colum Address
      SPI2_ExchangeByte(x0);
      SPI2_ExchangeByte(x1);
    SPI2_ExchangeByte(0x75);        // Set Row Address
      SPI2_ExchangeByte(y0);
      SPI2_ExchangeByte(y1);
    gCS_SetHigh();                  // DeSelect gCS
}

//----- 表示エリアのリセット
void rstArea(void){
    setArea(0,0,95,63);
}

//---  画面クリア
void gOLED_Clr(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1){
    gCS_SetLow();                   // Select gCS
    gDC_SetLow();                   // Select Comand
    SPI2_ExchangeByte(0x25);        // Line Command
      SPI2_ExchangeByte(x0);        // Start X
      SPI2_ExchangeByte(y0);        // Start Y
      SPI2_ExchangeByte(x1);        // End X
      SPI2_ExchangeByte(y1);        // End Y
    gCS_SetHigh();                  // DeSelect gCS
    __delay_ms(1);
}

//----  Set 256Color   ( R = 0-7, G = 0-7, B = 0-3 )
uint8_t gRGB256(uint8_t r,uint8_t g, uint8_t b){
    return (uint8_t)((r << 5) | (g << 2) | b);
}

//---  塗りつぶし指定
void gOLED_Fill(uint8_t md){
    gCS_SetLow();                   // Select gCs
    gDC_SetLow();                   // Select Comand
    SPI2_ExchangeByte(0x26);        // Fill Command
      SPI2_ExchangeByte(md);        // Start X
    gCS_SetHigh();                  // DeSelect gCs
}

//---  線描画
void gOLED_Line(uint8_t x0,uint8_t y0, uint8_t x1,uint8_t y1, uint8_t r, uint8_t g ,uint8_t b){
    gCS_SetLow();                   // Select gCs
    gDC_SetLow();                   // Select Comand
    SPI2_ExchangeByte(0x21);        // Line Command
      SPI2_ExchangeByte(x0);        // Start X
      SPI2_ExchangeByte(y0);        // Start Y
      SPI2_ExchangeByte(x1);        // End X
      SPI2_ExchangeByte(y1);        // End Y
      SPI2_ExchangeByte(r);         // Line color Red
      SPI2_ExchangeByte(g);         // Line color Green
      SPI2_ExchangeByte(b);         // Line color Blue
    gCS_SetHigh();                  // DeSelect gCs
}

//---  四角形描画
void gOLED_Rect(uint8_t x0,uint8_t y0, uint8_t x1,uint8_t y1, uint8_t r, uint8_t g ,uint8_t b){
    gCS_SetLow();                   // Select gCs
    gDC_SetLow();                   // Select Comand
    SPI2_ExchangeByte(0x22);        // Rect Command
      SPI2_ExchangeByte(x0);        // Start X
      SPI2_ExchangeByte(y0);        // Start Y
      SPI2_ExchangeByte(x1);        // End X
      SPI2_ExchangeByte(y1);        // End Y
      SPI2_ExchangeByte(r);         // Line color Red
      SPI2_ExchangeByte(g);         // Line color Green
      SPI2_ExchangeByte(b);         // Line color Blue
      SPI2_ExchangeByte(r);         // Fill color Red
      SPI2_ExchangeByte(g);         // Fill color Green
      SPI2_ExchangeByte(b);         // Fill color Blue
    gCS_SetHigh();                  // DeSelect gCS
}

//---  Test QT095 (1)
void test1(void){
    uint8_t i, j;
    uint8_t Dot1, Dot2, Dot3, Dot4;
    Dot1 = gRGB256(0,7,0);
    Dot2 = gRGB256(7,0,0);
    Dot3 = gRGB256(0,0,3);
    Dot4 = gRGB256(7,7,0);
    SSP2_ON();
    gOLED_Clr(0,0,95,63);
    gCS_SetLow();                   // Selct gCS
    gDC_SetHigh();                  // Selct data
    for(j=0; j<64; j++){
        for(i=0; i<96; i++){
            if(j<32){
                if(i<32) SPI2_ExchangeByte(Dot1);
                else     SPI2_ExchangeByte(Dot3);
            }else{
                if(i<48) SPI2_ExchangeByte(Dot2);
                else     SPI2_ExchangeByte(Dot4);
            }
        }
    }
    SSP2_OFF();
    gCS_SetHigh();
}

//---  Test QT095 (2) (Color Map)
void test2(void){
    uint8_t i,j,r,g,b,col;
    SSP2_ON();
    gOLED_Clr(0,0,95,63);
    gCS_SetLow();                   // Selct gCS
    gDC_SetHigh();                  // Selct data
    for(g=0; g<8; g++){
        for(i=0; i<8; i++){
            for(b=0;b<4;b++){
                for(r=0;r<8;r++){
                    col=(uint8_t)((r<<5)+(g<<2)+b);
                    SPI2_ExchangeByte(col);	
                    SPI2_ExchangeByte(col);	
                    SPI2_ExchangeByte(col);	
                }
            }     
        }
    }
    SSP2_OFF();
    gCS_SetHigh();  
}

//--- Test QT095 (3) (Draw Command)
void test3(void){
    SSP2_ON();
    gOLED_Clr(0,0,95,63);
    gOLED_Line( 0, 0,95,63,63,63,63);
    gOLED_Line( 0,63,95, 0, 0, 0,63);
    gOLED_Fill(0);                  // 塗りつぶし無し
    gOLED_Rect(16,12,78,51,63, 0, 0);
    gOLED_Fill(1);                  // 塗りつぶし有り
    gOLED_Rect(32,24,63,40, 0,63, 0);
    SSP2_OFF();
}

/***************************************
 *  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");
//    SDCard_CS_SetLow();
    if(SD_Mount() == FR_OK){        // SDマウント
        __delay_ms(2000);
        f_mount(0, "0:", 0);        // アンマウント
        EU_Puts("Un_Mounted");
    }
//    SDCard_CS_SetHigh();
    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){        // SDマウント
        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();             // ファイルクローズ&アンマウント
    }
//    LED_SetLow();
}

//--- SDカードへデータ書込コマンド
void SD_cmd_W(void){
    FRESULT res;
    EU_Puts("Start Command W");
    if(SD_Mount() == FR_OK){        // SDマウント
        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();             // ファイルクローズ&アンマウント
    }
//    LED_SetLow();
}

//--- ファイル名セット
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] = 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_U(void){
    FRESULT res;
    uint8_t i, n;
    EU_Puts("Start Command D");
    if(SD_Mount() == FR_OK){        // SDマウント
        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];               
                for(i = 0; i < n; i++){
                    sprintf(Msg,"%02X,",Buffer[i]);
                    StrWrite(Msg);
                    if((i % 16)==15) EU_Write_CR();
                }
                SSP2_ON();
                gOLED_Line( 0, 48,95,48,63,63,63);
                SSP2_OFF();
            }while(Length[0]!=0);
            EU_Write_CR();
        }else{
            sprintf(Msg,"** Can't open %s !!",FilNam);
            EU_Puts(Msg);           
        }
        SD_All_Close();             // ファイルクローズ&アンマウント
    }
//    LED_SetLow();
}

//--- SDカードからBMPファイル読込んで表示コマンド
void SD_cmd_V(void){
    FRESULT res;
    uint8_t i, n;

    if(F_ext != BMP){               // ファイルがBMPで無い?
        sprintf(Msg,"%s is not BMP File!",FilNam);
        EU_Puts(Msg);
        return;
    }
    EU_Puts("Start Command B");

    SSP2_ON();                      //グラフィック表示準備
    gOLED_Set64kMd();               // 64k(16ビット)カラーに
    rstArea();                      // 全画面を対象に
    SSP2_OFF();

    if(SD_Mount() == FR_OK){        // SDマウント
        res = f_open(&file, FilNam, FA_READ);       // ファイルオープン
        if(res == FR_OK){
            sprintf(Msg,"Open %s",FilNam);
            EU_Puts(Msg);
          //---  SDからヘッダー部を読込む 
            f_read(&file, Buffer, 138, (UINT *)Length);
            n = (uint8_t)Length[0];
            sprintf(Msg,"W:%d - H:%d\n",Buffer[0x12],Buffer[0x16]);
            EU_Puts(Msg);
            for(i = 0; i < n; i++){
                sprintf(Msg,"%02X,",Buffer[i]);
                StrWrite(Msg);
                if((i % 16)==15) EU_Write_CR();
            }
            EU_Write_CR();
          //--- SDからデータを読み出し、表示
            do{
                f_read(&file, Buffer, 192, (UINT *)Length); // SDから読込む
                n = (uint8_t)Length[0];

                SSP2_ON();                  // OLED選択
                gCS_SetLow();               // Select gCS
                gDC_SetHigh();              // Select Data
                
                for(i = 0; i < n; i+=2){
                    SPI2_ExchangeByte(Buffer[i+1]);         // 64k画素書込
                    SPI2_ExchangeByte(Buffer[i]);
                    sprintf(Msg,"%02X,%02X,",Buffer[i],Buffer[i+1]);
                    StrWrite(Msg);
                    if((i % 16)==14) EU_Write_CR();
                }
                gCS_SetHigh();              // DeSelect gCS
                SSP2_OFF();

            }while(Length[0]!=0);
            EU_Write_CR();
        }else{
            sprintf(Msg,"** Can't open %s !!",FilNam);
            EU_Puts(Msg);           
        }
        SD_All_Close();                 // ファイルクローズ&アンマウント
    }
//    LED_SetLow();

    SSP2_ON();                          //グラフィック表示準備
    gOLED_Set256Md();                   // 256(8ビット)カラーに
    rstArea();                          // 全画面を対象に
    SSP2_OFF();
}

/***************************************
 *  メイン関数
 ***************************************/
void main(void){
    uint8_t tMode = 0;                  // タイマカウンタ表示モードフラグ
    char   cmd;                         // 受信コマンド文字
    
    SYSTEM_Initialize();

    SSP2_ON();
    SSD1331_Init();
    SSP2_OFF();
 
  // タイマ0 Callback関数定義
    TMR0_SetInterruptHandler(TMR0_Process);
    
    EU_Puts("\n==== SD Test ====");
 
  // 割り込み許可
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
 
  //======= メインループ =========
    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 CMD = %c\n",RBuf,cmd);
            EU_Puts(Msg);

            switch(cmd){
                case 'T':   SD_cmd_T();     break;  // SDマウントテスト
                case 'R':   SD_cmd_R();     break;  // SDからデータ読出し
                case 'W':   SD_cmd_W();     break;  // SDにデータを書込む
                case 'X':   tMode = 1;      break;  // カウンタ表示OFF
                case 'C':   tMode = 0;      break;  // カウンタ表示ON 
                case 'F':   SD_cmd_F(RBuf); break;  // ファイル名セット
                case 'U':   SD_cmd_U();     break;  // 16進数でダンプ
                case 'V':   SD_cmd_V();     break;  // グラフィック描画
                case 'A':   test1();        break;  // グラフィックテスト1
                case 'B':   test2();        break;  // グラフィックテスト2
                case 'G':   test3();        break;  // グラフィックテスト3
                default:    EU_Puts("???"); break;  // 無効なコマンド
            }
            SFlg = 0;
        }
    }
}

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


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


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


BMPファイル カラー画像表示