アナログ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と申します。ちょっと失礼します。ちなみに、お使いのデバイスは何でしょうか?
まゆみ さん、こんにちは。チョコさんも、こんにちは。NoMaYです。> そうなると,何かがDTCを邪魔しているかもしれません。または,ノイズが影響している?デバイスの設定はひとまず問題なさそう、ということなったら、次に気になるのは、デバッガの影響でしょうか、、、 ブレークポイントでブレークさせたことで、割り込み関連のプログラムの動作がおかしくなることは、良くありますので、、、(今まであまり意識していませんでしたが、DTC/DMAも転送を1つずつ進めていく要因はDTC/DMAに入力されている割り込み要求信号ですので、動作がおかしくなることがあっても不思議では無いような気がしてきています、、、)それで、「CS+のウオッチで変換データbuffer3~9を見ている」というのは、どのようにして見ているのでしょうか?(1) プログラムのどこかにブレークポイントを設定してGo/Breakを繰り返している?⇒ そのブレークポイントでブレークすることでA/D変換終了割り込み要求をDTCが受け付け損ねる状況になる可能性はないですか?(2) プログラムを実行させたままリアルタイムRAMモニタ機能でウォッチしている?⇒ デバッガのプロパティでリアルタイムRAMモニタ機能を無効にすると問題の起きる/起きないに変化がありますか?⇒⇒ ただ、アルタイムRAMモニタ機能を無効にするとそもそもプログラムを実行させたままウォッチすることが出来なくなりますので、例えば以下のようにするなどして現象が発生するかどうかを確認してみて頂けませんか?・ AN3-AN6にそれぞれ1V,2V,3V,4Vを入力する (デバイスの動作電圧は5Vだとしていますので3.3Vなら電圧を調整して下さい)・ r_adc_interrupt()で変換値を読み出す時に以下のようなチェックルーチンを入れてNGならそこでブレークするようにする(例)
static void __near r_adc_interrupt(void){/* Start user code. Do not edit comment generated here */ 。。。途中省略。。。 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; if (buffer3の値が1V前後でない || buffer4の値が2V前後でない || buffer5の値が3V前後でない || buffer6の値が4V前後でない) { NOP(); /* 読み出し値が異常である */ /* ブレークポイントを設定する */ } 。。。途中省略。。。 } 。。。途中省略。。。/* End user code. Do not edit comment generated here */}
それで、すみません、チョコさんの以下のアドバイスには対処した状態(R_DTCD0_Start();が先でR_ADC_Start();が後)で試して欲しいと考えています。> R_ADC_Start();とR_DTCD0_Start();の順番が気になりますね。