/************************************************************************ * High_Speed_Oscillo_Test_2 * PIC24F GCシリーズに内蔵の高速ADCを使っての、高速オシロの実験_2 * * <実験計画> * Step1: REによるトリガ調整+SLOPE切替機能の追加実験 *      HOLD SW 追加実験 * Step2: アナログ回路全面改造(AC/DC切替・電圧レンジ切替追加) *      シングル・トリガ・モードの追加 * * MPU:PIC24FJ64GC006 * 2.4インチQVGA液晶モジュール(aitendo): UL024TF使用 * * デバッグ年月日: 2016/1/4 N.Ishii *************************************************************************/ #include #include "colorlcd_libdsPICVH.h" /* コンフィギュレーションの設定 */ // CONFIG4 #pragma config DSWDTPS = DSWDTPS1F // Deep Sleep Watchdog Timer Postscale Select bits (1:68719476736 (25.7 Days)) #pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock) #pragma config DSBOREN = OFF // Deep Sleep BOR Enable bit (DSBOR Disabled) #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (DSWDT Disabled) #pragma config DSSWEN = OFF // DSEN Bit Enable (Deep Sleep operation is always disabled) #pragma config RTCBAT = OFF // RTC Battery Operation Enable (RTC operation is discontinued in VBAT) #pragma config PLLDIV = DIV2 // PLL Input Prescaler Select bits (Oscillator divided by 2 (8 MHz input)) #pragma config I2C2SEL = PRI // Alternate I2C2 Location Select bit (I2C2 is multiplexed to SDA2/RA3 and SCL2/RA2 ) #pragma config IOL1WAY = OFF // PPS IOLOCK Set Only Once Enable bit (The IOLOCK bit can be set and cleared using the unlock sequence) // CONFIG3 #pragma config WPFP = WPFP127 // Write Protection Flash Page Segment Boundary (Page 127 (0x1FC00)) #pragma config SOSCSEL = OFF // SOSC Selection bits (Digital (SCLKI) mode) #pragma config WDTWIN = PS25_0 // Window Mode Watchdog Timer Window Width Select (Watch Dog Timer Window Width is 25 percent) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset Disabled) #pragma config WPDIS = WPDIS // Segment Write Protection Disable (Disabled) #pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select (Disabled) #pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory) // CONFIG2 #pragma config POSCMD = EC // Primary Oscillator Select (External-Clock Mode Enabled) #pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC) //#pragma config OSCIOFCN = OFF // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as CLKO (FOSC/2)) #pragma config FCKSM = CSDCMD // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching and Fail-Safe Clock Monitor are disabled) #pragma config FNOSC = PRIPLL // Initial Oscillator Select (Primary Oscillator with PLL module (XTPLL,HSPLL, ECPLL)) #pragma config ALTADREF = AVREF_RA // External 12-Bit A/D Reference Location Select bit (AVREF+/AVREF- are mapped to RA9/RA10) #pragma config ALTCVREF = CVREF_RA // External Comparator Reference Location Select bit (CVREF+/CVREF- are mapped to RA9/RA10) #pragma config WDTCMX = WDTCLK // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits) #pragma config IESO = OFF // Internal External Switchover (Disabled) // CONFIG1 #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler Select (1:32,768) #pragma config FWPSA = PR128 // WDT Prescaler Ratio Select (1:128) #pragma config WINDIS = OFF // Windowed WDT Disable (Standard Watchdog Timer) #pragma config FWDTEN = WDT_DIS // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled) #pragma config ICS = PGx2 // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC2/PGED2) #pragma config LPCFG = ON // Low power regulator control (Low voltage regulator controlled in sw by RETEN bit) #pragma config GWRP = OFF // General Segment Write Protect (Disabled) #pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled) #pragma config JTAGEN = OFF // JTAG Port Enable (Disabled) /// オシロ用変数 // グローバル変数、定数定義 int Index,POT,TSW,VSW, Ypos; char HOLD_ON_flag = 0; char hold_status = 0; char READY_flag = 0; char ready_status = 0; char POS_flag = 1; // Defult Trigger Slope is positive char re_b_m0; // ROTARY ENCODER OLD Temp char re_b_m1; // ROTARY ENCODER NEW Temp char re_b_m2; // ROTARY ENCODER EDGE Temp #define Max_Size 528 // サンプリング数(512+16) __attribute__((far)) unsigned int Buffer[Max_Size]; // Max 528 #define RE_A PORTFbits.RF4 #define RE_B PORTFbits.RF5 #define AC_DC_SW PORTDbits.RD0 #define TRIG_MODE_SW PORTFbits.RF3 #define HOLD_SW PORTGbits.RG8 #define SLOPE_SW PORTBbits.RB0 #define READY_SW PORTFbits.RF7 /// 関数プロトタイピング void Init(void); // ADC & DMA初期化 void Oscillo(void); void AxisDraw(void); void RotaryEncoderRead(void); void Oscillo_single_mode(void); void Single_trigger_mode(void); /*********** メイン関数 **************************/ int main(void){ int i; /// クロックの設定 8MHz→96MHz÷3=32MHz CLKDIVbits.RCDIV = 0; // 1/1 8MHz CLKDIVbits.CPDIV = 0; // 32/1= 32MHz /// I/Oの初期設定 TRISB = 0xFF3F; // RB1-5(OPアンプ+AN4pin), RB12〜 RB15:DSW 4bit is Input, RB0:SLOPE SW is Input TRISD = 0x0F01; // Output:LCD制御信号:RD7=RS, RD6=CS/, RD5=WR/, RD4=RST/, RD1,2,3= LED Input:RD9,10,11=ATT-A,B,C RD0=DC/AC SW TRISE = 0; // すべてOutput:LCDデータ 8bit:RE0〜 RE7 TRISF = 0x00B8; // RF3:TRG MODE SW, RF4:RE-A, RF5:RE-B, RF7:READY SW is input TRISG = 0x03C0; // RG6,7,9 Input(OPアンプpin), RG8 Input(HOLD SW) /// プルアップ設定 CNPU1bits.CN2PUE = 1; // RB0= SLOPE SW Pullup CNPU1bits.CN10PUE = 1; // RG8= HOLD SW Pullup CNPU2bits.CN17PUE = 1; // RF4= RE-A Pullup CNPU2bits.CN18PUE = 1; // RF5= RE-B Pullup CNPU5bits.CN71PUE = 1; // RF3= TRG MODE SW Pullup CNPU6bits.CN83PUE = 1; // RF7= READY SW Pullup CNPU4bits.CN49PUE = 1; // RD0= DC/AC SW Pullup CNPU1bits.CN12PUE = 1; // RB15= DSW_b3 Pullup CNPU3bits.CN32PUE = 1; // RB14= DSW_b2 Pullup CNPU2bits.CN31PUE = 1; // RB13= DSW_b1 Pullup CNPU2bits.CN30PUE = 1; // RB12= DSW_b0 Pullup /// 状態変化割込みピン許可 CNEN1bits.CN10IE = 1; // HOLD SW CNEN1bits.CN2IE = 1; // SLOPE SW CNEN6bits.CN83IE = 1; // READY SW /// アナログピン指定 ANSF = 0; // すべてデジタル ANSD = 0; // すべてデジタル ANSB = 0; // いったんデジタルにセット ANSBbits.ANSB1 = 1; // OA2NB ANSBbits.ANSB2 = 1; // OA2NC ANSBbits.ANSB3 = 1; // OA2OUT ANSBbits.ANSB4 = 1; // AN4 ADC Input ANSBbits.ANSB5 = 1; // OA1OUT ANSG = 0; // いったんデジタルにセット ANSGbits.ANSG6 = 1; // OA1PB ANSGbits.ANSG7 = 1; // OA1NE ANSGbits.ANSG9 = 1; // DAC1OUT /// タイマ2設定(A/D変換トリガ用) T2CON = 0; // Prescaler 1/1 TMR2 = 0; // カウンタクリア PR2 = 3; // 250nsec period (4MHz) // 液晶表示器の初期化 lcd_Init(); lcd_Clear(BLACK); lcd_Str(0, 0, "Start Oscillo", CYAN, BLACK); Delayms(1000); /// 状態変化割込み許可 IFS1bits.CNIF = 0; // フラグクリア IEC1bits.CNIE = 1; // 割り込み許可 /// DMA、ADC初期設定 Init(); /// ADC Start & Ready DMA ADSTATLbits.SL0IF = 0; // ADC Flag Clear DMACH0bits.CHEN = 1; // DMA Channel Enable & Start IFS0bits.DMA0IF = 0; // DMA Interrupt Flag Reset /// 変数初期化 POT = 512; // POT変数の初期化(トリガレベルを、REによりデジタル値で直に与える) Ypos = 116; // トリガレベルライン表示の、Yポジション初期化 /// メイン・ループ while(1){ if (TRIG_MODE_SW) { // Trigger is AUTO Mode T2CONbits.TON = 0; // タイマ2停止 TMR2 = 0; // タイマ2リセット /// Input Switch:サンプル周期設定 TSW = (~PORTB & 0xF000) >> 12; // 16進スイッチの入力 /// Set PS2 if (TSW >= 13) T2CONbits.TCKPS = 1; // PS2 = 1/8 else T2CONbits.TCKPS = 0; // PS2 = 1/1 /// スイッチの値により各処理へ分岐 switch(TSW){ case 0: // 10usec/div:サンプル周期= 0.25u PR2= 3; break; case 1: // 20usec/div:サンプル周期= 0.5u PR2= 7; break; case 2: // 50usec/div:サンプル周期= 1.25u PR2= 19; break; case 3: // 100usec/div:サンプル周期= 2.5u PR2= 39; break; case 4: // 200usec/div:サンプル周期= 5u PR2= 79; break; case 5: // 500usec/div:サンプル周期= 12.5u PR2= 199; break; case 6: // 1msec/div:サンプル周期= 25u PR2= 399; break; case 7: // 2msec/div:サンプル周期= 50u PR2= 799; break; case 8: // 5msec/div:サンプル周期= 125u PR2= 1999; break; case 9: // 10msec/div:サンプル周期= 250u PR2= 3999; break; case 10:// 20msec/div:サンプル周期= 500u PR2= 7999; break; case 11:// 50msec/div:サンプル周期= 1250u PR2= 19999; break; case 12:// 100msec/div:サンプル周期= 2500u PR2= 39999; break; case 13:// 200msec/div:サンプル周期= 5000u PR2= 9999; break; case 14:// 250msec/div:サンプル周期= 6250u PR2= 12499; break; case 15:// 500msec/div:サンプル周期= 12500u PR2= 24999; break; default: break; } LATDbits.LATD2 = 0; // Red LED OFF READY_flag = 0; ready_status = 0; //// Max_Size回サンプリング(DMA転送)→転送元:ADRES0(AD変換結果レジスタ)/転送先バッファ:Buffer[512+16] Index = 0; // バッファインデックス初期化 /// Max_Size回サンプリング終了待ち T2CONbits.TON = 1; // タイマ2開始、サンプリング開始 while(IFS0bits.DMA0IF == 0); // Wait Max_Size sampling /// 終了後の処理 T2CONbits.TON = 0; // Stop Timer2 & ADC IFS0bits.DMA0IF = 0; // Clear DMA Interrupt Flag /// 転送先バッファ:Buffer[512+16]には、12bitのAD変換値が格納されている。 /// 一方、QVGAのY方向のドット数は、240ドットしかないので、12bitも必要ない。 /// なので、2ビット右にシフトして、10bit精度に落とす。 for(i=0; i<528; i++){ Buffer[i]= Buffer[i] >> 2; } /// オシロ描画処理(Buffer+16の位置から描画が基本。先頭16個は捨てる。) Oscillo(); // Disp. Oscillo /// Cheack HOLD_RUN_SW Status while (HOLD_ON_flag) { hold_status = 1; } hold_status = 0; /// ロータリエンコーダ読込み(波形描画更新インターバル:約1秒も兼ねている) for(i= 0; i < 1000; ++i){ Delayms(1); RotaryEncoderRead(); // ロータリエンコーダ読込み } } else Single_trigger_mode(); } } /******************************************************* * Switch Change Notification Interrupts ********************************************************/ void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void) { Delayms(10); if (!hold_status) { // hold_status -> 0: RUN if (!HOLD_SW) HOLD_ON_flag = 1; } else { // hold_status -> 1: HOLD_ON Loop if (!HOLD_SW) HOLD_ON_flag = 0; } if (ready_status) { if (!READY_SW) READY_flag = 1; } if (!SLOPE_SW) { if (POS_flag) POS_flag = 0; else POS_flag = 1; } IFS1bits.CNIF = 0; // Clead CNIF Flag } /*********************************************************************** * オシロスコープ表示、保存したデータを表 * トリガを検出してその位置から320データ表示 * トリガが一致しなければ最初から320データ表示する * * 転送元:ADRES0(AD変換結果レジスタ)/転送先バッファ:Buffer[512+16] * Buffer+16の位置から描画が基本。先頭16個は捨てる。 **************************************************************************/ void Oscillo(void){ int i,x, Point; AxisDraw(); // 座標表示 Point = -1; // 最初のデータ /// トリガチェック /// Buffer[0]〜[15]のデータは捨てる。(パイプラインが詰まるまで、最高速:4Mspsの性能が出ないため→後閑さんの説明) /// なので、チェック対象のデータは、Buffer[16]〜 190ワード分の、Buiffer[205]までとする。 if (POS_flag) { // トリガ・スロープ:正 for(x=16; x<206; x++){ if((Buffer[x] < POT) && (Buffer[x+5] >= POT)){ Point = x; continue; } } } else { // トリガ・スロープ:負 for(x=16; x<206; x++){ if((Buffer[x+5] < POT) && (Buffer[x] >= POT)){ Point = x; continue; } } } /// トリガ成立、その位置から波形表示 if(Point != -1){ LATDbits.LATD1 = 1; // LED ON for(i=1; i<=320; i++) { lcd_Line(i, Buffer[i+Point-1]*5/22, i, Buffer[i+Point]*5/22, MAGENTA); } } // トリガ不成立、最初から表示する else { LATDbits.LATD1 = 0; // LED OFF for(i=1; i<=320; i++){ lcd_Line(i, Buffer[i-1]*5/22, i, Buffer[i]*5/22, MAGENTA); } } } /****************************************** * Drawing Coordinate Axis *******************************************/ void AxisDraw(void){ int i; lcd_Clear(BLACK); /// X、Y座標軸,補助線表示 for(i=0; i<319; i+=40) lcd_Line(i, 0, i, 231, BROWN); // Y axis:時間軸は、1目盛 40ドットとする。 for(i=0; i<239; i+=58) lcd_Line(0, i, 319, i, BROWN); // X axis:電圧軸は、以前のまま /// Disp. AC/DC if (AC_DC_SW == 0) lcd_Char(0, 16, 0x8C, YELLOW, BLACK); // DCキャラクタ表示 else lcd_Char(0, 16, 0x8B, YELLOW, BLACK); // ACキャラクタ表示 /// Disp. Unit Volt Axis (V/D or mV/D) VSW = (PORTD & 0x0E00) >> 9; // Read VSW SW switch(VSW){ case 0: lcd_Str(1,16,"50mV/D", CYAN, BLACK); break; case 1: lcd_Str(1,16,"0.1V/D", CYAN, BLACK); break; case 2: lcd_Str(1,16,"0.25V/D", CYAN, BLACK); break; case 3: lcd_Str(1,16,"0.5V/D", CYAN, BLACK); break; case 4: lcd_Str(1,16,"1.0V/D", CYAN, BLACK); break; case 5: lcd_Str(1,16,"2.5V/D", CYAN, BLACK); break; case 6: lcd_Str(1,16,"5.0V/D", CYAN, BLACK); break; case 7: lcd_Str(1,16,"10V/D", CYAN, BLACK); break; default:lcd_Str(1,16,"2.5V/D", CYAN, BLACK); break; } lcd_Line(310, Ypos, 319, Ypos, YELLOW); // トリガレベルライン描画 /// TRGエッジ表示 if (POS_flag) lcd_Char(18, 16, 0x8D, YELLOW, BLACK); // TRG+表示 else lcd_Char(18, 16, 0x8E, YELLOW, BLACK); // TRG-表示 /// Disp. HOLD LED if (HOLD_ON_flag == 1) LATDbits.LATD3 = 1; else LATDbits.LATD3 = 0; /// Disp. Unit Time Axis (msec/div) switch(TSW){ case 0: lcd_Str(19, 16, "10uS/D", CYAN, BLACK); break; case 1: lcd_Str(19, 16, "20uS/D", CYAN, BLACK); break; case 2: lcd_Str(19, 16, "50uS/D", CYAN, BLACK); break; case 3: lcd_Str(19, 16, "100uS/D", CYAN, BLACK); break; case 4: lcd_Str(19, 16, "200uS/D", CYAN, BLACK); break; case 5: lcd_Str(19, 16, "500uS/D", CYAN, BLACK); break; case 6: lcd_Str(19, 16, "1mS/D", CYAN, BLACK); break; case 7: lcd_Str(19, 16, "2mS/D", CYAN, BLACK); break; case 8: lcd_Str(19, 16, "5mS/D", CYAN, BLACK); break; case 9: lcd_Str(19, 16, "10mS/D", CYAN, BLACK); break; case 10: lcd_Str(19, 16, "20mS/D", CYAN, BLACK); break; case 11: lcd_Str(19, 16, "50mS/D", CYAN, BLACK); break; case 12: lcd_Str(19, 16, "100mS/D", CYAN, BLACK); break; case 13: lcd_Str(19, 16, "200mS/D", CYAN, BLACK); break; case 14: lcd_Str(19, 16, "250mS/D", CYAN, BLACK); break; case 15: lcd_Str(19, 16, "500mS/D", CYAN, BLACK); break; default: break; } } /************************************************** * ハードウェア初期化 *  OPAMP, DMA、ADC、DAC **************************************************/ void Init(void){ /*** OP AMP#1 Setting ****/ AMP1CONbits.AMPOE = 1; // Output Enable AMP1CONbits.NINSEL = 5; // OA1NE select(RG7) AMP1CONbits.PINSEL = 2; // OA1PB select(RG6) AMP1CONbits.SPDSEL = 1; // High Power AMP1CONbits.CMPSEL = 0; // AMP select AMP1CONbits.AMPEN = 1; // AMP Enable /*** OP AMP#2 Setting ****/ AMP2CONbits.AMPOE = 1; // Output Enable(RB3) AMP2CONbits.NINSEL = 3; // OA2NC select(RB2) AMP2CONbits.PINSEL = 2; // OA2PB select(RB1) AMP2CONbits.SPDSEL = 1; // High Power AMP2CONbits.CMPSEL = 0; // AMP select AMP2CONbits.AMPEN = 1; // AMP Enable /*** DMA CH0 Setting ****/ DMACONbits.DMAEN = 1; // DMA Enable DMACONbits.PRSSEL = 0; // Fixed Priority DMAH = 0x2000; // Upper Limit DMAL = 0x800; // Lower Limit DMACH0 = 0; // Stop Channel DMACH0bits.RELOAD = 1; // Reload DMASRC, DMADST, DMACNT DMACH0bits.TRMODE = 1; // Repeat Oneshot DMACH0bits.SAMODE = 0; // Source Addrs No Increment DMACH0bits.DAMODE = 1; // Dist Addrs Increment DMACH0bits.SIZE = 0; // Word Mode(16bit) DMASRC0 = (unsigned int)&ADRES0; // From ADC Buf0 select DMADST0 = (unsigned int)&Buffer; // To Buffer select DMACNT0 = Max_Size; // DMA Counter DMAINT0 = 0; // All Clear DMAINT0bits.CHSEL = 0x2F; // Select Pipeline ADC DMACH0bits.CHEN = 1; // Channel Enable IFS0bits.DMA0IF = 0; // Flag Reset /* BandGap BUF0 Setting */ BUFCON0 = 0; BUFCON0bits.BUFSTBY = 0; // normal mode BUFCON0bits.BUFREF = 0; // 1.2V BUFCON0bits.BUFEN = 1; // BG0 Enable /* //// 以下、DACは未使用なのでコメントアウトした。 //// DACによるバイアス電圧印加はやめ、抵抗による、AVCC/2分圧とした。 //// DAC Setting DAC1DAT = 0; DAC1CONbits.DACFM = 0; // Right Justfied DAC1CONbits.DACTRIG = 0; // Immediate Update DAC1CONbits.DACTSEL = 7; // None Trigger DAC1CONbits.DACREF = 3; // Ref = BGBUF0 1.2V×2=2.4V DAC1DAT = 0x02C0; // 出力をVDD/2=1.65Vにセット DAC1CONbits.DACEN = 1; // Enable */ /*** ADC Setting ***/ ADCON1 = 0; // All Clear ADCON2 = 0; ADCON3 = 0; ADCON1bits.FORM = 0; // unsigned Integer ADCON1bits.PWRLVL = 1; // Full Power ADCON2bits.ADPWR = 3; // Always powered ADCON2bits.PVCFG = 0; // Vref+=AVDD ADCON2bits.NVCFG = 0; // Vref-=VSS ADCON2bits.BUFORG = 1; // Use Indexed Buffer ADCON2bits.BUFINT = 0; // No buffer Interrupt ADCON3bits.ADRC = 0; // Select Fsys = 16MHz ADCON3bits.ADCS = 1; // Tad = 2Tsys = 125nsec(8MHz) /** Sample List #0 setting**/ ADL0CONH = 0; ADL0CONHbits.ASEN = 0; // disable auto-scan ADL0CONHbits.SLINT = 1; // Interrupt after every convert ADL0CONHbits.SAMC = 0; // aquisition time = 0.5Tad ADL0CONHbits.WM = 0; // all write ADL0CONL = 0; ADL0CONLbits.SLSIZE = 0; // 1 channel in the List ADL0CONLbits.SLTSRC = 5; // Timer2 Trigger ADL0CONLbits.SLEN = 1; // Enable Trigger ADL0PTR = 0; // Start from first /** Select Channel **/ ADTBL0bits.ADCH = 4; // AN4-REF- /** Execute Calibration ADC **/ ADCON1bits.ADON = 1; // ADC Enable while(ADSTATHbits.ADREADY == 0); ADCON1bits.ADCAL = 1; // Calibration Start while(ADSTATHbits.ADREADY == 0); ADL0CONLbits.SAMP = 1; // Start Sample ADL0CONLbits.SAMP = 0; // Start Conversion } /*********************************************** * ロータリエンコーダ読込み処理 * 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){ // 右回転の場合、トリガレベルアップ:+4ステップで最大レベル988の119ポイント ++Ypos; POT+= 4; if(POT > 976){ Ypos= 232; POT= 976; } } else{ // 左回転の場合、トリガレベルダウン:-4ステップで最小レベル32の120ポイント --Ypos; POT-= 4; if(POT < 48){ Ypos= 0; POT= 48; } } } } /****************************************************** * Disp. Oscillo and Cheack trigger for Single mode *******************************************************/ void Oscillo_single_trigger(void){ short i,x, Point; Point = -1; // 最初のデータ /// トリガチェック if (POS_flag) { // トリガ・スロープ:正 for(x=16; x<206; x++){ if((Buffer[x] < POT) && (Buffer[x+5] >= POT)){ Point = x; continue; } } } else { // トリガ・スロープ:負 for(x=16; x<206; x++){ if((Buffer[x+5] < POT) && (Buffer[x] >= POT)){ Point = x; continue; } } } /// トリガ成立、その位置から波形表示 if(Point != -1){ LATDbits.LATD1 = 1; // Green LED ON LATDbits.LATD2 = 0; // Red LED OFF AxisDraw(); for(i=1; i<=320; i++) { lcd_Line(i, Buffer[i+Point-1]*5/22, i, Buffer[i+Point]*5/22, MAGENTA); } READY_flag = 0; } // トリガ不成立、Retry sample else { LATDbits.LATD1 = 0; // Green LED ON } } /********************************************* * Single_trigger_mode **********************************************/ void Single_trigger_mode(void) { int i; hold_status = 1; while ((!READY_flag) && (!TRIG_MODE_SW)) { ready_status = 1; } if (!TRIG_MODE_SW) { ready_status = 0; LATDbits.LATD2 = 1; // Red LED ON //// Max_Size回サンプリング(DMA転送)→転送元:ADRES0(AD変換結果レジスタ)/転送先バッファ:Buffer[512+16] Index = 0; // バッファインデックス初期化 /// Max_Size回サンプリング終了待ち T2CONbits.TON = 1; // タイマ2開始、サンプリング開始 while(IFS0bits.DMA0IF == 0); // Wait Max_Size sampling /// 終了後の処理 T2CONbits.TON = 0; // Stop Timer2 & ADC IFS0bits.DMA0IF = 0; // Clear DMA Interrupt Flag /// 転送先バッファ:Buffer[512+16]には、12bitのAD変換値が格納されている。 /// 一方、QVGAのY方向のドット数は、240ドットしかないので、12bitも必要ない。 /// なので、2ビット右にシフトして、10bit精度に落とす。 for(i=0; i<528; i++){ Buffer[i]= Buffer[i] >> 2; } Oscillo_single_trigger(); } }