/************************************************************** * ビットマップファイル表示実験プログラム:PIC32MX_BMP_TEST_1.c * * <このTESTの目的> *  @ SDカードに収録されているBMPファイル(128*64ドット)を読出し * 同じ解像度のモノクロ液晶全面に、そのイメージを表示する。 *  A 表示方式は、ピクセル描画関数を使った簡単なものにしてみる。 * BMPデータは、画面左下隅から、右下隅に向かい、上に向かって * バイト単位で配列されているので、このビット列をシフト命令を * 使ってシフトしながら、1ビット毎に、'1'か、'0'かを判定して * 液晶の1ドット毎に、ON/OFF制御し描画する仕組みである。 * たぶん全画面を表示するのに時間は掛ると思うが、その時間を * 実測してみる。 * * 簡易テストなので、SWで、次のファイルをサーチする機能は無しにした。 * 但し、SDに収録されている、BMPファイルの、順次繰返し描画は可能にした。 * * 実験ハードは、以前製作した、ファイルリスト表示形式の、SD_MIDプレーヤを流用 * * ファイルシステム:MMD File System→ FAT16(FAT32互換) * Graphic LCD(Monochrome): SG12864A * * Condition: * 8MHz External X'tal Oscillator, 20x PLL (8MHzx20= 160MHz) * Fcy=160MHz/2=80MHz, Tcy=12.5ns * * CPU: PIC32MX340F256H * * N.Ishii 2014.10.9 *****************************************************************/ #include /* PIC32 peripheral library */ #include "glcd_lib32k.h" #include // コンフィギュレーション設定 // CPU=80MHz Peri=80MHz,HS+PLL,Divider=1/2,PLL=x20,WDT=Off #pragma config FNOSC=PRIPLL, POSCMOD=HS, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_1 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 /// ファイルシステム用変数 FSFILE *fptr; size_t result; SearchRec Record; SearchRec *rptr = &Record; /// BMPデータバッファ /// 62バイトというのは、ヘッダ情報部の、規定バイト数で /// ここは、今回は読み飛ばすだけにする。 /// 一方、BMPデータ本体部は、16バイト単位(画面の横方向の128ドット(16バイト)) /// で、バッファへ転送し、液晶の最下段左隅より描画を開始する。 /// それを、一画面分繰返すので、読出しに必要になる最低バッファサイズは、 /// 16バイト以上あればよいことになる。 unsigned char Buffer[62]; /// グローバル変数 short i; // ピクセルY座標 short j; // 横方向16バイト分の、ループ変数 short k; // 8ビットの、MSBから、ビットチェックするために、ビットシフトする時の // シフト数を合わせるための計算定数 /******* メインルーチン ***********/ int main(void) { //システム最適設定 SYSTEMConfigPerformance(80000000); mJTAGPortEnable(DEBUG_JTAGPORT_OFF); // JTAGを無効化 //I/O設定 AD1PCFG = 0xFFFE; // デジタルに // GLCD制御信号レベルの初期化 LCD_E = 0; LCD_CS1 = 1; LCD_CS2 = 1; LCD_RW = 1; LCD_DI = 1; LCD_TRIS = 0x0000; // LCDデータバス(DB0-DB7)オール出力(TRISE= 0) ///// ポート設定は、SD_MIDプレーヤのハードを流用するので、そのハードの設定のままにしてある。(今回は、SW未使用、VS1053b未使用) TRISD = 0x0F00; // SW2:SEL_SW,SW3:ENT_SW,未使用SW(SW4,SW5):入力 // LCD_CS1,CS2,RS:出力・デバッグLED:出力、他未使用ピンは出力設定 TRISF = 0x0034; // VS1053b_SCK1,SDO:出力、SDI1:入力・ LCD_E,RW:出力、他未使用ピンは入力設定 TRISG = 0x028C; // SD_SDO,SCK:出力、SDI:入力・他未使用ピンは入力設定 TRISB = 0x4FDF; // VS1053b_CS,RESET,DCS:出力、DREQ:入力・SD_CS:出力、WE,CD:入力、他未使用ピンは入力設定 CNPUE = 0x0060; // SD_CD(CN5),WE(CN6)のみ内部プルアップ LATDbits.LATD3 = 1; // デバッグLED消灯 // 液晶表示器の初期化 lcd_Init(); lcd_Clear(0); // 画面消去 LATDbits.LATD3 = 1; // デバッグLED消灯 /// カード挿入まで待ちファイル有無確認 while(fptr == 0){ lcd_Clear(0); // 画面消去 if(!MDD_MediaDetect()){ // カード挿入中か? lcd_Str(0, 0, "Wait Card Insert!"); // 挿入待ちメッセージ } else{ /*** ファイルオープンとファイル名表示 ***/ lcd_Str(0, 0, "Find Card OK! "); FSInit(); // FS初期化 /* 最初のファイルのサーチ */ result = FindFirst("*.BMP", ATTR_ARCHIVE, rptr); if(result != 0){ // BMPファイルありか? lcd_Str(0, 0, "Find No File? "); // ファイル無しメッセージ } else break; // ファイル発見で抜ける } delay_ms(500); // 0.5秒ごとに繰り返し } ////// ファイルが発見できた場合の処理 delay_ms(500); lcd_Str(1, 0, Record.filename); // ファイル名表示 delay_ms(1000); lcd_Clear(0); // 画面消去 fptr = FSfopen(Record.filename, "r"); // File Open (Read Mode) /************* メインループ ****************/ while(1) { if(fptr != 0){ // ファイルオープンに成功の場合、以下を実行 i= 0; // ピクセルY座標初期値 result=FSfread(Buffer,1,62,fptr); // ヘッダ情報部の、規定バイト数:62バイト分は、読み飛ばす //// 1ライン16ドット分の画素データ単位で、SDカードからデータを読込みながら、液晶へドット描画しイメージを表示する while(1){ // EOF(ファイルの終わり)まで、下の処理を繰返す result= FSfread(Buffer,1,16,fptr); // BMPデータを16バイト単位で、バッファ転送(1バイトを16回転送) if(result != 0){ /// 画面の横方向の128ドット分(16バイト)のバッファ内容(ビット=画素情報)を判断しながら、 /// 画素ON/OFF制御し、イメージ描画して行く for(j=0; j>(7-k))&0x01); // BMPデータ上と、ピクセル関数上の画素ON/OFF論理は逆の関係なので、バッファ転送後にデータ反転している } } i++; // 128ドット分の描画終了毎に、Y座標位置をインクリメント(Y座標初期値= 0) } else break; // EOFだったら、強制的に、このループを抜ける } FSfclose(fptr); // 1画面分のイメージ描画が終了したら、ファイルをクローズ delay_ms(2000); // 2秒間表示 lcd_Clear(0); // 画面消去 /// 次の、BMPファイルをサーチし、繰返す result = FindNext(rptr); // To Next File if ((result==0) && (Record.attributes == ATTR_ARCHIVE)) // 次の、BMPファイルが見つかったら、オープン fptr = FSfopen(Record.filename, "r"); else { // 次の、BMPファイルが見つからなかったら、最初のファイルをサーチして繰返す result = FindFirst("*.BMP", ATTR_ARCHIVE, rptr); if (result == 0) { fptr = FSfopen(Record.filename, "r"); // File Open (Read Mode) } } lcd_Str(1, 0, Record.filename); // ファイル名表示 delay_ms(1000); lcd_Clear(0); // 画面消去 } } }