/********************************************************************* * PIC32MX 波形発生 * DMAでメモリから直接I/Oへ転送しD/Aコンバータを制御 * DMA転送8MHz  出力波形最高周波数160kHz * * 140130:Original/ Mr.Gokan * Modified/ N.Ishii *********************************************************************/ #include /* PIC32 peripheral library */ // コンフィギュレーション設定 // CPU=80 5000) Width += 1000; if(Width > 500) // 左回転周波数ダウン Width += 100; // 低周波ではステップ大きく else Width++; if(Width > 32500) // 上限チェック Width = 32500; } else{ // 右回転周波数アップ if(Width >= 5000) Width -= 1000; if(Width >= 500) Width -= 100; // 低周波ではステップ大きく else Width--; if(Width < 4) // 下限チェック Width = 4; } while(PORTFbits.RF6 == 0); // RE-B相が、Lowの間、待つ Flag = 1; // 波形更新フラグオン mINT0ClearIntFlag(); // 割り込みフラグクリア } /****************************************** * INT1割り込み処理(SW5) * 波形種別切替制御 ******************************************/ void __ISR(7, ipl3) INT1Handler(void) { WaveKind++; // 波形指定更新 if(WaveKind > 5) // 5種類で循環 WaveKind = 0; lcd_clear(); // LCD消去 /**** 液晶表示器に波形種別表示 ******/ switch(WaveKind){ case 0: lcd_str("Sine Wave"); break; case 1: lcd_str("Rectangular Wave"); break; case 2: lcd_str("Triangle Wave"); break; case 3: lcd_str("Saw Wave"); break; case 4: lcd_str("User Define1"); break; case 5: lcd_str("User Define2"); break; default:lcd_str("Wave = ?????"); } delay_ms(800); // 0.8秒待ち表示確認 // while(PORTDbits.RD9 == 0); // DAチャンネル設定スイッチオンが押されている間は待つ(後閑氏コメントを直した) // RD9のSWは未使用にしたので、この記述は必要ないくなった(N.Ishiiコメント) Flag = 1; // 波形更新フラグオン mINT1ClearIntFlag(); // 割り込みフラグクリア } /* ////////////////////////////////////////////////////////////////////////////////////////// // INT2割り込み処理(SW3) // D/Aチャネル切替制御 // ※ D/Aチャンネルは、B側しか使わないので、このサブルーチンは不要、コメントアウトした ////////////////////////////////////////////////////////////////////////////////////////// void __ISR(11, ipl3) INT2Handler(void) { lcd_clear(); // LCD消去 if(PORTGbits.RG6 == 0){ // チャネル切替 LATGbits.LATG6 = 1; lcd_str("Select Channel B"); // B側切替表示 } else{ LATGbits.LATG6 = 0; lcd_str("Select Channel A"); // A側切替表示 } delay_ms(800); // 表示確認待ち while(PORTDbits.RD10 == 0); // 分解能設定スイッチオンが押されている間は待つ(後閑氏コメントを直した) Flag = 1; // 波形更新フラグオン mINT2ClearIntFlag(); // 割り込みフラグクリア } */ /**************************************************************************** * INT2割り込み処理(SW4) * 分解能の設定制御 最高分解能は255 * ※ DAチャンネル固定変更に伴い、INT2のSW割付を変更した(N.Ishiiコメント) *****************************************************************************/ //void __ISR(15, ipl3) INT3Handler(void) void __ISR(11, ipl3) INT2Handler(void) { lcd_clear(); // LCD消去 if(MaxRes == 20) MaxRes += 30; // 分解能+50 else MaxRes += 50; if(MaxRes > 250) // 250分解能を超えたか? MaxRes = 20; itostring(3, MaxRes, MsgRes+13); // 分解能を文字変換 lcd_str(MsgRes); // LCDに表示 delay_ms(800); // 表示確認待ち // while(PORTDbits.RD11 == 0); // スイッチオンの間待つ(後閑氏コメント) // RD11のSWは未使用(未接続)なので、この記述は必要ない(N.Ishiiコメント) Flag = 1; // 波形更新フラグオン // mINT3ClearIntFlag(); // 割り込みフラグクリア mINT2ClearIntFlag(); } /****************** メイン関数 ************************/ int main(void) { /**** システム設定 ****/ SYSTEMConfigPerformance(80000000); // システム最速化 mJTAGPortEnable(DEBUG_JTAGPORT_OFF); // JTAGを無効化 /***** I/O入出力モード設定 *******/ mPORTBSetPinsDigitalOut(0xFFFF); // LCD,LED mPORTCSetPinsDigitalIn(0xF000); // NC mPORTDSetPinsDigitalOut(0x00FF); // D/S CS mPORTDSetPinsDigitalIn(0xFF00); // Sw1-3 mPORTESetPinsDigitalOut(0xFFFF); // D/A mPORTFSetPinsDigitalIn(0x0064); // Rotally mPORTFSetPinsDigitalOut(0x0093); // SW,D/A mPORTGSetPinsDigitalOut(0xFFFF); // D/A /// DAC入力データ10bitの内、下位2bit(DB0(RF0), DB1(RF1))は未使用、 /// 上位8bitのみでCODE入力するため、下位2bitは、'0'にFIX /// ちなみに、後閑氏のオリジナルソースには、下位2bitをFIXする記述はどこにもなかった LATFbits.LATF0 = 0; // DB0 LATFbits.LATF1 = 0; // DB1 /******* DMA初期設定 *******/ /* AUTOで自動繰り返し、起動トリガをタイマ3割り込み */ DmaChnOpen(dmaChn, 0, DMA_OPEN_AUTO); DmaChnSetEventControl(dmaChn, DMA_EV_START_IRQ(_TIMER_3_IRQ)); /**** 出力コンペア初期設定 *****/ // PORT-Eに出力されたデータを、D/Aへ入力させるために、DAC-CS信号が必要 // そこで、T3と連携している出力コンペア・モジュールを使って、 // T3カウントの途中で、CS(OC5/RD4)に、1パルス出力されるように設定する OpenOC5(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 0x2, 0x6); /// D/AチャネルA側選択→ D/Aチャンネルは、B側しか使わないのでコメントアウトした /// 尚、ハード的に、DAC_A/Bピンを、'Hi'にし、B側セレクト固定にした // LATGbits.LATG6 = 0; /**** システム変数初期化 *****/ dmaChn = 0; // DMAチャネル0を使用 Width = 4; // 出力パルス幅最高に初期設定 MaxRes = 200; // 最大分解能初期設定 Flag = 1; // 波形更新フラグオン WaveKind = 0; // 波形種別正弦波初期設定 /**** 液晶表示器の初期化と開始メッセージ表示 *****/ lcd_init(); lcd_str(MsgStart); /* /// スイッチ割り込み許可(後閑氏オリジナル設定) ConfigINT0(EXT_INT_ENABLE | FALLING_EDGE_INT | EXT_INT_PRI_2); ConfigINT1(EXT_INT_ENABLE | RISING_EDGE_INT | EXT_INT_PRI_3); ConfigINT2(EXT_INT_ENABLE | RISING_EDGE_INT | EXT_INT_PRI_4); ConfigINT3(EXT_INT_ENABLE | RISING_EDGE_INT | EXT_INT_PRI_5); */ /// スイッチ割り込み許可(割込みレベル修正と、SW割付変更:140130 N.Ishii) ConfigINT0(EXT_INT_ENABLE | FALLING_EDGE_INT | EXT_INT_PRI_2); // RE-B相の立下りエッジによる外部トリガ ConfigINT1(EXT_INT_ENABLE | RISING_EDGE_INT | EXT_INT_PRI_3); // SW5:波形種別選択SW:立上りエッジによる外部トリガ // INT2は、DMAチャンネル選択SW4が割付られていたが、未使用とした為、 // 元々INT3に割付けられていた分解能設定SWの外部割込みに変更した // 従って、ConfigINT3の記述は削除した ConfigINT2(EXT_INT_ENABLE | RISING_EDGE_INT | EXT_INT_PRI_3); // SW4:分解能設定SW:立上りエッジによる外部トリガ /// 割り込みフラグクリア mINT0ClearIntFlag(); mINT1ClearIntFlag(); mINT2ClearIntFlag(); // mINT3ClearIntFlag(); // 割り込みフラグクリア→上記の理由でコメントアウト(INT3未使用) INTEnableSystemMultiVectoredInt(); // 割り込み許可 /********************** メインループ ***********************/ while(1) { if(Flag == 1) // 波形更新フラグオンか? { /***** 波形データ生成 ****/ switch(WaveKind) // 波形種別で分岐し波形データ生成 { case 0: // 正弦波 for(i=0; i0; i--) { //最下位桁から上位へ buffer--; //ポインター1 *buffer = (data % 10) + '0'; //その桁数値を文字にして格納 data = data / 10; //桁-1 } } /**************************************** * Floatから文字列へ変換 *  合計有効桁は8桁以下とすること ****************************************/ void ftostring(int seisu, int shousu, float data, char *buffer) { int i; long dumy; if(shousu != 0) //小数部桁ありか buffer += seisu+shousu+1; //全体桁数+小数点 else //小数部桁なしのとき buffer += seisu + shousu; //全体桁数のみ buffer--; //配列ポインタ-1 for(i=0; i0; i--) { //小数桁数分繰り返し *buffer =(dumy % 10)+'0'; //数値を文字に変換格納 buffer--; //格納場所下位から上位へ dumy /= 10; //次の桁へ } if(shousu != 0) { //小数桁0なら小数点なし *buffer = '.'; //小数点を格納 buffer--; //ポインタ-1 } for(i=seisu; i>0; i--) { //整数桁分繰り返し *buffer = (dumy % 10)+'0'; //数値を文字に変換格納 buffer--; //ポインタ-1 dumy /= 10; //次の桁へ } i = 0; // ブランキング処理 buffer++; while((i