;******************************************************
; ＦＭＳ        << PIC12F675 >>
;
; Version 3.00
; 2006/05/10 Nakasige-Tosikazu
;******************************************************
;======================================================
;発振器を４MHz
;RS232C 19200bps=1bit=52us 調歩同期
;8bit-1ST-NonP-NonFlow
;
;- input -
#DEFINE     P_IN        GPIO,1      ;GP1     = 入力信号
#DEFINE     P_OUT       GPIO,0      ;GP0     = RS232C出力
;                       
    LIST        P=PIC12F675
    INCLUDE     "P12F675.INC"

CB = _CPD_OFF               ;データEEPROMもプログラム・メモリも
CB &= _CP_OFF               ;コード・プロテクトしない
CB &= _BODEN_OFF            ;ブラウンアウト・リセットを使わない
CB &= _MCLRE_OFF            ;MCLRリセットを使わない
CB &= _PWRTE_ON             ;パワーアップ・タイマを使う
CB &= _WDT_ON               ;ウォッチドッグ・タイマを使う
CB &= _INTRC_OSC_NOCLKOUT   ;内部発振器を使う

    __CONFIG CB

    __IDLOCS H'0300'        ;バージョン3.00
;
;----------------------
; Data Define
;----------------------
    CBLOCK  H'20'           ;H20から汎用レジスタに割付
        C_TIM1              ;遅延タイマカウンタ
        C_IN                ;入力信号用カウンタ
        C_BIT               ;ビット位置カウンタ
    ENDC                    ;割付終了
;======================================================
;  Start program
;======================================================
;START
        ORG     H'0'        ;0番地スタート
        CALL    H'3FF'      ;内部発振器をキャリブレーションする
        BSF     STATUS,RP0
        MOVWF   OSCCAL      ;キャリブレーションデータを書く
        BCF     STATUS,RP0
        GOTO    MAIN
;======================================================
;  SubRoutines
;======================================================
;----------------------
;40us Timer Subroutine
;----------------------
TIM40
        MOVLW   D'9'        ;9回
        MOVWF   C_TIM1      ;ここまでで２サイクル
TIM40LP
        NOP
        DECFSZ  C_TIM1,F    ;このループは4サイクル
        GOTO    TIM40LP     ;2+4*9-1=37
        RETLW   0           ;37+2=39*1usec=39usec
;
;----------------------
;220us Timer Subroutine
;----------------------
TIM220
        MOVLW   D'54'       ;54回
        MOVWF   C_TIM1      ;ここまでで２サイクル
TIM220LP
        NOP
        DECFSZ  C_TIM1,F    ;このループは4サイクル
        GOTO    TIM220LP    ;2+4*54-1=217
        RETLW   0           ;217+2=219*1usec=219usec
;
;----------------------
;Send RS232C Subroutine
;----------------------
Send232C
        ;-----  RS232Cに送信 -----
S100
        ;-----  START BIT  -----
        BCF     P_OUT       ;Set Output to 0 (Start Bit)
        CALL    TIM40       ;39us

S110
        MOVLW   D'9'        ;8Bitなので８回
        MOVWF   C_BIT       ;ビット位置カウンタ
S120
        DECFSZ  C_BIT,F     ;減算をし結果が０ならスキップ 
        GOTO    S130        ;送信を繰り返す
        GOTO    S900        ;送信完了
S130
        ;-----  ビット送信 -----
        RRF     C_IN,F      ;右回転
        BTFSC   STATUS,C    ;Test Carry             【BTFSS】１だったらスキップ 
        GOTO    S001        ;Set Output to 0
        GOTO    S000        ;Set Output to 0
;==============================================
S000    ;-----  Ｌを送信   -----
        BCF     P_OUT       ;０にする
        CALL    TIM40       ;39us
        GOTO    S120
S001    ;-----  Ｈを送信   -----
        BSF     P_OUT       ;１にする
        CALL    TIM40       ;39us
        NOP
        GOTO    S120
;==============================================
S900
        ;-----  STOP BIT   -----
        BSF     P_OUT       ;Set Output to 1 (Stop bit)
        CALL    TIM40       ;39us
        CALL    TIM220      ;219us
        RETLW   0           ;戻る
;
;
;======================================================
;  Main Routine
;======================================================
MAIN
;----------------------
; Initialize Routine
;----------------------
INIT
        ; ----- 初期設定 -----
        BSF     STATUS,RP0  ;STATUSレジスタのRP0ビットを１に
                            ;してBank1(Page1)に切替える     【BSF】 ｆ レジスタの指定ビットを１にする
        MOVLW   B'11111110' ;弱プルアップなし
        MOVWF   OPTION_REG  ;WDTのTimeOutは18ms*64=1.152秒
        MOVLW   B'00000110' ;GP1/2入力 GP0出力
        MOVWF   TRISIO      ;入力出力モードを設定
        MOVLW   B'00110000' ;GP0/1/2/3ピンをアナログ入力モード解除
        MOVWF   ANSEL       ;A/D変換クロックはFrc(内部RC発振)
        BCF     STATUS,RP0  ;Bank0(Page0)に戻る             【BCF】 ｆ レジスタの指定ビットを０にする 
        MOVLW   B'00000111' ;GP2:0 をデジタルI/Oに設定
        MOVWF   CMCON       ;CMCON = CM0/CM1/CM2 ON (COMPARATOR OFF)
;
        ; ----- 初期クリア -----
        CLRF    C_TIM1      ;遅延タイマカウンタ
        CLRF    C_IN        ;入力信号用カウンタ
        CLRF    C_BIT       ;ビット位置カウンタ
        BSF     P_OUT       ;とりあえずＨにしておく
;
;----------------------
; Procedure Routine
;----------------------
PROC
        CLRWDT
        MOVLW   B'11111111' ;H'FFをWORKへ代入
        MOVWF   C_IN        ;信号用カウンタ
P100
        CLRWDT
        NOP
        NOP
        NOP
        ;----- 立上り信号判断 -----
        BTFSS   P_IN        ;入力信号がＨかどうか
        GOTO    P100        ;入力信号がＨになるまで待つ
P110
        CLRWDT
        ;-----  信号の送信   -----
        CALL    Send232C    ;RS232Cに信号を送る
P120
        ;-----  カウンタクリア -----
        CLRF    C_IN        ;入力信号用カウンタ 初期クリア
P130
        ;-----  信号の幅を計測 -----
        INCF    C_IN,F      ;入力信号用カウンタに＋１
        BTFSC   STATUS,Z    ;桁あふれすれば入力信号なし 【BTFSC】０だったらスキップ 
        GOTO    PROC        ;最初
        BTFSS   P_IN        ;入力信号がＨかどうか
        GOTO    P130        ;入力信号がＨになるまで待つ
        GOTO    P110        ;入力信号がＨになれば送信処理へ
;----------------------
;----------------------
        END
