/******************************************************************** * Scope_PIC32MX_RE_TRG_TEST.c * モノクロ単CHオシロのトリガを、RE(ロータリエンコーダ)で行う実験 * * 実験ハードは、PIC32MXトレーニング基板を使用 * 時間軸は、0.1mS/D固定 * * Graphic LCD(Monochrome): SG12864A * * Condition: * 8MHz External X'tal Oscillator, 20x PLL (8MHzx20= 160MHz) * Fcy=160MHz/2=80MHz, Tcy=12.5ns * * CPU: PIC32MX340F256H * * N.Ishii 2014.11.6 *********************************************************************/ #include /* PIC32 peripheral library */ #include "glcd_lib32k.h" // コンフィギュレーション設定 // CPU=80MHz Peri=80MHz,HS+PLL,Divider=1/2,PLL=x20,WDT=Off #pragma config FNOSC=PRIPLL, POSCMOD=HS, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_1 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 // トリガレベル・メッセージテーブル char MsgTrig[] = "Trg:xxxx"; /// Rotary ecoder #define RE_A PORTFbits.RF5 #define RE_B PORTFbits.RF6 ////----------------------------------------------------------------------------------- /// A Variable (Global) unsigned short Buffer1[192]; //unsigned short Buffer2[192]; unsigned short Index; short POT,Ypos; short i; char re_b_m0; // ROTARY ENCODER OLD Temp char re_b_m1; // ROTARY ENCODER NEW Temp char re_b_m2; // ROTARY ENCODER EDGE Temp char EndFlag; char HOLD_ON_flag = 0; char hold_status = 0; /// Function Prottypes void Oscillo(void); void AxisDraw(void); void dotyline(unsigned short x0); void dotxline(unsigned short y0); void RotaryEncoderRead(void); void itostring(char digit, unsigned int data, char *buffer); /************************************************ * Function Main ************************************************/ int main(void) { //システム最適設定 SYSTEMConfigPerformance(80000000); mJTAGPortEnable(DEBUG_JTAGPORT_OFF); // JTAGを無効化 //I/O設定 AD1PCFG = 0xFFFE; // GLCD制御信号レベルの初期化 LCD_E = 0; LCD_CS1 = 1; LCD_CS2 = 1; LCD_RW = 1; LCD_DI = 1; LCD_TRIS = 0x0000; // LCDデータバス(DB0-DB7)オール出力(TRISE= 0) TRISD = 0xFF17; // LCD_CS1,CS2,DI:全て出力・デバッグLED:出力・SW2-5:入力、他未使用ピンは入力設定 TRISF = 0xFFFC; // LCD_E,RW:全て出力、他未使用ピンは入力設定 TRISG = 0x028C; // SD_SDO,SCK:出力、SDI:入力・他未使用ピンは入力設定 TRISB = 0xFFDF; // RB5:SD_CS出力、RB4:SD_WE入力、RB3:SD_CD入力、RB2:AN2(トリガ入力)、RB1:AN1未使用、RB0:オシロ入力 CNPUE = 0x0060; // SD_CD(CN5),WE(CN6)のみ内部プルアップ LATDbits.LATD3 = 1; // デバッグLED消灯 // 液晶表示器の初期化 lcd_Init(); lcd_Clear(0); lcd_Str(0, 0, "Start Osccillo"); delay_ms(1000); /// ADC初期設定 AD1CON1 = 0x0044; // サンプルモード等設定 // b15:ON:0:ADCモジュールOFF // b14:FRZ:0:デバッグ中動作継続 // b13:ADSIDL:0:アイドルモードでも動作継続 // b12:x:0 //------------------------------------------------------------------------------------------ // b11:x:0 // b10:FORM<2>:0:データフォーマット= 整数16ビット // 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:CLRASAM:0:割込みで変換継続 //------------------------------------------------------------------------------------------ // b_3:x:0 // b_2:ASAM:1:サンプリングは最後の変換終了直後に開始する。SAMPビットは自動セットされる // b_1:SAMP:0:S/Hはホールド中 // b_0:DONE:0:ADCステータスビット //------------------------------------------------------------------------------------------ AD1CON2 = 0x003C; // スキャンモード等設定 // b15:VCFG<2>:0:VREF=AVDD-AVSS // b14:VCFG<1>:0: // b13:VCFG<0>:0: // b12:OFFCAL:0:較正モード無効 //------------------------------------------------------------------------------------------ // b11:x:0 // b10:CSCNA:0:※ 入力スキャンしない // b_9:x:0 // b_8:x:0 //------------------------------------------------------------------------------------------ // b_7:BUFS:0(R-Only):※ バッファフルステータス  // b_6:x:0          BUF_0〜7に書込み中、BUF8〜15内のデータにアクセスせよ // b_5:SMPI<3>:1:※ 16回のサンプル/変換動作完了毎に割込み発生 // b_4:SMPI<2>:1 //------------------------------------------------------------------------------------------ // b_3:SMPI<1>:1 // b_2:SMPI<0>:1 // b_1:BUFM:0:※ 16ワード単一結果バッファを使用 // b_0:ALTS:0:※ 常にMUXA入力選択を使用 //------------------------------------------------------------------------------------------ AD1CON3 = 0x0202; // ADCクロック等設定 // b15:ADRC:0:ADCクロックソース= システムクロックから取出したクロック // b14:x:0 // b13:x:0 // b12:SAMC<4>:0:自動サンプル時間(Acquisition Time)Tsmp= 2Tad= 2*75nS= 150nS(規格:≧132nSmin):80MIPS //------------------------------------------------------------------------------------------ // b11:SAMC<3>:0 // b10:SAMC<2>:0 // b_9:SAMC<1>:1 // b_8:SAMC<0>:0 //------------------------------------------------------------------------------------------ // b_7:ADCS<7>:0:ADCクロック周期(Tad)= 2*Tcy*(ADCS+1)= 2*12.5nS*(2+1)= 75nS(規格:≧65nSmin):80MIPS // b_6:ADCS<6>: // b_5:ADCS<5>:0: // 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 //------------------------------------------------------------------------------------------ /////////////////////////////////////////////////////////////////////////////////////////////// /// <総変換時間算出> ///  @ 80MIPSの場合 /// Tconv= 12Tad= 12*0.075uS= 0.9uS /// 総変換時間= Tsmp + Tconv= 0.15uS+ 0.9uS= 1.05uS /////////////////////////////////////////////////////////////////////////////////////////////// AD1CHS = 0x00000000; // MUX設定 // b31:CH0NB:0:B側のS/Hは未使用(負側入力をAVCCに接続) // b30:x:0 // b29:x:0 // b28:x:0 //------------------------------------------------------------------------------------------ // b27:CH0SB<3>:0 // b26:CH0SB<2>:0 // b25:CH0SB<1>:0 // b24:CH0SB<0>:0 //------------------------------------------------------------------------------------------ // b23:CH0NA:0:S/H(CH0)負側入力は、AVSSに接続 // b22:x:0 // b21:x:0 // b20:x:0 //------------------------------------------------------------------------------------------ // b19:CH0SA<3>:0:※ AN0 for CH0 +IN // b18:CH0SA<2>:0 // b17:CH0SA<1>:0 // b16:CH0SA<0>:0 //------------------------------------------------------------------------------------------ AD1CSSL = 0x0000; // 入力スキャンCH設定 // b15:CSS15:0:入力スキャンに、AN15を選択しない // b14:CSS14:0:入力スキャンに、AN14を選択しない // b13:CSS13:0:入力スキャンに、AN13を選択しない // b12:CSS12:0:入力スキャンに、AN12を選択しない //------------------------------------------------------------------------------------------ // b11:CSS11:0:入力スキャンに、AN11を選択しない // b10:CSS10:0:入力スキャンに、AN10を選択しない // b_9:CSS9:0:入力スキャンに、AN9を選択しない // b_8:CSS8:0:入力スキャンに、AN8を選択しない //------------------------------------------------------------------------------------------ // b_7:CSS7:0:入力スキャンに、AN7を選択しない // b_6:CSS6:0:入力スキャンに、AN6を選択しない // 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を選択しない //------------------------------------------------------------------------------------------ AD1PCFG = 0xFFFE; // アナログ/デジタルピン設定 // b15:PCFG15:1 // b14:PCFG14:1 // b13:PCFG13:1 // b12:PCFG12:1 //------------------------------------------------------------------------------------------ // b11:PCFG11:1 // b10:PCFG10: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 // b_2:PCFG2:1 // b_1:PCFG1:1 // b_0:PCFG0:AN0を、アナログ入力ピンに設定(他は全てデジタル入力ピンに設定) //------------------------------------------------------------------------------------------ AD1CON1bits.ADON = 1; // ADC Start mAD1ClearIntFlag(); // Clead AD1 IF Flag mAD1SetIntPriority(7); // AD1割込み優先レベル初期設定 mAD1SetIntSubPriority(3); // AD1割込みサブ優先レベル初期設定 mAD1IntEnable(1); // Enable ADC INT /// Timer3:T3初期設定= Tcy*PS*n= 0.0125uS*2*80 = 2uS(0.1mS/D固定) PR3 = 79; // n = 80 (PR3=n-1) T3CON = 0x0010; // T3_OFF, T3_GATE_OFF, T3_PS_1_2, T3_SOURCE_INT // 外部割込み初期設定 ConfigINT1(EXT_INT_ENABLE | RISING_EDGE_INT | EXT_INT_PRI_2); // HOLD_SW // 外部割り込みフラグのクリア mINT1ClearIntFlag(); // マルチベクタ割り込み設定、割り込み許可 INTEnableSystemMultiVectoredInt(); /// Inittalize Variable Index = 0; EndFlag = 0; /// POT変数の初期化(トリガレベルを、REによりデジタル値で直に与える) POT = 512; // センターレベル設定 Ypos = 32; // トリガレベルライン表示の、Yポジション初期化 /// メイン・ループ while(1){ /// 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; /// Cheack HOLD_RUN_SW Status while (HOLD_ON_flag){ hold_status = 1; } hold_status = 0; /// ロータリエンコーダ読込み(波形描画更新インターバル:約0.3秒も兼ねている) for(i= 0; i < 300; ++i){ delay_ms(1); RotaryEncoderRead(); // ロータリエンコーダ読込み } } } /************************************************ * ADC Interrupt: 2Channel, 4Times (Duble Buffer) * ADC Interrupt Period = T3_Period*2*4 *************************************************/ void __ISR(27, ipl7) AD1Interrupt(void) { //LATDbits.LATD3 = ~LATDbits.LATD3; mAD1ClearIntFlag(); // Clead IF Flag Buffer1[Index++] = ADC1BUF0; // 1Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF1; // 2Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF2; // 3Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF3; // 4Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF4; // 5Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF5; // 6Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF6; // 7Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF7; // 8Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF8; // 9Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUF9; // 10Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFA; // 11Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFB; // 12Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFC; // 13Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFD; // 14Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFE; // 15Times: Buffer <- AN0 Input Data Buffer1[Index++] = ADC1BUFF; // 16Times: Buffer <- AN0 Input Data if(Index >= 192){ // Buffer Full ? T3CONbits.TON = 0; // Buffer Full Then T3 OFF and EOC Flag ON EndFlag = 1; } } /**************************************************** * INT1外部割り込み処理(HOLD SW Read) ****************************************************/ void __ISR(7, ipl2) INT1Handler(void){ if (!hold_status) { // hold_status -> 0: RUN HOLD_ON_flag = 1; } else { // hold_status -> 1: HOLD_ON Loop HOLD_ON_flag = 0; } delay_ms(100); // チャッタリング回避 mINT1ClearIntFlag(); // 割り込みフラグクリア } /******************************************************* * Disp. Oscillo (Disp. Save Buffer Data) * Detect Trigger-> Disp. 128Data from this Position * Not Detect Trigger-> Disp. 128Data from Top Position *******************************************************/ void Oscillo(void){ unsigned short 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){ // LATDbits.LATD3 = 0; // LED ON 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 { // LATDbits.LATD3 = 1; // LED OFF 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_1: 左端の、Yライン描画 dotyline(51); // Y axis_2: 中央付近最初の、時間軸Yライン描画 dotyline(101); // Y axis_3: 右端付近2番目の、時間軸Yライン描画 lcd_Line(0, 32, 127, 32); // X axis dotxline(49); dotxline(17); /// Disp. HOLD if (HOLD_ON_flag == 1) LATDbits.LATD3 = 0; // LED ON else LATDbits.LATD3 = 1; // LED OFF lcd_Str(7,9,"0.1mS/div"); /// トリガレベルライン描画 lcd_Line(125, Ypos, 128, Ypos); // 終点のY座標を、128としないと、端までの、3ドット分のライン表示にならない /* /// トリガレベル値表示(デバッグ用) itostring(4, POT, MsgTrig + 4); // POTデータを文字列に変換 lcd_Str(0, 10, MsgTrig); // トリガレベル値表示 */ } /******************************************* * Assist Line X Coordinate Axis (Dot Line) ********************************************/ void dotxline(unsigned short y0){ unsigned short i; for(i=0; i<128; i+=3) lcd_Pixel(i, y0-1, 1); } /******************************************* * Assist Line Y Coordinate Axis (Dot Line) ********************************************/ void dotyline(unsigned short x0){ unsigned short i; for(i=0; i<64; i+=3) lcd_Pixel(x0-1, i, 1); } /*********************************************** * ロータリエンコーダ読込み処理 * RE-B相の立下りエッジを基準に、メインループで読込む ************************************************/ void RotaryEncoderRead(void) { //Read ROTARY ENCODER B_Clock re_b_m0 = RE_B; re_b_m2 = re_b_m1^(re_b_m0 & re_b_m1); //Neg_Edge Sence CLOCK re_b_m1 = re_b_m0; //Chenge New Data to Old Data m1 if (re_b_m2 == 1) { //Neg_Edge Sence B_Clock ? if(RE_A == 0){ // 右回転の場合、トリガレベルアップ:+16ステップで最大レベル1008の31ポイント ++Ypos; POT+= 16; if(POT > 1008){ Ypos= 63; POT= 1008; } } else{ // 左回転の場合、トリガレベルダウン:-16ステップで最小レベル0の32ポイント --Ypos; POT-= 16; if(POT < 0){ Ypos= 0; POT= 0; } } } } /***************************************** * 数値から文字列に変換 *****************************************/ 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'; // その桁数値を文字にして格納 data = data / 10; // 桁-1 } }