/********************************************************** * Scope Program * ソース名:Easy_4CH_LogAna_TEST.C * * PIC32MXトレーニング基板を使い、 * リピート・トレース・モード(オシロで言うノーマルトリガ) * の簡易チェックを行う * * 2.8インチQVGA液晶モジュール(aitendo): M028C9325TP * 320x240ドット 16ビットカラー 横置き表示 * * Condition: * 8MHz External X'tal Oscillator, 20x PLL (8MHzx20= 160MHz) * Fcy=160MHz/2=80MHz, Tcy=12.5ns * * CPU: PIC32MX340F256H * * N.Ishii 2014.7.11 ************************************************************/ #include /* PIC32 peripheral library */ #include "colorlcd_libdsPICVH.h" #include /// コンフィギュレーション設定 // 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 //------------------------------------------------------------ #define HOLD_RUN_SW PORTBbits.RB2 #define TRIG_MODE_SW PORTBbits.RB1 // トリガはCH1の立上り、立下りの2種類のみとした #define CH1 0x01 #define CH2 0x02 #define CH3 0x04 #define CH4 0x08 //------------------------------------------------------------ /// メッセージテーブル char str_Start[] = "Start Logic Analyzer Test"; 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"; /// A Variable (Global) /// Data Buffer for GLCD unsigned short Buffer[512]; unsigned short Index,SW; char EndFlag; char ch1_m0 = 0; // CH1入力エッジセンス用 char ch1_m1 = 0; char ch1_m2 = 0; char EdgeFlag = 0; char HOLD_ON_flag = 0; char hold_status = 0; char POS_flag = 1; // Defult Trigger Slope is positive unsigned short ptr; // バッファ読出しポインタ unsigned short Xpos= 0; /// 注意:Glcd_Line関数で扱う原点(0,0)は、左下角だが、 /// Glcd_Pixcel関数で扱う原点(0,0)は、左上角なので /// Yポジション(CH1 Lowレベル位置)の変数が、2個必要 unsigned short Ypos_line= 188; // Glcd_Line関数(エッジ描画で使用)の、CH1 Lowレベル位置初期化 unsigned short Ypos_dot= 51; // Glcd_Pixcel関数(レベル描画で使用)の、CH1 Lowレベル位置初期化 /// Function Prottypes void LogAna(void); void AxisDraw(void); void LogicCheck_and_GlcdDraw(char channel, unsigned short color); //void LogicCheck_and_GlcdDraw(unsigned short channel, unsigned short color); //void itostring(char digit, unsigned int data, char *buffer); /************************************************ * Function Main ************************************************/ int main(void) { //システム最適設定 SYSTEMConfigPerformance(80000000); mJTAGPortEnable(DEBUG_JTAGPORT_OFF); // JTAGを無効化 //I/O設定 AD1PCFG = 0xFFFF; //I/O設定 TRISE = 0x0000; // LCDデータバス(DB0-DB7)オール出力 TRISD = 0xFF07; // LCD_RS,CS,WR,RESET:全て出力・デバッグLED:出力・SW2-5:入力、他未使用ピンは入力設定 TRISF = 0xFFFF; // RF2-5:CH1-4入力(5Vトレラント・ピン)、RF0,RF1も入力設定(予備) TRISB = 0xFFFF; // RB1:TRG_MODE_SW, RB2:HOLD_SW入力, RB3:DSW-1入力、RB4:DSW-2入力、RB5:DSW-4入力、他未使用ピンも入力設定 LATDbits.LATD3 = 1; // デバッグLED消灯(TRG検出確認用) // 液晶表示器の初期化 Glcd_Init(); Glcd_Clear(BLACK); Glcd_Str(0, 0, str_Start, CYAN, BLACK); delay_ms(1000); /// Timer3:T3初期設定= Tcy*PS*n= 0.0125uS*2*400 = 10uS PR3 = 399; // n = 400 (PR3=n-1 OpenTimer3(T3_OFF | T3_SOURCE_INT | T3_PS_1_2, PR3); // タイマ3割り込み設定 ConfigIntTimer3(T3_INT_ON | T3_INT_PRIOR_7); //スイッチ状態変化割込み許可 // mCNOpen(CN_ON, CN3_ENABLE | CN4_ENABLE | CN5_PULLUP_ENABLE, CN6_PULLUP_ENABLE | CN7_PULLUP_ENABLE); // 上記書式に誤記が見付かり下記のように修正しました。(上記の書き方でもコンパイルエラーは発生せず動作も正常だったので気が付きませんでした) 140726 mCNOpen(CN_ON, CN3_ENABLE | CN4_ENABLE, CN5_PULLUP_ENABLE | CN6_PULLUP_ENABLE | CN7_PULLUP_ENABLE); // TRG_MODE_SW, HOLD_SW, DSW-1_PULLUP, DSW-2_PULLUP, DSW-4_PULLUP // TRG_MODE_SWと、HOLD_SWの、プルアップは治具の外部プルアップを使用 mCNClearIntFlag(); //割り込みフラグクリア ConfigIntCN(CHANGE_INT_ON | CHANGE_INT_PRI_2); // 割り込み有効化 // マルチベクタ割り込み設定、割り込み許可 INTEnableSystemMultiVectoredInt(); /// Inittalize Variable Index = 0; EndFlag = 0; //// メイン・ループ while(1){ /// Switching Sampling Period SW = (~PORTB & 0x0038) >> 3; // Read Decimal Dip SW switch(SW){ case 0: PR3 = 39; // 1usec break; case 1: PR3 = 79; // 2usec break; case 2: PR3 = 159; // 4usec break; case 3: PR3 = 399; // 10usec break; case 4: PR3 = 799; // 20usec break; case 5: PR3 = 1599; // 40usec break; case 6: PR3 = 3999; // 100usec break; case 7: PR3 = 7999; // 200usec break; default:PR3 = 399; // 10usec break; } /// Draw a Graph of Input Logic Data EndFlag = 0; // Clear End Flag Index = 0; T3CONbits.TON = 1; // T3ON-> CH入力サンプリング開始 while(!EndFlag); LogAna(); // Disp. LogAna EndFlag = 0; Index = 0; /// Cheack HOLD_RUN_SW Status while (HOLD_ON_flag) { hold_status = 1; } hold_status = 0; delay_ms(1000); // Disp. is 1.0Sec Period } } /*********************************************************** * T3割込み処理 * CH入力サンプル〜 メモリーにロジックレベル・データ格納 ************************************************************/ void __ISR(12, ipl7) T3Handler(void) { mT3ClearIntFlag(); //割り込みフラグクリア //LATDbits.LATD3 = ~LATDbits.LATD3; if (EdgeFlag == 0) { /// CH1入力エッジ・チェック ch1_m0 = PORTFbits.RF2; //New CH1 Data if (POS_flag) ch1_m2 = ch1_m1^(ch1_m0 | ch1_m1); //Pos_Edge Sence CH1 Input else ch1_m2 = ch1_m1^(ch1_m0 & ch1_m1); //Neg_Edge Sence CH1 Input ch1_m1 = ch1_m0; //Chenge New Data to Old Data m1 if (ch1_m2 == 1) EdgeFlag= 1; } if (EdgeFlag== 1) { /// 最初に、CH1入力エッジ(立上りか、立下りを選択可)を検出したら、 /// そこから各CH入力のロジックレベル・データを、512バイト分メモリーに格納する Buffer[Index] = (PORTF & 0x3C) >> 2; // b3:CH4, b2:CH3, b1:CH2, b0:CH1 ++Index; if(Index >= 512) { // Buffer Full ? T3CONbits.TON = 0; // Buffer Full Then T1 OFF EndFlag = 1; // and End Flag ON EdgeFlag= 0; } } } /********************************************* * スイッチ状態変化割り込み処理 * HOLD SW, TRIG_MODE_SW **********************************************/ void __ISR(26, ipl2) CNHandler(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 (!TRIG_MODE_SW) { if (POS_flag) POS_flag = 0; else POS_flag = 1; } mCNClearIntFlag(); //割り込みフラグクリア } /**************************************** * 保存したロジックレベル・データを読出し * ロジアナ表示する *****************************************/ void LogAna(void){ AxisDraw(); // 座標表示 /// 液晶の、1画面分(横:320dot)に各CHのロジック状態を描画する for(ptr= 1; ptr< 321; ptr++) { LogicCheck_and_GlcdDraw(CH1, MAGENTA); // CH1ロジック状態描画 Ypos_line= 137; // CH2の基準線に描画移動 Ypos_dot= 102; LogicCheck_and_GlcdDraw(CH2, GREEN); // CH2ロジック状態描画 Ypos_line= 86; // CH3の基準線に描画移動 Ypos_dot= 153; LogicCheck_and_GlcdDraw(CH3, CYAN); // CH3ロジック状態描画 Ypos_line= 35; // CH4の基準線に描画移動 Ypos_dot= 204; LogicCheck_and_GlcdDraw(CH4, YELLOW); // CH4ロジック状態描画 Ypos_dot= 51; // Yポジション初期化 Ypos_line= 188; Xpos++; // Xポジションを1つ進める } Xpos= 0; } /****************************************** * Drawing Coordinate Axis *******************************************/ void AxisDraw(void){ int i; Glcd_Clear(BLACK); /// X、Y座標軸表示 Glcd_Line(0, 0, 0, 239, BROWN); // 左端ライン Glcd_Line(49, 0, 49, 239, BROWN); // Y axis:最初のライン for(i=99; i<319; i+=50) Glcd_Line(i, 0, i, 239, BROWN); // Y axis:3〜7本目までのライン(最右端は引かない) Glcd_Line(0, 0, 319, 0, BROWN); // 最下位ライン:下外枠ライン Glcd_Line(0, 35, 319, 35, BROWN); // X axis :4CH Lowレベルライン Glcd_Line(0, 86, 319, 86, BROWN); // X axis :3CH Lowレベルライン Glcd_Line(0, 137, 319, 137, BROWN); // X axis :2CH Lowレベルライン Glcd_Line(0, 188, 319, 188, BROWN); // X axis :1CH Lowレベルライン Glcd_Line(0, 239, 319, 239, BROWN); // 最上位ライン:上外枠ライン /// サンプル周期表示 switch(SW){ case 0: Glcd_Str(8, 16, str_1us, WHITE, BLACK); break; case 1: Glcd_Str(8, 16, str_2us, WHITE, BLACK); break; case 2: Glcd_Str(8, 16, str_4us, WHITE, BLACK); break; case 3: Glcd_Str(8, 16, str_10us, WHITE, BLACK); break; case 4: Glcd_Str(8, 16, str_20us, WHITE, BLACK); break; case 5: Glcd_Str(8, 16, str_40us, WHITE, BLACK); break; case 6: Glcd_Str(8, 16, str_100us, WHITE, BLACK); break; case 7: Glcd_Str(8, 16, str_200us, 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) LATDbits.LATD3 = 0; else LATDbits.LATD3 = 1; } /************************************************************ * ロジック・レベル・バッファの内容を、引数により * 各CH毎に、チェックし、ロジック・レベル状態を液晶に描画する * 判断すべきロジック・レベル状態は、以下の4種類 * @ Hiレベル(変化なし) * A Loレベル(変化なし) * B 立上りエッジ * C 立下りエッジ * * 引数:channel * 0x01:CH1 * 0x02:CH2 * 0x04:CH3 * 0x08:CH4 * * color * MAGENTA (CH1) * GREEN (CH2) * CYAN (CH3) * YELLOW (CH4) *************************************************************/ void LogicCheck_and_GlcdDraw(char channel, 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 (((Buffer[ptr-1] & channel) >> shift == 0) && ((Buffer[ptr] & channel) >> shift == 0)) { // Lowレベル検知なので以下の、ドット描画を行う Glcd_Pixel(Xpos, Ypos_dot, color); } if (((Buffer[ptr-1] & channel) >> shift == 1) && ((Buffer[ptr] & channel) >> shift == 1)) { // Hiレベル検知なので以下の、ドット描画を行う Glcd_Pixel(Xpos, Ypos_dot-19, color); } if (((Buffer[ptr-1] & channel) >> shift == 0) && ((Buffer[ptr] & channel) >> shift == 1)) { // 立上りエッジ検知なので以下の、ライン描画を行う Glcd_Line(Xpos, Ypos_line, Xpos, Ypos_line+19, color); } if (((Buffer[ptr-1] & channel) >> shift == 1) && ((Buffer[ptr] & channel) >> shift == 0)) { // 立下りエッジ検知なので以下の、ライン描画を行う Glcd_Line(Xpos, Ypos_line+19, Xpos, Ypos_line, color); } } /* ///////////////////////////////////////// // 数値から文字列に変換 ///////////////////////////////////////// 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 } } */