/******************************************************************************* * ソース名:PIC32MX_UL024TF_SD_TEST.C * * <このTESTの目的> *  @ SDカードに格納されているファイルリストをGLCDに表示してみる *  A SDカードに格納されている、任意の位置のファイルを読出し *   それを実行する * (その実行とは、最終目標は、選ばれたMP3ファイルの再生であるが * 今回は、ファイルリスト表示と、選択動作までのテストとする) * * <テスト仕様概要> *  @ SDに格納されている、MP3ファイルを、16個まで読出し、そのファイルリスト *    を、GLCDに表示する(今回は、スクロール機能は無しとする) *  A SELECT SW(タッチ)で、選択したいファイルの所へ、●キャラクタを移動 *  B ENTER SW(タッチ)で、選択を確定する(今回のTESTはここまでとする) * * ファイルシステム:MMD File System→ FAT16(FAT32互換) * 2.4inch QVGAカラー液晶(aitendo): UL024TF * * Condition: * 8MHz External X'tal Oscillator, 20x PLL (8MHzx20= 160MHz) * Fcy=160MHz/2=80MHz, Tcy=12.5ns * * CPU: PIC32MX340F256H * * N.Ishii 2016.7.14 * 2022.6.1 * PIC32MXトレーニング基板に搭載のPICが壊れた_その対策 * 隣の空ピン:PIC-53pin:RD3(現在デバッグLED)を、LCD_RST/に置換えてみる。 **********************************************************************************/ #include /* PIC32 peripheral library */ #include "colorlcd_libdsPICVH.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 /// タッチボタン座標データ short Button[2][2] = {{400,840}, // [0]:ボタン-1 {160,880} // [1]:ボタン-2 }; /* short Button[2][2] = {{470,929}, // [0]:ボタン-1 {448,938} // [1]:ボタン-2 }; */ char str_N[]= "Nxx"; // FileNo表示用 short Count; char MsgScrn[] = "X=xxxx Y=xxxx"; // 座標表示 /// ファイルシステム用変数 FSFILE *fptr; size_t result; SearchRec Record; SearchRec *rptr = &Record; char FileName[20][9]; /// グローバル変数 short FileNo; /// プロトタイプ void DispFiles(void); void SetupScreen(void); short Getscreen(unsigned int chn); short CheckBtn(short x, short y); void Process(short sw); void itostring(char digit, unsigned short data, char *buffer); /******* メインルーチン ***********/ int main(void) { //システム最適設定 SYSTEMConfigPerformance(80000000); mJTAGPortEnable(DEBUG_JTAGPORT_OFF); // JTAGを無効化 //I/O設定 AD1PCFG = 0xFFFF; // 全てデジタルに(タッチ用設定は、AN4(X-)、AN3(Y+)なので、0xFFE7) TRISE = 0x0000; // LCDデータバス(DB0-DB7)オール出力 TRISD = 0xFFA7; // LCD_CS,RESET:全て出力・デバッグLED:出力・SW2-5:入力、他未使用ピンは入力設定 TRISB = 0x4FC7; // VS1011_CS,RESET,DCS:出力、DREQ:入力・SD_CS:出力、LCD_WR,LCD_RS:出力、他未使用ピンは入力設定 // (今回は、VS1011は未使用だが、将来使う予定なので、その設定にしておく) TRISF = 0xFFFC; // 今回Fポートは未使用だが、RF0,RF1のみ出力設定にした // LATDbits.LATD3 = 1; // デバッグLED消灯 220601 /* /// RD4ポートチェック //// while(1){ LATDbits.LATD4 = 0; delay_ms(500); LATDbits.LATD4 = 1; delay_ms(500); } //////////////////// /// RD3ポートチェック //// while(1){ LATDbits.LATD3 = 0; delay_ms(500); LATDbits.LATD3 = 1; delay_ms(500); } //////////////////// */ /// 液晶表示器の初期化 Glcd_Init(); Glcd_Clear(BLACK); Glcd_Str(0, 0, "SD Test", CYAN, BLACK); delay_ms(1000); Glcd_Clear(BLACK); //タイマ1設定 50msec周期 タッチスクリーン用 12.5nsecx256x15625=50msec OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_256, 15624); /// 変数初期化 Count= 0; SetupScreen(); // ADC設定変更 FileNo= 0; // タイマ1割り込み設定 ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_2); /// カード挿入まで待ちファイル有無確認(CDの無いUL024TF使用のため、MDD_MediaDetect()の戻り値を強制的に、'1':挿入にしている。) while(fptr == 0){ Glcd_Clear(BLACK); // 画面消去 if(!MDD_MediaDetect()){ // カード挿入中か? Glcd_Str(0, 0, "Wait Card Insert!", CYAN, BLACK); // 挿入待ちメッセージ(今回はここは常に実行しない) } else{ // 常にカード挿入状態を実行する。 /*** ファイルオープンとファイル名表示 ***/ Glcd_Str(0, 1, "Find Card OK!", CYAN, BLACK); FSInit(); // FS初期化 /* 最初のファイルのサーチ */ result = FindFirst("*.*", ATTR_ARCHIVE, rptr); if(result != 0){ // ファイルありか? Glcd_Str(0, 1, "Find No File?", CYAN, BLACK); // ファイル無しメッセージ } else break; // ファイル発見で抜ける } delay_ms(500); // 0.5秒ごとに繰り返し } /// ファイルが発見できた場合の処理 DispFiles(); // ファイル名一覧表示処理 Glcd_Char(16, 8, 0xE9, GREEN, BLACK); // ボタン-1:Select 表示(キャラクタ) Glcd_Char(25, 8, 0xE9, YELLOW, BLACK); // ボタン-2:Enter 表示(キャラクタ) Glcd_Char(0, 0, 0xE4, GREEN, BLACK); // '●'を選択初期位置(先頭)に表示); //マルチベクタ割り込み設定、割り込み許可 INTEnableSystemMultiVectoredInt(); /// メイン ループ while(1){ } } //-------------------------------------------------------------------------------- /****************************************** * タイマ1割り込み処理(50msec周期) * タッチスクリーン アナログ入力 *******************************************/ void __ISR(4, ipl2) T1Handler(void) { static short i, Xset, Yset, Xold, Yold; mT1ClearIntFlag(); //割り込みフラグクリア /// タッチスクリーン用の、AD1PCFGLレジスタの設定に戻す AD1PCFG = 0xFFE7; // AN4(X-)、AN3(Y+) /// X座標入力 TRISBbits.TRISB3 = 0; // RB3(Y+), RE7(Y-) is output TRISEbits.TRISE7 = 0; LATBbits.LATB3 = 1; // Set Voltage LATEbits.LATE7 = 0; TRISBbits.TRISB4 = 1; // RB4(AN4):X-入力 TRISEbits.TRISE6 = 1; // RE6(DB6兼):X+側は、入力設定で、Hi-Zとする for(i=0; i<100; i++) Nop(); // 充電待ち 11usec Xset = Getscreen(0x00040000); // 座標値取得 /// Y座標入力 TRISEbits.TRISE6 = 0; // RE6(X+), RB4(X-) is output TRISBbits.TRISB4 = 0; LATEbits.LATE6 = 1; // Set Voltage LATBbits.LATB4 = 0; TRISBbits.TRISB3 = 1; // RB3(AN3):Y+入力 TRISEbits.TRISE7 = 1; // RE7(DB7兼):Y-側は、入力設定で、Hi-Zとする for(i=0; i<100; i++) Nop(); // 充電待ち 11usec Yset = Getscreen(0x00030000); // 座標値取得 /// X,Y座標入力後、LCD信号と兼用ピンの設定を全て、デジタル出力に戻す AD1PCFG = 0xFFFF; // 全てデジタル出力 TRISBbits.TRISB4 = 0; // WR出力 TRISBbits.TRISB3 = 0; // RS出力 TRISEbits.TRISE6 = 0; // DB6出力 TRISEbits.TRISE7 = 0; // DB7出力 /// タッチしていないときの回避 if((Xset > 60)&&(Yset < 1000)){ /// 確実なタッチの検出 if((abs(Xset - Xold) < 15) && abs(Yset - Yold) < 15){ Count++; if(Count >= 3){ Count = 0; Process(CheckBtn(Xset, Yset)); // 押されてボタンの処理とタッチ座標位置表示 } } else Count = 0; Xold = Xset; Yold = Yset; } } /******************************** * 座標取得実行関数 ********************************/ short Getscreen(unsigned int chn) { short i; AD1CON1bits.ADON = 0; AD1CON1bits.DONE = 0; // 手動の場合は変換開始前に、DONEビットをクリアする必要あり(自動クリアしない) AD1CHS = chn; // Select Channel AD1CON1bits.ADON = 1; AD1CON1bits.SAMP = 1; for(i=0; i<100; i++) // Wait Aquisition 11usec Nop(); AD1CON1bits.SAMP = 0; // A/D convert start while(!AD1CON1bits.DONE); // wait conversion return(ADC1BUF0); // return result } /**************************************** * タッチスクリーン用設定変更 ****************************************/ void SetupScreen(void) { /* ADCの設定 */ AD1CON1bits.ADON = 0; AD1CON1 = 0x0000; // ADオフ、手動制御、10bit分解能 AD1CON2 = 0; // AVdd, AVss, SCANなし,MUXAのみ AD1CON3 = 0x0304; // AD用クロック周期:Tad = 10*Tcy= 10*12.5= 125nS/サンプル時間:3Tad= 3*125= 375nS // Tad= 2* 周辺用クロック(Tpbclk=Tcy)* (ADCS(7:0)設定+1)= 2* 12.5* (4+1) AD1CHS = 0x00000000; // チャネル選択(※ S/Hチャンネル設定は上位16bitでする) AD1PCFG = 0xFFE7; // AN4(X-)、AN3(Y+) AD1CSSL = 0; // 自動スキャンなし AD1CON1bits.ADON = 1; // AD有効化 } /********************************************************** * タッチボタン判定処理 * タッチポイントの座標から、押されたボタンの種別No.を取得 * し、その値を返す ***********************************************************/ short CheckBtn(short x, short y) { short i, btn; /// タッチ座標位置表示(デバッグ用) itostring(4, x, MsgScrn+2); itostring(4, y, MsgScrn+9); Glcd_Str(3, 16, MsgScrn, GREEN, BLACK); /// ボタンチェック btn = -1; for(i=0; i<2; i++){ if((x > Button[i][0]-15)&&(x < Button[i][0]+15)){ if((y > Button[i][1]-15)&&(y < Button[i][1]+15)) btn = i; } } return(btn); } /************************************************** * タッチ・ボタンごとの処理 ***************************************************/ void Process(short sw) { short i; switch(sw){ case 0: /// ボタン-1:Select FileNo++; // 次の行へ if(FileNo < 16) { for(i=0; i<=FileNo; i++) // 2つ目以降のファイルが選択された場合、 Glcd_Char(0, i, 0x20, BLACK, BLACK); // その前に表示されている、選択キャラクタ'●'をクリアする Glcd_Char(0, FileNo, 0xE4, GREEN, BLACK); // '●'を選択位置に表示 } else{ // 最終行を超えた場合、先頭に戻す FileNo = 0; Glcd_Char(0, 15, 0x20, BLACK, BLACK); // その前に表示されている、選択キャラクタ'●'をクリアする Glcd_Char(0, FileNo, 0xE4, GREEN, BLACK); // '●'を選択初期位置(先頭)に表示 } break; case 1: /// ボタン-2:Enter /// ファイルNo.表示 itostring(2, FileNo, str_N+1); Glcd_Str(23, 16, str_N, WHITE, BLACK); // 'Nxx'表示 LATDbits.LATD3 = 0; // Green LED ON while(1); break; default: break; } } /*************************************** * 整数からASCII文字に変換 ****************************************/ void itostring(char digit, unsigned short data, char *buffer) { char i; buffer += digit; // 最後の数字位置 for(i=digit; i>0; i--) { // 変換は下位から上位へ buffer--; // ポインター1 *buffer = (data % 10) + '0'; // ASCIIへ data = data / 10; // 次の桁へ } } /*************************************************** * ファイルリストの表示 * 最大16ファイルで制限 ****************************************************/ void DispFiles(void){ short i, j; Glcd_Clear(BLACK); // 全画面消去 /// ファイル名の表示 i = 0; j = 0; /// 最初のファイル名の表示と格納 while(Record.filename[j] != 0){ // 名称最後か? FileName[i][j] = Record.filename[j]; // 格納 j++; } Glcd_Str(2, i++, Record.filename, CYAN, BLACK); // 最初のファイル名の表示 /// すべてのファイル名の表示と格納 while(FindNext(rptr) == 0){ // 次のファイルサーチ //// ファイル発見できれば表示し格納 j = 0; // 文字列ポインタリセット if(Record.attributes==ATTR_ARCHIVE) // 発見できたか? while(Record.filename[j] != 0){ // 名称の最後か? FileName[i][j] = Record.filename[j];// 格納 j++; } Glcd_Str(2, i++, Record.filename, CYAN, BLACK); // ファイル名表示 if(i>=16) // 16個目を超えたか? break; // 終わって抜ける } }