/**********************************************/ /* Arduino UNO R4 minima, 1Hz位相差検出 */ /**********************************************/ // 入力ピン // D2 P105 GPT1A キャプチャ入力A 外部から1Hzを入力 ↓を検出 // キャプチャと同時にGTCNTクリア // D3 P104 GPT1B キャプチャ入力B 比較入力 ↓を検出 // 12MHz外付け水晶発振を有効に // タイマー1インプットキャプチャフラグ #define CK_TCFA (R_GPT1->GTST_b.TCFA) // GPT1インプットキャプチャAチェック #define CLR_TCFA (R_GPT1->GTST_b.TCFA = 0) // インプットキャプチャAクリア #define CK_TCFB (R_GPT1->GTST_b.TCFB) // GPT1インプットキャプチャBチェック #define CLR_TCFB (R_GPT1->GTST_b.TCFB = 0) // インプットキャプチャBクリア // 文字出力バッファ char str_bff[80]; // sprintfで使用 /***** メインクロックをPLLに切り替え *****/ // m:逓倍値(8~16) d:分周値(2,4) // mもdも範囲チェックしていない void PLLon(int m, int d) { R_SYSTEM->PRCR = 0xA501; // クロック関連レジスタのプロテクト解除 // メインクロック水晶発振 R_SYSTEM->MOSCWTCR = 0b1001; // 発振安定32.768ms待ち (初期値2.08ms) R_SYSTEM->MOSCCR_b.MOSTP = 0; // XTAL発振開始 while(!R_SYSTEM->OSCSF_b.MOSCSF); // 発振安定待ち MOSCSFが1で安定 // PLL切り替え R_SYSTEM->PLLCCR2_b.PLLMUL = m - 1; // m逓倍 (8~31) R_SYSTEM->PLLCCR2_b.PLODIV = d / 2; // d分周 (2,4) 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() { // 水晶発振on 48MHz発生 (逓倍数,分周比を指定) // PLLon(8, 2); // PLLに切り替え (12MHz*8/2) PLLon(6, 2); // ★ (16MHz*6/2) // PLLon(8, 4); // ★ (16MHz*8/4) // モジュールストップ解除 R_MSTP->MSTPCRD_b.MSTPD5 = 0; // 32bit PWMモジュールストップ解除 R_MSTP->MSTPCRD_b.MSTPD6 = 0; // 16bit PWMモジュールストップ解除 R_MSTP->MSTPCRD_b.MSTPD14 = 0; // POEGモジュールストップ解除 // D2:P105 GPT1A キャプチャ入力A R_PFS->PORT[1].PIN[5].PmnPFS_b.PCR = 1; // P105入力pullup R_PFS->PORT[1].PIN[5].PmnPFS_b.PSEL = 0b00010; // GTETRGA入力に R_PFS->PORT[1].PIN[5].PmnPFS_b.PMR = 1; // 周辺機能有効 R_GPT1->GTICASR_b.ASGTRGAF = 1; // A↓でキャプチャ R_GPT1->GTCSR_b.CSGTRGAF = 1; // A↓でクリア // D3:P104 GPT1B キャプチャ入力B R_PFS->PORT[1].PIN[4].PmnPFS_b.PCR = 1; // P105入力pullup R_PFS->PORT[1].PIN[4].PmnPFS_b.PSEL = 0b00010; // GTETRGB入力に R_PFS->PORT[1].PIN[4].PmnPFS_b.PMR = 1; // 周辺機能有効 R_GPT1->GTICBSR_b.BSGTRGBF = 1; // B↓でキャプチャ R_GPT1->GTCR_b.CST = 1; // GPT1カウント開始 // Serialでデータ出力 Serial.begin(9600); // 9600BPSで while (!Serial); // USB接続チェック } /***** キャプチャデータ *****/ int32_t d_cap[2]; // キャプチャA,B値 // Aにジャスト1Hzを入れるとcap[0]は48000000となる int32_t d_ab; // 差分(A-B)データ プラスの値 int32_t m_ab; // 前回の差分保存データ int32_t d_dev; // 差分からの偏差 int32_t m_dev; // 偏差保存データ int32_t m_cap0; // cap A保存データ byte f_mab; // A-B差分保存済みフラグ /***** LOOP *****/ void loop() { Serial.println("1Hz_PHX01.ino 2025-06-07"); // タイトル while(1){ if(CK_TCFA){ // キャプチャA発生 CLR_TCFA; // Aフラグクリア if(CK_TCFB){ // キャプチャBあり? CLR_TCFB; // Bフラグクリア d_cap[0] = R_GPT1->GTCCR[0]; // CAP Aデータ保存 d_cap[1] = R_GPT1->GTCCR[1]; // CAP Bデータ保存 d_ab = d_cap[0] - d_cap[1]; // A-B 差分 if(f_mab == 0){ // 初めての差分 f_mab = 1; m_ab = d_ab; // 差分を保存 m_cap0 = d_cap[0]; // Aキャプチャ値を保存 } else{ // 差分2回目以降 d_dev = d_ab - m_ab; // 偏差:差分の差 if(abs(d_dev) >= (d_cap[0] / 2)){ // 前回との差が48Mの半分越え if(d_dev >= 0){ // 差がプラス d_dev = d_dev - d_cap[0]; // 偏差を修正 } else{ // 差がマイナス d_dev = d_dev - m_dev + m_cap0; // 偏差を修正 } } sprintf(str_bff, "%11u %11u %11d %11d", d_cap[0], d_cap[1], // A,Bキャプチャ値 d_ab, // A-B差分 d_dev); // 偏差 Serial.println(str_bff); m_ab = d_ab; // 差分を保存 m_dev = d_dev; // 偏差を保存 m_cap0 = d_cap[0]; // Aキャプチャ値を保存 } } else{ // ★ capAが来た時にcapBが無かったら // Serial.println(); // 改行で知らせる } } } }