目次

シート上下動制御

 ビニールハウスでは、温度管理のため、側面にある
 シートを上下動させて、換気をしています。




 シートを手動で開閉するのは、農家にとってはハウスが
 多くなるにつれ重労働となるため、機械での代行が主流
 となっています。

 シートを上下動するため、輪軸をモータで回転させて
 対応しています。



 モータが回転すると、シートは上下に動きます。

 上に動くときは、ローターに巻き取られ、下に
 動くときは、ローターから送り出されます。
 シートが下に動くときは、錘により重力を追加。
 (錘には、磁石をつけておきます。)

 スイッチを押すと、モータでシートを上下動させる
 プログラムを作成してみます。

 仕様は、次のように決めました。

 仕様から、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)でモータ回転停止

 モータ回転の指令とセンサーの出力値により
 回転と自動停止のシーケンスを考えます。
  1. 回転指令を待つ(指令が着たら、2に遷移)
  2. センサー値入力(3に遷移)
  3. センサー値が3なら、5に遷移 センサー値が0、2なら、シートを下に移動させて停止後、4に遷移 センサー値が1なら、シートを上に移動させて停止後、4に遷移
  4. 1に遷移
  5. 音と光を出す(6に遷移)
  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

目次

inserted by FC2 system