/**************************************************************** * easy_audio_fft_analyzer_v2 * * 512ポイントは固定にし、サンプル周波数を、切替えられる * ようにした。(リセット時に読込む簡易的な方法にした。) * 次の3種類にし、分解能も選べるようにした。 * @ 32kサンプル/512ポイント= 分解能:62.5Hz *    表示Fレンジ= 0〜 約16kHz(62.5Hz × 256dot) * A 16kサンプル/512ポイント= 分解能:31.25Hz *    表示Fレンジ= 0〜 約8kHz(31.25Hz × 256dot) * B 8kサンプル/512ポイント= 分解能:15.625Hz *    表示Fレンジ= 0〜 約4kHz(15.625Hz × 256dot) * * 2.4インチQVGA液晶モジュール(aitendo): UL024TF * * Condition: * 8MHz External X'tal Oscillator, 10x PLL (8MHzx10= 80MHz) * Fcy=80MHz/2=40MHz, Tcy=25ns * * CPU: dsPIC33FJ64GP802 * * 2016.5.17 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); #define powerOf2 9 #define fftPoints (1<= 240) ypos= 239; lcd_Line(i, 20, i, ypos, WHITE); ypos_old[i]= ypos; // 今回のY座標データを、オールド配列に転送し次回の比較要素とする } } else { // 2回目以降のFFT表示 for(i=0;i<256;i++){ ypos= 20 + lcdData[i]; if(ypos >= 240) ypos= 239; if(ypos != ypos_old[i]) { // 前のレベル(Y座標)と、今回のレベルが違っていたら以下を実行 if(ypos > ypos_old[i]) { // 今回のレベルが大きい場合 lcd_Line(i, ypos_old[i], i, ypos, WHITE); // プラス分のみライン描画 } if(ypos < ypos_old[i]) { // 今回のレベルが小さい場合 for(j= ypos+1; j< ypos_old[i]+1; j++) { lcd_Pixel(i, 239-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 TRISA = 0x000D; // RA1,RA4 is Out, Other is Inpu TRISB = 0x000F; // Set QVGA Port Direction CNPU1 = 0x00E0; // RB1,2,3 pull up LATAbits.LATA1 = 1; // Red LED OFF // GLCD初期化 lcd_Init(); lcd_Clear(BLACK); // クリア lcd_Str(0, 0, "Start FFT", CYAN, BLACK); delay_ms(1000); lcd_Clear(0); /// 下部X座標軸の目盛描画 lcd_Line(0, 20, 256, 20, GREEN); // 下部X座標軸 /// 目盛描画 for(i= 0; i <= 256; i+= 4){ lcd_Line(i, 20, i, 15, GREEN); } /// 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) lcd_Str(0,16,"0Hz", CYAN, BLACK); // 最小周波数表示 lcd_Str(7,16,"250Hz/div", CYAN, BLACK); // デビジョン表示 lcd_Str(20,16,"16kHz", CYAN, BLACK); // 最大周波数表示 break; case 1: PR3 = 2499; // 62.5uS(16kHz) lcd_Str(0,16,"0Hz", CYAN, BLACK); // 最小周波数表示 lcd_Str(7,16,"125Hz/div", CYAN, BLACK); // デビジョン表示 lcd_Str(20,16,"8kHz", CYAN, BLACK); // 最大周波数表示 break; case 2: PR3 = 4999; // 125uS(8kHz) lcd_Str(0,16,"0Hz", CYAN, BLACK); // 最小周波数表示 lcd_Str(7,16,"62.5Hz/div", CYAN, BLACK);// デビジョン表示 lcd_Str(20,16,"4kHz", CYAN, BLACK); // 最大周波数表示 break; default:PR3 = 1249; // 31.25uS(32kHz) lcd_Str(0,16,"0Hz", CYAN, BLACK); // 最小周波数表示 lcd_Str(7,16,"250Hz/div", CYAN, BLACK); // デビジョン表示 lcd_Str(20,16,"16kHz", CYAN, BLACK); // 最大周波数表示 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; delay_ms(500);; // P_ON時のインパルスノイズ入力をFFT表示させない為の遅延 T3CONbits.TON = 1; // T3ON-> ADC Start // main loop while(1) { // A/D result store in resultData } }