/************************************************************** * dsPIC33F_FftAnalyzerテスト_2 * * ADCを使って入力信号のFFT解析表示を行う実験 * ハードは、自作オシロ初号機を使用する。 * (MPUをPIC24Hと互換のPIC33Fに差替える。) * * Graphic LCD(Monochrome): SG12864A * * Condition: * 8MHz External X'tal Oscillator, 10x PLL (8MHzx10= 80MHz) * Fcy=80MHz/2=40MHz, Tcy=25ns * * CPU: dsPIC33FJ64GP802 * * N.Ishii 2016.4.8 * N.Ishii 2016.4.13 * XOR的なクリア方式を、もう少し追及してみる。 * カレント描画する時、前のレベル状態で、クリア処理を変える * N.Ishii 2016.5.16 * CNPU2 = 0x0080;→ このプルアップ設定(液晶のストローブ信号)は不要なので削除 ***************************************************************/ #include "p33FJ64GP802.h" #include "glcd_lib.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); #define powerOf2 6 #define fftPoints (1<= 64) ypos= 63; // このリミットが無いとオーバーレンジした時、液晶表示がバラケル lcd_Line(4*i, 10, 4*i, ypos); ypos_old[i]= ypos; // 今回のY座標データを、オールド配列に転送し次回の比較要素とする } } else { // 2回目以降のFFT表示 for(i=0;i<32;i++){ ypos= 10 + lcdData[i]/30; if(ypos >= 64) ypos= 63; if(ypos != ypos_old[i]) { // 前のレベル(Y座標)と、今回のレベルが違っていたら以下を実行 if(ypos > ypos_old[i]) { // 今回のレベルが大きい場合 lcd_Line(4*i, ypos_old[i], 4*i, ypos); // プラス分のみライン描画 } if(ypos < ypos_old[i]) { // 今回のレベルが小さい場合 for(j= ypos+1; j< ypos_old[i]+1; j++) { lcd_Pixel(4*i, j, 0); // その分のドットをオフ(消去)する } } } // (前のレベル(Y座標)と、今回のレベルが同じだったら何もしない) ypos_old[i]= ypos; // 今回のY座標データを、次回の比較要素とするため、オールド配列に転送 } } } writePoint++; if ( writePoint == fftPoints ) { writePoint = 0; fast_flag= 0; } IFS0bits.AD1IF = 0; // clear A/D interuppt flag } // Main routine int main(void) { /// Initialize Clock OSCCON = 0x00300; // PRIPLL指定 CLKDIV = 0x0100; // クロックの分周1:2に設定 PLLFBD = 0x0026; // 40倍 8MHz÷2×40÷2 = 80MHz /// Initialize Port AD1PCFGL = 0xFFFA; // AD Channel-0,2(RA0,2) is Aanalog Input RA1(AN1)デジタル出力⇒ デバッグLED LATB = 0xFF7F; // only LCD_E is low // TRISA = 0x000F; // RA4のみ出力 TRISA = 0x000D; // RA1,RA4 is Out, Other is Inpu TRISB = 0x000F; // ポートの入出力モード設定 CNPU1 = 0x00E0; // RB1,2,3 pull up // CNPU2 = 0x0080; // このプルアップ設定(液晶のストローブ信号)は不要。無くても動く。 160516 LATAbits.LATA1 = 1; // Green LED OFF lcd_Init(); // GLCD初期化 lcd_Clear(0); lcd_Str(0, 0, "Start FFT"); Delay1m(1000); lcd_Clear(0); /// 下部X座標軸の目盛描画 lcd_Line(0, 10, 127, 10); // 下部X座標軸 // 目盛描画 for(i= 0; i < 128; i+= 4){ lcd_Line(i, 10, i, 9); } lcd_Str(7,9,"250Hz/div"); // デビジョン表示 /// ADC設定 AD1CON1bits.ADON= 0; // ADC OFF AD1CHS0= 0x0000; // AN0ピンを、CH0のサンプルホールドに接続 AD1CON1= 0x8444; // AD ON, 12bitADC, 整数, T3同期, 自動サンプルON AD1CON2= 0x0000; // 常にCH0を変換しアドレス0から書込み AD1CON3= 0x0210; // Tad= 16Tcy, Tsamp= 2Tad AD1CSSL= 0x0000; // 入力スキャンしない /// T3設定:T3= Tcy*PS*n= 0.025uS*1*2500 = 62.5uS(16kHz) PR3 = 2499; // n = 2500 (PR3=n-1) T3CON = 0x0000; // T3_OFF, T3_GATE_OFF, T3_PS_1_1, T3_SOURCE_INT // enable interrupt IEC0bits.AD1IE = 1; // Enable ADC INT writePoint = 0; Delay1m(500); // P_ON時のインパルスノイズ入力をFFT表示させない為の遅延 T3CONbits.TON = 1; // T3ON-> ADC Start // main loop while(1) { // A/D result store in resultData } }