/************************************************************ * Scope 2CH Test Program * Graphic LCD(Monochrome): SG12864A * * Condition: * 8MHz External X'tal Oscillator, 10x PLL (8MHzx10= 80MHz) * Fcy=80MHz/2=40MHz, Tcy=25ns * * CPU: PIC24HJ12GP202 * * Original Program: Mr.Gokan * Mod. N.Ishii 2013.3.6 ***************************************************************/ #include #include "glcd_lib.h" /// Set Configuration Word: 8MHz External X'tal OSC _FBS(BSS_NO_FLASH & BWRP_WRPROTECT_OFF ) _FGS(GSS_OFF & GCP_OFF & GWRP_OFF ) _FOSCSEL(FNOSC_PRIPLL & IESO_ON) _FOSC(FCKSM_CSECME & IOL1WAY_OFF & POSCMD_XT ) _FWDT(FWDTEN_OFF & WINDIS_OFF) _FPOR(FPWRT_PWR32 & ALTI2C_OFF) /// A Variable (Global) /// Data Buffer for GLCD int Buffer1[192]; int Buffer2[192]; int Index,POT,SW; char EndFlag; /// Function Prottypes void Oscillo(void); void AxisDraw(void); void dotyline(int x0); void dotxline(int y0); /************************************************ * Function Main ************************************************/ int main(void){ /* Initialize Clock */ CLKDIVbits.PLLPRE = 0; // PLLPRE=1/2 to 4MHz PLLFBDbits.PLLDIV = 40; // PLLDIV=1/40 to 160MHz CLKDIVbits.PLLPOST = 0; // PLLPOST=1/2 to 80MHz then 40MIPS /* Initialize Port */ AD1PCFGL = 0xFFF8; // AN0-2 are Analog LATB = 0xFF7F; // only LCD_E is low TRISA = 0x000F; // RA4 is Out, Other is Input // TRISA = 0x000D; // RA1,RA4 is Out, Other is Input 110506 TRISB = 0x000F; // Set GLCD Port Direction CNPU1 = 0x00E0; // RB1,2,3 pull up // LATAbits.LATA1 = 1; // Green LED OFF Add 110506 /* Initialize GLCD */ lcd_Init(); lcd_Clear(0); lcd_Str(0, 0, "Start Osccillo"); Delay1m(1000); // Add 110505 /* /// Initialize ADC(単CHオシロの設定) AD1CON1 = 0x0044; // Module Off, 10bit, Format Integer, T3 Trigger, Auto Sample(Only AN0) AD1CON2 = 0x041E; // Vref=AVdd-AVss,Interrupt Timmin=8 Times (Divide Buffer) AD1CON3 = 0x0203; // Acquisition Time=2Tad, 1Tad=3*Tcy (75nsec*14=1.05usec) AD1CHS123= 0x0000; // AD Channel-0,1,2,3 Select AD1CHS0 = 0x0000; // AD Channel-0 Select AD1CSSL = 0x0005; // Auto Scan CH0,2 // AD1PCFGL = 0xFFF8; // AD Channel-0,1,2(RA0,1,2) is Aanalog Input AD1PCFGL = 0xFFFA; // AD Channel-0,2(RA0,2) is Aanalog Input 110506 */ /// Initialize ADC(2CHオシロの設定:4CH同時サンプリング:※印が変更したビット) AD1CON1 = 0x004C; // b15:ADON:0:ADCモジュールOFF // b14:x:0 // b13:ADSIDL:0:アイドルモードでも動作継続 // b12:ADDMABM:0:DMAバッファはスキャッタ/ギャザモードで書込まれる //------------------------------------------------------------------------------------------ // b11:x:0 // b10:AD12B:0:10bitで4CHのAD動作 // b_9:FORM<1>:0:データフォーマット= 整数 // b_8:FORM<0>:0 //------------------------------------------------------------------------------------------ // b_7:SSRC<2>:0:サンプルクロックソース= T3一致でサンプリング終了し変換開始(ADC1の場合) // b_6:SSRC<1>:1 // b_5:SSRC<0>:0 // b_4:x:0 //------------------------------------------------------------------------------------------ // b_3:SIMSAM:1:※ 同時サンプリング // b_2:ASAM:1:サンプリングは最後の変換終了直後に開始する。SAMPビットは自動セットされる // b_1:SAMP:0:S/Hはホールド中 // b_0:DONE:0:ADCステータスビット //------------------------------------------------------------------------------------------ AD1CON2 = 0x0202; // b15:VCFG<2>:0:VREF=AVDD-AVSS // b14:VCFG<1>:0: // b13:VCFG<0>:0: // b12:x:0 //------------------------------------------------------------------------------------------ // b11:x:0 // b10:CSCNA:0:※ 今回は4CH同時サンプルなので、4つのS/H(CH0〜3)を使用し入力スキャンは使用しない // b_9:CHPS<1>:1:※ 4CH(CH0〜3)を変換 // b_8:CHPS<0>:0: (AN3はDSW-1デジタル入力としているのでAVSS=0Vが変換される) //------------------------------------------------------------------------------------------ // b_7:BUFS:0(R-Only):※ バッファフルステータス  // b_6:x:0          BUF_0〜7に書込み中、BUF8〜15内のデータにアクセスせよ // b_5:SMPI<3>:0:※ 4CH同時サンプルの場合は、1回のサンプルで4CH分の同時サンプル終了後、4CH分の // b_4:SMPI<2>:0   変換が完了する毎にAD割込みを発生させる //------------------------------------------------------------------------------------------ // b_3:SMPI<1>:0 // b_2:SMPI<0>:0 // b_1:BUFM:1:最初の割込みで、BUF0から書込みを開始し、次の割込みでBUF8から開始する // b_0:ALTS:0 //------------------------------------------------------------------------------------------ // AD1CON3 = 0x0203;→ この設定だと、Tad=25nS*(3+1)=100nSで、 // 総変換時間= Tsmp + (Tconv*4)= 0.2u + (1.2uS*4)= 5.0uS // になり、0.2msec/divレンジのサンプル周期:4uSに対し、 // 総変換時間:5uS>4uSの関係になり、変換が終わらない内に次のサンプル // をしようとするため正しい周期で波形を表示できない。以下の設定に変更した。 AD1CON3 = 0x0202; // 130306変更 // b15:ADRC:0:ADCクロックソース= システムクロックから取出したクロック // b14:x:0 // b13:x:0 // b12:SAMC<4>:0:自動サンプル時間(Acquisition Time)Tsmp=2Tad(150nS(40MIPS)) //------------------------------------------------------------------------------------------ // b11:SAMC<3>:0 // b10:SAMC<2>:0 // b_9:SAMC<1>:1 // b_8:SAMC<0>:0 //------------------------------------------------------------------------------------------ // b_7:x:0 // b_6:x:0 // b_5:ADCS<5>:0:ADCクロック周期(Tad)= Tcy*(ADCS+1)= 25nS*(2+1)= 75nS(規格:≧70nSmin):40MIPS // b_4:ADCS<4>:0 //------------------------------------------------------------------------------------------ // b_3:ADCS<3>:0 // b_2:ADCS<2>:0 // b_1:ADCS<1>:1 // b_0:ADCS<0>:0 //------------------------------------------------------------------------------------------ //////////////////////////////////////////////////////////////////////////////////////////////// /// <総変換時間算出> ///  @ 40MIPSの場合 /// Tconv= 12Tad= 12*0.075uS= 0.9uSなので、 /// 総変換時間= Tsmp + (Tconv*4)= 0.15u + (0.9uS*4)= 3.75uS /////////////////////////////////////////////////////////////////////////////////////////////// AD1CHS123= 0x0000; // b15:x:0 // b14:x:0 // b13:x:0 // b12:x:0 //------------------------------------------------------------------------------------------ // b11:x:0 // b10:CH123NB<1>:0:B側のS/Hは未使用 // b_9:CH123NB<0>:0 // b_8:CH123SB:0: //------------------------------------------------------------------------------------------ // b_7:x:0 // b_6:x:0 // b_5:x:0 // b_4:x:0 //------------------------------------------------------------------------------------------ // b_3:x:0 // b_2:CH123NA<1>:0:S/H(CH1-3)負側入力は、AVSSに接続 // b_1:CH123NA<0>:0 // b_0:CH123SA:0:AN0 for CH1 +IN/ AN1 for CH2 +IN/ AN2 for CH3 +IN(CH1〜3はS/HのCH) //------------------------------------------------------------------------------------------ AD1CHS0 = 0x0003; // b15:CH0NB:0:B側のS/Hは未使用 // b14:x:0 // b13:x:0 // b12:CH0SB<4>:0 //------------------------------------------------------------------------------------------ // b11:CH0SB<3>:0 // b10:CH0SB<2>:0 // b_9:CH0SB<1>:0 // b_8:CH0SB<0>:0 //------------------------------------------------------------------------------------------ // b_7:CH0NA:0:S/H(CH0)負側入力は、AVSSに接続 // b_6:x:0 // b_5:x:0 // b_4:CH0SA<4>:0:※ AN3 for CH0 +IN //------------------------------------------------------------------------------------------ // b_3:CH0SA<3>:0 // b_2:CH0SA<2>:0 // b_1:CH0SA<1>:1 // b_0:CH0SA<0>:1 //------------------------------------------------------------------------------------------ AD1CSSL = 0x0000; // b15:x:0 // b14:x:0 // b13:x:0 // b12:x:0 //------------------------------------------------------------------------------------------ // b11:x:0 // b10:x:0 // b_9:x:0 // b_8:x:0 //------------------------------------------------------------------------------------------ // b_7:x:0 // b_6:x:0 // b_5:CSS5:0:入力スキャンに、AN5を選択しない // b_4:CSS4:0:入力スキャンに、AN4を選択しない //------------------------------------------------------------------------------------------ // b_3:CSS3:0:入力スキャンに、AN3を選択しない // b_2:CSS2:0:入力スキャンに、AN2を選択しない // b_1:CSS1:0:入力スキャンに、AN1を選択しない // b_0:CSS0:0:入力スキャンに、AN0を選択しない //------------------------------------------------------------------------------------------ AD1PCFGL = 0xFFF8; // b15:x:1 // b14:x:1 // b13:x:1 // b12:x:1 //------------------------------------------------------------------------------------------ // b11:x:1 // b10:x:1 // b_9:PCFG9:1 // b_8:PCFG8:1 //------------------------------------------------------------------------------------------ // b_7:PCFG7:1 // b_6:PCFG6:1 // b_5:PCFG5:1 // b_4:PCFG4:1 //------------------------------------------------------------------------------------------ // b_3:PCFG3:1:AN3は、デジタル入力ピンに設定(RB1:DSW-1として使用:この場合MUXはAVSS=0Vに接続される) // b_2:PCFG2:0:AN2を、アナログ入力ピンに設定 // b_1:PCFG1:0:AN1を、アナログ入力ピンに設定 // b_0:PCFG0:0:AN0を、アナログ入力ピンに設定 //------------------------------------------------------------------------------------------ AD1CON1bits.ADON = 1; // ADC Start IEC0bits.AD1IE = 1; // Enable ADC INT /* Inittalize Timer3:T3= Tcy*PS*n= 0.025uS*1*400 = 10uS */ PR3 = 399; // n = 400 (PR3=n-1): Mod. 0x018F-> 399 110423 T3CON = 0x0000; // T3_OFF, T3_GATE_OFF, T3_PS_1_1, T3_SOURCE_INT /* Inittalize Variable */ Index = 0; EndFlag = 0; /****** Main Loop ****/ while(1){ /* Switching Sampling Period */ SW = (~PORTB & 0x000E) >> 1; // Read Decimal Dip SW /// Add Branch Set PS3: 110425 if (SW == 7) T3CONbits.TCKPS = 1; // PS3 = 1/8 else T3CONbits.TCKPS = 0; // PS3 = 1/1 /* /// 単CHオシロの場合の、T3サンプル周期設定 switch(SW){ case 0: PR3 = 79; // 2usec (Mod. 0x004F-> 79 110423):0.2msec/div break; case 1: PR3 = 199; // 5usec (Mod. 0x00C7-> 199 110423):0.5msec/div break; case 2: PR3 = 399; // 10usec (Mod. 0x018F-> 399 110423):1.0msec/div break; case 3: PR3 = 799; // 20usec (Mod. 0x031F-> 799 110423):2.0msec/div break; /// Add Sampling Period: 110423 case 4: PR3 = 1999; // 50usec:5.0msec/div break; case 5: PR3 = 3999; // 100usec:10msec/div break; case 6: PR3 = 19999; // 500usec:50msec/div break; case 7: PR3 = 24999; // 5msec:500msec/div break; // default:PR3 = 399; // 10usec (Mod. 0x018F-> 399 110423):1.0msec/div default:PR3 = 199; // 5usec:0.5msec/div 修正 130226 break; } */ /// 2CHオシロ(4CH同時サンプリング)の場合の、T3サンプル周期設定 switch(SW){ case 0: PR3 = 159; // 4usec:0.2msec/div break; case 1: PR3 = 399; // 10usec:0.5msec/div break; case 2: PR3 = 799; // 20usec:1.0msec/div break; case 3: PR3 = 1599; // 40usec:2.0msec/div break; /// Add Sampling Period: 110423 case 4: PR3 = 3999; // 100usec:5.0msec/div break; case 5: PR3 = 7999; // 200usec:10msec/div break; case 6: PR3 = 39999; // 1000usec:50msec/div break; case 7: PR3 = 49999; // 10msec:500msec/div break; default:PR3 = 399; // 10usec:0.5msec/div break; } /* Draw a Graph of Input Wave Data */ EndFlag = 0; // Clear End of Convertion Flag Index = 0; T3CONbits.TON = 1; // T3ON-> ADC Start while(!EndFlag); Oscillo(); // Disp. Oscillo EndFlag = 0; Index = 0; Delay1m(500); // Disp. is 0.5Sec Period // LATAbits.LATA1 = 1; // Green LED OFF Add 110506 } } /* ////////////////////////////////////////////////// // 単CHオシロの場合の、ADC割込み関数 // ADC Interrupt: 2Channel, 4Times (Duble Buffer) // ADC Interrupt Period = T3_Period*2*4 ////////////////////////////////////////////////// void __attribute__((interrupt, auto_psv)) _ADC1Interrupt(void) { IFS0bits.AD1IF = 0; // Clead IF Flag if(AD1CON2bits.BUFS){ // '1'-> Useing ADC1BUF8- ADC1BUFE Side (Access is ADC1BUF0- ADC1BUF6 Side) Buffer1[Index++] = ADC1BUF0; // 1Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF2; // 2Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF4; // 3Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF6; // 4Times: Buffer <- AN0 Input Data POT = ADC1BUF7; // Store is AN2 Trigger Potentio Input ADC Value } else{ // '0'-> Useing ADC1BUF0- ADC1BUF6 Side (Access is ADC1BUF8- ADC1BUFE Side) Buffer1[Index++] = ADC1BUF8; // 1Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFA; // 2Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFC; // 3Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFE; // 4Times: Buffer <- AN0 Input Data POT = ADC1BUFF; // Store is AN2 Trigger Potentio Input ADC Value } if(Index >= 192){ // Buffer Full ? T3CONbits.TON = 0; // Buffer Full Then T3 OFF and EOC Flag ON EndFlag = 1; } } */ /****************************************************** * 2CHオシロの場合の、ADC割込み関数(4CH同時サンプリング) * ADC Interrupt: 4Channel, 1Times (Duble Buffer) * ADC Interrupt Period = T3_Period(サンプル周期と等しい) *******************************************************/ void __attribute__((interrupt, auto_psv)) _ADC1Interrupt(void) { IFS0bits.AD1IF = 0; // Clead IF Flag if(AD1CON2bits.BUFS){ // '1'-> Useing ADC1BUF8- ADC1BUFE Side (Access is ADC1BUF0- ADC1BUF6 Side) /// x = ADC1BUF0→ AN3 Input Data(AN3は、DSW-1デジタル入力なので何もしない) Buffer1[Index] = ADC1BUF1; // Buffer1[] <- AN0 Input Data(オシロのCH1) Buffer2[Index] = ADC1BUF2; // Buffer2[] <- AN1 Input Data(オシロのCH2) POT = ADC1BUF3; // POT <- AN2 Input Data((オシロのトリガ・ポテンショレベル) } else{ // '0'-> Useing ADC1BUF0- ADC1BUF6 Side (Access is ADC1BUF8- ADC1BUFE Side) /// x = ADC1BUF8→ AN3 Input Data(AN3は、DSW-1デジタル入力なので何もしない) Buffer1[Index] = ADC1BUF9; // Buffer1[] <- AN0 Input Data(オシロのCH1) Buffer2[Index] = ADC1BUFA; // Buffer2[] <- AN1 Input Data(オシロのCH2) POT = ADC1BUFB; // POT <- AN2 Input Data((オシロのトリガ・ポテンショレベル) } ++Index; if(Index >= 192){ // Buffer Full ? T3CONbits.TON = 0; // Buffer Full Then T3 OFF and EOC Flag ON EndFlag = 1; } } /******************************************************* * Disp. Oscillo (Disp. Save Buffer Data) * Detect Trigger-> Disp. 128Data from this Position * Not Detect Trigger-> Disp. 128Data from Top Position *******************************************************/ void Oscillo(void){ int i,x; AxisDraw(); // Drawing Coordinate Axis x = 0; // First Data /* Check Trigger */ while((x < 128) && !((Buffer1[x]=POT))){ x++; } /* Detect Trigger-> Disp. 128Data from this Position */ if(x<64){ // LATAbits.LATA1 = 0; // Green LED ON Add 110506 for(i=0; i<127; i++){ lcd_Line(i, Buffer1[i+x]/16, i+1, Buffer1[i+x+1]/16); lcd_Line(i, Buffer2[i+x]/16, i+1, Buffer2[i+x+1]/16); } } /* Not Detect Trigger-> Disp. 128Data from Top Position */ else { // LATAbits.LATA1 = 1; // Green LED OFF Add 110506 for(i=0; i<127; i++){ lcd_Line(i, Buffer1[i]/16, i+1, Buffer1[i+1]/16); lcd_Line(i, Buffer2[i]/16, i+1, Buffer2[i+1]/16); } } } /****************************************** * Drawing Coordinate Axis *******************************************/ void AxisDraw(void){ lcd_Clear(0); lcd_Line(0, 0, 0, 63); // Y axis dotyline(54); dotyline(107); lcd_Line(0, 32, 127, 32); // X axis dotxline(49); // dotxline(16); dotxline(17); // Mod 110505 /* Disp. Unit Time Axis (msec/div) */ switch(SW){ case 0: lcd_Str(7,7,"0.2msec/div"); // Mod. dec-> div 110423 break; case 1: lcd_Str(7,7,"0.5msec/div"); break; case 2: lcd_Str(7,7,"1.0msec/div"); break; case 3: lcd_Str(7,7,"2.0msec/div"); break; // break文が抜けていたので追加:130226 /// Add Disp. Unit Time Axis: 110423 case 4: lcd_Str(7,7,"5.0msec/div"); break; case 5: lcd_Str(7,7,"10msec/div"); break; case 6: lcd_Str(7,7,"50msec/div"); break; case 7: lcd_Str(7,6,"500msec/div"); break; default:lcd_Str(7,7,"0.5msec/div"); break; } } /******************************************* * Assist Line X Coordinate Axis (Dot Line) ********************************************/ void dotxline(int y0){ int i; for(i=0; i<128; i+=3) lcd_Pixel(i, y0-1, 1); } /******************************************* * Assist Line Y Coordinate Axis (Dot Line) ********************************************/ void dotyline(int x0){ int i; for(i=0; i<64; i+=3) lcd_Pixel(x0-1, i, 1); }