;マグネットアクチェータードライバ  Ver. 0.3 MAGDRV03.ASM
;1450μsec 以下のパルスで左出力、1550μsec 以上で右出力
;PIC16F84A @4MHz
LIST P=PIC16F84A
INCLUDE "P16F84A.INC"
__CONFIG _HS_OSC & _PWRTE_ON & _CP_OFF & WDT_OFF
CNT020 EQU 0CH ;20μsec timer use
CNT050 EQU 0DH ;50μsec
CNT100 EQU 0EH ;100μsec
CNT1400 EQU 0FH :1400μsec
CNT1600 EQU 11H ;1600μsec
ORG 0
MAIN
BSF STATUS,RP0 ;バンク 1 に切替え
CLRF TRISB ;ポート B をすべて出力にセット
BCF STATUS,RP0 ;バンク 0 に戻る
MOVLW B'00000000' ;RB0-RB7 Low set
MOVWF TRISB
MOVLW 0H
MOVWF CNT1400 ;CNT1400 RESET
MOVWF CNT1600 ;CNT1600 RESET
;メインループ
LOOP
TP1 BTFSC PORTA,4 ;RA4 が Low の場合次の命令をスキップ
GOTO TP1
TP2 BTFSS PORTA,4 ;RA4 が High の場合次の命令をスキップ
GOTO TP2
TP3 CALL WAIT100 ;100μsec
CALL WAIT100 ;200
CALL WAIT100 ;300
CALL WAIT100 ;400
CALL WAIT100 ;500
CALL WAIT100 ;600
CALL WAIT100 ;700
CALL WAIT100 ;800
BTFSS PORTA,4 ;RA4 が High の場合次の命令をスキップ
GOTO WRONG ;800μsec以下のパルスは不正とみなして排除
CALL WAIT100 ;900
CALL WAIT100 ;1000
CALL WAIT100 ;1000
CALL WAIT100 ;1100
CALL WAIT100 ;1200
CALL WAIT100 ;1300
CALL WAIT100 ;1400
CALL WAIT050 ;1450
;1450μsec 以下なら OUT1400 の処理へ
BTFSS PORTA,4 ;RA4 が High の場合次の命令をスキップ
GOTO OUT1400
CALL WAIT050 ;1500μsec
;1500μsec 以下なら OUT1500 の処理へ
BTFSS PORTA,4 ;RA4 が High の場合次の命令をスキップ
GOTO OUT1500
CALL WAIT020 ;1520μsec
;1550μsec 以上なら OUT1600 の処理へ
GOT1600
;800μsec 以下のパルスは不正とみなす処理ルーチン
WRONG
MOVLW B'00000000' ;RB0-RB7 Low set
MOVWF TRISB
MOVLW 0H
MOVWF CNT1400 ;CNT1400 RESET
MOVWF CNT1600 ;CNT1600 RESET
GOTO LOOP
;1400μsec 処理ルーチン
OUT1400
BTFSS CNT1400,0 ;CNT1400 が 1 (初めてのパルス)でない場合次の命令をスキップ
CALL WAIT020 ;初めてのパルスなら 20μsec 待つ
BTFSS PORTA,4 ;RA4 が High の場合次の命令をスキップ
GOTO CHECK1400
MOVLW B'00000000' RB0-RB7 Low set
MOWF TRISB
MOVLW 0H
MOVWF CNT1400 ;CNT1400 RESET
MOVWF CNT1600 ;CNT1600 RESET
GOTO LOOP
CHECK1400 ;初めてのパルスなら CNT1400 をインクリメント、二度目のパルスなら出力へ
BTFSC CNT1400,0 ;CNT1400 が 0 (初めてのパルス)の場合次の命令をスキップ
GOTO OUTRB4
INCF CNT1400,F ;CNT1400 をインクリメント
GOTO LOOP
OUTRB4
MOVLW B'11110000' ;RB0-RB3 High RB4-RB7 Low set
MOVWF TRISB
MOVLW 0H
MOVWF CNT1600 ;CNT1600 RESET
GOTO LOOP
;1500μsec 処理ルーチン
OUT1500
MOVLW B'00000000' ;RB0-RB7 Low set
MOVWF TRISB
MOVLW 0H
MOVWF CNT1400 ;CNT1400 RESET
MOVWF CNT1600 ;CNT1600 RESET
GOTO LOOP
;1600μsec 処理ルーチン
OUT1600
BTFSS CNT1600,0 ;CNT1600 が 1 (初めてのパルス)でない場合次の命令をスキップ
CALL WAIT020 ;初めてのパルスなら 20μsec 待つ
BTFSC PORTA,4 ;RA4 が Low なら次の命令をスキップ
GOTO CHECK1600
MOVLW B'00000000' ;RB0-RB7 Low set
MOVWF TRISB
MOVLW 0H
MOVWF CNT1400 ;CNT1400 RESET
MOVWF CNT1600 ;CNT1600 RESET
GOTO LOOP
CHECK1600 ;初めてのパルスなら CNT1600 をインクリメント、二度目のパルスなら出力へ
BTFSC CNT1600,0 ;CNT1600 が 0 (初めてのパルス)の場合次の命令をスキップ
GOTO OUTRB3
INCF CNT1600,F ;CNT1600 をインクリメント
GOTO LOOP
OUTRB3 MOVLW B'00001111' ;RB0-RB3 High RB4-RB7 Low set
MOVWF TRISB
MOVLW 0H
MOVWF CNT1400 ;CNT1400 RESET
GOTO LOOP
;20μsec wait timer
WAIT020
MOVLW 05H
MOVWF CNT020
TIMLP1 DECFSZ CNT020,F
GOTO TIMLP1
NOP
NOP
RETURN
;100μsec wait timer
WAIT100
MOVLW 17H
MOVWF CNT100
TIMLP2 NOP
DECFSZ CNT100,F
GOTO TIMLP2
NOP
NOP
NOP
RETURN
;50μsec wait timer
WAIT050
MOVLW 0CH
MOVWF CNT050
TIMLP3 NOP
DECFSZ CNT050,F
GOTO TIMLP3
RETURN
END