アナログAN3-AN9の7CHをスキャンモードでDTC転送で読み込んでいます。
メインループで、タイマー1msec割り込みを利用し、2msec毎にADスタート、DTCスタートしております。
AD変換終了割り込みでCHを切替ていますが、CS+のウオッチで変換データbuffer3~9を見ていると、
たまにbuffer3にbuffer4のデータが読み込まれたり(ほかのCHも同じことがおこっている)
しています。
ADスタートかDTC転送のどこを修正したらよいか困っており、ご教授をお願い致します。
ソース
メインループ r_main.c
while (1U) { ---
if(timer_2msec == 0) /****** 2m sec 周期 *****/ { timer_2msec = 2; NOP(); R_ADC_Start(); //A/Dコンバータスタート R_DTCD0_Start(); // DTC enabled }
割り込み処理 r_cg_adc_user.c
static void __near r_adc_interrupt(void){ /* Start user code. Do not edit comment generated here */
R_ADC_Stop(); //ADCS = 0U
if(ad_ch_fg == 0){ buffer3 = (g_ad_value[0U] & 0xFFC0U) >> 6U; buffer4 = (g_ad_value[1U] & 0xFFC0U) >> 6U; buffer5 = (g_ad_value[2U] & 0xFFC0U) >> 6U; buffer6 = (g_ad_value[3U] & 0xFFC0U) >> 6U; NOP(); ADS = 0x07; // AN7-AN10に切替 NOP(); NOP(); NOP(); R_ADC_Start(); //ADCS = 1U R_DTCD0_Start(); //DTCスタート } else if(ad_ch_fg == 1){ buffer7 = (g_ad_value[0U] & 0xFFC0U) >> 6U; buffer8 = (g_ad_value[1U] & 0xFFC0U) >> 6U; buffer9 = (g_ad_value[2U] & 0xFFC0U) >> 6U; bufferA = (g_ad_value[3U] & 0xFFC0U) >> 6U; NOP(); ADS = 0x03; // AN3-AN6に切替 NOP(); NOP(); NOP(); ad_fin_fg = 0; } ad_ch_fg ^= 0x01; NOP(); /* End user code. Do not edit comment generated here */}
まゆみ さん、こんにちは。チョコさんも、こんにちは。NoMaYです。振り子のように(というか螺旋階段?)アッチを疑いコッチを疑い再度アッチを疑い、という具合ですみませんが、添付されていたソースとここまでのやり取りを見直していて気になったのですが、リピート転送の場合、毎回、R_DTCD0_Start();する必要ってあったんでしょうか?(実は、リピート転送を実際に使ったことが無くて、デバイスのマニュアルを確認しようと思い始めたところです。あと、R_DTCD0_Start();の中身はどうなっていたかな、と自分のHDDの中の他のプロジェクトを確認してみようと思います。それから、似た感じのシミュレータのプロジェクトを作ってみようかなぁ、とも思います。)[訂正] すみません、リピートモード割り込みを使わないといけないので、毎回、R_DTCD0_Start();しないといけないのですね。失礼しました。
まゆみ さん、こんにちは。チョコさんも、こんにちは。NoMaYです。RL78/G14で似た感じのプロジェクトを作ってGo/Break/Stepとかさせていて思い浮かんだのですが、A/Dとタイマの割り込み以外にも割り込みは動いているとは思っているのですが、他の割り込みの影響で、「A/Dスキャン変換のDTC転送リピートモード割り込み要求」のCPU受け付けタイミングがミリ秒オーダー(かつ、不運にも、絶妙なタイミング)で遅延したりしていないでしょうか?例えば、試しに以下のようなソースにするとどうなるでしょうか?(他にも気になる点を2つほどコメントに書き込んでいます。)
timer_2msec = 0; ad_fin_fg = 0; ad_ch_fg = 0; while (1U) { // タイマ割り込み周期は ちゃんと 1m sec か? // 以下の判定処理は 200usec に 1回 程度は確実に行われるか? if(timer_2msec == 0) /****** 2m sec 周期 *****/ { if (ad_fin_fg == 0) // A/Dスキャン変換完了済み { timer_2msec = 2; ad_fin_fg = 1; NOP(); R_DTCD0_Start(); // DTC enabled R_ADC_Start(); // A/Dコンバータスタート } else // 未完(DTC転送リピートモード割り込みが m sec オーダーで保留された?) { timer_2msec = 1; // もう 1m sec 待つ(それでも未完なら更に待つ) } } }
気になったのは、その様な状況ですと、以下のR_ADC_Stop();が何か悪影響を与えるのではないかと思ったのです。(メインでR_ADC_Start()したA/Dスキャン変換を、途中で、受け付けが遅延した割り込み内でR_ADC_Stop()してしまっていないだろうか?)
static void __near r_adc_interrupt(void){ /* Start user code. Do not edit comment generated here */ R_ADC_Stop(); //ADCS = 0U if(ad_ch_fg == 0) { buffer3 = (g_ad_value[0U] & 0xFFC0U) >> 6U; buffer4 = (g_ad_value[1U] & 0xFFC0U) >> 6U; buffer5 = (g_ad_value[2U] & 0xFFC0U) >> 6U; buffer6 = (g_ad_value[3U] & 0xFFC0U) >> 6U; NOP(); ADS = 0x07; // AN7-AN10に切替 NOP(); NOP(); NOP(); R_DTCD0_Start(); //DTCスタート R_ADC_Start(); //ADCS = 1U } else if(ad_ch_fg == 1) { buffer7 = (g_ad_value[0U] & 0xFFC0U) >> 6U; buffer8 = (g_ad_value[1U] & 0xFFC0U) >> 6U; buffer9 = (g_ad_value[2U] & 0xFFC0U) >> 6U; bufferA = (g_ad_value[3U] & 0xFFC0U) >> 6U; NOP(); ADS = 0x03; // AN3-AN6に切替 NOP(); NOP(); NOP(); ad_fin_fg = 0; } ad_ch_fg ^= 0x01; NOP(); /* End user code. Do not edit comment generated here */}
また、この話は、以下の話とも関係があるかも知れません。> ・メインルーチンの2msタイマのところ(DTCスタート、ADCスタートの前)にブレークポイントを設定してGo/Breakを繰り返すと、 AN3-AN6にそれぞれ100、1023、200、300を入力した状態 で、異常な数値は表示されないことを確認しました。> (下位の数ビットは振れているので、データは更新されていると思います、例えばAN3が、100とか101が表示される)[追記]すみません、1つ書き忘れました。AN3~AN10のA/Dスキャン変換では、AN3-AN6の組とAN7-AN10の組とで、合計2回の「A/Dスキャン変換のDTC転送リピートモード割り込み要求」が発生しますが、シミュレータで試していると、各組のA/Dスキャン変換には150usecほどの時間が掛かるようで、1回目の割り込みと2回目の割り込みの間には少なくとも150usecほどの間が開くのですが、1回目の割り込みの受け付けが2msec弱ほど遅延した後、2回目の割り込みの受け付けが2msecをごくわずかオーバーしてしまった、というような状況が頭に思い浮かびました。
まゆみ さん、こんにちは。NoMaYです。その後、どうでしょうか?進展はありましたでしょうか?
まゆみ さん、こんにちは。NoMaYです。> ADコンバータの変換時間を遅くすると、解消するのではないかということがわかりました。> もともと、CPUのシステムクロック8MHz、AD変換時間4.75μs(38/fclk)としていましたが> これを、変換時間19μs(152/fclk)とすると、AD値が異常の時にカウントアップさせていたカウンタが> カウントしなくなるこを確認しております。これは、他のDTC転送にざっくりと 4.75μs/125ns=38バイト ぐらい以上のDTCブロック転送があって(DTCコントロールデータの読み込みや書き戻しの分もあるのでもうちょっと少なくても起きるかも)、その転送中に各A/D変換終了割り込み要求の1つ(or 複数)をDTCが受け付け損ねてしまったのかな、、、あるいは、DTC保留命令で構成された何かのフラグ待ちループが4.75μs以上継続してしまって、同じことが起きてしまったとか、、、それでは最終結果の書き込みを待つようにします。
まゆみ さん、こんにちは。NoMaYです。その後、どうでしょうか?最終結果に関してのまとめは出来上がりそうでしょうか?
まゆみ さん、こんにちは。NoMaYです。その後、どうでしょうか?再開することは出来ましたでしょうか?