ADコンバータとDTC転送(ソフトウエアトリガ、スキャン、ワンショット変換)で他の端子のアナログデータを読み込む

アナログ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 */
}

 

Parents
  • まゆみ さん、こんにちは。チョコさんも、こんにちは。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();の順番が気になりますね。

Reply
  • まゆみ さん、こんにちは。チョコさんも、こんにちは。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();の順番が気になりますね。

Children
  • チョコさん、NoMaYさん、こんにちは。ご回答ありがとうございます。

    ・「CS+のウオッチで変換データbuffer3~9を見ている」のは、
    デバッグツールにE1を使用しており、デバッグツールの設定→実行中のメモリアクセス→実行中に表示更新を行うを「はい」に設定。表示更新間隔を200msにして、リアルタイムで数値を見ております。
    (10bitの値を10進数で表示している)


    ・ AN3-AN6にそれぞれ100、1023、200、300を入力した状態 (値はたまに違うアナログ端子のデータが表示されるが、だいたいは正常な値が表示されるので、この値にボリュームで調整した)にし、
    異常値の時に、カウンタをカウントアップさせてみました。

    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 > 200 | buffer4 < 900 | buffer5 >300 | buffer6 >400){
    NOP();
    test16++;
    }

    これで、test16の値がカウントアップしていることを確認しました。
    上記のNOP();でブレークポイントを設定すると、STOPすることも確認しました。
    (その時、例えばbuffer3に1023が表示されたり、buffer6に101が表示されたりする)

    現在は、R_ADC_Start();とR_DTCD0_Start();の順番を(R_DTCD0_Start();が先でR_ADC_Start();が後)にしておりますが、症状は改善していない状況です。

    ・メインルーチンの2msタイマのところ(DTCスタート、ADCスタートの前)にブレークポイントを設定してGo/Breakを繰り返すと、 AN3-AN6にそれぞれ100、1023、200、300を入力した状態 で、異常な数値は表示されないことを確認しました。
    (下位の数ビットは振れているので、データは更新されていると思います、例えばAN3が、100とか101が表示される)

    このような状況から、DTCかADのタイミング?がずれたりしているのか・・・と考えております。