/****************************************************************************************** * PIC24FJ64GA002 のSPIを使用して3.2"グラフィックLCD(MSP3217(ILI9341搭載))の * 表示テストをするプログラム:各種テスト * * プロジェクト名:PIC24F_GLCD_ILI9341_TEST * * IDE&Compiler: MPLAB IDE v8.60 * File: PIC24F_GLCD_ILI9341_TEST.c * * PIC24Fトレーニング基板を使い、QVGA表示テストを行った。 * * Condition: * 8MHz Internal RC oscillator, 4x PLL (8MHzx4= 32MHz) * Fcy=32MHz/2=16MHz, Tcy=62.5ns * * CPU: PIC24FJ64GA002 * * 初期プロジェクト作成年月日: 2023/10/9 N.Ishii * * <進捗履歴> * 231009 * ・drawPixel関数を作成し動作確認 * ・drawLine関数を作成し動作確認 * ・drawCircle関数を作成し動作確認 * * 231010 * ・drawChar及び、drawStr関数を作成し動作確認 * * 231012 * ・drawImage関数を作成し動作確認 * * 231013 * ・drawLine関数のデモ(次第に小さな四角形描画)を変更 *  フルサイズにすると、この液晶の特性なのか、正面から見た場合 *  最上部のラインは見えるが、最下位と最左右のラインは見えなくなるので変更 ********************************************************************************************/ //========================= // ヘッダーファイル //========================= #include "p24FJ64GA002.h" #include "skSPIlib.h" #include "ILI9341.h" //================================= // コンフィギュレーション設定 //================================= _CONFIG1( WDTPS_PS1 // ウォッチドッグタイマ有効時のポストスケーラ(1:1) & FWPSA_PR32 // ウォッチドッグタイマ有効時のプリスケーラ(1:32) & WINDIS_OFF // ウオッチドッグにウインドウ式は使わない & FWDTEN_OFF // ウオッチドッグの有効/無効は"RCON.SWDTEN"ビットで行う & ICS_PGx1 // In-Circuit Debuggersの通信チャネルは(PGEC1とPGED1上で通信します) & GWRP_OFF // プログラムメモリ空間の書き込みは許可する & GCP_OFF // プログラムメモリ空間のコード・プロテクトは無効 & JTAGEN_OFF // JTAG は使用しない ) /// Fosc = FRC (Fosc=32MHz) _CONFIG2( POSCMOD_NONE // 外部オシレータの動作モードの選択 (外部オシレータは使わない) & I2C1SEL_PRI // I2C1で使用するピンは、SDA1(RB9)/SCL1(RB8)を使用 & IOL1WAY_OFF // 周辺機器のピン割り付けは何度でも変更出来る様に許可 & OSCIOFNC_ON // OSCOピン機能の選択 (OSCOピンはデジタルI/O=RA3とする) & FCKSM_CSDCMD // クロックの監視やクロック切替え操作はしない & FNOSC_FRCPLL // 内部オシレータでPLL動作させる // & FNOSC_FRC // 内部オシレータでPLL動作無し (デバッグ用:Fcy= 16MHz→ 4MHzにダウン 230630) & SOSCSEL_SOSC // デフォルト電力(High-Power)発振器モードとする & WUTSEL_LEG // 電圧レギュレータのウェイクアップに必要な時間はデフォルト(190us) & IESO_OFF // Foscの2段階切り替えでの起動はしない ) char str_Hellow[] = "Hellow"; char str_World[] = "World !!"; char str_Tokyo[] = "Tokyo"; char str_Japan[] = "Japan"; char str_Chiyodaku[] = "Chiyodaku"; char str_Sotokanda[] = "Sotokanda"; char str_Akihabara[] = "Akihabara"; char str_AKB48[] = "AKB48"; /************************** * メイン関数 ***************************/ int main(void) { unsigned char i,j, index; unsigned int color; int T0 = 5000; /// ウオッチドッグは無効化 _SWDTEN = 0; /// システムクロックの設定(Fosc=32MHz FCY=16MIPS) _RCDIV = 0b000; // FRCポストスケーラは8MHz(8Mhz x 4XPLL=32MHz) // CPU Peripheral Clock Ratio Select bits 000 = 1:1 /// I/O情報の設定 AD1PCFG = 0b1111111111111111; // アナログは使用しない。デジタルI/Oに割当 TRISA = 0b0000000000000000; // PORTAは全て出力に設定 (1で入力 0で出力) TRISB = 0b0000001000000000; // RB9(SDO MISO)は入力、他は全て出力に設定 // PORTA = 0b0000000000000000; // ピン出力の初期化(全てLOWにする) PORTA = 0b0000000000011000; // ピン出力の初期化(RA3,4のみHIでLED OFF他はLOWにする) 230630 PORTB = 0b0001110001000000; // ピン出力の初期化 RB6,10,11,12はHIGH、他は全てLOWにする ///// 今回、SDカードのテストは省略するが、SPI1の設定だけはしておく //// SPIのPPS(Peripheral Pin Select)の設定 (SPIの信号を入出力するICのピンを設定します) /// SPI1用(SD card用)ピン設定 RPOR3bits.RP6R =9; // SPI1 SS(CS) RP6(RB6) RPOR3bits.RP7R =7; // SPI1 SDO(MOSI) RP7(RB7) RPOR4bits.RP8R =8; // SPI1 SCK(SCK) RP8(RB8) RPINR20bits.SDI1R=9; // SPI1 SDI(MISO) RP9(RB9) TRISBbits.TRISB6=0; // RP6(RB6)ピン は出力 TRISBbits.TRISB7=0; // RP7(RB7)ピン は出力 TRISBbits.TRISB8=0; // RP8(RB8)ピン は出力 TRISBbits.TRISB9=1; // RP9(RB9)ピン は入力 CNPU2bits.CN21PUE = 1; // RP9(CN21) pull up /// SPI2用(G LCD用)ピン設定 RPOR6bits.RP12R =12; // SPI2 SS(CS) RP12(RB12) RPOR6bits.RP13R =10; // SPI2 SDO(MOSI) RP13(RB13) RPOR7bits.RP14R =11; // SPI2 SCK(SCK) RP14(RB14) TRISBbits.TRISB12=0; // RP12(RB12)ピン は出力 TRISBbits.TRISB13=0; // RP13(RB13)ピン は出力 TRISBbits.TRISB14=0; // RP14(RB14)ピン は出力 //--------------------- // 周辺機器初期化 //--------------------- //// SPI 初期化 /// SD用 SPI1_Init(SPI1_MODE0, SPI1_PPRE_DIV4, 0); //プライマリプリスケールの分周 4:1 (16MHz x 1/4 = 4MHz) /* /// TFT用 SPI2_Init(SPI2_MODE0, SPI2_PPRE_DIV1, 0); //プライマリプリスケールの分周 1:1 SPI2_Init(SPI2_MODE0, SPI2_SPRE_DIV2, 0); //セカンダリプリスケールの分周 2:1 (16MHz x 1/2 = 8MHz) */ //SPI2_setDataMode(SPI2_MODE0); // MODE0 //SPI2_setClockDivider(SPI2_PPRE_DIV1,SPI2_SPRE_DIV2); // プライマリプリスケールの分周 1:1 // セカンダリプリスケールの分周 2:1 (16MHz x 1/2 = 8MHz) /// TFT用 SPI2_Init(SPI2_MODE0, SPI2_PPRE_DIV1, 0); //プライマリプリスケールの分周 1:1 (16MHz x 1/1 = 16MHz) //SPI2_Init(SPI2_MODE0, SPI2_PPRE_DIV64, 0); //プライマリプリスケールの分周 1:64 (4MHz x 1/64 = 62.5kHz:デバッグ用) //--------------------- // ILI9341 TFT 初期化 //--------------------- tft_begin(); fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア ///文字列描画---------------------------------------------------------------------------------------------- drawStr(0,0,str_Hellow,ILI9341_BLACK,ILI9341_WHITE); drawStr(1,1,str_World,ILI9341_RED,ILI9341_WHITE); drawStr(2,2,str_Japan,ILI9341_BLUE,ILI9341_WHITE); drawStr(3,3,str_Tokyo,ILI9341_WHITE,ILI9341_BLACK); drawStr(4,4,str_Chiyodaku,ILI9341_RED,ILI9341_BLACK); drawStr(5,5,str_Sotokanda,ILI9341_GREEN,ILI9341_BLACK); drawStr(6,6,str_Akihabara,ILI9341_RED,ILI9341_YELLOW); drawStr(7,7,str_AKB48,ILI9341_GREEN,ILI9341_YELLOW); delay_ms(T0); // 5秒待ち fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア ///-------------------------------------------------------------------------------------------------------- /// ASCII文字の描画---------------------------------------------------------------------------------------- for(j=0; j<17; j++){ // ASCII文字全表示: 26文字/行 * 17文字/列=442キャラクタ for(i=0; i<26; i++){ index = j*26+i+0x20; // スペースコードから開始し、1行26文字で繰返し if (j<4) drawChar(i, j, index, ILI9341_WHITE, ILI9341_BLACK); // 文字表示制御 if ((j>3) && (j<8)) drawChar(i, j, index, ILI9341_GREEN, ILI9341_BLACK); if ((j>7) && (j<12))drawChar(i, j, index, ILI9341_RED, ILI9341_BLACK); if ((j>11) && (j<17))drawChar(i, j, index, ILI9341_YELLOW, ILI9341_BLACK); } } delay_ms(T0); // 5秒待ち fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア ///-------------------------------------------------------------------------------------------------------- //----------------------------- // 描画関数チェック(描画デモ) //----------------------------- /// 全画面を各色で塗潰し(fillRect関数チェック) -------------------------------------------------------- for (i= 0; i < 5; i++) { switch(i) { case 0: color = ILI9341_BLACK;break; case 1: color = ILI9341_RED;break; case 2: color = ILI9341_GREEN;break; case 3: color = ILI9341_BLUE;break; case 4: color = ILI9341_WHITE;break; } fillRect(0, 0, 320, 240, color); // 全画面塗潰し delay_ms(500); } fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア delay_ms(500); fillRect(100, 80, 100, 80, ILI9341_GREEN); // 中央付近に小さな塗潰し四角形を描画 delay_ms(T0); // 5秒待ち ///----------------------------------------------------------------------------------------------------- /// 斜め直線描画(drawPixel関数チェック)--------------------------------------------------------------- fillRect(0, 0, 320, 240, ILI9341_WHITE); // 全画面を白クリア for(i=0; i<240; i++){ // 斜め直線の表示: 白ベタ背景・黒線表示 drawPixel(i,i,ILI9341_BLACK); drawPixel(240+i, i,ILI9341_BLACK); } delay_ms(T0); // 5秒待ち fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面を黒クリア for(i=0; i<240; i++){ // 斜め直線: 黒ベタ背景・白線表示 drawPixel(i,i,ILI9341_WHITE); drawPixel(240+i, i,ILI9341_WHITE); } delay_ms(T0); // 5秒待ち fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア ///----------------------------------------------------------------------------------------------------- /* /// 直線描画テスト(drawLine関数チェック)--------------------------------------------------------------- i = 0; for(j=0; j<120; j+=10){ // ボックス表示 drawLine(j,j, 319-j, j,ILI9341_YELLOW); // 次第に小さなボックスへ drawLine(j,j, j, 239 -j,ILI9341_YELLOW); drawLine(319-j,239-j, 319-j,j,ILI9341_YELLOW); drawLine(319-j,239-j, j,239-j,ILI9341_YELLOW); delay_ms(500); } */ /// 直線描画テスト(drawLine関数チェック)--------------------------------------------------------------- i = 0; for(j=2; j<113; j+=10){ // ボックス表示 drawLine(j,j, 317-j, j,ILI9341_YELLOW); // 次第に小さなボックスへ(12個のボックス) drawLine(j,j, j, 237 -j,ILI9341_YELLOW); drawLine(317-j,237-j, 317-j,j,ILI9341_YELLOW); drawLine(317-j,237-j, j,237-j,ILI9341_YELLOW); delay_ms(500); } delay_ms(T0); fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア ///---------------------------------------------------------------------------------------------------------- /// 円の描画(drawCircle関数チェック)------------------------------------------------------------------------- for(i = 0; i < 10; i++){ drawCircle(320/2 + 5*i,240/2,240/2,ILI9341_GREEN); } delay_ms(T0); fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア ///---------------------------------------------------------------------------------------------------------- /// イメージ描画(drawImage関数チェック) drawImage(); PORTAbits.RA4=0; // GREEN LED ON while(1); }