/**************************************************************** * dsPIC33F_OLED_FftAnalyzer_Test * * 512ポイント固定 * サンプル周波数切替え * 次の3種類、分解能選択可能 * @ 32kサンプル/512ポイント= 分解能:62.5Hz *    表示Fレンジ= 0〜 約8kHz(62.5Hz × 128dot) * A 16kサンプル/512ポイント= 分解能:31.25Hz *    表示Fレンジ= 0〜 約4kHz(31.25Hz × 128dot) * B 8kサンプル/512ポイント= 分解能:15.625Hz *    表示Fレンジ= 0〜 約2kHz(15.625Hz × 128dot) * * OLEDモジュール: UG-2864HSWEG01 * * Condition: * 8MHz External X'tal Oscillator, 10x PLL (8MHzx10= 80MHz) * Fcy=80MHz/2=40MHz, Tcy=25ns * * CPU: dsPIC33FJ64GP802 * * 2017.11.1 N.Ishii ******************************************************************/ #include "p33FJ64GP802.h" #include "SSD1306_OLEDlib_dsPIC33F.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); //// FFT関連 #define powerOf2 9 #define fftPoints (1<= 64) ypos= 63; Draw_Line(i, 10, i, ypos, WHITE); ypos_old[i]= ypos; // 今回のY座標データを、オールド配列に転送し次回の比較要素とする } } else { // 2回目以降のFFT表示 for(i=0;i<128;i++){ // 512ポイントFFTだが、OLEDの表示分解能が、X方向128dotなので、ループ数=128 ypos= 10 + oledData[i]/3; if(ypos >= 64) ypos= 63; if(ypos != ypos_old[i]) { // 前のレベル(Y座標)と、今回のレベルが違っていたら以下を実行 if(ypos > ypos_old[i]) { // 今回のレベルが大きい場合 Draw_Line(i, ypos_old[i], i, ypos, WHITE); // プラス分のみライン描画 } if(ypos < ypos_old[i]) { // 今回のレベルが小さい場合 for(j= ypos+1; j< ypos_old[i]+1; j++) { Draw_Pixel(i, j, BLACK); // その分のドットをオフ(消去)する } } } // (前のレベル(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 = 0x000D; // RA1,RA4 is Out, Other is Input TRISB = 0x000F; // ポートの入出力モード設定 CNPU1 = 0x00E0; // RB1,2,3 pull up LATAbits.LATA1 = 1; // Green LED OFF /// OLED表示器の初期化と開始メッセージ表示 OLED_init(); OLED_ROMstr("Start FFT !!"); Delay1m(1000); OLED_clear_all(BLACK); // 全画面クリア /// 下部X座標軸の目盛描画 Draw_Line(0, 10, 127, 10, WHITE); // 下部X座標軸 // 目盛描画 for(i= 0; i < 128; i+= 4){ Draw_Pixel(i, 9, WHITE); } /// 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*1250 = 31.25uS(32kHz)) sw = (PORTB & 0x000E) >> 1; // リセット時に、Decimal Dip SWを読込む switch(sw){ case 0: PR3 = 1249; // 31.25uS(32kHz):表示Fレンジ= 0〜 約8kHz(62.5Hz × 128dot) OLED_locate(72,7); // x=13キャラ目のx座標(dot単位)指定= (13-1)*6= 72 OLED_ROMstr("250Hz/div"); // デビジョン表示 break; case 1: PR3 = 2499; // 62.5uS(16kHz):表示Fレンジ= 0〜 約4kHz(31.25Hz × 128dot) OLED_locate(72,7); OLED_ROMstr("125Hz/div"); // デビジョン表示 break; case 2: PR3 = 4999; // 125uS(8kHz):表示Fレンジ= 0〜 約2kHz(1dot当たり8k/512=15.625Hzで、128dot分表示なので、2k) OLED_locate(66,7); OLED_ROMstr("62.5Hz/div"); // デビジョン表示 break; default:PR3 = 1249; // 31.25uS(32kHz) OLED_locate(72,7); OLED_ROMstr("250Hz/div"); // デビジョン表示 break; } 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 } }