マイコン・メモ
RX220でチャタリング・キャンセル
ホームページに戻るトップページに戻る前ページに戻る次のページへ最終ページへ
マイコンRX220で、押しボタンスイッチのチャタリングキャンセル処理について、これまで製作したものを基に紹介します。
ここでは、「フルカラー・デジタル時計」用に作成したものを例にして説明します。
1.回路

 以降は、次の回路図のように5個の押しボタンスイッチ(以降はキーまたはキースイッチと呼びます)がマイコンRX220のポート4のb4~b0に接続されているものとして説明します。
 各キーの名称は、フルカラー・デジタル時計で使用した名称です。
フルカラー・デジタル時計のキー入力回路図
 SHIFTキーは、各キーに2つの役割を持たせるためのもので、パソコン・キーボードのシフトキーと似たものです。
 各キーは下表のように、長押しを認識できるもの、オートリピートが使用できるものがあります。

ビット キー名称
(下段はSHIFTを押しながら)
オートリピート/長押しの有無
b0 SHIFT (キーの機能を拡張する)
b1 SET 長押し可
ALARM2※ 長押し可
b2 DOWN(▼) オートリピート可
TIMER 長押し可
b3 UP(▲) オートリピート可
ALARM 長押し可
b4 MODE 長押し可
MODE2 長押し可
 ※ALARM2は「フルカラー・デジタル時計」を機能アップした「音声時計」で追加された機能です。

2.キー認識のタイムチャート

 下図に、キーを操作したときのON/OFF認識方法を、タイムチャートで示します。
 通常押したときの各キーの認識方法は、「A 通常押しの場合」にあるようにキーを押したときをONとみなすのではなく、離した時をONとします。押したときにONとみなすと、キーの長押しを認識しようとする場合に、先に通常押しとして認識してしまい、長押しを認識できなくなるためです。
 ただし、同じ場面で通常押しか長押しのどちらか一方しか受け付けなくてよいのであれば、押したときにONとみなす方法も可能です。例えば、H8/3694Fを使ったデジタル時計の製作では、そのような方法を採用しています。
◇CHAT_TIME,RPT_STTIM,RPT_INTTIMの意味を下記に示します(ソースリスト"Keyin.c"を参照)。
 ・CHAT_TIME=チャタリングキャンセル時間
 ・RPT_STTIM=長押し時間、兼オートリピート開始時間
 ・RPT_INTTIM=オートリピート周期
◇(カッコ)内は、プログラム中で使用しているフラグ等の変数を表しています。
キー入力処理タイムチャート
A.通常押しの説明

 入力ポート(P44~P40)から読み込んだキーのON/OFF状態がCHAT_TIME時間安定したとき、その時のON/OFF状態を現在の状態としてメモリst_KeyStateに保持します。これが、チャタリングキャンセルです。
 その現在の状態がON→OFFに変化したとき、それまでのON時間がCHAT_TIME以上RPT_STTIM未満であれば、そのキーは「通常押し」されたと認識します。

B.長押しの説明

 入力ポート(P44~P40)から読み込んだキーのON状態が安定している時間が、RPT_STTIM時間に達した場合「長押し」として認識されます。
 長押しは、ONしてからRPT_STTIM時間後に一度だけ認識するもので、以後ONが続いても(押し続けても)変化ありません。

C.オートリピートの説明

 オートリピートとは、キーを押し続けることで、何回も押した時と同様の効果を得られる機能です。
 この例でオートリピートは、長押し同様にON状態の安定がRPT_STTIM時間に達した後、RPT_INTTIM周期で通常押しと同じ認識を繰り返す動作です。したがって、最初の認識までRPT_STTIM時間かかります。
 なおオートリピートは、同一のキーで長押し機能を併せ持つことができません。つまり、長押し機能があるキーはオートリピートしません。ちなみに、通常押しと長押しは別々のフラグ(st_KeyValid, st_KeyLong)を割り当てて区別しています(ソースリスト"Keyin.c"を参照)。


3.ヘッダファイル "Keyin.h"

 次のソースリストの、行36~44にある"KEY_xxxxx"がキーコードです。キー入力プログラム"Keyin.c"を使う場合は、この"Keyin.h"をインクルードして、キーコード"KEY_xxxxx"を使ってキーを判別します。
 なお、リスト中にあるBYTE型とは、無符号8ビットデータである unsigned char型 のことで、ヘッダファイル"typedefine.h"で定義しています。
ヘッダファイルKeyin.h

4.キー入力プログラム"Keyin.c"

 次のソースリストは、キー入力プログラム"Keyin.c"の前半部分で、関数KeyChatCancelは前出のタイムチャートで説明したキースイッチの読み込みに関する処理をすべて行っています。ただし、入力ポートの初期化や定周期割り込み発生に関するものは含まれていません。
 "Keyin.c"を使う場合、10mSの定周期割り込み処理から(割り込みをマスク状態で)関数KeyChatCancelを一定周期で呼び出す必要があります。
 行25~27で定義されている CHAT_TIME,RPT_STTIM,RPT_INTTIMは10mS単位の値で、変更することが可能です。ただし、CHAT_TIME < RPT_STTIM である必要があります。
 ソースリストにあるように、キースイッチのON/OFF認識は各キーに対応したフラグ(st_KeyValid, st_KeyLong)のビットで独立して行っています。チャタリングキャンセルも、各キーに対応したタイマカウンタst_awChatTime[ ]およびst_awSWOnTime[ ]を使って、各キー独立に行っています。
 通常押しを示すフラグst_KeyValidと長押しを示すフラグst_KeyLongは、以降で説明する読み込み関数WaitKeyTimeおよびGetKeyで読み込み都度にクリアされるので、一度のキー押し(キーON)を複数回読み込むことはありません。
 なお、リストにあるWORD型とは、無符号16ビットデータである unsigned short型 のことで、ヘッダファイル"typedefine.h"で定義しています。
注意:前出の回路図にあるように、各キースイッチはポート4のb4~b0に接続されていなければ正常動作しません。

ソースファイルKeyin.cの前半

 次のソースリストは、キー入力プログラム"Keyin.c"の後半部分で、関数KeyChatCancelで作成されたフラグ(st_KeyState, st_KeyValid, st_KeyLong)をキーコードとして読み込むための関数群です。

ソースファイルKeyin.cの後半

以下に関数の説明をします。

■GetKeyState(void)
 各キーの現在のON/OFF状態st_KeyStateを読み込みます。戻り値のKEYDAT_T型については、ヘッダファイル"Keyin.h"をご覧ください。

■WaitKeyTime(WORD wTime, KEYDAT_T* pKeyCode, KEYDAT_T* pKeyLong) 
 時間指定付きでいずれかのキー入力を待ち合わせます。特定のキーだけ待つことはできません。
 通常押しのキーだけがあって長押しのキーがなかった場合は、pKeyLong->ALL=0となります。同様に、長押しキーだけがあった場合は、pKeyCode->ALL=0となります。
 もし、何もキーが押されないままwTimeで指定した時間が経過すると、関数WaitKeyTimeはFALSE(=0)を返します。反対に、何かキーが押された場合は、*pKeyCodeまたは*pKeyLongにキーコードを格納してTRUE(≠0)を返します。
 なお、関数WaitKeyTimeは割り込みマスク状態で呼んではいけません。

■GetKey(KEYDAT_T* pKeyCode, KEYDAT_T* pKeyLong) 
 関数WaitKeyTimeと同様にキー入力を読み込みますが、待ち合わせをしません。
 この関数を呼んだ時点で何かキーが押されていれば、*pKeyCodeまたは*pKeyLongにキーコードを格納してTRUE(≠0)を返しますが、何も押されていなければFALSE(=0)を返します。
 pKeyLongにNULLを与えた場合の動作は、関数WaitKeyTimeと同じです。
注意:このプログラム例は、正常にコンパイルおよび正常に動作することを保証するものではありません。


5.関数WaitKeyTimeの使用例

 次のソースリストは、先に説明した関数WaitKeyTimeの使用方法を説明するプログラム例です。ただし、これは説明用のためこのまま実際に使用できるわけではありません。
 引数として、待ち時間1000mSと、KEYDAT_T型変数KeyCodeとKeyLongのアドレスを渡し、関数WaitKeyTimeを呼んでいます。もし何もキーが押されなければ、1000mS後に関数WaitKeyTimeからFALSEが返ってきます。キーが押されれば、KeyCodeまたはKeyLongにキーコード(KEY_xxxxx)が入ってTRUEが返ってきます。
 後は、キーコードによって処理を振り分けます。この例では、SETキー長押しでXX日付を設定し、その他のいくつかのキーでは値 I_xxxxx を戻り値として関数SampleFunctionから戻るようになっています。


ホームページに戻るトップページに戻る前ページに戻る次のページへ最終ページへ
■■■ 注 意 ■■■
1.ここに掲載された内容(写真,図,表などを含む)の、全てまたは一部を無断で使用しないでください。
2.ここで紹介した手法(構造や仕組み,回路,プログラムなどを含む)を使用したことにより、問題や不利益が発生したとしても一切関知しません。
3.ここで紹介したプログラム例は、正常なコンパイルおよび正常な動作を保証するものではありません。