お世話になります初心者IKUZOと申しますプログラム中でタイミング遅延を正確にする関数を作成したいと思うのですがサンプル等教えていただけませんでしょうか?タイマー等のサンプルはあるみたいですがLEDを割込みで変化させるようなものが見当たりますがRXシリーズでやっていた以下のようなものが欲しいです/////////////////////////////////////////////////////////////////////////CMT0を使用したタイマ///////////////////////////////////////////////////////////////////////void R_CMT_Wait(unsigned short cnt){ /* ---- Stop CMT0 counting ---- */ /* CMSTR0 - Compare Match Timer Start Register 0 b15:b2 Reserved - The write value should be 0. b1 STR1 - Count Start 1 - CMT1.CMCNT count is stopped. b0 STR0 - Count Start 0 - CMT0.CMCNT count is stopped. */ CMT.CMSTR0.BIT.STR0 = 0; /* CMT0 count is stopped. */ /* ---- Clear the CMT0 count ---- */ /* CMCNT - Compare Match Timer Counter */ CMT0.CMCNT = 0x0000; /* ---- Wait time set is other than 0? ---- */ if (0 != cnt) { /* ---- Decrement the wait time ---- */ cnt = cnt - 1; } /* ---- Set the CMT0 wait time ---- */ /* CMCOR - Compare Match Timer Constant Register */ CMT0.CMCOR = cnt; /* ---- Clear the CMT0 interrupt request ---- */ while (1 == IR(CMT0,CMI0)) { IR(CMT0,CMI0) = 0; /* CMT0.CMI0 interrupt request is cleared. */ } /* ---- Start CMT0 counting ---- */ /* CMSTR0 - Compare Match Timer Start Register 0 b0 STR0 - Count Start 0 - CMT0.CMCNT count is started. */ CMT.CMSTR0.BIT.STR0 = 1; /* ---- CMI0 interrupt request generated? ---- */ while (0 == IR(CMT0,CMI0)) { }
/* ---- Stop CMT0 counting ---- */ /* CMSTR0 - Compare Match Timer Start Register 0 b0 STR0 - Count Start 0 - CMT0.CMCNT count is stopped. */ CMT.CMSTR0.BIT.STR0 = 0;
/* Clear IR flag */ IR(CMT0,CMI0) = 0;}/////////////////////////////////////////////////////////////////////////CMT0を使用したタイマ///////////////////////////////////////////////////////////////////////割込みは使用しない方法が良いです。
チョコです。
RXの方の細かいところは分からないので,適当に作ってみました。
タイマはTM01をインターバルタイマとして使用します。インターバルは特に気にしなかったので,デフォルトの100usそのままです。使いたい時間に変更して下さい。
割り込みは使用しないに設定します。
これで,コード生成します。
後は,r_main.cのmain関数を以下のようにして1秒の時間待ちを行うようにしてみました。
while (1U) { R_CMT_Wait( 10000 ); /* 1秒待ち */ NOP(); }
ここで使用しているR_CMT_Wait関数は以下のようにしています。
/************************************************************************************************************************ Function Name: R_CMT_Wait* Description : TM01(インターバルタイマ)を用いて指定した時間を待つ* Arguments : 100us単位での待ち時間* Return Value : None***********************************************************************************************************************/void R_CMT_Wait( uint16_t cnt ){ R_TAU0_Channel1_Start(); /* TM01スタート */ for ( ; cnt > 0 ; cnt-- ) { while ( TMIF01 == 0 ) /* 100us経過を待つ */ { NOP(); } TMIF01 = 0; /* 割り込みフラグクリア */ } R_TAU0_Channel1_Stop(); /* TM01停止 */}
この関数では,最初にTM01に起動を掛けて,カウント完了の割り込みTMIF01がセットされるのを待っています。
TMIF01がセットされ,whileループを抜けたらTMIF01をクリアします。
この処理を引数で渡された回数ループすることで,指定された時間を待ってからTM01を停止して戻ります。
こんなところではどうでしょう。空いている(入出力で使用しない)チャネルを使って,時間は適当に変更して下さい。
追記
待ちたい時間の仕様が分からないので,100us単位での時間測定にしてしまいましたが,細かい(CPUのクロック単位での)
指定が必要なら,下のようにTDR01レジスタにカウント値を設定して,forの部分を削除してください。
void R_CMT_Wait( uint16_t cnt ){ TDR01 = cnt;
R_TAU0_Channel1_Start(); /* TM01スタート */ while ( TMIF01 == 0 ) /* 100us経過を待つ */ { NOP(); } TMIF01 = 0; /* 割り込みフラグクリア */ R_TAU0_Channel1_Stop(); /* TM01停止 */}
チョコさんいつもお世話になっていますやってみましたがどうも腑に落ちなくてうまくいっていないようです原因がどうもわかりません、単位が100uSにならないようですコンパイラーの最適化でループが無視されているのでしょうか?画面はmain();からTAU1_Wait(100);を呼び出しています/////////////////////////////////////////////////////////////////////////TAU1/////////////////////////////////////////////////////////////////////////100=4uSになります//1000=32uSになります//10000=313uSになります//33333=だいたい1mSぐらいvoid TAU1_Wait( uint16_t cnt ){ P5 |=0x02;//LED2消灯(オシロで監視) TDR01=cnt; TAU0_Channel1_Start while(TMIF01==0){ NOP(); } TMIF01=0; TAU0_Channel1_Stop P5 &=~0x02;//LED2点灯(オシロで監視)}/////////////////////////////////////////////////////////////////////////TAU1///////////////////////////////////////////////////////////////////////
初期設定は
// Channel 1 used as interval timer TMR01 = _0000_TAU_CLOCK_SELECT_CKM0 | _0000_TAU_CLOCK_MODE_CKS | _0000_TAU_16BITS_MODE | _0000_TAU_TRIGGER_SOFTWARE | _0000_TAU_MODE_INTERVAL_TIMER | _0000_TAU_START_INT_UNUSED; TDR01 = _0C7F_TAU_TDR01_VALUE;です。
チョコさんいつもお世話になっています 「コンパイラとは無関係」わかりました、 他をみるのですが、原因がつかめなくて、
#define TAU0_Channel1_Start \ TS0 |= _0002_TAU_CH1_START_TRG_ON;
#define TAU0_Channel1_Stop \ TT0 |= _0002_TAU_CH1_STOP_TRG_ON;
void TAU1_Wait( uint16_t cnt );
/////////////////////////////////////////////////////////////////////// //TAU設定 /////////////////////////////////////////////////////////////////////// TAU0EN = 1U; // supplies input clock TPS0 = _0000_TAU_CKM0_FCLK_0 | _0000_TAU_CKM1_FCLK_0 | _0000_TAU_CKM2_FCLK_1 | _0000_TAU_CKM3_FCLK_8; // Stop all channels TT0 = _0001_TAU_CH0_STOP_TRG_ON | _0002_TAU_CH1_STOP_TRG_ON | _0004_TAU_CH2_STOP_TRG_ON | _0008_TAU_CH3_STOP_TRG_ON | _0010_TAU_CH4_STOP_TRG_ON | _0020_TAU_CH5_STOP_TRG_ON | _0040_TAU_CH6_STOP_TRG_ON | _0080_TAU_CH7_STOP_TRG_ON | _0200_TAU_CH1_H8_STOP_TRG_ON | _0800_TAU_CH3_H8_STOP_TRG_ON; // Mask channel 0 interrupt TMMK00 = 1U; // disable INTTM00 interrupt TMIF00 = 0U; // clear INTTM00 interrupt flag // Mask channel 1 interrupt TMMK01 = 1U; // disable INTTM01 interrupt TMIF01 = 0U; // clear INTTM01 interrupt flag // Mask channel 1 higher 8 bits interrupt TMMK01H = 1U; // disable INTTM01H interrupt TMIF01H = 0U; // clear INTTM01H interrupt flag // Mask channel 2 interrupt TMMK02 = 1U; // disable INTTM02 interrupt TMIF02 = 0U; // clear INTTM02 interrupt flag // Mask channel 3 interrupt TMMK03 = 1U; // disable INTTM03 interrupt TMIF03 = 0U; // clear INTTM03 interrupt flag // Mask channel 3 higher 8 bits interrupt TMMK03H = 1U; // disable INTTM03H interrupt TMIF03H = 0U; // clear INTTM03H interrupt flag // Mask channel 4 interrupt TMMK04 = 1U; // disable INTTM04 interrupt TMIF04 = 0U; // clear INTTM04 interrupt flag // Mask channel 5 interrupt TMMK05 = 1U; // disable INTTM05 interrupt TMIF05 = 0U; // clear INTTM05 interrupt flag // Mask channel 6 interrupt TMMK06 = 1U; // disable INTTM06 interrupt TMIF06 = 0U; // clear INTTM06 interrupt flag // Mask channel 7 interrupt TMMK07 = 1U; // disable INTTM07 interrupt TMIF07 = 0U; // clear INTTM07 interrupt flag // Set INTTM00 low priority TMPR100 = 1U; TMPR000 = 1U; // Set INTTM04 low priority TMPR104 = 1U; TMPR004 = 1U; // Set INTTM07 low priority TMPR107 = 1U; TMPR007 = 1U; // Channel 0 used as square output function TMR00 = _0000_TAU_CLOCK_SELECT_CKM0 | _0000_TAU_CLOCK_MODE_CKS | _0000_TAU_COMBINATION_SLAVE | _0000_TAU_TRIGGER_SOFTWARE | _0000_TAU_MODE_INTERVAL_TIMER | _0000_TAU_START_INT_UNUSED; TDR00 = _027F_TAU_TDR00_VALUE; TO0 |= _0001_TAU_CH0_OUTPUT_VALUE_1; TOE0 |= _0001_TAU_CH0_OUTPUT_ENABLE; // Channel 1 used as interval timer TMR01 = _0000_TAU_CLOCK_SELECT_CKM0 | _0000_TAU_CLOCK_MODE_CKS | _0000_TAU_16BITS_MODE | _0000_TAU_TRIGGER_SOFTWARE | _0000_TAU_MODE_INTERVAL_TIMER | _0000_TAU_START_INT_UNUSED; TDR01 = _0C7F_TAU_TDR01_VALUE; // Channel 4 used as square output function TMR04 = _0000_TAU_CLOCK_SELECT_CKM0 | _0000_TAU_CLOCK_MODE_CKS | _0000_TAU_COMBINATION_SLAVE | _0000_TAU_TRIGGER_SOFTWARE | _0000_TAU_MODE_INTERVAL_TIMER | _0000_TAU_START_INT_UNUSED; TDR04 = _0C7F_TAU_TDR04_VALUE; TOM0 &= ~_0010_TAU_CH4_OUTPUT_COMBIN; TOL0 &= ~_0010_TAU_CH4_OUTPUT_LEVEL_L; TO0 &= ~_0010_TAU_CH4_OUTPUT_VALUE_1; TOE0 |= _0010_TAU_CH4_OUTPUT_ENABLE; // Channel 7 is used to measure input pulse interval TMR07 = _0000_TAU_CLOCK_SELECT_CKM0 | _0000_TAU_COMBINATION_SLAVE | _0000_TAU_CLOCK_MODE_CKS | _0100_TAU_TRIGGER_TIMN_VALID | _0000_TAU_TIMN_EDGE_FALLING | _0004_TAU_MODE_CAPTURE | _0000_TAU_START_INT_UNUSED; TOM0 &= ~_0080_TAU_CH7_OUTPUT_COMBIN; TOL0 &= ~_0080_TAU_CH7_OUTPUT_LEVEL_L; TO0 &= ~_0080_TAU_CH7_OUTPUT_VALUE_1; TOE0 &= ~_0080_TAU_CH7_OUTPUT_ENABLE; NFEN1 &= (uint8_t)~_80_TAU_CH7_NOISE_ON; // disable using noise filter of TI07 pin input signal // Set TO00 pin P0 &= 0xFDU; PM0 &= 0xFDU; // Set TO04 pin P4 &= 0xFBU; PM4 &= 0xFBU; // Set TI07 pin PMC4 &= 0xFDU; PM4 |= 0x02U; /////////////////////////////////////////////////////////////////////// //TAU設定 ///////////////////////////////////////////////////////////////////////
チョコさんいつもお世話になっていますmain();に以下のように設定しまして1mSの波形が観測できました、正常に動作しています、先の高解像度のほうとともに使用させていただきます、 P5 &=~0x02;//LED2点灯 TAU1_Wait(10); P5 |=0x02;//LED2消灯 TAU1_Wait(10); P5 &=~0x02;//LED2点灯