目次
前
次
シート上下動制御
ビニールハウスでは、温度管理のため、側面にある
シートを上下動させて、換気をしています。
シートを手動で開閉するのは、農家にとってはハウスが
多くなるにつれ重労働となるため、機械での代行が主流
となっています。
シートを上下動するため、輪軸をモータで回転させて
対応しています。
モータが回転すると、シートは上下に動きます。
上に動くときは、ローターに巻き取られ、下に
動くときは、ローターから送り出されます。
シートが下に動くときは、錘により重力を追加。
(錘には、磁石をつけておきます。)
スイッチを押すと、モータでシートを上下動させる
プログラムを作成してみます。
仕様は、次のように決めました。
- モータ回転は、1個のスイッチで指定
- モータ回転は、ドラバICを使い、2ビットで指定
- シートが指定位置まで移動したら、モータは自動停止
- シートの位置情報は、2個のセンサーで与える
- センサーは、その位置にシートがあれば論理値'1'を出力
- センサーは、その位置にシートがないと論理値'0'を出力
仕様から、2センサー情報入力と2ビットの制御信号出力を
すればよいと、理解できます。
センサーは、リードスイッチを利用します。
リードスイッチは、磁石に反応して接点を開閉するので
センサー回路を次のようにすればよいはず。
センサー回路の出力を、ポート2の上位4ビットに接続
して、現在の状態を取得する処理は、以下。
GETS:
; push
SEL RB1
; set pointer
MOV R0,#SENSOR
; get state
IN A,P2
; exchange nibbles
SWAP A
; masking
ANL A,#3
; store
MOV @R0,A
; pop
SEL RB0
;
ret
シートの位置と、論理値の組合せを見ておきます。
(AOUT2,AOUT1)=(0,0) シートは、中間のどこかにある
(AOUT2,AOUT1)=(0,1) シートは、下にある
(AOUT2,AOUT1)=(1,0) シートは、上にある
(AOUT2,AOUT1)=(1,1) 存在しない状態である
モータドライバは、Hブリッジを内蔵したICを利用。
IN1、IN2の組み合わせで、正転、逆転、停止、ブレーキを
かけられます。
IN1、IN2をポート1の0、1ビットに接続して
モータの回転方向を制御できるようにします。
(IN2,IN1)=(P1.1,P1.0)=(0,1)で下向きに回転
(IN2,IN1)=(P1.1,P1.0)=(1,0)で上向きに回転
(IN2,IN1)=(P1.1,P1.0)=(0,0)でモータ回転停止
モータ回転の指令とセンサーの出力値により
回転と自動停止のシーケンスを考えます。
- 回転指令を待つ(指令が着たら、2に遷移)
- センサー値入力(3に遷移)
- センサー値が3なら、5に遷移
センサー値が0、2なら、シートを下に移動させて停止後、4に遷移
センサー値が1なら、シートを上に移動させて停止後、4に遷移
- 1に遷移
- 音と光を出す(6に遷移)
- リセット指示があれば、音と光を止めて、1に遷移
指示がなければ、5に遷移
シーケンスを定義したので、最上位の処理を
記述します。
MAIN:
; get trigger
CALL GETC
; judge trigger
MOV R1,#TRG
MOV A,@R1
ANL A,#1
JZ MAINX
; clear flag
CLR A
MOV @R1,A
; check state
MOV R1,#SENSOR
MOV A,@R1
MOV R2,A
; ? 0
MOV A,R2
ANL A,#3
JZ MAIN0
; ? 1
MOV A,R2
ADD A,#255
JZ MAIN1
; ? 2
MOV A,R2
ADD A,#254
JZ MAIN2
; ? 3
MOV A,R2
ADD A,#253
JZ MAIN3
; others
JMP MAINX
; default move DOWN
MAIN0:
JMP MAIN2
; move UP
MAIN1:
; set pointer
MOV R0,#DDR
MOV A,#2
; store
MOV @R0,A
; perform
CALL UPDWN
; next
JMP MAINX
; move DOWN
MAIN2:
; set pointer
MOV R0,#DDR
MOV A,#1
; store
MOV @R0,A
; perform
CALL UPDWN
; next
JMP MAINX
; illeagal handling
MAIN3:
CALL LSP
MAINX:
JMP MAIN
あると仮定して用意したサブルーチンを
定義してきます。
回転指令
回転指令は、レベルトリガーで処理します。
ポート2の6ビット目にプッシュスイッチを接続。
このスイッチを押したときに、6ビット目が'1'と
なるようにハードウエアを構成。
レベルトリガーなので、ポート2の6ビット目の
論理値を取得し、メモリに保存します。
サブルーチンは、以下。
GETC:
; push
SEL RB1
; set pointer
MOV R0,#TRG
; get state
IN A,P2
; exchange nibbles
SWAP A
; masking
ANL A,#4
; shift
RR A
RR A
; masking
ANL A,#1
; store
MOV @R0,A
; pop
SEL RB0
;
ret
モータ回転と自動停止
モータの回転方向は、メモリに格納されてサブルーチンを
呼び出すので、格納された値を、ポート1に出力。
センサー値と回転方向の論理値は、同じになっているので
2つの値が一致したなら、回転を停止して、サブルーチン
を終了します。
コードは、以下。
UPDWN:
; push
SEL RB1
; get direction
MOV R0,#DDR
MOV A,@R0
; copy
MOV R2,A
; impress
OUTL P1,A
UPDWNL:
; get sensor state
IN A,P2
; exchange nibbles
SWAP A
; masking
ANL A,#3
; copy
MOV R3,A
; get direction
MOV A,R2
; 2's compliment
CPL A
INC1 A
; judge
ADD A,R3
JZ UPDWNX
JMP UPDWNL
UPDWNX:
; impress
CLR A
OUTL P1,A
; pop
SEL RB0
;
ret
警報処理
警報は、センサー値が3となっていて、0から2
までしかシステムが出力しないため、おかしいと
判断します。
何かしらの不具合があるので、原因を除去して
対応するように、ユーザーに促します。
光と音でわかるように、ポート1の3、4ビットに
LEDとブザーを接続して、警報を出します。
光と音は、デバイスに矩形波を出力すれば充分。
次のようにサブルーチンを定義します。
LSP:
; push
SEL RB1
LSP0:
; impress
MOV A,#12
OUTL P1,A
; wait
MOV R7,#255
LSP1:
DJNZ R7,LSP1
; impress
CLR A
OUTL P1,A
; wait
MOV R7,#255
LSP2:
DJNZ R7,LSP2
; judge
IN A,P2
SWAP A
ANL A,#8
JNZ LSPX
JMP LSP0
LSPX:
; pop
SEL RB0
;
ret
警報出力を終了するには、解除スイッチを押して対応します。
回路は、以下。
必要なサブルーチンを用意したので、アセンブリ言語
ソースコードにまとまます。
INCLUDE 8048.LIB
;*******************
; value and address
;*******************
TRG equ 18h
SENSOR equ 19h
DDR equ 1Ah
;****************
; define symbols
;****************
ENTRY equ 0h
E_INT equ 3h
E_TIM equ 7h
;*******************
; interrupt vectors
;*******************
org ENTRY
jmp START
; external interrupt
org E_INT
RETR
; timer interrupt
org E_TIM
RETR
org 10h
;**************
; sub routines
;**************
INIT:
; disable external interrupt
dis i
; disable timer interrupt
dis tcnti
; initialize I/O
clr a
outl p1,a
outl p2,a
;
RET
GETC:
; push
SEL RB1
; set pointer
MOV R0,#TRG
; get state
IN A,P2
; exchange nibbles
SWAP A
; masking
ANL A,#4
; shift
RR A
RR A
; masking
ANL A,#1
; store
MOV @R0,A
; pop
SEL RB0
;
ret
GETS:
; push
SEL RB1
; set pointer
MOV R0,#SENSOR
; get state
IN A,P2
; exchange nibbles
SWAP A
; masking
ANL A,#3
; store
MOV @R0,A
; pop
SEL RB0
;
ret
UPDWN:
; push
SEL RB1
; get direction
MOV R0,#DDR
MOV A,@R0
; copy
MOV R2,A
; impress
OUTL P1,A
UPDWNL:
; get sensor state
IN A,P2
; exchange nibbles
SWAP A
; masking
ANL A,#3
; copy
MOV R3,A
; get direction
MOV A,R2
; 2's compliment
CPL A
INC A
; judge
ADD A,R3
JZ UPDWNX
JMP UPDWNL
UPDWNX:
; impress
CLR A
OUTL P1,A
; pop
SEL RB0
;
ret
LSP:
; push
SEL RB1
LSP0:
; impress
MOV A,#12
OUTL P1,A
; wait
MOV R7,#255
LSP1:
DJNZ R7,LSP1
; impress
CLR A
OUTL P1,A
; wait
MOV R7,#255
LSP2:
DJNZ R7,LSP2
; judge
IN A,P2
SWAP A
ANL A,#8
JNZ LSPX
JMP LSP0
LSPX:
; pop
SEL RB0
;
ret
;**************
; main routine
;**************
org 100h
START:
call INIT
MAIN:
; get trigger
CALL GETC
; judge trigger
MOV R1,#TRG
MOV A,@R1
ANL A,#1
JZ MAINX
; clear trigger
CLR A
MOV @R1,A
; check state
MOV R1,#SENSOR
MOV A,@R1
MOV R2,A
; ? 0
MOV A,R2
ANL A,#3
JZ MAIN0
; ? 1
MOV A,R2
ADD A,#255
JZ MAIN1
; ? 2
MOV A,R2
ADD A,#254
JZ MAIN2
; ? 3
MOV A,R2
ADD A,#253
JZ MAIN3
; others
JMP MAINX
; default move DOWN
MAIN0:
JMP MAIN2
; move UP
MAIN1:
; set pointer
MOV R0,#DDR
MOV A,#2
; store
MOV @R0,A
; perform
CALL UPDWN
; next
JMP MAINX
; move DOWN
MAIN2:
; set pointer
MOV R0,#DDR
MOV A,#1
; store
MOV @R0,A
; perform
CALL UPDWN
; next
JMP MAINX
; illeagal handling
MAIN3:
CALL LSP
MAINX:
JMP MAIN
end
アセンブル結果は、以下。
0000 ;*******************
0000 ; value and address
0000 ;*******************
0018 TRG equ 18h
0019 SENSOR equ 19h
001A DDR equ 1Ah
0000
0000 ;****************
0000 ; define symbols
0000 ;****************
0000 ENTRY equ 0h
0003 E_INT equ 3h
0007 E_TIM equ 7h
0000
0000 ;*******************
0000 ; interrupt vectors
0000 ;*******************
0000 org ENTRY
0000 2400 + jmp START
0002
0002 ; external interrupt
0002 org E_INT
0003 93 + RETR
0004
0004 ; timer interrupt
0004 org E_TIM
0007 93 + RETR
0008
0008 org 10h
0010 ;**************
0010 ; sub routines
0010 ;**************
0010 INIT:
0010 ; disable external interrupt
0010 15 + dis i
0011 ; disable timer interrupt
0011 35 + dis tcnti
0012 ; initialize I/O
0012 27 + clr a
0013 39 + outl p1,a
0014 3A + outl p2,a
0015 ;
0015 83 + RET
0016
0016 GETC:
0016 ; push
0016 D5 + SEL RB1
0017 ; set pointer
0017 B818 + MOV R0,#TRG
0019 ; get state
0019 0A + IN A,P2
001A ; exchange nibbles
001A 47 + SWAP A
001B ; masking
001B 5304 + ANL A,#4
001D ; shift
001D 77 + RR A
001E 77 + RR A
001F ; masking
001F 5301 + ANL A,#1
0021 ; store
0021 A0 + MOV @R0,A
0022 ; pop
0022 C5 + SEL RB0
0023 ;
0023 83 + ret
0024
0024 GETS:
0024 ; push
0024 D5 + SEL RB1
0025 ; set pointer
0025 B819 + MOV R0,#SENSOR
0027 ; get state
0027 0A + IN A,P2
0028 ; exchange nibbles
0028 47 + SWAP A
0029 ; masking
0029 5303 + ANL A,#3
002B ; store
002B A0 + MOV @R0,A
002C ; pop
002C C5 + SEL RB0
002D ;
002D 83 + ret
002E
002E UPDWN:
002E ; push
002E D5 + SEL RB1
002F ; get direction
002F B81A + MOV R0,#DDR
0031 F0 + MOV A,@R0
0032 ; copy
0032 AA + MOV R2,A
0032 ; impress
033 39 + OUTL P1,A
0034 UPDWNL:
0034 ; get sensor state
0034 0A + IN A,P2
0035 ; exchange nibbles
0035 47 + SWAP A
0036 ; masking
0036 5303 + ANL A,#3
0038 ; copy
0038 AB + MOV R3,A
0039 ; get direction
0039 FA + MOV A,R2
003A ; 2's compliment
003A 37 + CPL A
003B 17 + INC A
003C ; judge
003C 6B + ADD A,R3
003D C641 + JZ UPDWNX
003F 0434 + JMP UPDWNL
0041 UPDWNX:
0041 ; impress
0041 27 + CLR A
0042 39 + OUTL P1,A
0043 ; pop
0043 C5 + SEL RB0
0044 ;
0044 83 + ret
0045
0045 LSP:
0045 ; push
0045 D5 + SEL RB1
0046 LSP0:
0046 ; impress
0046 230C + MOV A,#12
0048 39 + OUTL P1,A
0049 ; wait
0049 BFFF + MOV R7,#255
004B LSP1:
004B EF4B + DJNZ R7,LSP1
004D
004D ; impress
004D 27 + CLR A
004E 39 + OUTL P1,A
004F ; wait
004F BFFF + MOV R7,#255
0051 LSP2:
0051 EF51 + DJNZ R7,LSP2
0053
0053 ; judge
0053 0A + IN A,P2
0054 47 + SWAP A
0055 5308 + ANL A,#8
0057 965B + JNZ LSPX
0059 0446 + JMP LSP0
005B LSPX:
005B ; pop
005B C5 + SEL RB0
005C ;
005C 83 + ret
005D
005D ;**************
005D ; main routine
005D ;**************
005D org 100h
0100 START:
0100 1410 + call INIT
0102
0102 MAIN:
0102 ; get trigger
0102 1416 + CALL GETC
0104
0104 ; judge trigger
0104 B918 + MOV R1,#TRG
0106 F1 + MOV A,@R1
0107 5301 + ANL A,#1
0109 C63D + JZ MAINX
010B ; clear trigger
010B 27 + CLR A
010C A1 + MOV @R1,A
010D
010D ; check state
010D B919 + MOV R1,#SENSOR
010F F1 + MOV A,@R1
0110 AA + MOV R2,A
0111
0111 ; ? 0
0111 FA + MOV A,R2
0112 5303 + ANL A,#3
0114 C627 + JZ MAIN0
0116
0116 ; ? 1
0116 FA + MOV A,R2
0117 03FF + ADD A,#255
0119 C629 + JZ MAIN1
011B
011B ; ? 2
011B FA + MOV A,R2
011C 03FE + ADD A,#254
011E C632 + JZ MAIN2
0120
0120 ; ? 3
0120 FA + MOV A,R2
0121 03FD + ADD A,#253
0123 C63B + JZ MAIN3
0125
0125 ; others
0125 243D + JMP MAINX
0127
0127 ; default move DOWN
0127 MAIN0:
0127 2432 + JMP MAIN2
0129
0129 ; move UP
0129 MAIN1:
0129 ; set pointer
0129 B81A + MOV R0,#DDR
012B 2302 + MOV A,#2
012D ; store
012D A0 + MOV @R0,A
012E ; perform
012E 142E + CALL UPDWN
0130 ; next
0130 243D + JMP MAINX
0132
0132 ; move DOWN
0132 MAIN2:
0132 ; set pointer
0132 B81A + MOV R0,#DDR
0134 2301 + MOV A,#1
0136 ; store
0136 A0 + MOV @R0,A
0137 ; perform
0137 142E + CALL UPDWN
0139 ; next
0139 243D + JMP MAINX
013B
013B ; illeagal handling
013B MAIN3:
013B 1445 + CALL LSP
013D
013D MAINX:
013D 2402 + JMP MAIN
013F
013F end
HEXファイルの内容は、以下。
:020000002400DA
:010003009369
:010007009365
:10001000153527393A83D5B8180A475304777753EB
:1000200001A0C583D5B8190A475303A0C583D5B825
:100030001AF0AA390A475303ABFA37176BC64104C3
:10004000342739C583D5230C39BFFFEF4B2739BF80
:0D005000FFEF510A475308965B0446C58335
:1001000014101416B918F15301C63D27A1B919F1FD
:10011000AAFA5303C627FA03FFC629FA03FEC6321A
:10012000FA03FDC63B243D2432B81A2302A0142E44
:0F013000243DB81A2301A0142E243D14452402A7
:00000001FF
目次
前
次