目次

ハードウエアテスト(その17)

 緊急警報を出力するシステム動作を、エミュレートします。




 システム動作から、状態遷移図を作成して考えます。

 状態値を0から4として状態遷移図を作成。



 状態遷移図から状態が変化する条件がわかるので
 状態遷移の処理をサブルーチンで記述。

200 ' update
210 IF S=3 && D=1 LET S,4
220 IF S=2 && (A=1 || B=1 || C=1) LET S,3
230 IF S=1 LET S,2
240 IF S=0 && (A=1 || B=1 || C=1) LET S,1
250 LET A,0:LET B,0:LET C,0:LET D,0
260 IF S=4 LET S,0
270 RETURN

 ボタンスイッチが押されたことを、変数A、B、C、Dに
 情報として入れられていると仮定しました。250行で変数
 AからDをクリアしないと、0から1の変化を検知できない
 ので、この行は必須です。

 変数AからDにボタンスイッチが押されたなら1が入っています。

 ボタンスイッチには、チャタリングがあるのでチャタリング除去を
 シフトレジスタを使って実現しています。
 エッジトリガーで、スイッチが0から1に変化したときに
 変数AからDに1を格納。

 配列[1]から[4]をボタンスイッチ#1、#2、#3、#4のための
 シフトレジスタとして、サブルーチンを呼出す度にシフト。
 さらにIN_1、IN_2、IN_3、IN_4の論理値を入力。

 [11]から[14]は、左に1ビットシフトしたなら、マスク後
 IN命令の入力値を追加。左シフトは2倍処理で対応です。

100 ' debouncing
110 FOR I=1 TO 4
120  LET [I],[I] * 2
130  LET [I],[I] & 14
140  LET [I],[I] | IN(I)
150 NEXT
160 IF [1]=1 LET A,1
170 IF [2]=1 LET B,1
180 IF [3]=1 LET C,1
190 IF [4]=1 LET D,1
195 RETURN

 シフトレジスタの4ビット中の最後の1ビットが1なら
 ボタンが押されているとし、配列[1]、[2]、[3]に論理値
 の1を設定しておきます。

 状態変数Sの値に応じて、LEDの点灯、消灯を考えます。
 LEDを点灯することだけを情報として格納しておきます。

 状態変数の値で、LEDの点灯指定は、サブルーチンで
 配列[11]、[12]、[13]、[14]に情報として格納。

300 ' value
310 LET [11],0,0,0,0
320 IF S=2 LET [11],1,1,1,0
330 IF S=3 LET [11],0,0,0,1
340 RETURN

 状態が1のときには、LEDの#1から#3を点滅するので
 LEDを扱うサブルーチンでまとめて処理することに。

 4LEDは、OUT_1、OUT_2、OUT_3に接続されているとして
 論理値1をOUT命令で出力すると点灯とします。
 情報は配列[11]、[12]、[13]、[14]に格納してあると仮定。

 状態を表現する変数Sの値で、動作を振り分けて対応します。

400 ' blink
410 IF S<>1 GOTO 470
420 FOR I=1 TO 10
430  OUT 1,1:OUT 2,1:OUT 3,1:WAIT 30
440  OUT 1,0:OUT 2,0:OUT 3,0:WAIT 30
450 NEXT
460 GOTO 480
470 FOR I=1 TO 4:OUT I,[I+10]:NEXT
480 RETURN

 Sの値が1であるときと1でないときの2つに分けて処理。

 Sの値が1のときは、10回OUT命令で1と0を出力。
 1、0を出力後、点灯、消灯状態を維持するため
 WAITで待ちを入れて対応します。

 今回は、10回の繰り返しをFOR文で処理しています。
 点滅回数の調整は、TOの右にある値で調整可能。

 Sの値が0でないときは、配列[11]から[14]に保存して
 いる論理値を、OUT命令でLEDに与えるだけ。

 最後にサブルーチンを動かすブロックをまとめます。

10 '
20 CLV:OUT 1,0:OUT 2,0:OUT 3,0:OUT 4,0
30 GOSUB 100
40 GOSUB 200
50 GOSUB 300
60 GOSUB 400
70 IF BTN() GOTO 90
80 GOTO 30
90 END

 IchigoJam基板上のボタンを押すと、終了できます。

 全体をまとめると、以下。

10 '
20 CLV:OUT 1,0:OUT 2,0:OUT 3,0:OUT 4,0
30 GOSUB 100
40 GOSUB 200
50 GOSUB 300
60 GOSUB 400
70 IF BTN() GOTO 90
80 GOTO 30
90 END
100 ' debouncing
110 FOR I=1 TO 4
120  LET [I],[I] * 2
130  LET [I],[I] & 14
140  LET [I],[I] | IN(I)
150 NEXT
160 IF [1]=1 LET A,1
170 IF [2]=1 LET B,1
180 IF [3]=1 LET C,1
190 IF [4]=1 LET D,1
195 RETURN
200 ' update
210 IF S=3 && D=1 LET S,4
220 IF S=2 && (A=1 || B=1 || C=1) LET S,3
230 IF S=1 LET S,2
240 IF S=0 && (A=1 || B=1 || C=1) LET S,1
250 LET A,0:LET B,0:LET C,0:LET D,0
260 IF S=4 LET S,0
270 RETURN
300 ' value
310 LET [11],0,0,0,0
320 IF S=2 LET [11],1,1,1,0
330 IF S=3 LET [11],0,0,0,1
340 RETURN
400 ' blink
410 IF S<>1 GOTO 470
420 FOR I=1 TO 10
430  OUT 1,1:OUT 2,1:OUT 3,1:WAIT 30
440  OUT 1,0:OUT 2,0:OUT 3,0:WAIT 30
450 NEXT
460 GOTO 480
470 FOR I=1 TO 4:OUT I,[I+10]:NEXT
480 RETURN

 ラベル利用で、次のようにも書けます。

10 '
20 CLV:OUT 1,0:OUT 2,0:OUT 3,0:OUT 4,0
30 @LOOP
40 GSB @DBX :GSB @UPX
50 GSB @PVAL:GSB @BLINK
60 IF BTN() GOTO @EXIT
70 GOTO @LOOP
80 @EXIT
90 END
100 @DBX
110 FOR I=1 TO 4
120  LET [I],[I] * 2
130  LET [I],[I] & 14
140  LET [I],[I] | IN(I)
150 NEXT
160 IF [1]=1 LET A,1
170 IF [2]=1 LET B,1
180 IF [3]=1 LET C,1
190 IF [4]=1 LET D,1
195 RTN
200 @UPX
210 IF S=3 && D=1 LET S,4
220 IF S=2 && (A=1 || B=1 || C=1) LET S,3
230 IF S=1 LET S,2
240 IF S=0 && (A=1 || B=1 || C=1) LET S,1
250 LET A,0:LET B,0:LET C,0:LET D,0
260 IF S=4 LET S,0
270 RTN
300 @PVAL
310 LET [11],0,0,0,0
320 IF S=2 LET [11],1,1,1,0
330 IF S=3 LET [11],0,0,0,1
340 RTN
400 @BLINK
410 IF S<>1 GOTO 470
420 FOR I=1 TO 10
430  OUT 1,1:OUT 2,1:OUT 3,1:WAIT 30
440  OUT 1,0:OUT 2,0:OUT 3,0:WAIT 30
450 NEXT
460 GOTO 480
470 FOR I=1 TO 4:OUT I,[I+10]:NEXT
480 RTN


目次

inserted by FC2 system