/****************************************************************************************** * PIC24FJ64GA002 のSPIを使用して3.2"グラフィックLCD(MSP3217(ILI9341搭載))の * 表示テストをするプログラム_1:四角形を各色で塗潰すのみのテスト * * プロジェクト名:PIC24F_GLCD_ILI9341_TEST_SIMPLE * * IDE&Compiler: MPLAB IDE v8.60 * File: PIC24F_GLCD_ILI9341_TEST_SIMPLE.c * * PIC24Fトレーニング基板を使い、QVGA表示テストを行った。 * * Condition: * 8MHz Internal RC oscillator, 4x PLL (8MHzx4= 32MHz) * Fcy=32MHz/2=16MHz, Tcy=62.5ns * * CPU: PIC24FJ64GA002 * * デバッグ年月日: 2023/10/4 N.Ishii * * <変更履歴> * 230727 * ・MADCTL再設定で設定変更を追加 * ・各関数で直接w・hを入力していたが、そこに入力する数値をテレコにする * 230728 * ・tft_begin()後のMADCTLレジ再設定の前後に、TFT_CS= 0;とTFT_CS= 1;が抜けていた * ので追加した。 * 230801 * ・TFTのSPI転送速度= 16MHzはスペックオーバーなので、4MHzにダウン * 230802 * ・TFTのSPI転送速度= 8MHzに設定可なので変更した。(スペック上は、10MHzmaxなので丁度良い) * ・WIDTHとHIGHTのテレコ修正が必要な箇所が、後1箇所あったので修正した。ILI9341.c * 230802-2 * ・SPI2スピード設定は、16MHzでも動いたことを大元で最初から用意されているhexで確認出来てるので * これを信じ、16MHzに戻しておく。 * 230805 * ・MADCTL: Memory Access Control設定を最初から0xE8(横表示・原点:左上隅・w= 320,h= 240)に変更 * ・今全画面クリアして、全画面を赤で塗り潰すで、止めているが、 * これを「ゆるプロ」のsimple proにあるように、黒-> 赤-> 緑-> 青-> 白の塗りつぶし *  の各ステート0.5秒ごとの繰返しにし、ledをトグル点滅させる。 * 230810 * ・Rotation設定を、0xE8から0x28に変更: ILI9341.c * 230817 * ・SPI2のエッジ・極性設定を、MODE0から、MODE2に変更したがngで0に戻した * ↑↑↑ * ここまで、MPLAB XIDE での履歴 * *========================================================================================== * * ここから引き継いで、MPLAB IDE v8.60 での履歴 * 231004 * ・MPLAB IDE v8.60に適合するようソースを変更。コンパイルokだが、白画面のまま変わらず * 231005 * ・spiのclkとdataのタイミングが気になっている。再度転送速度を、62.5kHzに落として確認 *  -> タイミングは問題ない模様 * 231006 * ・TFT初期化の冒頭で、CSをアクティブLoにするが、一瞬Loになってから直ぐにHiに戻ってしまう *  事を確認した。 *  -> CSをアクティブLo後、DCをHiにしているが、DCレベルの初期化はmain頭で既に済んでいるので *   ダブル処理になる。ここを削除したら、TFT初期化ルーチンを実行の間、CSはアクティブLo *   をキープするようになり初めて塗潰し動作を確認出来た。 *   ただし未だおかしい。横方向は良いのだが、縦方向が上部の一部しか塗潰さない・・ *   しかし何故、この処理をしたら良くなったかはよく判らない。 *   CSとDCのタイミングの問題が改善されたのかな・・・ *   まあ長い間ここで悩んでいたのが解決したので良しとする。 * *  -> fillRect関数内で以下修正した *    (1) 340- -> 320 (塗潰し範囲オーバー判断の箇所) *    (2) px=(unsigned long)(w * h);が思い通リ動いていないようで *      直に、320x240=76800なので、px= 76800としたら、全画面塗潰しはokになる * 231007 * ・px = (long)w * h;としたら、変数対応の塗潰しokになる * 231008 * ・中央付近に小さな塗潰し四角形を描画を追加 ********************************************************************************************/ //========================= // ヘッダーファイル //========================= #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段階切り替えでの起動はしない ) //=========================== // グローバル変数 //=========================== //========================= // 関数のプロトタイプ宣言 //========================= // void testFillScreen(); /************************** * メイン関数 ***************************/ int main(void) { char i; unsigned int color; /// ウオッチドッグは無効化 _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(); //------------------------ // 画面塗り潰しデモ繰返し //------------------------ while(1){ 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); // 全画面塗潰し // PORTAbits.RA3=0; // RED LED ON delay_ms(500); // PORTAbits.RA3=1; // RED LED OFF } fillRect(0, 0, 320, 240, ILI9341_BLACK); // 全画面クリア delay_ms(500); fillRect(100, 80, 100, 80, ILI9341_GREEN); // 中央付近に小さな塗潰し四角形を描画 delay_ms(500); } }