/**************************************************************** * UL024TF_Touch_Test * * UL024TFの、タッチパネルが動くか確かめるだけの簡単な実験 * * 2.4インチQVGA液晶モジュール(aitendo): UL024TF * * Condition: * 8MHz External X'tal Oscillator, 10x PLL (8MHzx10= 80MHz) * Fcy=80MHz/2=40MHz, Tcy=25ns * * CPU: dsPIC33FJ64GP802 * * 2016.7.3 N.Ishii ******************************************************************/ #include "p33FJ64GP802.h" #include "colorlcd_libdsPICVH.h" #include /// コンフィギュレーション設定 80MHz _FOSCSEL(FNOSC_PRIPLL & IESO_OFF); // Prim OSC _FOSC(FCKSM_CSDCMD & IOL1WAY_OFF & OSCIOFNC_OFF & POSCMD_XT); _FWDT(FWDTEN_OFF); _FPOR(ALTI2C_OFF & FPWRT_PWR32); _FICD(JTAGEN_OFF & ICS_PGD1); /// タッチ・ボタンのキャラクタコード char MsgBUTTON[] = {0xE9, 0}; // ■ /// LEDのキャラクタコード char MsgLEDon[] = {0xE4, 0}; // ● char MsgLEDoff[] = {0xE3, 0}; // ○ /// タッチボタン座標データ int Button[2][2] = {{480,840}, // [0]:ボタン-1 {430,830} // [1]:ボタン-2 }; int Count; char MsgScrn[] = "X=xxxx Y=xxxx"; // 座標表示 /// 関数プロトタイピング void SetupScreen(void); int Getscreen(unsigned int chn); int CheckBtn(int x, int y); void Process(int sw); void itostring(char digit, unsigned int data, char *buffer); //--------------------------------------------------------------------- /************************************************ * メイン関数 ************************************************/ int main(void){ /// Setup System OSCCON = 0x00300; // PRIPLL指定 CLKDIV = 0x0100; // クロックの分周1:2に設定 PLLFBD = 0x0026; // 40倍 8MHz÷2×40÷2 = 80MHz /// Setup PORT In/Out TRISA = 0xFFED; // RA1:LED,RA4:RSTは出力、他は入力 TRISB = 0x00D3; // LCD関連全て出力(RB2:WR,RB3:RS,RB5:CS,RB8-15:DATA)他は入力 LATAbits.LATA1 = 1; // Green LED OFF /// 液晶表示器の初期化 lcd_Init(); lcd_Clear(BLACK); lcd_Str(0, 0, "Touch Test", CYAN, BLACK); lcd_Str(0, 15, MsgBUTTON, GREEN, BLACK); // ボタン-1表示(キャラクタ) lcd_Str(8, 15, MsgBUTTON, YELLOW, BLACK); // ボタン-2表示(キャラクタ) lcd_Str(4, 14, MsgLEDoff, RED, BLACK); // LED消灯表示(キャラクタ) /// タイマ1設定 50msec周期 タッチスクリーン用 T1CON = 0x0030; PR1 = 7800; // 50msec IFS0bits.T1IF = 0; // 割り込みフラグクリア IEC0bits.T1IE = 1; // 割り込み許可 /// 変数初期化 Count = 0; SetupScreen(); // ADC設定変更 /// タイマ1 T1CONbits.TON = 1; /// メイン ループ while(1){ } } //-------------------------------------------------------------------------------- /****************************************** * タイマ1割り込み処理(50msec周期) * タッチスクリーン アナログ入力 *******************************************/ void __attribute__((interrupt, auto_psv)) _T1Interrupt(void) { static int i, Xset, Yset, Xold, Yold; IFS0bits.T1IF = 0; // 割り込みフラグクリア /// タッチスクリーン用の、AD1PCFGLレジスタの設定に戻す AD1PCFGL = 0xFFCF; // AN4-5 is analog /// X座標入力 TRISBbits.TRISB3 = 0; // RB3(Y+), RB15(Y-) is output TRISBbits.TRISB15 = 0; LATBbits.LATB3 = 1; // Set Voltage LATBbits.LATB15 = 0; TRISBbits.TRISB2 = 1; // RB2(AN4):X-入力 TRISBbits.TRISB14 = 1; // RB14(DB6兼):X+側は、入力設定で、Hi-Zとする for(i=0; i<50; i++) Nop(); // 充電待ち 11usec Xset = Getscreen(4); // 座標値取得 /// Y座標入力 TRISBbits.TRISB14 = 0; // RB14(X+), RB2(X-) is output TRISBbits.TRISB2 = 0; LATBbits.LATB14 = 1; // Set Voltage LATBbits.LATB2 = 0; TRISBbits.TRISB3 = 1; // RB3(AN5):Y+入力 TRISBbits.TRISB15 = 1; // RB15(DB7兼):Y-側は、入力設定で、Hi-Zとする for(i=0; i<50; i++) Nop(); // 充電待ち 11usec Yset = Getscreen(5); // 座標値取得 /// X,Y座標入力後、LCD信号と兼用ピンの設定を全て、デジタル出力に戻す AD1PCFGL = 0xFFFF; // 全てデジタル出力 TRISBbits.TRISB2 = 0; // WR出力 TRISBbits.TRISB3 = 0; // RS出力 TRISBbits.TRISB14 = 0; // DB6出力 TRISBbits.TRISB15 = 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; } } /******************************** * 座標取得実行関数 ********************************/ int Getscreen(unsigned int chn) { int i; AD1CON1bits.ADON = 0; AD1CHS0 = chn; // Select Channel AD1CON1bits.ADON = 1; AD1CON1bits.SAMP = 1; for(i=0; i<50; 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; // 3Tad , Tad = 5*Tcy AD1CON4 = 0; // 1word DMAバッファ AD1CHS123 = 0; // 同時サンプルなし AD1CHS0 = 0x0000; // チャネル選択 AD1PCFGL = 0xFFCF; // AN4-5 is analog AD1CSSL = 0; // 自動スキャンなし AD1CON1bits.ADON = 1; // AD有効化 } /********************************************************** * タッチボタン判定処理 * タッチポイントの座標から、押されたボタンの種別No.を取得 * し、その値を返す ***********************************************************/ int CheckBtn(int x, int y) { int i, btn; /// タッチ座標位置表示(デバッグ用) itostring(4, x, MsgScrn+2); itostring(4, y, MsgScrn+9); lcd_Str(3, 16, MsgScrn, GREEN, BLACK); /// ボタンチェック btn = -1; for(i=0; i<2; i++){ if((x > Button[i][0]-60)&&(x < Button[i][0]+40)){ if((y > Button[i][1]-70)&&(y < Button[i][1]+70)) btn = i; } } return(btn); } /************************************************** * タッチ・ボタンごとの処理 ***************************************************/ void Process(int sw) { switch(sw){ case 0: /// ボタン-1 LATAbits.LATA1 = 0; // Green LED ON lcd_Str(4, 14, MsgLEDon, RED, BLACK); // LED点灯表示(キャラクタ) break; case 1: /// ボタン-2 LATAbits.LATA1 = 1; // Green LED OFF lcd_Str(4, 14, MsgLEDoff, RED, BLACK); // LED消灯表示(キャラクタ) break; default: break; } } /*************************************** * 整数からASCII文字に変換 ****************************************/ void itostring(char digit, unsigned int data, char *buffer) { char i; buffer += digit; // 最後の数字位置 for(i=digit; i>0; i--) { // 変換は下位から上位へ buffer--; // ポインター1 *buffer = (data % 10) + '0'; // ASCIIへ data = data / 10; // 次の桁へ } }