要約:アラーム制御パネルは、家庭でも職場でも日常生活の一部となっています。このアーティクルは、MAX-IDE開発環境で作成された、低電力LCDマイクロコントローラMAXQ2000を利用したアラーム制御のサンプルアプリケーションについて説明します。MAXQ2000は、LCDディスプレイ、PIN (暗証番号)入力キーパッド、圧電ブザー、および磁気リードスイッチなどのセキュリティアプリケーションで標準的に使われるペリフェラルと容易にインタフェースすることができます。
アラームコントロールパネルには、普通、さまざまな入力デバイスとユーザディスプレイが使われています。よく使われるコンポーネントは以下のようなものです。
ユーザからの入力を受け付けるデバイス:4 x 4のスイッチキーパッド
ユーザに対する出力を表示するデバイス:LCDディスプレイ
入力デバイス:磁気リードスイッチ
出力デバイス:圧電ブザー
このようにさまざまなコンポーネントを、シンプルなアプリケーションとパワフルで柔軟なMAXQ2000マイクロコントローラで管理・制御することができます。MAX-IDE開発環境とMAXQアセンブリ言語で作られたこのアプリケーションをダウンロード 可能です。コードの前提となっているのは、以下のハードウェアを持つMAXQ2000評価キットボードです。
キーパッド:Grayhill 16ボタン(4行4列)キーパッド96BB2-006-F
圧電ブザー:CEP-1172
磁気リードスイッチ:標準的なシングルループタイプ
設計目標
サンプルアプリケーションは以下のタスクを実行します。
磁気リードスイッチをモニタリングし、ドアや窓が開いているか閉じているかを検出します。
キーパッドからPINを入力することによって、システムセキュリティの設定・解除ができるようにします。
ステータス情報をLCDに表示します。
キー入力やセンサ開閉を検知すると、圧電ブザーを鳴らして音による警告を行います。
システムセキュリティが設定され、かつ、センサが開を検知すると、ブザーを鳴らし続けます。
図1 に示すように、アラーム制御アプリケーションの動作には、CLOSED、OPEN、SET、ALERTという4つのステータスがあります。
図1. アラーム制御アプリケーションには、CLOSED、OPEN、SET、ALERTという4つのステータスがあります。
磁気リードスイッチとのインタフェース
警報システムでは、磁気リードスイッチの磁気部分とリードスイッチ部分を別の場所に取り付けます。磁気部分はドアや窓の動くところに取り付け、スイッチ部分は枠組みに固定します。ドアや窓が閉まっていると、磁気によってリードスイッチが閉じ、アラームは発報していません。システムセキュリティが設定され、ドアや窓が開くと、リードスイッチのステートが変化し、MAXQ2000が侵入警報を発報します。
リードスイッチは、ポートピンP5.2とP5.3間に接続するだけでMAXQ2000とインタフェースします。P5.2がアクティブロープルダウン(PD = 1、PO = 0)、P5.3が弱プルアップ入力(PD = 0、PO = 1)に設定されているとき、リードスイッチが閉じるとP5.3がゼロを読み込み、開くと1を読み込みます。
move PD5.2, #1 ; Drive one side of reed switch LOW
move PO5.2, #0
move PD5.3, #0 ; Set weak pullup high on other side
move PO5.3, #1
...
ML_Closed_Check:
move C, PI5.3
jump NC, ML_Closed_L ; Switch is closed, continue in this state
call ShortBeep
call ShortPause
call ShortBeep
call ShortPause
call ShortBeep
call ShortPause
call ShortBeep
call ShortPause
jump ML_Open ; Switch is open, transition to OPEN state
4 x 4キーパッドとのインタフェース
アラーム制御システムでは、PINを確実に入力したり、システムセキュリティの設定・解除を行ったり、システムの構成を変更するためにキーパッドを用います。今回のサンプルアプリケーションで使用するキーパッドは4 x 4グリッドの16スイッチです。スイッチは行と列のマトリクスになっており(図2 )、キーパッドスイッチを押すと、ある行とある列が接続されます。たとえば、「3」キーを押すと、行3と列1が接続されます。
図2. キーパッドスイッチは、4行4列のグリッドになっています。
キーパッドには、キーパッドマトリクスの各行と各列ごとに端子が出ており、全部で8本のインタフェース端子があります。キーパッドとMAXQ2000のEVキットの接続は以下のようになります。
Pin
Connect
Port Pin
JU2 Pin
1
Row 1
P6.0
54
2
Row 2
P6.1
52
3
Row 3
P6.2
50
4
Row 4
P6.3
48
5
Col 1
P6.4
46
6
Col 2
P6.5
44
7
Col 3
P7.0
42
8
Col 4
P7.1
40
今回のアプリケーションでは、EVキットボードを以下のように構成します。
DIPスイッチ
以下のスイッチはオフにします:SW1スイッチすべて、SW3.1、SW3.7、SW3.8、SW6.1、SW6.4、SW6.5、SW6.6、SW6.7、およびSW6.8
その他のDIP スイッチはどのようなステートでも大丈夫です。
ジャンパ
以下のジャンパはOPENにします:JU5、JU6、JU8、およびJU9
以下のジャンパはCLOSEDにします:JU1、JU2、JU3およびJU11
その他のジャンパはどのようなステートであっても構いません。
列スキャン
キーパッドは行と列という構成になっているため、ある行、あるいはある列の4個のスイッチのステートを同時に読むことができます。1列目の4個のスイッチのステートを読み取るためには、まず、そのラインをローにプルダウンし、他の列はトライステートとします(図3 )。次に、各行のラインを弱プルアップとします。最後に、4本の行ラインをポートピン入力に接続します。こうすると、スイッチが押されている行の入力だけがロー、残りはハイになります。
同様に、1行に並んだ4個のスイッチのステートは、その行のラインをローにプルダウンし、4列ともに入力と弱プルアップを設定すれば読み取ることができます。行と列は交換可能です。
サンプルアプリケーションの構成では、4本の行ライン(キーパッド端子の1から4まで)が同じ入力ポート(P6[3:0])に接続されるため、同時に読み取ることが簡単です。このため、サンプルアプリケーションでは、1列分のスイッチを同時にスキャンするようにしています。キーパッドに接続した8本のポートピンラインについては、4種類のセットアップがありえます。セットアップごとに、4個のスイッチのステートを読み取ることができます。読み込まれているスイッチが閉じていれば全入力ラインはローを読み込み、スイッチが開いていればハイを読み込みます。
STATE
P6.0
P6.1
P6.2
P6.3
P6.4
P6.5
P7.0
P7.1
1
Input - 1
Input - 4
Input - 7
Input - *
low
tri-state
tri-state
tri-state
2
Input - 2
Input - 5
Input - 8
Input - 0
tri-state
low
tri-state
tri-state
3
Input - 3
Input - 6
Input - 9
Input - #
tri-state
tri-state
low
tri-state
4
Input - A
Input - B
Input - C
Input - D
tri-state
tri-state
tri-state
low
図3. MAXQ2000は、列1をローにプルダウンして、最初の4つのキーパッドスイッチのステートを読み取ります。
割込駆動のステートマシン
キーが押されている間に確実に読み取るためには、キーパッドの4列をすばやくスキャンする必要があります。また、複数回のキー操作をスイッチのチャタリングと誤判断することを避けるために、一定時間以上、スイッチが押されてスイッチ押下と判断される必要があります。以上は、いずれも、アプリケーションの中心であるタイマーを使った割込ルーチンによってすぐに実現可能です。このようにすることによって、4列のいずれかを定期的にスキャンし、キーが押されている時間を計るアプリケーションが可能になります。
RELOAD equ 0FF00h
StartTimer:
move IIR.3, #1 ; Enable interrupts for module 3
move IMR.3, #1
move T2V0, #RELOAD
move T2R0, #0h
move T2C0, #0h
move Acc, T2CFG0 ; Set timer 0 to run from HFClk/128
and #08Fh
or #070h
move T2CFG0, Acc
move T2CNA0.3, #1 ; Start timer 0
move T2CNA0.7, #1 ; Enable timer 0 interrupts
ret
タイマーのリロード値によって割込頻度を制御します。キー押下を確実にとらえるためには、このリロード値を十分に小さくする必要があります。さらに、キー応答が遅くならないようにするためには、リロード値を長くして、処理時間を消費しすぎないようにする必要もあります。いろいろと実験した結果、上記にあるように0FF00hという値にたどり着きました(およそ2.4msごとに1回)。
4つのスイッチをひとまとめにした列ラインをローに駆動すると、押下されたスイッチを経由して接続動作を行い、入力ラインをローにするために、若干の時間、待つ必要となるかもしれません。どの程度の時間がかかるかは、スイッチのオン抵抗や同時に押された列スイッチの数によって異なります。列ラインをローにプルダウンしてから4個のスイッチのステートを読むまで割込サービスルーチンに遅延をかけなくても済むように、あるステートの列ラインをあらかじめローにプルダウンするようにしました。(図4 )
図4. 4つのキースキャンステートのそれぞれにおいて、アプリケーションは、4個のスイッチのステートを読み取るとともに、次の4個の読み取り準備を行います。
MAXQ2000の割込ベクター(IV)は実行時にセットすることができるので、アプリケーションは次のステート値を割込ベクターレジスタに保持します。タイマーから割込がかかると、現在のキースキャンステートのハンドラルーチンが、次のステートのハンドラルーチンに割込ベクターアドレスを設定します。
org 0000h
Main:
call InitializeLCD
move PD6, #010h ; For state 1
move PO6, #00Fh ; For all states
move PD7, #000h ; For state 1
move PO7, #000h ; For all states
move IV, #State1
call StartTimer
move IC, #1 ; Enable global interrupts
jump $
State1:
push PSF
push Acc
move Acc, PI6
and #000Fh ; Grab lowest four bits only
sla4
move A[13], Acc
move PD6, #020h ; For state 2
move PD7, #000h
move T2V0, #RELOAD ; Set reload value
move T2CNB0.1, #0 ; Clear interrupt flags
move T2CNB0.3, #0
move IV, #State2
pop Acc
pop PSF
reti
他の4ステートのハンドラルーチンも同様ですが、すでに情報を集め、A[13]ホールディングレジスタに保存されているスイッチビットのORに若干の調整を行います。このステートルーチンでは、3つのワーキングアキュムレータを使用します。
A[13]は、キーパッドを通し現在のパスで読み込んだ全スイッチステートのビット行列を保持します。ステート4の読み込みが完了すると、このレジスタに保持されるビットは以下のようになります。ここで1のビットは開いた(押されていない)キースイッチを示し、0ビットは閉じた(押された)キースイッチを示します。
BIT 15
BIT 14
BIT 13
BIT 12
BIT 11
BIT 10
BIT 9
BIT 8
BIT 7
BIT 6
BIT 5
BIT 4
BIT 3
BIT 2
BIT 1
BIT 0
*
7
4
1
2
5
8
0
3
6
9
#
D
C
B
A
スイッチのデバウンシング
ステート4に到達してすべてのキーのスキャンが終了すると、押されたキーを認めるかどうかの判断をしなければなりません。シンプルなデバウンシング手法としては、16個のスイッチそれぞれについてカウンタ値を保持するという方法があります。ステート4に到達したとき、キーが押されていたらカウンタをインクリメントします。キーが押されていない場合は、カウンタをデクリメントします。このカウンタが一定値に達すると、キーが押されたものとして登録します。キーを押下しつづけたときキーリピートにならないように(コンピュータキーボードではキーリピートが普通ですが、キーパッドではキーリピートさせません)、一度登録されたキーがもう一度登録されるためには、まず、(キーの押下が終わり)カウンタがゼロまでデクリメントされなければならないようにする必要があります。
16のキーすべてのステートを1つのレジスタに保持しているため、もっとシンプルで、かつ、メモリ消費量が少ないデバウンシングソリューションが考えられます。このアプリケーションの保持するカウンタ値は1つとし、ビットパターンが前回のスキャンで読んだパターンと等しいときにカウンタ値をインクリメントします。
State4:
push PSF
push Acc
move Acc, PI6
and #000Fh ; Grab low four bits only
or A[13]
cmp A[15]
jump E, State4_End ; Ignore the last debounced pattern
cmp A[14]
jump E, State4_Match
move LC[0], #DEBOUNCE
move A[14], Acc ; Reset current bit array
キーリピート防止の為、ビットパターンをもう一度認める条件は、ビットパターンがキー押下と認めるだけの時間一定であり、且つ、他のビットパターン(キー押下がないアイドルステートも含む)が認められた後のみとします。
複数キー同時押下の処理
キーパッド入力デバイスの使用では、複数キーの同時押下が可能です。サンプルアプリケーションのデバウンシングコードでは、2番目のキーが押されるとデバウンスインターバルのカウントが最初に戻りますが、デバウンスインターバル自体が短いため、これが問題になることはありません。
ビットパターンが認められると、アキュムレータを使い、押下されたキーのビットについて、16ビットすべてをローテーションしてそれぞれキャリービットに入れ、その際にビットごとにチェックすることができます。サンプルアプリケーションのコードは、最初に押下されたキーのみに反応しますが、必要であれば、この変更も容易です。
State4_Match:
djnz LC[0], State4_End
move A[15], Acc ; Reset last debounced pattern
rrc
jump NC, State4_KeyA
rrc
jump NC, State4_KeyB
rrc
jump NC, State4_KeyC
rrc
jump NC, State4_KeyD
rrc
jump NC, State4_Key3
rrc
jump NC, State4_Key6
rrc
jump NC, State4_Key9
rrc
jump NC, State4_KeyPound
rrc
jump NC, State4_Key2
rrc
jump NC, State4_Key5
rrc
jump NC, State4_Key8
rrc
jump NC, State4_Key0
rrc
jump NC, State4_Key1
rrc
jump NC, State4_Key4
rrc
jump NC, State4_Key7
rrc
jump NC, State4_KeyStar
jump State4_End
LCDディスプレイのインタフェース
MAXQ2000のEVキットに搭載されているLCDディスプレイは、図5 のようなセグメントを持ちます。
図5. このLCDディスプレイには、4.5桁の7セグメント文字を表示することができます。
まず、LCDディスプレイをスタティック駆動モードに初期化し、イネーブルとします。この処理が終わると、セグメントを適切に設定することによって、ディスプレイ上に文字を描くことができます。
InitializeLCD:
move LCRA, #03E0h ; xxx0001111100000
; 00 - DUTY : Static
; 0111 - FRM : Frame freq
; 1 - LCCS : HFClk / 128
; 1 - LRIG : Ground VADJ
; 00000 - LRA : RADJ = max
move LCFG, #0F3h ; 1111xx11
; 1111 - PCF : All segments enabled
; 1 - OPM : Normal operation
; 1 - DPE : Display enabled
move LCD0, #00h ; Clear all segments
move LCD1, #00h
move LCD2, #00h
move LCD3, #00h
move LCD4, #00h
ret
PINの入力
CLOSED状態とSET状態、ALERT状態では、PINを入力してアラームコントローラの状態を変更することができます。文字が入力されるごとに、A[10]に保持されるワーキング値を左にシフトし、新しい文字とのORをとります。同時に、LCDディスプレイ上の小数点が左に動き、入力した文字数を表示します。セキュリティ上の理由から、入力されたPINをディスプレイに表示することはしません。
State4_Key0:
move Acc, #0000h
jump State4_Shift
State4_Key1:
move Acc, #0001h
jump State4_Shift
State4_Key2:
move Acc, #0002h
jump State4_Shift
....
State4_Shift:
move A[12], Acc
move Acc, A[10]
cmp #0FFFFh ; flag indicating no PIN entry allowed
; in current state
jump E, State4_NoKey
move Acc, A[11] ; key count
cmp #04 ; if already at 4 (should have been cleared)
jump E, State4_NoKey
add #1
move A[11], Acc
move Acc, A[10]
sla4
or A[12]
move A[10], Acc
4文字すべてが入力されると、入力されたPINをハードコーディングされた値と比較します。この入力された値がPINと一致すると、適切な状態に移行します。
PIN_VALUE equ 03870h ; Just a random number
;; "Closed" state code
ML_Closed:
move A[10], #00000h ; Reset PIN value
move A[11], #0 ; Reset number of PIN chars entered
move LCD3, #LCD_CHAR_C
move LCD2, #LCD_CHAR_L
move LCD1, #LCD_CHAR_5
move LCD0, #LCD_CHAR_D
ML_Closed_L:
move Acc, A[11]
cmp #4 ; 4 characters entered?
jump NE, ML_Closed_Check
move Acc, A[10]
cmp #PIN_VALUE ; PIN matches?
jump E, ML_Set
call LongBeep ; Beep on incorrect PIN and reset
move A[10], #0000h
move A[11], #0
move LCD3.7, #0
ML_Closed_Check:
move C, PI5.3 ; Check reed switch
jump NC, ML_Closed_L ; Closed, stay in current state
call ShortBeep ; 4 short beeps signal transition
call ShortPause
call ShortBeep
call ShortPause
call ShortBeep
call ShortPause
call ShortBeep
call ShortPause
jump ML_Open ; Switch opened, go to OPEN state
圧電ブザーの使い方
アプリケーションでは、小型圧電ブザーにより以下の2つの機能を実現しています。(1)キー押下や不正なPINの入力に対し、音によるフィードバックを提供する。(2)システムセキュリティが設定されているときリードスイッチが開くとアラームを発報する。
デモ目的の場合、MAXQ2000の2つのポートピンに接続するだけで小型圧電ブザーをインタフェースすることができます。圧電ブザーの電流駆動を増加するために、ポートピンは差動で駆動されます。また、ブザーのトーン周波数は、ドライバコードのループカウント数によって決まります。
ShortBeep:
move LC[1], #100 ; Number of cycles
SB_L1:
move PO5.6, #0
move PO5.7, #1
move Acc, #2000 ; Count for forward polarity period
SB_L2:
sub #1
jump NZ, SB_L2
move PO5.6, #1
move PO5.7, #0
move Acc, #2000 ; Count for reverse polarity period
SB_L3:
sub #1
jump NZ, SB_L3
djnz LC[1], SB_L1
ret
実際の警報システムでは、強力な駆動回路を用いて圧電ブザーを駆動するか、ブザーの共振周波数で駆動して音量を上げるなどが考えられます。
まとめ
MAXQ2000は専用LCDコントローラペリフェラルで、LCDディスプレイに容易かつ直接つなぐことができます。MAXQ2000の柔軟なポートピン配置により、マルチプレクス型キーパッドも簡単に読むことができます。マトリクス接続されたキーのすべては、タイマー割込駆動型のステートマシンによって、最小のプロセッサオーバーヘッドでスキャンとデバウンシングを行うことができます。最後に、圧電ブザーと磁気リードスイッチも、MAXQ2000にある汎用ポートピンを使って、容易に制御可能です。
この記事はMER Vol 5に掲載されています。
フィードバックをお寄せください。 内容に満足されましたか、あるいは満足されていませんか?もっと良いページにできると思いますか?あるいは、単なるコメントでも結構です。フィードバックをお待ちしています。 —マキシムはお客様からいただく訂正、提案を元に改善していきます。
このページを評価し、フィードバックを送信する。
APP 3546: Jun 20, 2005
アプリケーションノート3546,
AN3546,
AN 3546,
APP3546,
Appnote3546,
Appnote 3546