目次

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

 次のようなシステムでの動作を考えます。




 システム動作をみて、状態遷移図を作成して実現手段を考えます。

 状態値を0から4として状態遷移図を描きます。



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

200 ' update sate
210 GOSUB 300
220 IF S=1 && [1]=1 LET S,4
225 IF S=0 && [1]=1 LET S,1
230 IF S=2 && [2]=1 LET S,4
235 IF S=0 && [2]=1 LET S,2
240 IF S=3 && [3]=1 LET S,4
245 IF S=0 && [3]=1 LET S,3
250 LET [1],0,0,0
260 IF S=4 LET S,0
270 RETURN

 ボタンスイッチが押されたことを、配列[1]、[2]、[3]に
 入れられているとしました。

 配列[1]、[2]、[3]にボタンスイッチが押されたなら
 1が入っていると仮定。

 ボタンスイッチには、チャタリングがあるので
 チャタリング除去を、シフトレジスタを使って
 実現します。

 変数A、B、Cをボタンスイッチ#1、#2、#3のための
 シフトレジスタとして、サブルーチンを呼び出す度
 にシフトして、IN_1、IN_2、IN_3の論理値を入力。

 IN_1からIN_4は、プルアップされているので左に1ビット
 シフトしたなら、マスクしてIN命令で入力した値を追加
 して処理します。左シフトを2倍する処理で対応。

300 ' debouncing
310 LET A,A * 2:LET B,B * 2:LET C,C * 2
320 LET A,A & 14:LET B,B & 14:LET C,C & 14
330 LET A,A | IN(1):LET B,B | IN(2):LET C,C | IN(3)
340 IF A=14 LET [1],1
350 IF B=14 LET [2],1
360 IF C=14 LET [3],1
370 RETURN

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

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

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

400 ' update LED value
410 LET [21],0,0,0
420 IF S=1 LET [21],1
430 IF S=2 LET [22],1
440 IF S=3 LET [23],1
450 RETURN

 常に状態変数の値を見て、情報を再設定してしまえば
 点滅を扱うサブルーチンの定義だけになります。

 個々のLEDは、OUT_1、OUT_2、OUT_3に接続されているとして
 論理値の1をOUT命令で出力すると点灯とし、点灯と消灯の
 情報を配列[31]、[32]、[33]に格納してあると仮定。

 消灯では、次のように[31]から[33]にすべて0を設定後
 繰返しで印加すればよいはず。

500 ' impress
510 LET [31],0,0,0
520 FOR I=1 TO 3:OUT I,[I+30]:NEXT
530 RETURN

 配列[21]、[22]、[23]に点灯指定の情報が入っているので
 配列[31]、[32]、[33]に配列[21]、[22]、[23]の内容を
 コピーして処理します。

500 ' impress
510 LET [31],0,0,0
520 LET [31],[21],[22],[23]
530 FOR I=1 TO 3:OUT I,[I+30]:NEXT
540 RETURN

 点滅するには、カウンタを用意して、その数値の範囲を
 利用しての判定を加えて対応。更に、点滅する状態値を
 もっているかを判断しておきます。カウンタはシステム
 カウンタを使います。

500 ' impress
510 LET T,TICK() & 1:LET [31],0,0,0
520 IF S<>0 LET [31],[21],[22],[23]
530 IF T=1 GOTO 550
540 FOR I=1 TO 3:OUT I,[I+30]:NEXT:GOTO 560
550 FOR I=1 TO 3:OUT I,0:NEXT
560 RETURN

 点滅ではないとき状態値は0なので、状態値が1、2、3の
 いずれかであれば、配列[31]から[33]に、[21]から[23]の値
 をコピーして対応。

 変数と配列の値を初期化します。

100 ' initialize
110 CLV
120 FOR I=1 TO 3:OUT I,0:NEXT
130 RETURN

 全体の動きを考えてまとめます。

10 ' control state
20 GOSUB 100 :' initialzie
30 GOSUB 200 :' update state
40 GOSUB 400 :' update LED value
50 GOSUB 500 :' impress
60 IF BTN() GOTO 80
70 GOTO  30
80 END

 IchigoJam基板上にあるボタンを押すと終了する仕様に
 しておきます。

 IchigoJamのプログラムは、全体で1024文字になるので
 全体の動きを統括する部分のコメントを外してまとめて
 おけばよいでしょう。

10 ' control state
20 GOSUB 100
30 GOSUB 200
40 GOSUB 400
50 GOSUB 500
60 IF BTN() GOTO 80
70 GOTO  30
80 END
100 ' initialize
110 CLV
120 FOR I=1 TO 3:OUT I,0:NEXT
130 RETURN
200 ' update sate
210 GOSUB 300
220 IF S=1 && [1]=1 LET S,4
225 IF S=0 && [1]=1 LET S,1
230 IF S=2 && [2]=1 LET S,4
235 IF S=0 && [2]=1 LET S,2
240 IF S=3 && [3]=1 LET S,4
245 IF S=0 && [3]=1 LET S,3
250 LET [1],0,0,0
260 IF S=4 LET S,0
270 RETURN
300 ' debouncing
310 LET A,A * 2:LET B,B * 2:LET C,C * 2
320 LET A,A & 14:LET B,B & 14:LET C,C & 14
330 LET A,A | IN(1):LET B,B | IN(2):LET C,C | IN(3)
340 IF A=14 LET [1],1
350 IF B=14 LET [2],1
360 IF C=14 LET [3],1
370 RETURN
400 ' update LED value
410 LET [21],0,0,0
420 IF S=1 LET [21],1
430 IF S=2 LET [22],1
440 IF S=3 LET [23],1
450 RETURN
500 ' impress
510 LET T,TICK() & 1:LET [31],0,0,0
520 IF S<>0 LET [31],[21],[22],[23]
530 IF T=1 GOTO 550
540 FOR I=1 TO 3:OUT I,[I+30]:NEXT:GOTO 560
550 FOR I=1 TO 3:OUT I,0:NEXT
560 RETURN

 スイッチを押したときに論理値の1となる場合、シフトレジスタ
 による処理を変更して対応します。

10 ' control state
20 GOSUB 100
30 GOSUB 200
40 GOSUB 500
50 IF BTN() GOTO 70
60 GOTO 30
70 END
100 ' initialize
110 CLV
120 FOR I=1 TO 3:OUT I,0:NEXT
130 RETURN
200 ' update sate
210 GOSUB 300
220 IF S=1 && [1]=1 LET S,4
225 IF S=0 && [1]=1 LET S,1
230 IF S=2 && [2]=1 LET S,4
235 IF S=0 && [2]=1 LET S,2
240 IF S=3 && [3]=1 LET S,4
245 IF S=0 && [3]=1 LET S,3
250 LET [1],0,0,0
260 IF S=4 LET S,0
270 GOSUB 400
280 RETURN
300 ' debouncing
310 LET A,A * 2:LET B,B * 2:LET C,C * 2
320 LET A,A & 14:LET B,B & 14:LET C,C & 14
330 LET A,A | IN(1):LET B,B | IN(2):LET C,C | IN(3)
340 IF A=1 LET [1],1
350 IF B=1 LET [2],1
360 IF C=1 LET [3],1
370 RETURN
400 ' update LED value
410 LET [21],0,0,0
420 IF S=1 LET [21],1
430 IF S=2 LET [22],1
440 IF S=3 LET [23],1
450 RETURN
500 ' impress
510 LET T,TICK() & 1:LET [31],0,0,0
520 IF S<>0 LET [31],[21],[22],[23]
530 IF T=1 GOTO 550
540 FOR I=1 TO 3:OUT I,[I+30]:NEXT:GOTO 560
550 FOR I=1 TO 3:OUT I,0:NEXT
560 RETURN

 変数初期化をサブルーチンにしなければ、もう少し短くできます。

10 ' control state
20 CLV:OUT 1,0:OUT 2,0:OUT 3,0
30 GOSUB 100
40 GOSUB 400
50 IF BTN() GOTO 70
60 GOTO 30
70 END
100 ' update sate
110 GOSUB 200
120 IF S=1 && [1]=1 LET S,4
125 IF S=0 && [1]=1 LET S,1
130 IF S=2 && [2]=1 LET S,4
135 IF S=0 && [2]=1 LET S,2
140 IF S=3 && [3]=1 LET S,4
145 IF S=0 && [3]=1 LET S,3
150 LET [1],0,0,0
160 IF S=4 LET S,0
170 GOSUB 300
180 RETURN
200 ' debouncing
210 LET A,A * 2:LET B,B * 2:LET C,C * 2
220 LET A,A & 14:LET B,B & 14:LET C,C & 14
230 LET A,A | IN(1):LET B,B | IN(2):LET C,C | IN(3)
240 IF A=1 LET [1],1
250 IF B=1 LET [2],1
260 IF C=1 LET [3],1
270 RETURN
300 ' update LED value
310 LET [21],0,0,0
320 IF S=1 LET [21],1
330 IF S=2 LET [22],1
340 IF S=3 LET [23],1
350 RETURN
400 ' impress
410 LET T,TICK() & 1:LET [31],0,0,0
420 IF S<>0 LET [31],[21],[22],[23]
430 IF T=1 GOTO 450
440 OUT 1,[31]:OUT 2,[32]:OUT 3,[33]:GOTO 460
450 OUT 1,0:OUT 2,0:OUT 3,0
460 RETURN

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

10 ' control state
20 CLV:OUT 1,0:OUT 2,0:OUT 3,0
30 @LOOP
40 GSB @UPDATE
50 GSB @IMPRESS
60 IF BTN() GOTO @EXIT
70 GOTO @LOOP
80 @EXIT
90 END
100 @UPDATE
110 GSB @DEBOUNCE
120 IF S=1 && [1]=1 LET S,4
125 IF S=0 && [1]=1 LET S,1
130 IF S=2 && [2]=1 LET S,4
135 IF S=0 && [2]=1 LET S,2
140 IF S=3 && [3]=1 LET S,4
145 IF S=0 && [3]=1 LET S,3
150 LET [1],0,0,0
160 IF S=4 LET S,0
170 GSB @UPDLED
180 RTN
200 @DEBOUNCE
210 LET A,A * 2:LET B,B * 2:LET C,C * 2
220 LET A,A & 14:LET B,B & 14:LET C,C & 14
230 LET A,A | IN(1):LET B,B | IN(2):LET C,C | IN(3)
240 IF A=1 LET [1],1
250 IF B=1 LET [2],1
260 IF C=1 LET [3],1
270 RTN
300 @UPDLED
310 LET [21],0,0,0
320 IF S=1 LET [21],1
330 IF S=2 LET [22],1
340 IF S=3 LET [23],1
350 RTN
400 @IMPRESS
410 LET T,TICK() & 1:LET [31],0,0,0
420 IF S<>0 LET [31],[21],[22],[23]
430 IF T=1 GOTO 450
440 OUT 1,[31]:OUT 2,[32]:OUT 3,[33]:GOTO 460
450 OUT 1,0:OUT 2,0:OUT 3,0
460 RTN

 プッシュスイッチとLEDを実装した次の基板を使い
 動作確認しました。




目次

inserted by FC2 system