Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

RL78/G13 基本的な多重割り込み処理の操作方法

皆様、

初心者です。ご教示お願いします。

・外部のモメンタリSWに接続した割り込みP137端子(INTP0)と12bitインターバルタイマを使い、外部割り込みSWのチャタリング防止のプログラムを作成しました。

・INTP0で呼ばれる#pragmaで定義される割り込みルーチンプログラムの冒頭に、12bitインターバルタイマによるwait_25ms()を記述したところ、このwait_25ms()のHALT()で止まってしまいます。

・そこで、割り込みルーチンのwait_25ms()の代わりに、割り込みを使用しないNOP()を繰り替えすループを作成したところ(100ms程度?)、P137のSW動作はうまく行くようになりました。

お尋ねしたいのは、

(1)外部SWのチャタリング防止のウエイトのために、12bitインターバルタイマを使用するには、どうしたらよいのでしょうか?

(2)INTP0のデフォルト割り込み優先順位は"2"のようです(H/Wマニュアル)。インターバルタイマはこれより低い順位です。wait_25ms()の前に、EI()を入れ、後にDI()を挿入すればことたりるのでしょうか?

初歩的な内容ですが、よろしくお願いします。

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

    まず、きっと他の人からも同様の指摘があると思いますが、(多重割り込みを使うといっても)割り込み処理内で25ms待つのは良くないですよ。(と私は思っています。)

    どうするかというと、こんな感じでしょうか、、、

    (1) INTP0内でタイマを起動して一旦retiする
    (2) タイマの割り込み処理が呼ばれたら、それをチャタリング除去待ち時間完了の合図とし、何らかの処理をする

  • わわいです
    スイッチを割り込み入力につなぐというのはダメです
    そもそもスイッチにはチャタリングが発生するので、割り込み入力につなぐと、そのチャタリングの分だけ割り込みが発生するってことになります
    非常に短い時間のうちに割り込が連続して発生する、ということになります
    そこでどういう事が起こるかというのを十分把握して実装するならいいですが、そういうわけじゃないときには、あなたが経験しているような不可解な現象に悩まされることになります

    そもそも、チャタリング除去ごときに割り込み入力は使うべきではありません
    #Arduinoの工作記事なんかを見てると多用されてるようですが。。

    単にタイマ割り込みで10msごとぐらいでスイッチ入力をモニタしてればチャタリング除去はできます
  • こんにちは。NoMaYです。

    > 非常に短い時間のうちに割り込が連続して発生する、ということになります

    確かに、そうですね。

    実は、私は実務でチャタリング除去処理すら書いたことが無いという、少々経験が偏っている人物だったりするので、後は本物のベテランの方にお任せします。(でないと、間違ったことを言いそうなので、、、)

    #最近、FreeRTOSのサンプルプログラムでvTaskDelay()によるチャタリング除去を書いていたので反応してしまいました、、、すみません、、、

  • In reply to NoMaY:

    NoMayさん、わいわいさん

    ご指導ありがとうございます。
    本来の多重割り込みの基本的な使い方から、チャタリング対策処理に話題が移りました。
    チャタリング対策処理に関し、お二人に共通しているのは、INTP0の外でタイマーを使うということですね。これは了解いたしました。

    >わいわいさん
    INTP0は、チャタリング除去ではなく、SW押下のチェックのために使用したいというのがそもそもです。
    SWがバタついても、P137の"最初"のエッジ低下が認識されると、INTP0の割り込みルーチンに飛びます。
    このルーチンの始めにタイマーでウエイトさせ、その後、プルアップされているP137のステータスを再度確認し、0であれば、SWが押されたというフラグをセットし割り込みルーチンを抜けるというロジックです。現在は、割り込みを使用しないタイマーを使っています。
    チャタリング防止あるいはSW押下の認識方法とは別に、このような場合に、wait_25ms()というタイマー割り込みのHALT()を避けるにはどうしたらよいでしょうか?

    よろしくお願いします。
  • In reply to tok2010:

    失礼しました。わわいさんでした。
    NoMayさん、わわいさん

    ご指導ありがとうございます。
    本来の多重割り込みの基本的な使い方から、チャタリング対策処理に話題が移りました。
    チャタリング対策処理に関し、お二人に共通しているのは、INTP0の外でタイマーを使うということですね。これは了解いたしました。

    >わわいさん
    INTP0は、チャタリング除去ではなく、SW押下のチェックのために使用したいというのがそもそもです。
    SWがバタついても、P137の"最初"のエッジ低下が認識されると、INTP0の割り込みルーチンに飛びます。
    このルーチンの始めにタイマーでウエイトさせ、その後、プルアップされているP137のステータスを再度確認し、0であれば、SWが押されたというフラグをセットし割り込みルーチンを抜けるというロジックです。現在は、割り込みを使用しないタイマーを使っています。
    チャタリング防止あるいはSW押下の認識方法とは別に、このような場合に、wait_25ms()というタイマー割り込みのHALT()を避けるにはどうしたらよいでしょうか?

    よろしくお願いします。
  • In reply to tok2010:

    わわいです
    > このような場合に、wait_25ms()というタイマー割り込みのHALT()を避けるにはどうしたらよいでしょうか?

    そうしなければ動かない、ということが、そもそもSW入力を割り込みに入れているため、でしょう。
    そこをどうにかしましょう。
  • In reply to わわい:

    わわいです
    このような状況でどう処理をするか、というと、来た複数の割り込みを、それぞれ適切に処理をする、ということになります。

    一つのスイッチのアクション、入れるときと切るときに複数の割り込みがかかります。それを適切に処理をしましょう。

    #複数の割り込み、それは数個かもしれないし、数十個かもしれない。

    それができないでいるからこそ、不要なウェイトを噛ませたり割り込みをディセーブルしないといけないことになります

    #RL78はあんまし使ったことないので、具体的なことは言えませぬ
  • In reply to tok2010:

    toko2010さん NAKAといいます。
    toko2010さんがやりたいことと違うかもしれませんが、INTP0の割込みが入ったら、割込み処理の一番初めでINTP0の割込みを禁止してしまうのはどうでしょうか?あとは適当なチャタリングが収まるタイミング(タイマーでもいいし、定期処理で数えてもいい)で再度INTP0割込みを許可するのは?toko2010さんがどれだけ早くこのスイッチを押したいかによりますが、手で押すならせいぜい0.5sくらい?SWの機械的チャタリングなら100msもあれば収まるとおもいます。もっと早くSWの確認を確実にしたいのでしょうか?高橋名人のように......古!!!!

     

    例えば

    /************************/
    /*外部入力0割り込み関数*/
    /************************/
    void __near IRQ0_INT(void)
    {
     PMK0 = 1; //IRQ0割り込みの禁止
     PIF0 = 0; //IRQ0割り込み要求フラグクリア
     f_SW = 1; //SW押されたフラグ
    }

    /************************/
    /*MAINの中で  */
    /************************/
    while(1)
    {
      if(f_1ms)    //1msの定期処理
      {
     
        if(f_SW == 1)
         {
           c_100ms++;
            if(c_100ms >= 100)
            {
             c_100ms=0;
             PMK0 = 0;        //IRQ0割り込みの許可

            f_SW = 0; //SW押されたフラグ
            }
         }

      }

    }

    みたいな

     

    P.S.

    僕も普通の手で押すSWにINTP0は使わないかな?SLEEP状態の機器を起こしたりする時なんかは使うけど....

  • 私ならわわいさんの最初のレスの通りにします。
    「初心者が多重割り込み」を使うってことは無謀だし「SWを割込みに繋ぐ」のも厳しいです。
    「コンデンサでチャタリングを取る」工夫は出来ませんか?
    それがダメなら、タイマ割込みで見張れば簡単になると思います。

    >本来の多重割り込みの基本的な使い方から、チャタリング対策処理に話題が移りました。
    ↑これを読むと、tok2010さんはホントに初心者なのですか?
    なんとなくそうは思えないんですが・・・
  • In reply to NAKA:

    NAKAさん

    ご指導ありがとうございます。

    割り込み関数の中での、

    PMK0 = 1; //IRQ0割り込みの禁止

    PIF0 = 0; //IRQ0割り込み要求フラグクリア

    さらに後続の処理で、

    PMK0 = 0;        //IRQ0割り込みの許可

    について了解いたしました。

    これを、私の割り込み関数の中にいれたところ、割り込みを使用しないウエイトを使うと、以前よりも安定的に動作し始めました。このPMK0、PIF0の操作をしないと、わわいさんが言われるように、SW押下でバタつくと思います。

    以下が現在のコードで、赤字部部分がご教示いただいた箇所です。ここで、インターバルタイマを使用したwait_50ms() に変更し、SW押下すると、このタイマで停止してしまいます。このコードには、多重割り込みのネスティング、特に多重割り込みの優先順位の取り扱いに誤りがあると考えます。INTP0の優先順位変更が必要だと思いますが、当方には不詳です。

    static void __near r_intc0_interrupt(void)

    {

       /* Start user code. Do not edit comment generated here */

       PMK0 = 1;  //INTP0割り込みの禁止(=割り込みマスクオン)

       PIF0 = 0;  //INTP0割り込み要求フラグクリア

       // wait_50ms();

       // wait_50ms();

       wait_noint(); // 割り込みを使用しないNOP()のforループ

       if ( 0 == P13_bit.no7 )

       {

       NOP();

       band_counter++;

       if ( band_counter > 10)

       {

       band_counter = 1;

       }

       }

       PMK0 = 0; //INTP0割り込み許可(=割り込みマスククリア)

       /* End user code. Do not edit comment generated here */

    }

  • In reply to Moo:

    Mooさん

    ご指導ありがとうございます。
    仰るように、当方のような初心者には多重割り込み処理は難しいと思います。
    割り込みは、省電力設計に重要だと、どこかの記事で読みました。これまで、わたくしは初心者の域を出ず、あまり割り込みを使用せず、ポーリング手法を中心に考えていました。
    今回は、無謀にも、チャタリングという課題を使い、この多重割り込みを勉強しようと考えた次第です。
    引き続きよろしくご指導お願いいたします。
  • こんにちは。NoMaYです。

    リプライは控えるつもりでしたが、1つ思い出したのは、以下のスレッドに多重割り込みの話題と試せるコードがありますよ、ということです。見てみてはどうでしょうか。(G13<-->G14とマイコンは違いますが、コードの肝心な部分は同じだと思います。)

    多重割り込み時に優先順位が同じ場合のとき
    japan.renesasrulz.com/cafe_rene/f/forum18/5880/thread/

    EB68さんの 2019/8/1 13:48 の投稿
    G14多重割り込み.zip
     

  • チョコです。
    スイッチについては,いろんな人がコメントされているので,私はRL78の多重割り込みについて説明します。
    >(2)INTP0のデフォルト割り込み優先順位は"2"のようです
    これは,ディフォルト・プライオリティのことで,単に同時に発生した同じ優先度(下で説明)の割り込みのどれを受け付けるかを示すだけで,多重割り込みとは無関係です。
    多重割り込みの多重は,各割り込みに対して「優先順位指定フラグ・レジスタ」で指定する4レベルの優先順位を対象としたものです。ディフォルトでは,全ての割り込みはレベル3(最低優先度)になっており,優先的に処理させたい割り込みの優先順位を高く(レベル2~レベル0(最優先)のどれかに)変更します。その上で,優先順位の低い割り込み処理の先頭で割り込みを許可(EI();)します。
    通常は,割り込みが受け付けられると,割り込み禁止状態になり,それ以上は優先順位によらず割り込みは受け受けません。優先順位が低い割り込み処理の先頭で割り込みを許可することで,実行中の割り込みより優先順位が高い割り込みは受け付け可能になります。これが,多重割り込みです。
  • In reply to NoMaY:

    NoMayさん

    多重割り込みに関するスレッドのご紹介多謝です。かふぇルネで多重割り込みで記事を検索しましたが、これは未見でした。早速のEB68さんのプロジェクトを立ち上げて眺めています。このプロジェクトは、コード生成プロパティのAPI関数の出力制御がすべてのコードを出力するとなっており、生成されたr_cg_intc_user.cのコードの修正箇所等を見ております。また、マニュアルの多重割り込み処理の票のPDFも参考になりました。NoMayさんの赤字の書き込みでモヤモヤ感がなくなりました。
    これまで、あまりレジスタ設定を触ったことはないので大変勉強になります。
    ありがとうございました。
  • In reply to チョコ:

    チョコさん
    いつもご指導ありがとうございます(簡易IICでもお世話になりました。現在動作中です)。

    はい。今回のスレッドの目的は、「多重割り込み処理」のことでした。
    さて、デフォルト・プライオリティは、H/Wマニュアルの割り込み優先順位に関する表16-1 (p828)で見つけた用語です。同表の注1を読んでも、割り込みの優先順位と認識し、多重割り込みの処理優先順位とは違うこととは考えませんでした。4レベルの優先順位については、これは別なページで記載があり、これとデフォルト・プライオリティの区別がつきませんでした。今回のチョコさんのコメントで違いが分かりました。

    4レベルの優先順位について、デフォルトではレベル3とのことですが、コード生成画面において、「優先順位」という選択肢があり、ここで指定することになっていますが、このデフォルトが"低"ということですね。これまであまり認識しておりませんでした。現在、取り組んでいるINTP0とITはいずれも"低"でした。これでは、通常では多重割り込みは不可ですね。

    引き続きご指導お願いいたします。

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page