// RA4M1コアボードのGPT1で周波数カウンタを試す // // D2 P105 GPT1A クロック入力↓エッジカウント // D3 P104 GPT1B Hレベルでカウント // D5 P102 GPT2B 1Hzパルス出力 // ポートH/L制御出力 #define D8_H (R_PORT3->PODR_b.PODR4 = 1) // D8:P304 H/L #define D8_L (R_PORT3->PODR_b.PODR4 = 0) // タイマー1インプットキャプチャフラグ #define CK_TCFB (R_GPT1->GTST_b.TCFB) // GPT1インプットキャプチャチェック #define CLR_TCFB (R_GPT1->GTST_b.TCFB = 0) // インプットキャプチャクリア // 文字出力バッファ char chr_bff[40]; // sprintfで使用 /***** メインクロックをPLLに切り替え *****/ void PLLon(void) { byte b; R_SYSTEM->PRCR = 0xA501; // クロック関連レジスタのプロテクト解除 // メインクロック水晶発振 R_SYSTEM->MOSCWTCR = 0b1001; // 発振安定32.768ms待ち (初期値2.08ms) R_SYSTEM->MOSCCR_b.MOSTP = 0; // XTAL発振開始 while(R_SYSTEM->MOSCCR_b.MOSTP); // MOSTPの状態, 0の確認 while(!R_SYSTEM->OSCSF_b.MOSCSF) // 発振安定待ち MOSCSFが1で安定 // PLL切り替え R_SYSTEM->PLLCCR2_b.PLLMUL = 12 - 1; // 12逓倍 16MHz*12 = 192MHz R_SYSTEM->PLLCCR2_b.PLODIV = 0b10; // 4分周 192MHz/4 = 48MHz R_SYSTEM->PLLCR_b.PLLSTP = 0; // PLL開始 while(!R_SYSTEM->OSCSF_b.PLLSF); // PLL安定待ち PLLSFが1で安定 R_SYSTEM->SCKSCR_b.CKSEL = 0b101; // クロックソースをPLLに R_SYSTEM->PRCR = 0xA500; // プロテクト戻す } /***** SETUP *****/ void setup() { // ポート設定 pinMode(8, OUTPUT); // D8:P304 // PFSプロテクト解除 R_PMISC->PWPR_b.B0WI = 0; // PFS書き込みプロテクト解除 R_PMISC->PWPR_b.PFSWE = 1; // (プロテクト戻してないよ) R_MSTP->MSTPCRD_b.MSTPD5 = 0; // 32bit PWMモジュールストップ解除 R_MSTP->MSTPCRD_b.MSTPD6 = 0; // 16bit PWMモジュールストップ解除 R_MSTP->MSTPCRC_b.MSTPC14 = 0; // ELCモジュールストップ解除 // D5:P102 1Hz出力 (19.2.5 , 19.6) R_PFS->PORT[1].PIN[2].PmnPFS_b.PDR = 1; // ポート出力 R_PFS->PORT[1].PIN[2].PmnPFS_b.PSEL = 0b00011; // GTIOC2B出力に R_PFS->PORT[1].PIN[2].PmnPFS_b.PMR = 1; // 周辺機能有効 // GPT2 B出力 1Hz発生 この↓エッジでキャプチャ (22.2.14) R_GPT2->GTCR_b.TPCS = 0b1010; // PCLKD/1024 46875Hz R_GPT2->GTPR = 46875 - 1; // 1Hz R_GPT2->GTCCR[1] = 46875 / 2; // GTIOCBがHになるカウント R_GPT2->GTIOR_b.GTIOB = 0b00110; // GTIOC2B 周期の終わりでL, B一致でH R_GPT2->GTIOR_b.OBE = 1; // B出力許可 R_GPT2->GTCR_b.CST = 1; // カウント開始 // GPT1(32bit)をELC(イベントリンク)でキャプチャ (22.2.11) // D3 P104 GPT1B Hレベルに R_PFS->PORT[1].PIN[4].PmnPFS_b.PCR = 1; // P104入力pullup R_PFS->PORT[1].PIN[4].PmnPFS_b.PSEL = 0b00011; // GTIOC1B入力に R_PFS->PORT[1].PIN[4].PmnPFS_b.PMR = 1; // 周辺機能有効 R_GPT1->GTICBSR_b.BSELCA = 1; // ELC_GPTAでBキャプチャ // D2 P105 GPT1A クロック入力 upカウント(22.2.8) R_PFS->PORT[1].PIN[5].PmnPFS_b.PCR = 1; // P105入力pullup R_PFS->PORT[1].PIN[5].PmnPFS_b.PSEL = 0b00011; // GTIOC1A入力に R_PFS->PORT[1].PIN[5].PmnPFS_b.PMR = 1; // 周辺機能有効 R_GPT1->GTUPSR_b.USCAFBH = 1; // B=HでA↓でカウントアップ R_GPT1->GTCR_b.CST = 1; // カウント開始 // ELC GPT2のオーバーフローでELC_GPTAを発生 (18.2.3) R_ELC->ELSR[0].HA = ELC_EVENT_GPT2_COUNTER_OVERFLOW; // GPT2_OVF R_ELC->ELCR_b.ELCON = 1; // ELC有効に } /***** LOOP *****/ void loop() { int f_cap0 = 0; // 最初のキャプチャ int f_frq = 0; // 周波数確定フラグ uint32_t cnt_0, cnt_1; // キャプチャ前回値と今回値 uint32_t cnt_frq; // 1秒で周波数出力 // PLL on クロックを水晶発振に切り替え PLLon(); // PLLに切り替え // シリアル Serial.begin(9600); // 9600BPSで while (!Serial); // USB接続チェック Serial.println("TEST GPT1_CAP02"); // loop while(1){ // キャプチャをチェック if(CK_TCFB != 0){ // キャプチャ発生 D8_H; // (!!!) CLR_TCFB; // フラグクリア cnt_1 = R_GPT1->GTCCR[1]; // CAP Bデータ if(f_cap0 == 0){ // 初めてのキャプチャ cnt_0 = cnt_1; // cap0にコピー f_cap0 = 1; } cnt_frq = cnt_1 - cnt_0; // 前回値との差分 cnt_0 = cnt_1; // cap0にコピー f_frq = 1; // 周波数確定 D8_L; // (!!!) } // 周波数表示 キャプチャのたびに出力 if(f_frq){ // 周波数確定? sprintf(chr_bff, "%8ld.%03ldkHz (%08lX)", cnt_frq / 1000, cnt_frq % 1000, cnt_1); // 32bitカウント値 Serial.println(chr_bff); f_frq = 0; // 次を待つ } } } // <2025-05-07 JH3DBO>