RL78でAIN0/P20をプログラム中でアナログとデジタルを変更

現在、RL78でAIN0/P20のポートをデジタルとアナログの設定をプログラム中で変更するようにしています。

デバッガーを接続した状態では動作するのですが、書き込んで動作させると動作しません。

立ち上がりはアナログで設定

アナログ入力が0になったらポートをデジタルに変更

ポート入力がHighになったら、アナログ入力にポートを変更をしているのですが、

書き込んだ状態では、アナログからデジタルには変わっているようですが、

ポートがHighになった時のif文が実行されないようです。

 

どのたか原因は判りますでしょうか?

  • 具体的な情報が提供されない上での推測となりますが

    > 原因は判りますでしょうか?

    なんか間違えてるか勘違いか思い込みによるものではないかと思います。
  • チョコです。
    そのようなアナログとデジタルと端子の使い方を変えるような使い方はお勧めできません。
    そもそも、デジタル入力では、中間レベルで貫通電流が流れるので、中間電位にとどまるような信号は問題です。
    それと、ポート入力は0.7VDD以上でないとハイ・レベルと保証されていませんが、それは問題ないのでしょうか。
    また、訳のわからない状態で疑うのは、WDTがいたずらしていないかです。コード生成を使っていると、ディフォルトでONになっているので、要注意です。
  • チョコ様

    WDTはOFFになっている事を確認しました。

    while (1U)

       {

    int j;

    HALT(); /* Wait for interrupt */

    ADIF = 0U; /* Clear INTAD request */

    R_ADC_Get_Result(&g_result_buffer);         /* Get result */

    NOP();

    P2_bit.no0 == 0;

    if(g_result_buffer <=5) // 0.16V以下になったら

    {

    R_ADC_Stop(); //ADストップ

    ADCE = 0; //ADモードOFF

    ADPC = 0x01; //AIN0をP20に設定

        PM2 = _01_PMn0_MODE_INPUT | _02_PMn1_MODE_INPUT | _04_PMn2_MODE_INPUT | _F8_PM2_DEFAULT;

    LED2 = 1;

        LED1 = 0;

    }

        if(g_result_buffer <= 155) // 0.5V以下で赤点灯

        {

       LED2 = 1;

       LED1 = 0;

    }

          if(g_result_buffer > 800) // 2.8V以上で緑点灯

    {

       LED2 = 0;

       LED1 = 1;

    }

    R_ADC_Stop();

    if(P2_bit.no1 == 1) //P20がHighになったら(2.64V以上)

    {

     ADPC = 0x02; //P20をAIN0に変更

     PM2 = _01_PMn0_NOT_USE | _02_PMn1_MODE_INPUT | _04_PMn2_MODE_INPUT | _F8_PM2_DEFAULT;

     ADCE = 1; //ADモードON

     R_ADC_Set_OperationOn();

     R_ADC_Start();

    }

    for(j = 0 ; j < 1 ; j++)

    {

    for (count=0U; count<25000U; count++)

        {

                NOP();

        }

    }

    R_ADC_Start();

       }

    上記プログラムで、書き込んだ状態だとif(g_result_buffer <=5) のところは実行されているようですが、

    if(P2_bit.no1 == 1) が実行されていないようです。

    デバッガを接続した状態だと if(P2_bit.no1 == 1) も実行されているのは確認できました。

    その他何が考えられますでしょうか?

  • 見づらいので整形してみました。

    
    while (1U)
    {
        int j;
    
        HALT(); /* Wait for interrupt */
        ADIF = 0U; /* Clear INTAD request */
        R_ADC_Get_Result(&g_result_buffer);         /* Get result */
        NOP();
        P2_bit.no0 == 0;
        if(g_result_buffer <=5) // 0.16V以下になったら
        {
            R_ADC_Stop(); //ADストップ
            ADCE = 0; //ADモードOFF
            ADPC = 0x01; //AIN0をP20に設定
            PM2 = _01_PMn0_MODE_INPUT | _02_PMn1_MODE_INPUT | _04_PMn2_MODE_INPUT | _F8_PM2_DEFAULT;
            LED2 = 1;
            LED1 = 0;
        }
        if(g_result_buffer <= 155) // 0.5V以下で赤点灯
        {
            LED2 = 1;
            LED1 = 0;
        }
        if(g_result_buffer > 800) // 2.8V以上で緑点灯
        {
            LED2 = 0;
            LED1 = 1;
        }
        R_ADC_Stop();
        if(P2_bit.no1 == 1) //P20がHighになったら(2.64V以上)
        {
            ADPC = 0x02; //P20をAIN0に変更
            PM2 = _01_PMn0_NOT_USE | _02_PMn1_MODE_INPUT | _04_PMn2_MODE_INPUT | _F8_PM2_DEFAULT;
            ADCE = 1; //ADモードON
            R_ADC_Set_OperationOn();
            R_ADC_Start();
        }
        for(j = 0 ; j < 1 ; j++)
        {
            for (count=0U; count<25000U; count++)
            {
                NOP();
            }
        }
        R_ADC_Start();
    }
    
    

    この内の 3つの if、

    
        if(g_result_buffer <=5) // 0.16V以下になったら
    
    
    
        if(g_result_buffer <= 155) // 0.5V以下で赤点灯
    
    
    
        if(g_result_buffer > 800) // 2.8V以上で緑点灯
    
    

    使用されているマイコンや動作条件も不明ですが、10bit の ADコンバータでリファレンス電圧が 3.3V と仮定すると、

    
        3.3/1024*5   = 0.01611328125
        3.3/1024*155 = 0.49951171875
        3.3/1024*800 = 2.578125
    
    

    0.5V 以外数字が合ってない感じですね。

    また、3つの if の条件に引っ掛からなくとも R_ADC_Stop() を呼んでアナログ入力を止めてますが、ロジック的に意図されたものなのか疑問に思います。R_ADC_Start() を 2か所で呼んでるのも不思議な感じですね。

  • チョコさんがおっしゃっるように、端子をアナログとデジタルで切替えるのは、やめた方が良いと思います。

    端子としてはずっとアナログ入力として使用し、プログラム上で「今はアナログ利用かデジタル利用か」「デジタルモードの時は電圧値から、今のH/Lを保持、HからLに変化、LからHに変化」を判断する方法もあります。
  • チョコです。

    PM2のDEFAULT値がF8と言うことから、P2はP20-P22しかないので20pinのG13あたりですかね。(G11の10pinもP2は3本だけですが、A/Dとの切り替えはPMCなので、違います。)

    ところで、提示されている処理は、少しおかしいように見えます。

    「P2_bit.no0 == 0;」は意味不明です。言語レベルだけでなく、RL78ではアナログ入力をポートとして読むと必ず0になります。ここでの、P2操作は全く無駄です。

    そもそも、A/Dをどのようなモードで使っているかわからないので、ここのA/D制御で問題ないか正確なところは分かりませんが、A/Dが停止した状態でもR_ADC_Startとするのは問題があります。(ADPCでポートにしても、A/D変換そのものは実行されます。ADCEが0なので、禁止された状態での変換動作ですが。)

    ifだけでなく、elseも活用して、おかしな制御にならないようにすることをお勧めします。

  • わかさん、こんにちは。NoMaYと申します。

    話が巻き戻ってしまって申し訳ないのですが、なぜ以下の処理をさせようとしたのですか?このようにしなければならない、と、わかさんが考えられた理由がある筈と思ったのです。(投稿されたソースコードを見ても理由を推測出来るような記述はありませんでしたので。)

    > 立ち上がりはアナログで設定
    > アナログ入力が0になったらポートをデジタルに変更
    > ポート入力がHighになったら、アナログ入力にポートを変更をしているのですが、

  • チョコです。

    >話が巻き戻ってしまって申し訳ないのですが、なぜ以下の処理をさせようとしたのですか?

    おそらく、消費電力を抑制するためだと想像します。何しろ、A/D変換では最大1.7mAの電流が流れますから。

    これが目的なら、必要ないときにR_ADC_Start()関数を呼び出すのはNGです。

    R_ADC_Start()関数を呼び出すと、A/Dコンバータは動作しようとします。)

     

    何を目的に提示された処理を行おうとしているかを明確にしてもらえれば、もっと役に立つレスがあると思います。