/************************************************************** * ソース名:Easy_6CH_LogAna_V2_test.C * * 2.4インチ・カラーQVGA液晶モジュール(aitendo): UL024TF互換品 * * Condition: * 10MHz External X'tal Oscillator, 1/2 x 20x PLL (5MHzx20= 100MHz) * Fcy= Fosc= 100MHz, Tcy=10ns * * CPU: PIC32MX370F512H * * N.Ishii 2017.9.26 ***************************************************************/ #include #include #include "colorlcd_libPIC32MXVH.h" /// 外部クロック 100MHzで動作、周辺クロック:システムクロック = 1:1(外部X'tal Oscillator= 10MHz) // DEVCFG3 #pragma config FSRSSEL = PRIORITY_7 // Shadow Register Set Priority Select (SRS Priority 7) #pragma config PMDL1WAY = OFF // Peripheral Module Disable Configuration (Allow multiple reconfigurations) #pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration (Allow multiple reconfigurations) // DEVCFG2 #pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider) #pragma config FPLLMUL = MUL_20 // PLL Multiplier (20x Multiplier) #pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1) // DEVCFG1 #pragma config FNOSC = PRIPLL // Oscillator Selection Bits (External X'tal Osc with PLL) #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled) #pragma config IESO = OFF // Internal/External Switch Over (Disabled) #pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode) #pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled) #pragma config FPBDIV = DIV_1 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1) #pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled) #pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576) #pragma config WINDIS = OFF // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode) #pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls)) #pragma config FWDTWINSZ = WISZ_25 // Watchdog Timer Window Size (Window Size is 25%) // DEVCFG0 #pragma config DEBUG = OFF // Background Debugger Enable (Debugger is Disabled) #pragma config JTAGEN = OFF // JTAG Enable (JTAG Disabled) #pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1) #pragma config PWP = OFF // Program Flash Write Protect (Disable) #pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled) #pragma config CP = OFF // Code Protect (Protection Disabled) //------------------------------------------------------------ #define HOLD_RUN_SW PORTBbits.RB0 #define TRIG_SLOPE_SW PORTBbits.RB1 // トリガはCH1の立上り、立下りの2種類のみとした #define TRIG_MODE_SW PORTGbits.RG6 #define READY_SW PORTGbits.RG7 #define HOLD_LED LATDbits.LATD3 #define READY_LED LATGbits.LATG8 #define MAG_SW PORTBbits.RB1 // HOLD中のみ有効になるSWで、SLOPE SWを流用する #define CH1 0x01 #define CH2 0x02 #define CH3 0x04 #define CH4 0x08 #define CH5 0x10 #define CH6 0x20 //------------------------------------------------------------ /// メッセージテーブル char str_Start[] = "Easy 6CH LogAna V2"; char str_WaitTrig[] = "Waiting for trigger"; char str_0_8us[] = "40uS/D SMP= 0.8uS"; char str_1us[] = "50uS/D SMP= 1uS"; char str_2us[] = "0.1mS/D SMP= 2uS"; char str_4us[] = "0.2mS/D SMP= 4uS"; char str_10us[] = "0.5mS/D SMP= 10uS"; char str_20us[] = "1mS/D SMP= 20uS"; char str_40us[] = "2mS/D SMP= 40uS"; char str_100us[]= "5mS/D SMP= 100uS"; char str_200us[]= "10mS/D SMP= 200uS"; char str_400us[]= "20mS/D SMP= 400uS"; /// A Variable (Global) /// Data Buffer for GLCD unsigned char Buffer[512]; unsigned short Index,SW; unsigned short Dummy; char EndFlag; 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 SwCount = 0; char edg_flag[6]; unsigned short ptr; // バッファ読出しポインタ unsigned short Xpos= 0; /// 注意:Glcd_Line関数で扱う原点(0,0)は、左下角だが、 /// Glcd_Pixcel関数で扱う原点(0,0)は、左上角なので /// Yポジション(CH1 Lowレベル位置)の変数が、2個必要 unsigned short Ypos_line= 208; // Glcd_Line関数(エッジ描画で使用)の、CH1 Lowレベル位置初期化 unsigned short Ypos_dot= 31; // Glcd_Pixcel関数(レベル描画で使用)の、CH1 Lowレベル位置初期化 unsigned short x_temp; /// Function Prottypes void LogAna(void); void AxisDraw(void); void LogicCheck_and_GlcdDraw(char channel, unsigned short Xtrg, unsigned short color); void LogAna_single_trigger(void); void Single_trigger_mode(void); void LogAnaMag(char mag, short loop); void LogicCheck_and_GlcdDrawMag(char channel, unsigned short Xtrg, char mag, unsigned short color); //void itostring(char digit, unsigned int data, char *buffer); /************************************************ * Function Main ************************************************/ int main(void) { short i; // Data Memory SRAM wait states: Default Setting = 1; set it to 0 BMXCONbits.BMXWSDRM = 0; // SRAMのウェイトステートを0にする // Flash PM Wait States: MX Flash runs at 3 wait states @ 100 MHz CHECONbits.PFMWS = 3; // フラッシュのプリフェッチを3ウェイトステートに対応(100MHz動作時) // Prefetch-cache: Enable prefetch for cacheable PFM instructions CHECONbits.PREFEN = 1; //プリフェッチキャッシュ有効 __builtin_mtc0(16, 0, (__builtin_mfc0(16, 0) & 0xfffffff8 | 3)); // キャッシュ有効化 // Set the interrupt controller for multi-vector mode INTCONSET = _INTCON_MVEC_MASK; //割り込みをマルチベクタモードに設定 // Set the CP0 Status IE bit to turn on interrupts globally __builtin_enable_interrupts(); //割り込み有効化 /// I/O設定 // AN*ピンと共用ピンになっているピンを、全てデジタル・ピンに設定(デフォルト=アナログ・ピン設定なので注意) ANSELB = 0x0000; // RB0-15として使用 ANSELD = 0x0000; // RD1-3として使用 ANSELE = 0x0000; // RE2,RE4-7として使用 ANSELG = 0x0000; // RG6-9として使用 TRISB = 0xFFFF; // RB1:TRG_SLOPE_SW, RB2:HOLD_SW入力, RB3:DSW-1入力、RB4:DSW-2入力、RB5:DSW-4入力、他未使用ピンも入力設定 TRISD = 0xFF07; // LCD_RS,CS,WR,RESET:全て出力・HOLD_LED:出力・SW2-5:入力、他未使用ピンは入力設定 TRISE = 0x0000; // LCDデータバス(DB0-DB7)オール出力 TRISF = 0xFFFF; // RF0-5:CH1-6入力(5Vトレラント・ピン) TRISG = 0xFEFF; // RG6:TRIG_MODE_SW, RG7:READY_SW入力, RG8:READY_LED出力 HOLD_LED = 1; // HOLD_LED消灯 READY_LED = 1; // READY_LED消灯 // 内部プルアップ設定 CNPUBSET = 0x003F; // DSW-8,DSW-4.DSW-2,DSW-1,SLP_SW,HLD_SW CNPUGSET = 0x00C0; // RDY_SW,TRG_MODE /// 液晶表示器の初期化 Glcd_Init(); Glcd_Clear(BLACK); Glcd_Str(0, 0, str_Start, CYAN, BLACK); delay_ms(1000); /// タイマ2割込み周期設定= Tcy*PS*n= 0.000000010mS*256*500 = 10uS T2CON = 0x10; // prescale 1:2, 16bit mode PR2 = 499; // PR2= n-1= 499 TMR2 = 0; // clear Timer 2 counter /// タイマ2割込み設定 IPC2bits.T2IP = 7; // T2割り込み優先度7に設定 IFS0bits.T2IF = 0; // T2割り込みフラグをクリア IEC0bits.T2IE = 1; // T2割り込み有効化 /// スイッチ状態変化割込み設定 CNCONB = 0x8000; // RBポートのCN検出モジュール有効化 CNCONG = 0x8000; // RGポートのCN検出モジュール有効化 CNENB = 0x0003; // RB0=HOLD_SW, RB1=SLP_SWを、CNピンとして有効化 CNENG = 0x0080; // RG7=READY_SWを、CNピンとして有効化 // ダミー入力で、PIC内外の状態を一致させ、割込み要因をリセットする // これがないと、CN割込み許可直後に割込みが発生してしまうことがある。 Dummy= PORTB; Dummy= PORTG; IPC8bits.CNIP = 2; // CN割込み優先度2に設定 IFS1 = 0x00042000; // CNB,G割込みフラグをクリア IEC1 = 0x00042000; // CNB,G割込み有効化 /// マルチベクタ割り込み設定 INTCONbits.MVEC = 1; // マルチベクタ割込みモード //// メイン・ループ while(1){ /// Inittalize Variable Index = 0; EndFlag = 0; if (TRIG_MODE_SW) { // Trigger is Normal Mode /// Switching Sampling Period SW = (PORTB & 0x003C) >> 2; // Read Decimal Dip SW switch(SW){ case 0: PR2 = 39; // 0.8usec break; case 1: PR2 = 49; // 1usec break; case 2: PR2 = 99; // 2usec break; case 3: PR2 = 199; // 4usec break; case 4: PR2 = 499; // 10usec break; case 5: PR2 = 999; // 100usec break; case 6: PR2 = 1999; // 200usec break; case 7: PR2 = 4999; // 400usec break; case 8: PR2 = 9999; // 1000usec break; case 9: PR2 = 19999; // 2000usec break; default:PR2 = 499; // 10usec break; } READY_LED = 1; // OFF READY_flag = 0; ready_status = 0; T2CONbits.TON = 1; // T2ON-> CH入力サンプリング開始 while(!EndFlag); for(i= 0; i < 512; ++i) Buffer[i] = Buffer[i] & 0x3F; // 6CHデータの為、上位2bitマスクして格納し直す。 LogAna(); // Disp. LogAna EndFlag = 0; Index = 0; /// Cheack HOLD_RUN_SW Status while (HOLD_ON_flag) { hold_status = 1; /// Mag SW(拡大率選択:Slope SWを流用)読込み delay_ms(10); // チャッタ回避 if(!MAG_SW) { ++SwCount; if(SwCount > 3) SwCount= 0; /// 指定の倍率・ループ回数(データ数)でロジック拡大表示 switch(SwCount){ case 0: LogAnaMag(1, 320); // 等倍表示 break; case 1: LogAnaMag(2, 160); // 2倍表示 break; case 2: LogAnaMag(5, 64); // 5倍表示 break; case 3: LogAnaMag(10, 32); // 10倍表示 break; default:; break; } } while(!MAG_SW); // SWリリース待ち(Hiになるまで待つ) } hold_status = 0; SwCount= 0; for(i= 0; i < 6; ++i) edg_flag[i]= 0; delay_ms(1000); // Disp. is 1.0Sec Period } else Single_trigger_mode(); } } /*********************************************************** * T2割込み処理 * CH入力サンプル〜 メモリーにロジックレベル・データ格納 ************************************************************/ void __ISR(8, IPL7AUTO) T2Interrupt(void) { IFS0bits.T2IF = 0; // Reset interrupt flag Buffer[Index] = PORTF; // 6CH分のデータをバッファへ格納(割込み処理時間を極力少なくする為、マスク処理はメインに移した。) ++Index; if(Index >= 512) { // Buffer Full ? T2CONbits.TON = 0; // Buffer Full Then T2 OFF EndFlag = 1; // and End Flag ON } } /********************************************* * スイッチ状態変化割り込み処理 * HOLD SW, TRIG_MODE_SW, TRIG_SLOPE_SW **********************************************/ void __ISR(33, IPL2AUTO) CNInterrupt(void) { delay_ms(10); // スイッチ安定待ち if (!hold_status) { // hold_status -> 0: RUN if (!HOLD_RUN_SW) HOLD_ON_flag = 1; } else { // hold_status -> 1: HOLD_ON Loop if (!HOLD_RUN_SW) HOLD_ON_flag = 0; } if (ready_status) { if (!READY_SW) READY_flag = 1; } if((!hold_status) && (!ready_status)) { // 通常モード時のみ以下を実行(拡大モード時はパス) if (!TRIG_SLOPE_SW) { if (POS_flag) POS_flag = 0; else POS_flag = 1; } } delay_ms(10); // スイッチON->OFF時の、チャッタ回避 Dummy= PORTB; // 状態合わせ Dummy= PORTG; IFS1 = 0; // CNB,G割込みフラグをクリア } /************************************************************** * トリガ検知を行った後、保存したロジックレベル・データを読出し * ロジアナ表示する ***************************************************************/ void LogAna(void){ unsigned short i, x; AxisDraw(); // 座標表示 x= 0; /// Check Trigger if (POS_flag) { // Trigger Slope is positive while((x < 192) && !(((Buffer[x] & CH1) == 0) && ((Buffer[x+1] & CH1) == 1))) { x++; } } else { // Trigger Slope is negative while((x < 192) && !(((Buffer[x] & CH1) == 1) && ((Buffer[x+1] & CH1) == 0))) { x++; } } //// Detect Trigger-> Disp. 320Data from this Position if(x<128){ /// 液晶の、1画面分(横:320dot)に各CHのロジック状態を描画する for(ptr= 0; ptr< 320; ptr++) { LogicCheck_and_GlcdDraw(CH1, x, MAGENTA); // CH1ロジック状態描画 Ypos_line= 174; // CH2の基準線に描画移動 Ypos_dot= 65; LogicCheck_and_GlcdDraw(CH2, x, GREEN); // CH2ロジック状態描画 Ypos_line= 140; // CH3の基準線に描画移動 Ypos_dot= 99; LogicCheck_and_GlcdDraw(CH3, x, CYAN); // CH3ロジック状態描画 Ypos_line= 106; // CH4の基準線に描画移動 Ypos_dot= 133; LogicCheck_and_GlcdDraw(CH4, x, YELLOW); // CH4ロジック状態描画 Ypos_line= 72; // CH5の基準線に描画移動 Ypos_dot= 167; LogicCheck_and_GlcdDraw(CH5, x, ORANGE); // CH5ロジック状態描画 Ypos_line= 38; // CH6の基準線に描画移動 Ypos_dot= 201; LogicCheck_and_GlcdDraw(CH6, x, BLUE); // CH6ロジック状態描画 Ypos_dot= 31; // Yポジション初期化 Ypos_line= 208; Xpos++; // Xポジションを1つ進める } Xpos= 0; x_temp= x; // HOLD中の、拡大表示の時のために、テンポラリに退避 } /// Not Detect Trigger-> Disp. "Waiting for trigger" else Glcd_Str(0, 0, str_WaitTrig, WHITE, BLACK); } /****************************************************** * Disp. Oscillo and Cheack trigger for Single mode *******************************************************/ void LogAna_single_trigger(void){ unsigned short i, x; x= 0; // First Data /// Check Trigger if (POS_flag) { // Trigger Slope is positive while((x < 192) && !((Buffer[x] & CH1) == 0 && (Buffer[x+1] & CH1) == 1)) { x++; } } else { // Trigger Slope is negative while((x < 192) && !((Buffer[x] & CH1) == 1 && (Buffer[x+1] & CH1) == 0)) { x++; } } //// Detect Trigger-> Disp. 320Data from this Position if(x<128){ READY_LED = 1; // OFF AxisDraw(); /// 液晶の、1画面分(横:320dot)に各CHのロジック状態を描画する for(ptr= 0; ptr< 320; ptr++) { LogicCheck_and_GlcdDraw(CH1, x, MAGENTA); // CH1ロジック状態描画 Ypos_line= 174; // CH2の基準線に描画移動 Ypos_dot= 65; LogicCheck_and_GlcdDraw(CH2, x, GREEN); // CH2ロジック状態描画 Ypos_line= 140; // CH3の基準線に描画移動 Ypos_dot= 99; LogicCheck_and_GlcdDraw(CH3, x, CYAN); // CH3ロジック状態描画 Ypos_line= 106; // CH4の基準線に描画移動 Ypos_dot= 133; LogicCheck_and_GlcdDraw(CH4, x, YELLOW); // CH4ロジック状態描画 Ypos_line= 72; // CH5の基準線に描画移動 Ypos_dot= 167; LogicCheck_and_GlcdDraw(CH5, x, ORANGE); // CH5ロジック状態描画 Ypos_line= 38; // CH6の基準線に描画移動 Ypos_dot= 201; LogicCheck_and_GlcdDraw(CH6, x, BLUE); // CH6ロジック状態描画 Ypos_dot= 31; // Yポジション初期化 Ypos_line= 208; Xpos++; // Xポジションを1つ進める } Xpos= 0; READY_flag = 0; x_temp= x; // シングルトリガモード時のREADY待ちで行う拡大表示ののために、テンポラリに退避 } /// トリガ未検知の場合は何もしない } /********************************************* * Single_trigger_mode **********************************************/ void Single_trigger_mode(void) { unsigned short i; hold_status = 1; while ((!READY_flag) && (!TRIG_MODE_SW)) { // READY待ち ready_status = 1; /// Mag SW(拡大率選択:Slope SWを流用)読込み if(x_temp < 128) { // シングルトリガ検知時のみ、拡大表示有効 delay_ms(10); // チャッタ回避 if(!MAG_SW) { ++SwCount; if(SwCount > 3) SwCount= 0; /// 指定の倍率・ループ回数(データ数)でロジック拡大表示 switch(SwCount){ case 0: LogAnaMag(1, 320); // 等倍表示 break; case 1: LogAnaMag(2, 160); // 2倍表示 break; case 2: LogAnaMag(5, 64); // 5倍表示 break; case 3: LogAnaMag(10, 32); // 10倍表示 break; default:; break; } } while(!MAG_SW); // SWリリース待ち(Hiになるまで待つ) } } SwCount= 0; for(i= 0; i < 6; ++i) edg_flag[i]= 0; if (!TRIG_MODE_SW) { ready_status = 0; READY_LED = 0; // ON T2CONbits.TON = 1; // T3ON-> CH入力サンプリング開始 while(!EndFlag); // T2割込み処理へ:6CH分のデータ収集 for(i= 0; i < 512; ++i) Buffer[i] = Buffer[i] & 0x3F; LogAna_single_trigger(); // 6CH分のデータ収集が全て終了したら、ロジアナ表示する } } /****************************************** * Drawing Coordinate Axis *******************************************/ void AxisDraw(void){ int i; Glcd_Clear(BLACK); /// X、Y座標軸表示 for(i=0; i<319; i+=50) Glcd_Line(i, 0, i, 239, BROWN); // Y axis Glcd_Line(0, 0, 319, 0, BROWN); // 最下位ライン:下外枠ライン Glcd_Line(0, 38, 319, 38, BROWN); // X axis :6CH Lowレベルライン for(i=72; i<209; i+=34) Glcd_Line(0, i, 319, i, BROWN); // X axis :5CH〜 1CH Lowレベルライン Glcd_Line(0, 239, 319, 239, BROWN); // 最上位ライン:上外枠ライン /// サンプル周期表示 switch(SW){ case 0: Glcd_Str(8, 16, str_0_8us, WHITE, BLACK); break; case 1: Glcd_Str(8, 16, str_1us, WHITE, BLACK); break; case 2: Glcd_Str(8, 16, str_2us, WHITE, BLACK); break; case 3: Glcd_Str(8, 16, str_4us, WHITE, BLACK); break; case 4: Glcd_Str(8, 16, str_10us, WHITE, BLACK); break; case 5: Glcd_Str(8, 16, str_20us, WHITE, BLACK); break; case 6: Glcd_Str(8, 16, str_40us, WHITE, BLACK); break; case 7: Glcd_Str(8, 16, str_100us, WHITE, BLACK); break; case 8: Glcd_Str(8, 16, str_200us, WHITE, BLACK); break; case 9: Glcd_Str(8, 16, str_400us, WHITE, BLACK); break; default:Glcd_Str(8, 16, str_10us, WHITE, BLACK); break; } /// TRGエッジ表示 if (POS_flag) Glcd_Char(7, 16, 0x8D, YELLOW, BLACK); // TRG+表示 else Glcd_Char(7, 16, 0x8E, YELLOW, BLACK); // TRG-表示 /// Disp. HOLD LED if (HOLD_ON_flag == 1) HOLD_LED = 0; else HOLD_LED = 1; } /************************************************************ * ロジック・レベル・バッファの内容を、引数により * 各CH毎に、チェックし、ロジック・レベル状態を液晶に描画する * 判断すべきロジック・レベル状態は、以下の4種類 * ? Hiレベル(変化なし) * ? Loレベル(変化なし) * ? 立上りエッジ * ? 立下りエッジ * * 引数:channel * 0x01:CH1 * 0x02:CH2 * 0x04:CH3 * 0x08:CH4 * 0x10:CH5 * 0x20:CH6 * * Xtrg * トリガ検知点のバッファ位置(x変数の値が代入される) * * color * MAGENTA (CH1) * GREEN (CH2) * CYAN (CH3) * YELLOW (CH4) * ORANGE (CH5) * BLUE (CH6) *************************************************************/ void LogicCheck_and_GlcdDraw(char channel, unsigned short Xtrg, unsigned short color){ char shift; if (channel == CH1) shift= 0; if (channel == CH2) shift= 1; if (channel == CH3) shift= 2; if (channel == CH4) shift= 3; if (channel == CH5) shift= 4; if (channel == CH6) shift= 5; if (((Buffer[ptr+Xtrg] & channel) >> shift == 0) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 0)) { // Lowレベル検知なので以下の、ドット描画を行う Glcd_Pixel(Xpos, Ypos_dot, color); } if (((Buffer[ptr+Xtrg] & channel) >> shift == 1) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 1)) { // Hiレベル検知なので以下の、ドット描画を行う Glcd_Pixel(Xpos, Ypos_dot-19, color); } if (((Buffer[ptr+Xtrg] & channel) >> shift == 0) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 1)) { // 立上りエッジ検知なので以下の、ライン描画を行う Glcd_Line(Xpos, Ypos_line, Xpos, Ypos_line+19, color); } if (((Buffer[ptr+Xtrg] & channel) >> shift == 1) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 0)) { // 立下りエッジ検知なので以下の、ライン描画を行う Glcd_Line(Xpos, Ypos_line+19, Xpos, Ypos_line, color); } } /************************************************************************ * HOLD中に、保存したロジックレベル・データを読出し * ロジアナの拡大表示をする。 * * HOLD前に、バッファリング後、トリガ検知をし、検知点のバッファ位置:x * は既に判っていて、その値は、テンポラリ:x_tempに保存されている。 *************************************************************************/ void LogAnaMag(char mag, short loop){ unsigned short i; AxisDraw(); // 座標表示 /// 液晶の、1画面分(横:320dot)に各CHのロジック状態を描画する for(ptr= 0; ptr< loop; ptr++) { // 倍率によってループ数が変わる LogicCheck_and_GlcdDrawMag(CH1, x_temp, mag, MAGENTA); // CH1ロジック状態描画 Ypos_line= 174; // CH2の基準線に描画移動 Ypos_dot= 65; LogicCheck_and_GlcdDrawMag(CH2, x_temp, mag, GREEN); // CH2ロジック状態描画 Ypos_line= 140; // CH3の基準線に描画移動 Ypos_dot= 99; LogicCheck_and_GlcdDrawMag(CH3, x_temp, mag, CYAN); // CH3ロジック状態描画 Ypos_line= 106; // CH4の基準線に描画移動 Ypos_dot= 133; LogicCheck_and_GlcdDrawMag(CH4, x_temp, mag, YELLOW); // CH4ロジック状態描画 Ypos_line= 72; // CH5の基準線に描画移動 Ypos_dot= 167; LogicCheck_and_GlcdDrawMag(CH5, x_temp, mag, ORANGE); // CH5ロジック状態描画 Ypos_line= 38; // CH6の基準線に描画移動 Ypos_dot= 201; LogicCheck_and_GlcdDrawMag(CH6, x_temp, mag, BLUE); // CH6ロジック状態描画 Ypos_dot= 31; // Yポジション初期化 Ypos_line= 208; /// 次のXポジション(始点)へ進める Xpos= Xpos + mag; } Xpos= 0; for(i= 0; i < 6; ++i) edg_flag[i]= 0; } /************************************************************ * ロジック・レベル・バッファの内容を * チェックし、ロジック・レベル状態を液晶に描画する * (拡大表示用) *************************************************************/ void LogicCheck_and_GlcdDrawMag(char channel, unsigned short Xtrg, char mag, unsigned short color){ char shift; // ch毎の状態判断の為のビットシフト数と、ch毎のエッジ検知フラグ配列のポインタとして使う if (channel == CH1) shift= 0; if (channel == CH2) shift= 1; if (channel == CH3) shift= 2; if (channel == CH4) shift= 3; if (channel == CH5) shift= 4; if (channel == CH6) shift= 5; /// 倍率表示 if(mag == 1) Glcd_Str(1, 16, "x1", WHITE, BLACK); if(mag == 2) Glcd_Str(1, 16, "x2", WHITE, BLACK); if(mag == 5) Glcd_Str(1, 16, "x5", WHITE, BLACK); if(mag == 10) Glcd_Str(1, 16, "x10", WHITE, BLACK); /// ロジック表示 if (((Buffer[ptr+Xtrg] & channel) >> shift == 0) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 0)) { /// Lowレベル検知描画 if(mag == 1) { // 等倍表示 Glcd_Pixel(Xpos, Ypos_dot, color); } else { // 拡大表示 if(!edg_flag[shift]) { // Lowレベル検知描画が続いている場合 Glcd_Line(Xpos, Ypos_line, Xpos + mag, Ypos_line, color); } else { // エッジ検知描画後に、Lowレベル検知描画の場合 Glcd_Line(Xpos - mag, Ypos_line, Xpos + mag, Ypos_line, color); edg_flag[shift]= 0; } } } if (((Buffer[ptr+Xtrg] & channel) >> shift == 1) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 1)) { /// Hiレベル検知描画 if(mag == 1) { // 等倍表示 Glcd_Pixel(Xpos, Ypos_dot-19, color); } else { // 拡大表示 if(!edg_flag[shift]) { // Hiレベル検知描画が続いている場合 Glcd_Line(Xpos, Ypos_line+19, Xpos + mag, Ypos_line+19, color); } else { // エッジ検知描画後に、Hiレベル検知描画の場合 Glcd_Line(Xpos - mag, Ypos_line+19, Xpos + mag, Ypos_line+19, color); edg_flag[shift]= 0; } } } if (((Buffer[ptr+Xtrg] & channel) >> shift == 0) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 1)) { // 立上りエッジ検知なので以下の、ライン描画を行う Glcd_Line(Xpos, Ypos_line, Xpos, Ypos_line+19, color); edg_flag[shift]= 1; } if (((Buffer[ptr+Xtrg] & channel) >> shift == 1) && ((Buffer[ptr+Xtrg+1] & channel) >> shift == 0)) { // 立下りエッジ検知なので以下の、ライン描画を行う Glcd_Line(Xpos, Ypos_line+19, Xpos, Ypos_line, color); edg_flag[shift]= 1; } } /* ///////////////////////////////////////// // 数値から文字列に変換 ///////////////////////////////////////// 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 } } */