皆様、
初心者です。ご教示お願いします。
・外部のモメンタリ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()を挿入すればことたりるのでしょうか?
初歩的な内容ですが、よろしくお願いします。
こんにちは。NoMaYです。> 非常に短い時間のうちに割り込が連続して発生する、ということになります確かに、そうですね。実は、私は実務でチャタリング除去処理すら書いたことが無いという、少々経験が偏っている人物だったりするので、後は本物のベテランの方にお任せします。(でないと、間違ったことを言いそうなので、、、)#最近、FreeRTOSのサンプルプログラムでvTaskDelay()によるチャタリング除去を書いていたので反応してしまいました、、、すみません、、、
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状態の機器を起こしたりする時なんかは使うけど....
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_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 */