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 */
}

 

  • NoMaYさん、こんにちは。まゆみです。
    回答遅くで、申し訳ありません。
    仕事は少し再開しつつありますが、まだ見れていない状況です。
    また、まとまりそうであれば、書き込み致します。
  • まとまったと言えるかどうかわかりませんが、書き込みしておきます。

    割り込みの処理は下記のようにしました。

    static void __near r_adc_interrupt(void)
    {
    /* Start user code. Do not edit comment generated here */

    /* ------------------------------------------------------------
    AD変換スキャンモード
    ------------------------------------------------------------*/

    if(adcnt == 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;

    ADS = 0x07; // AN7-AN10に切替
    adcnt++;
    NOP();

    R_DTCD0_Start(); //DTCスタート
    R_ADC_Start(); //ADCS = 1U
    }

    else if(adcnt == 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;

    ADS = 0x0b; // AN11-AN12に切替
    adcnt++;
    NOP();

    R_DTCD0_Start(); //DTCスタート
    R_ADC_Start(); //ADCS = 1U

    }

    else if(adcnt == 2){
    bufferB = (g_ad_value[0U] & 0xFFC0U) >> 6U;

    ADS = 0x03; // AN03-AN06に切替
    adcnt = 0;
    NOP();

    ad_fin_fg = 0;

    }
    NOP();


    これをメインルーチンで1ms毎に呼び出しています。
    if(timer_3 == 0) /****** 1m sec 周期 *****/
    {
      if (ad_fin_fg == 0) // A/Dスキャン変換完了済み
       {
    R_DTCD0_Start(); // DTC enabled
        R_ADC_Start(); // A/Dコンバータスタート
        ad_fin_fg = 1;
    timer_3 = 1;
    test16++;
        NOP();
    }
    adin_avg();
    }


    この記述で、AD変換のスピードが17μs(136/fclk)であれば正常に動作。
    これ以下に早くすると動作がおかしくなります。(隣のchのAD値を読んだりする)

    ちなみにメインルーチン側の
     if (ad_fin_fg == 0) // A/Dスキャン変換完了済み
    を外すと、AD変換は1回のみで、後は動かなくなりました。



    結局なぜこうなっているか、というのはわかりませんが。。。
    DTCの転送タイミングとか、AD変換の速度に注意しなければいけないということでしょうか。。
  • まゆみ さん、こんにちは。NoMaYです。

    > 結局なぜこうなっているか、というのはわかりませんが。。。
    > DTCの転送タイミングとか、AD変換の速度に注意しなければいけないということでしょうか。。

    以前にも書きましたが、以下のようなことは起きていないでしょうか?

    > 他のDTC転送にざっくりと 4.75μs/125ns=38バイト ぐらい以上のDTCブロック転送があって(DTCコントロールデータの読み込みや書き戻しの分もあるのでもうちょっと少なくても起きるかも)

    ↑つまり、個別の(1回の)A/D変換割り込み(というかDTC起動)間隔よりも長い時間が掛かる他のDTC転送は存在していないかどうか、ということです。そのようなDTC転送が始まってしまっていると他のDTC転送要求は保留される訳なので、一定間隔で発生する個別の(1回の)A/D変換割り込み(というかDTC起動)の直前辺りに先にそのような長時間のDTC転送が始まるケースがあると、A/D変換のDTC転送ですっぽ抜けるものが出てくるような気がするのです。

    > DTC保留命令で構成された何かのフラグ待ちループが4.75μs以上継続して

    ↑DTC転送は、先程のような他のDTC転送により保留されるケースの他に、上記のようにDTC保留命令だけで構成されたループをうっかり記述してしまうと、そのループでもDTC転送が保留されてしまう、というケースがあります。(以下の別スレッドへの私の投稿を参照して下さい。) これには、以下のような、割り込み要求フラグが立つことを待つ、だけの単純なループも該当すると考えられるのです。

        DI();
        ここで割り込み要求を発生させる何らかの処理を行う
        while (割り込み要求フラグ == 0) → CC-RLでは1命令の条件分岐命令となる筈 → DTC保留命令のみのループ
        {
            ;
        }
        EI();

    RL78 FreeRTOS APIを特別なおまじない記述無しで割り込みルーチンから呼び出せるようにしてみた(CC-RL/GNURL78)
    japan.renesasrulz.com/cafe_rene/f/forum21/5845/rl78-freertos-api-cc-rl-gnurl78/33975#33975

    (5) DTC保留命令によりタスク切り替えが起きなくなることへの対処

    以下のRL78/G14のユーザーズマニュアルのハードウェア編の画面コピーの通り、幾つかの命令の実行時にDTC転送が保留されることがあるのですが、...以後省略...


    丁度、本日、以下のスレッドが投稿されていましたが、割り込みが他の割り込みやDI/EIによる割り込み禁止区間で保留されるように、DTC転送も他のDTC転送やDTC保留命令によって保留されることがあり、そういうDTC転送の保留が発生しているのではなかろうか、という気がしたのです。

    A/D変換スキャンモードで割り込み消える?
    japan.renesasrulz.com/cafe_rene/f/forum18/6366/a-d
     

  • NoMaYさん、こんにちは。
    レスありがとうございます。

    DTC転送はAD変換割込みだけで使用しております。
    DTCの保留ですか。。。割込みの優先順位とかも関係ありそうですかね。
    優先順位は、気にせずでしたので、どれもが同じ低になっています。
    そのあたりも確認してみたいと思います。