1 装置構成図

 

2 回路図

(1)スタート制御装置

 

(2)検知装置

 

3 フローチャート

 

4 プログラム

スタート制御装置のプログラム、検知装置のプログラムをそれぞれ示します。

マイクロチップ社のPIC KIT3、MPLAB IDEを使用して、マイコンPIC16F648Aへの書き込みを行います。

それぞれの最新バージョンをセットで使用します。

スタート制御装置 v190120←v190112←v180915←v180707←v180527

検知装置      v180716←v180716←v180716←v180716←v180602

 

注:スタート制御装置に使用するマイコンは内部クロックで作動させていますので、マイコン毎に精度がばらつきます(Data Sheetでは誤差±1%)。スタート制御装置のドン音発生と検知装置のダイオードが消えるタイミングが1ms程度以内に収まるように変数DataZの値を設定します(6~10程度の範囲になります)。

 

(1)スタート制御装置プログラム

;******************************************************

; 短距離通過タイム計測システム(スタート制御プログラム)

;******************************************************

;PIC16F648のピン配置-------------------------

;     DB7      DB6      DB5      DB4                E        RW        RS     LED     

;      RA1     RA0      RA7      RA6      Vdd      RB7      RB6      RB5      RB4  

;      18       17       16       15       14       13       12       11       10 

;

;       1        2        3        4        5        6        7        8        9 

;      RA2     RA3      RA4      MCLR     Vss      RB0      RB1      RB2      RB3

;      busy*   音  start準備中LOW              DIP*    RX*      TX     タクトSW*

;                    RA4はオープンドレイン(BCF=0, BSFはONでも)             

;****** *は入力 その他は出力   **********************

;v190120

;v190112からの変更点

;内部オシロの誤差補正変数DataZ(6から10程度に設定要す)追加

;バントナルの時間補正1msずらした

;検知装置のv180716とセットで使用する

    

    

    LIST    P=16F648A

    #INCLUDE    P16F648A.INC

;    内蔵オシロ 定電圧監視OFF(CP OFF)  外部プルアップ(MCLRE ON)

    __CONFIG  _INTRC_OSC_NOCLKOUT & _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _MCLRE_ON

;              (内蔵オシロとMCLREの内部プルアップの同時設定は警告文が出る)

;******************************

;    変数レジスタ定義

;******************************

    #define    D_RS    PORTB,5

    #define    D_RW    PORTB,6

    #define    D_E    PORTB,7

 

    #define    D_DB4    PORTA,6    ;

    #define    D_DB5    PORTA,7    ;

    #define    D_DB6    PORTA,0    ;

    #define    D_DB7    PORTA,1    ;

    

    ;PORTAの設定(液晶IN、OUT設定)

PORT_OUT    equ    B'00000100'    ;DB5 ,DB4 , - , start, 音,busy,DB7 ,DB6

PORT_IN        equ    B'11000111'    ;DB5*,DB4*, - , start, 音,busy,DB7*,DB6* 

 

    CBLOCK    020h

    D_ADRESH    ; ADRESH保存

    COUNT1        ; タイムカウンタ変数

    COUNT2        ; タイムカウンタ変数

    COUNT3        ; タイムカウンタ変数

    COUNT4        ; タイムカウンタ変数

    T2m_count    ; タイムカウンタ変数

    T10m_count    ; タイムカウンタ変数

    T100m_count    ; タイムカウンタ変数

    T1_count    ; 汎用タイムカウンタ変数

    LP_count0    ;汎用ループカウンタ

    LP_count1    ;汎用ループカウンタ

    LP_count3    ;汎用ループカウンタ

    Ts_count    ;サウンド用カウント

    txdata        ; * 送信データ(8ビット)格納用変数

    txdata2        ;2桁目データ

    txdata1        ;1桁目データ

    M_data        ;SLEEP時の保存データ

            ;bit0 機能設定表示中にボタンが押されたら1、押されなければ0のまま。    

            ;bit1 SET-スタート間隔を0は固定、1はランダム

    S_count        ;モード変更のスイッチ押した回数のカウンタ

    R_data        ;ランダム変数

    LCD_WDATA    ;LCD用変数

    LCD_RDATA    ;LCD用変数

    MsgNO        ;メッセージの番号

    DataZ        ;内部OSCの補正値

    COUNTZ

    ENDC

 

;

;**********************************

;    ポートセット、初期化

;**********************************

    org    0        ;プログラム開始アドレス

 

    movlw    b'00000111'    

    movwf    CMCON        ;コンパレータを使用しない

                ;(RA0-RA3はデジタルピンで使用)

 

    bsf    STATUS, RP0    ;◆RP0=1にして、バンク0→1にする

;    movlw    b'00000000'

;    movwf    VRCON        ;CMCONとVRCONをこの設定

                ;にてRA0,RA1,RA2,RA3,RA4をデジタルにて使用可能。

 

    MOVLW    b'00001000'    ; 内部クロックを使用するCLOCK=4MHz のみ

    MOVWF   PCON

 

    movlw    PORT_OUT    ;最初のポートAの入出力設定:RA2(busy)が入力。

                ;その他は出力(液晶のDB4,5,6,7は最初は出力)

 

    movwf    TRISA

 

    movlw    b'00001011'    ;ポートBの入出力設定:RB0,1,3入力、それ以外出力

    movwf    TRISB

    MOVLW    B'00000101'    ;2,1,0:カウントモード指定011:16 100:32 101:64 110:128 

                ;7:    0でプルアップ有効にする--RB0-RB7が全てプルアップ-

    MOVWF    OPTION_REG    ;プリセットカウンタへ出力

 

                ;RS232C設定---

    MOVLW    B'00100110'    ;送信の設定

    MOVWF    TXSTA        ;

    MOVLW    D'25'        ;ボレートの設定(9.6k 高速モード 4MHZ)

    MOVWF    SPBRG        ;    

    bcf    STATUS, RP0    ;◆バンクを元に戻す

 

                ;RS232C設定---

    MOVLW    B'10010000'    ;受信の設定(p.113)

    MOVWF    RCSTA    

 

    movlw    D'10'        ;内臓オシロ使用に対する精度補正値

                ;6から10あたりに調整値があると思われる

    movwf    DataZ        ;------------------------------------------------------------------------------

    

    clrf    PORTB

    bsf        PORTB,4        ;;;;;;;;;LED ON;;;;;;;;;;;

    nop

 

    bsf    PORTA,4        ;バントナルへの信号(オープンドレイン状態))

    nop

 

;LCD設定

    call    T04sWAIT

    call    LCD_INI        ;液晶初期化

    

    call    clear01        ;プログラムバージョン表示

    call    gyou_1S    

    movlw    D'77'

    movwf    MsgNO

    call    MSG01    

 

    bcf    PORTB,4        ;;;;;;;;;LED OFF;;;;;;;;;;

    nop        

 

 

;EEDATA読み込み

    bsf    STATUS,RP0     ;◆ Bank 1

    movlw    00h        ;アドレス指定

    movwf    EEADR

    bsf     EECON1,RD

    movfw    EEDATA

    bcf    STATUS,RP0     ;◆ Bank 0    

    movwf    M_data        

;*******************************

;    メインルーチン

;*******************************

MAIN

    call    gyou_1        ;1行目に"ナガオシ"と表示

    movlw    D'21'

    movwf    MsgNO

    call    MSG01    

    call    gyou_2        ;2行目に"スタート"と表示

    movlw    D'28'

    movwf    MsgNO

    call    MSG01    

    call    gyou_3        ;3行目に"ミジカオシ"と表示

    movlw    D'35'

    movwf    MsgNO

    call    MSG01    

    call    gyou_4        ;4行目に"データ"と表示

    movlw    D'42'

    movwf    MsgNO

    call    MSG01    

 

MAIN_LOOP

;---------------------- スタート準備と信号待ち-----------------------------------

    ;スイッチの確認

    movfw    R_data        ;R_dataに値を加算(疑似ランダム値を入力する)

     addlw    D'162'

    movwf    R_data

    btfsc    PORTB,3        ;タクトスイッチをチェック(0だったらスキップ)

    goto    musen    

    call    T04sWAIT

    call    T04sWAIT

    btfsc    PORTB,3        ;長押しの場合はスキップしてスタートシーケンスへ    

    goto    signal1        ;短押しの場合はデータ要求信号を出す

    goto    START

 

    ;無線信号の確認

musen

    call    RSreceive00

    movfw    txdata

    sublw    '4'

    btfsc    STATUS,Z    ;引き算結果が0でなかったら(Z=0)だったらスキップ

    goto    m_shori        ;引き算結果が0(Z=1)だったらm_shoriに行く

 

    goto    MAIN_LOOP

 

;-------------------------------------------------------------------------------

;スタート************************************************************************

START

    bsf    PORTB,4        ;;;;;;;;;LED ON;;;;;;;;;;;

    nop

;    bcf    PORTA,4        ;指ストップウォッチへの信号(0V信号)

;    nop

 

;------- 無線への出力1(受信側への準備指示"20"を送信)-------

    movlw    "2"        ;---------------------------------------------------

    movwf    txdata2

    movlw    "0"        ;---------------------------------------------------

    movwf    txdata1    

    call    TXDX01

    call    T100mWAIT

    call    T20mWAIT

    call    T20mWAIT

;------- 無線への出力2(受信側への準備指示"20"を送信)-------

    call    TXDX01

    call    T100mWAIT

    call    T20mWAIT    

    call    T20mWAIT

;------- 無線への出力3(受信側への準備指示"20"を送信)-------

    call    TXDX01    

    call    T100mWAIT

    call    T20mWAIT    

    call    T20mWAIT    

;------- 無線への出力4(受信側への準備指示"20"を送信)-------

    call    TXDX01    

    call    T100mWAIT

    call    T20mWAIT    

    call    T20mWAIT    

;------- 無線への出力5(受信側への準備指示"20"を送信)-------

    call    TXDX01    

    call    T100mWAIT

    call    T20mWAIT    

    call    T20mWAIT    

;------- 無線への出力6(受信側への準備指示"20"を送信)-------

    call    TXDX01

    

;----------------音---------------------------

    call    T40mBEEP    ;ピ

    call    T100mWAIT

    btfsc    M_data,1    ;ランダムモードの場合(1)の場合

                ;スキップしない(ピピと鳴る)

    call    T40mBEEP    ;ピ

;---------------------------------------------

    call    T1sWAIT

 

;--------------on your mark---------------------------------------------------

    call    clear01

    call    gyou_1S        ;1行目に"ON YOUR "と表示

    movlw    D'0'

    movwf    MsgNO

    call    MSG01    

    call    gyou_2S        ;2行目に" MARK"と表示

    movlw    D'7'

    movwf    MsgNO

    call    MSG01    

 

;3秒ぴー音

    movlw    D'40'    

    movwf    LP_count1        

bee1

    call    T10mBEEP

    call    T10mWAIT

    call    T10mWAIT

    call    T10mWAIT

    decfsz    LP_count1,f

    goto    bee1

 

;    goto    wait3s    ;****************************************temp******************

    

;ランダムかフィクスを設定---------------------------------------------------------

;モード表示

    clrf    S_count

mode_hyouji

    call    clear01

    call    gyou_1S        ;1行目に"ランダム"か"フィックス"かを表示

    btfss    M_data,1

    goto    fix_hyouji

    movlw    D'49'

    movwf    MsgNO

    call    MSG01

    goto    tugi    

fix_hyouji

    movlw    D'56'

    movwf    MsgNO

    call    MSG01

tugi

    call    gyou_2S        ;2行目指定

    movlw    D'63'        ;モードデスと表示

    movwf    MsgNO

    call    MSG01

 

    call    gyou_3S        ;3行目指定

    movlw    D'70'        ;ヘンコウ?と表示

    movwf    MsgNO

    call    MSG01

 

    call    switchCK    ;スイッチ押されたらM_data,0が1になって帰ってくる。

    movfw    M_data        ;ワークレジスタにM_dataをセット

    btfss    M_data,0    ;M_data,0が1だったらスキップして反転処置をする

    goto    J44        ;ループを抜ける

    xorlw    B'00000010'    ;ビット1を反転する。

    movwf    M_data        ;ワークレジスタデータをM_dataに戻す

    incf    S_count        ;スイッチ押された回数をカウントしする

    goto    mode_hyouji    ;モード表示に戻る

J44

;M_dataを保存する++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    btfss    S_count,0    ;奇数回スイッチが押されてたらデータ変更なので書き込みする。

    goto    wait3s

    movfw    M_data        ;M_dataをwregistorに移してからバンク切り替えする

    bsf    STATUS,RP0    ;Bank 1/////////////////////////

    movwf    EEDATA        ;EEDATAはバンク1で有効

    movlw    00h        ;アドレス指定

    movwf    EEADR

    bsf    EECON1,WREN    ;Enable write

    movlw    55h        ;Unlock write

    movwf    EECON2

    movlw    0AAh

    movwf    EECON2

    bsf    EECON1,WR    ;Start the write

wait999

    btfsc    EECON1,WR

    goto    wait999

    bcf    STATUS,RP0    ;Bank 0////////////////////////////    

 

wait3s

;------3秒待ち-------------------------------------

    call    clear01

    call    T1sWAIT

    call    T1sWAIT

    call    T1sWAIT

 

;----------------1秒ブー音(SET音)-----------------------------

    call    clear01

    call    gyou_3S        ;3行目に" SET"と表示

    movlw    D'14'

    movwf    MsgNO

    call    MSG01    

 

    movlw    D'50'    

    movwf    LP_count1        

bee3

    call    T10mBEEP

    call    T10mWAIT

    decfsz    LP_count1,f

    goto    bee3

    

;0.8秒待ち(信号6回送信分をの0.7秒考慮)---------------

;    call    T04sWAIT

;    call    T04sWAIT

    call    T100mWAIT

 

    ;追加時間待ち

    movlw    D'125'        ;固定時間をLP_count1にセット

    movwf    LP_count1        

    btfss    M_data,1    ;ランダムモード(1)の場合スキップしてランダム処理する

    goto    wait2

    movfw    R_data        ;ランダムの場合ランダム時間(R_data)をLP_count1にセット

    movwf    LP_count1    ;

wait2

    call    T2_5mWAIT    ;2.5mmsの時間待ち

    decfsz    LP_count1,f

    goto    wait2

 

;DataZ調整時は、"7"を選択"1"から"5"はコメントにする。調整後は"1"から"5"に戻す。

;----------------計測開始を送信("16"を送信)------------

    movlw    "1"

    movwf    txdata2

    movlw    "6"

    movwf    txdata1

    call    TXDX01    

    call    T100mWAIT

    call    T20mWAIT

    call    T20mWAIT

;----------------計測開始を送信("15"を送信)------------

    movlw    "5"

;    movlw    "7"    ;------------------------------------------------

    movwf    txdata1

    call    TXDX01        

    call    T100mWAIT

    call    T20mWAIT

    call    T20mWAIT    

;----------------計測開始を送信("14"を送信)------------

    movlw    "4"

;    movlw    "7"    ;-------------------------------------------------

    movwf    txdata1

    call    TXDX01        

    call    T100mWAIT

    call    T20mWAIT

    call    T20mWAIT    

;----------------計測開始を送信("13"を送信)------------

    movlw    "3"

;    movlw    "7"    ;--------------------------------------------------

    movwf    txdata1

    call    TXDX01        

    call    T100mWAIT

    call    T20mWAIT

    call    T20mWAIT

;----------------計測開始を送信("12"を送信)------------

    movlw    "2"

;    movlw    "7"    ;----------------------------------------------------

    movwf    txdata1

    call    TXDX01        

    call    T100mWAIT

    call    T20mWAIT

    call    T20mWAIT

;----------------計測開始を送信("11"を送信)------------

    movlw    "1"

;    movlw    "7"    ;-----------------------------------------------------

    movwf    txdata1

    call    TXDX01

;---------127ms待ち-------送信から受信までにかかる時間

    movlw    D'32'         

    movwf    LP_count0        

LOOPcc                

    call    T1mWAIT        

    decfsz    LP_count0,f    

    goto    LOOPcc

 

    bcf    PORTA,4    ;バントナルへの信号 ;0V

    nop    

 

    movlw    D'95'         

    movwf    LP_count0        

LOOPcd                

    call    T1mWAIT        

    decfsz    LP_count0,f    

    goto    LOOPcd

    

    

;----------------------------

    bcf    PORTB,4    ;;;;;;;;;LED OFF;;;;;;;;;;;

    nop

    

    call    T40mBEEP    ;40msの間音を出す

    call    T40mBEEP    ;40msの間音を出す

 

    bsf    PORTA,4        ;バントナルへの信号 オープンドレイン信号

    nop

    nop

    nop

    call    T1mWAIT    

    call    T1mWAIT        

    

    call    clear01

 

;    call    T04sWAIT    ;********************************temp*********************

;    call    T04sWAIT

;    call    T04sWAIT

;    call    T04sWAIT    

;    call    T04sWAIT

;    call    T04sWAIT

;    call    T04sWAIT

;    call    T04sWAIT    

;    goto    START        ;*******************************temp**********************

    

    goto    MAIN

 

;================================================

;             表示指示信号送信("3"を送信)

;================================================

signal1

    ;LCDクリア-------------------------------------

    movlw    B'00000001'    ;液晶クリア

    movwf    LCD_WDATA

    call    LCD_SET

 

 

    ;----------------表示指示信号送信("30"を送信)------------

    movlw    "3"

    movwf    txdata2

    movlw    "0"

    movwf    txdata1    

    call    TXDX01    

 

    goto    MAIN

 

;-------タイム表示---------------------------------------------------------------

;--------識別番号により表示位置を変える-------------------------------------------

m_shori

    call    RSreceive1    ;識別番号をよむ(1,2,3,4のいずれか)

 

    movfw    txdata

    sublw    "1"

    btfss    STATUS,Z

    goto    kiban2

    call    gyou_1S        ;1行目7列位置番号

    goto    hyouji

 

kiban2

    movfw    txdata

    sublw    "2"

    btfss    STATUS,Z

    goto    kiban3

    call    gyou_2S        ;2行目7列位置番号

    goto    hyouji

 

kiban3

    movfw    txdata

    sublw    "3"

    btfss    STATUS,Z

    goto    kiban4

    call    gyou_3S        ;3行目7列位置番号

    goto     hyouji

 

kiban4

 

    call    gyou_4S        ;4行目7列位置番号

 

;RS232Cからデータを読んで表示する-------------------------

hyouji                

    movfw    txdata    ;識別番号表示

    movwf    LCD_WDATA

    call    LCD_DATA_WRITE

    call    RSreceive1    ; ":"後受信---------------------------

 

    movlw    20H        ;1文字スペース

    movwf    LCD_WDATA

    call    LCD_DATA_WRITE

 

    call    R23_LCD        ;A信号(左センサ)の上位データから読みLCDに書き込む

    call    R23_LCD

    call    RSreceive1    ;":"後受信----------------------------

    movlw    2EH        ;小数点表示

    movwf    LCD_WDATA    ;

    call    LCD_DATA_WRITE    ;

    call    R23_LCD

    call    R23_LCD

    call    RSreceive1    ;":"後受信----------------------------

 

    movlw    20H        ;1文字スペース

    movwf    LCD_WDATA

    call    LCD_DATA_WRITE

 

    call    R23_LCD        ;B信号(右センサ)の上位から読みLCDに書き込む

    call    R23_LCD

    call    RSreceive1    ;":"後受信---------------------------------

    movlw    2EH        ;小数点表示

    movwf    LCD_WDATA    ;

    call    LCD_DATA_WRITE    ;

    call    R23_LCD

    call    R23_LCD

 

    ;LED点滅

    bsf        PORTB,4    ;LED ONとする

    call    T20mWAIT

    bcf        PORTB,4

    call    T20mWAIT

    bsf        PORTB,4    ;LED ONとする

    call    T20mWAIT

    bcf        PORTB,4

    goto     MAIN

;---------------------------------------------------------------

;-------------------------------

TXDX01

    movlw    'T'

    movwf    txdata        ;文字データを転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movlw    'X'

    movwf    txdata        ;文字データを転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movlw    'D'

    movwf    txdata        ;文字データを転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movlw    'A'

    movwf    txdata        ;文字データを転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movfw    txdata2        ;txdata2 ******************************************

    movwf    txdata        ;txdata2 を転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movfw    txdata1        ;txdata1 ******************************************

    movwf    txdata        ;txdata1 を転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movlw    0dh

    movwf    txdata        ;文字データを転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行

    movlw    0ah

    movwf    txdata        ;文字データを転送用変数にいれて

    call    RSsend        ;RS232C出力ルーチン実行    

    return

 

;-----RSR232Cデータを読み、LCDに出力する

R23_LCD

    call    RSreceive1    ;データ受信

    movfw    txdata

    movwf    LCD_WDATA

    call    LCD_DATA_WRITE

    return

;------------------------------------------------

 

 

;================================================

;            RS232C 受信ルーチン

;              txdataに取り込み  

;================================================

RSreceive00      ;信号なければ、0として直ちに戻る

        ;”:”以外だったら0として直ちに戻る。

        ;":"だったら次の文字を持って帰る(10msのうち信号なければ戻る)。

    call RSreceive

    movfw    txdata

    sublw    ':'

    btfss    STATUS,Z    ;引き算結果が0(z=0で一致)だったらスキップ

    goto    endRS    

 

    ;":"の場合の処理

    call    RSreceive1    ;":"の次のデータを持って帰る

    goto    endff

endRS

    movlw    '/'        ;データが”:”前であれば、"/"に変換してから戻る

    movwf    txdata    

endff

    return

 

;----------------------------------------------------------------

RSreceive    ;データがなければ、"/"をいれて戻る

    movlw    '/'

    movwf    txdata        ;データには/を入れておく

    btfss    PIR1,RCIF    ;データがなければ戻る

    return

    goto    Tugi_shori    ;あれば、Tugi_shoriにジャンプ

 

RSreceive1    ;":"後の処理(データがあるはずなので、来るまで待つ。

        ;ただし6msまってもデータがこなければ戻る)

    movlw    D'20'

    movwf    COUNT4

    movlw    '/'

    movwf    txdata        ;データには0を入れておく

    btfsc    PIR1,RCIF    ;データがなければスキップ。あればRSreseive2で次の処理

    goto    Tugi_shori

    call    T01mWAIT

    call    T01mWAIT

    call    T01mWAIT    

    decfsz    COUNT4        ;0になったらリターン。でなければRSreceive1に戻る

    goto    RSreceive1

    return

 

Tugi_shori    

    btfss    RCSTA,OERR    ;データがあればオーバーランチェク

    goto    next_ck

    bcf    RCSTA,CREN    ;エラーがあれば解除し戻る

    bsf    RCSTA,CREN

    return    

next_ck                ;フレーミングエラーチェック

    btfss    RCSTA,FERR

    goto    receive_txdata

    movfw    RCREG        ;エラーがあれば解除し戻る

    return            ;

receive_txdata

    movfw    RCREG

    movwf    txdata

 

    return

;================================================

;             RS232C 送信ルーチン

;              txdataの値を送信  

;================================================

 

RSsend

    btfss    PIR1,TXIF

    goto    RSsend

    movfw    txdata

    movwf    TXREG

    return

 

;===================================================

;       液晶関連サブルーチン

;===================================================

; 初期化サブルーチン

LCD_INI

    bcf        D_E        ;

    bcf        D_RW        ;write:R/W=0

    bcf        D_RS        ;Command:RS=0

    call    T20mWAIT        ;15ms以上待つ

 

    movlw    B'00110000'    ;Function set(1回目)

    movwf    LCD_WDATA

    call    LCD_SEND_8BITMODE

    call    T1mWAIT        ; 1[ms]待つ 4.1ms以上待つ

    call    T1mWAIT        ; 1[ms]待つ

    call    T1mWAIT        ; 1[ms]待つ

    call    T1mWAIT        ; 1[ms]待つ

    call    T1mWAIT        ; 1[ms]待つ

 

    movlw    B'00110000'    ;Function set (2回目)

    movwf    LCD_WDATA

    call    LCD_SEND_8BITMODE

    call    T01mWAIT        ;0.1[ms]待つ

 

    movlw    B'00110000'    ;Function set (3回目:8bitモードに設定)

    movwf    LCD_WDATA

    call    LCD_SEND_8BITMODE

    call    T01mWAIT        ;0.1[ms]待つ

 

    movlw    B'00100000'    ;Function set (4bitモードに設定)

    movwf    LCD_WDATA

    call    LCD_SEND_8BITMODE

    call    T01mWAIT        ;0.1[ms]待つ

 

    ;4bitモード(上位4bitに加え、下位4bitも有効)

    movlw    B'00101100'    ;0,0,function=1, DL=0(4bit mode), N=1(2行),F=1(5*10dot),*,*

    movwf    LCD_WDATA

    call    LCD_SET_NB    ;BUSYチェックはしない

    call    T01mWAIT        ;0.1[ms]待つ

 

    movlw    B'00001000'    ;0,0,0,0,表示ON/OFF設定=1,Display off D=0,C=0(カーソルON),B=0(カーソル点滅OFF)

    movwf    LCD_WDATA

    call    LCD_SET

    

    movlw    B'00001110'    ;0,0,0,0,表示ON/OFF設定=1,Display on D=1,C=1(カーソルOFF),B=0(カーソル点滅Off)

    movwf    LCD_WDATA

    call    LCD_SET

    

    movlw    B'00000110'    ;0,0,0,0, 0,Entryモード=1,インクリメントI/D=1,表示シフトS=0

    movwf    LCD_WDATA

    call    LCD_SET

 

    return

 

;++++++++ LCD4BITモードでの書き込み操作+++++++++++++++++++++

;---------------LCD設定、busyチェックしない

LCD_SET_NB

    bcf    D_RS        ;RS=0:LCD設定

    goto    LCD_SEND_4BITMODE

 

;---------------LCD設定、busyチェックする

LCD_SET

    call    LCD_BUSY

    bcf    D_RS        ;RS=0:LCD設定

    goto    LCD_SEND_4BITMODE

 

;---------------LCDにデータ送信(busyチェックする)

LCD_DATA_WRITE

    call    LCD_BUSY

    bsf    D_RS        ;RS=1:DATA操作設定

 

;++++++++++++++4ビットモードでLCD_WDATA1バイト送る+++++++++++++

LCD_SEND_4BITMODE

    bcf    D_DB4

    bcf    D_DB5

    bcf    D_DB6

    bcf    D_DB7

    btfsc    LCD_WDATA,4

    bsf    D_DB4

    btfsc    LCD_WDATA,5

    bsf    D_DB5        

    btfsc    LCD_WDATA,6

    bsf    D_DB6

    btfsc    LCD_WDATA,7

    bsf    D_DB7

    bsf    D_E        ; E信号を 0→1→0にしてデータ送信

    bcf    D_E        ; 

 

    bcf    D_DB4

    bcf    D_DB5

    bcf    D_DB6

    bcf    D_DB7

    btfsc    LCD_WDATA,0

    bsf    D_DB4

    btfsc    LCD_WDATA,1

    bsf    D_DB5        

    btfsc    LCD_WDATA,2

    bsf    D_DB6

    btfsc    LCD_WDATA,3

    bsf    D_DB7

    bsf    D_E        ; E信号を 0→1→0にしてデータ送信

    bcf    D_E        ; 

    return

 

;;------  8ビットモードでLCD_WDATAの上位4ビットを送る--------

LCD_SEND_8BITMODE

    bcf    D_DB4

    bcf    D_DB5

    bcf    D_DB6

    bcf    D_DB7

 

    btfsc    LCD_WDATA,4

    bsf    D_DB4

    btfsc    LCD_WDATA,5

    bsf    D_DB5        

    btfsc    LCD_WDATA,6

    bsf    D_DB6

    btfsc    LCD_WDATA,7

    bsf    D_DB7

 

    bsf    D_E        ; E信号を 0→1→0にしてデータ送信

    bcf    D_E        ; 

 

    return

 

;-----------液晶からデータを読む

LCD_READ

    clrf    LCD_RDATA

 

    bsf    D_E        ;E high

    btfsc    D_DB7        ; 上位4ビットを読む

    bsf    LCD_RDATA,7

    btfsc    D_DB6

    bsf    LCD_RDATA,6

    btfsc    D_DB5

    bsf    LCD_RDATA,5

    btfsc    D_DB4

    bsf    LCD_RDATA,4

    bcf    D_E        ;E low

 

    nop

    nop

 

    bsf    D_E        ;E high

    btfsc    D_DB7        ; 下位4ビットを読む

    bsf    LCD_RDATA,3

    btfsc    D_DB6

    bsf    LCD_RDATA,2

    btfsc    D_DB5

    bsf    LCD_RDATA,1

    btfsc    D_DB4

    bsf    LCD_RDATA,0

    bcf    D_E        ;E low

    

    return

 

;--------------液晶のbusyフラグチェック

LCD_BUSY

    bsf    STATUS,RP0    ;◆バンク 1

    movlw    PORT_IN        ; DB4~DB7のピンを入力にする

    movwf    TRISA

    bcf    STATUS,RP0    ;◆バンク0

    bcf    D_RS        ;RS=0:データ以外の操作設定

    bsf    D_RW        ;readモードに設定

loop_LCD

    call    LCD_READ

    btfsc    LCD_RDATA,7    ;busyフラグチェック(1はbusy)

    goto    loop_LCD    ;busy時loopくりかえし

 

    bcf    D_RW        ;writeモードに設定

    bsf    STATUS,RP0    ;◆バンク1

    movlw    PORT_OUT    ;DB4~DB7のピンを出力にもどす

    movwf    TRISA        ;

    bcf    STATUS,RP0    ;◆バンク0

 

    return

 

gyou_1

    movlw    B'10000000'    ;1行目左端位置番号----------------------

    movwf    LCD_WDATA

    call    LCD_SET

    return

gyou_2

    movlw    B'11000000'    ;2行目左端位置番号

    movwf    LCD_WDATA

    call    LCD_SET

    return

gyou_3

    movlw    B'10010100'    ;3行目左端位置番号

    movwf    LCD_WDATA

    call    LCD_SET

    return

gyou_4

    movlw    B'11010100'    ;4行目左端位置番号

    movwf    LCD_WDATA

    call    LCD_SET

    return

 

gyou_1S

    movlw    B'10000111'    ;1行目左7列位置番号---------------------

    movwf    LCD_WDATA

    call    LCD_SET

    return

gyou_2S

    movlw    B'11000111'    ;2行目左7列位置番号

    movwf    LCD_WDATA

    call    LCD_SET

    return

gyou_3S

    movlw    B'10011011'    ;3行目左7列位置番号

    movwf    LCD_WDATA

    call    LCD_SET

    return

gyou_4S

    movlw    B'11011011'    ;4行目左7列位置番号

    movwf    LCD_WDATA

    call    LCD_SET

    return

 

clear01

    movlw    B'00000001'    ;液晶クリア

    movwf    LCD_WDATA

    call    LCD_SET

    return

 

;-------------------------------------------------------------------------------

;******4秒間スイッチの押下を待つ。 押されたら M_data,0を1にする****************

switchCK

    bcf    M_data,0

    movlw    D'40'

    movwf    LP_count3    

loop99

    call    T100mWAIT

    btfss    PORTB,3        ;

    goto    hyoujiX

    decfsz    LP_count3

    goto    loop99

    goto    jump99

hyoujiX

    bsf    M_data,0    ;スイッチが押されたことを記録する。

    call    T10mBEEP    ;10msの間音を出す

    call    T100mWAIT

jump99    

    return

 

;=================================================

;       音サブルーチン

;=================================================

;--;4kHzのビープ音を10ms継続--------------------------

; 4kHz=.25ms 4Mhz=.00025ms 1STEP=.00025*4=.001ms 250STEPで.25mSとなる  

T10mBEEP    

    movlw    D'40'         ;1

    movwf    Ts_count    ;1

    goto    LOOP71

 

;--;4kHzのビープ音を40ms継続---------------------------

; 4kHz=.25ms 4Mhz=.00025ms 1STEP=.00025*4=.001ms 250STEPで.25mSとなる  

T40mBEEP    

    movlw    D'160'         ;1

    movwf    Ts_count    ;1

 

LOOP71

    bsf        PORTA,3    ;1 送信ポートGP2をhighに

    call    TIME100STEP    ;100

    call    TIME10STEP    ;10

    call    TIME10STEP    ;10    

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    bcf    PORTA,3        ; 1 送信ポートGP2をLOWに

    call    TIME100STEP    ; 100

    call    TIME10STEP    ; 10

    call    TIME10STEP    ; 10    

    nop                    ; 1

    decfsz    Ts_count,f    ; 1(2)

    goto    LOOP71        ; 2

    return            ;2

 

;=================================================

;       タイマサブルーチン

;=================================================

;-----------0.5msecのタイムループ-------------------

T01mWAIT            ;2

    movlw    D'23'        ;1

    movwf    COUNT1        ;1

LOOP1

    nop            ;1

    decfsz    COUNT1,f    ;1  2  最後は 2 

    goto    LOOP1        ;2

    nop            ;1

    nop            ;1

    return            ;2   4+4*24-1+4=103  μs

 

;-----------1msecのタイムループ------------------

T1mWAIT                ;2

    movlw    D'120'        ;1

    movwf    COUNT2        ;1

LOOP2

    goto    $+1        ;2

    goto    $+1        ;2

    nop            ;1

    decfsz    COUNT2,f    ;1  最後は 2

    goto    LOOP2        ;2   4+8*120-1=963

 

    movfw    DataZ        ;1  10がのみなる------補正部分部-------------------------------------------

    movwf    COUNTZ        ;1

LOOPZ    

    decfsz    COUNTZ,f    ;1 最後は 2

    goto    LOOPZ        ;2    2+3*10-1=31

 

    goto    $+1        ;2

    goto    $+1        ;2

    return            ;2               6

                ;         合計1000

 

                ;----------- 2.5mS待つ    1STEP=.00025*4=.001ms=1μs

T2_5mWAIT                ;2 (call分)

    movlw    D'23'        ;1

    movwf    T2m_count    ;1

T2mloop

    call    TIME100STEP    ;100

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    decfsz  T2m_count,F    ;1(2) 

    goto    T2mloop        ;2            4+107*22*108=2466

    return                ;  2

 

;---------- 10.000mS待つ    1STEP=.00025*4=.001ms=1μs

T10mWAIT                ;2 (call分)

    movlw    D'97'        ;1

    movwf    T10m_count    ;1

T10mloop

    call    TIME100STEP    ;100

    decfsz  T10m_count,F    ;1(2)

    goto    T10mloop    ;2        4+103*96+108=10000

    nop            ;   1

    nop            ;   1

    nop            ;   1

    nop            ;   1

    return            ;   2            

 

;-----------約20msecのタイムループ-------------------

T20mWAIT

    movlw    D'20'

    movwf    COUNT3

LOOP3

    call    T1mWAIT    

    decfsz    COUNT3,f

    goto    LOOP3

    return    

 

;----------- 約100ms待つ

T100mWAIT

    movlw    D'100'        ;

    movwf    T100m_count    ;

LOOP100m

    call    T1mWAIT        ;

    decfsz    T100m_count,f

    goto    LOOP100m

    return            ;

 

;-----------約0.4s待つ

T04sWAIT                ;2 (call分)

    movlw    D'40'        ;1

    movwf    T1_count    ;1 

T04sloop

    call    T10mWAIT    ;10000

    decfsz  T1_count,F    ;1(2)  

    goto    T04sloop    ;2            4+10003*39+10004=400121

    return                 ;  2

 

;-----------約1s待つ

T1sWAIT                ;2 (call分)

    movlw    D'100'        ;1

    movwf    T1_count    ;1

T1sloop    

    call    T10mWAIT    ;10000

    decfsz  T1_count,F    ;1(2)

    goto    T1sloop        ;2

    return            ;  2

 

;-----------10STEP待つ

;10STEP(10μs=0.01ms) 

TIME10STEP            ;2 (call分)

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    return            ;2 

 

;-----------100STEP待つ

;100STEP(0.1ms) 

TIME100STEP                ;2  (call分)

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    call TIME10STEP        ;10

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    nop            ;1

    return            ;2 

    

 

;**********************文字列処理****************************************

;MsgNO番号に応じたメッセージを表示する-MgsNOに番号を入れてからコールする------------

MSG01

    movlw    D'7'

    movwf    LP_count0

loop_x01    

    movfw    MsgNO        ;PCLに加算する数をワークレジスタに入れサブルーチンをコールする    

    call    MOJI_ALL

    movwf    LCD_WDATA

    call    LCD_DATA_WRITE

    incf    MsgNO

    decfsz    LP_count0    ;7個データ処理したら戻る(文字数は7個ずつに限定)

    goto    loop_x01    

    return

 

;*******************************文字列******************************************

 

    org    0x390

MOJI_ALL

    clrf    PCLATH

    bsf        PCLATH,0

    bsf        PCLATH,1

    addwf    PCL,f

;0

    retlw    "O"

    retlw    "N"

    retlw    " "

    retlw    "Y"

    retlw    "O"

    retlw    "U" 

    retlw    "R"

;7

    retlw    " "

    retlw    "M"

    retlw    "A"

    retlw    "R" 

    retlw    "K"

    retlw    " "

    retlw    " "

;14

    retlw    " "

    retlw    "S"

    retlw    "E"

    retlw    "T"

    retlw    " "

    retlw    " "

    retlw    " "

;21

    retlw    "ナ"

    retlw    "カ"

    retlw    "゙"

    retlw    "オ"

    retlw    "シ"

    retlw    " "

    retlw    " "

;28

    retlw    B'01111110'

    retlw    "ス"

    retlw    "タ"

    retlw    "-"

    retlw    "ト"

    retlw    " "

    retlw    " "

;35

    retlw    "ミ"

    retlw    "シ"

    retlw    "゙"

    retlw    "カ"

    retlw    "オ"

    retlw    "シ"

    retlw    " "

;42

    retlw    B'01111110'

    retlw    "テ"

    retlw    "゙"

    retlw    "-"

    retlw    "タ"

    retlw    " "

    retlw    " "

;49

    retlw    "ラ"

    retlw    "ン"

    retlw    "タ"

    retlw    "゙"

    retlw    "ム"

    retlw    " "

    retlw    " "

;56

    retlw    "フ"

    retlw    "ィ"

    retlw    "ッ"

    retlw    "ク"

    retlw    "ス"

    retlw    " "

    retlw    " "

;63

    retlw    "モ"

    retlw    "-"

    retlw    "ト"

    retlw    "゙"

    retlw    "テ"

    retlw    "゙"

    retlw    "ス"

 

;70

    retlw    "ヘ"

    retlw    "ン"

    retlw    "コ"

    retlw    "ウ"

    retlw    "?"

    retlw    " "

    retlw    " "    

 

;77

    retlw    "v"

    retlw    "1"

    retlw    "9"

    retlw    "0"

    retlw    "1"

    retlw    "2"

    retlw    "0"        

    end

 

 

 

 

(2)検知装置プログラム

 

;******************************************************

; 短距離通過タイム計測システム(検知装置プログラム)

;                                                               

;  VOUT     SCL                                 SDA      LED     識別0*    識別1*  

;  RA1      RA0      OSC      OSC      Vdd      RB7      RB6      RB5      RB4  

;  18       17       16       15       14       13       12       11       10 

;

;   1        2        3        4        5        6        7        8        9 

;  RA2      RA3      RA4      RA5      Vss      RB0      RB1      RB2      RB3

; busy *   signalB*  signalA*  MCLR                       RX*      TX       

;                                                    

;  * は入力信号

;******************************************************

;v180716

;v180602からの変更点

;通信エラー防止するため通信回数を複数回に変更

;最初の信号から最後の信号までの待ち時間を0.16sから0.20sに変更

;スタート制御装置のv180707とセットで使用する

    

    LIST P=16F648A

    #INCLUDE P16F648A.INC

 

; 内蔵オシロ(HSにすると不安定) 定電圧監視    内部でプルアップ

    __CONFIG  _XT_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _MCLRE_OFF

 

;******************************

; 変数レジスタ定義

;******************************

    CBLOCK 020h

    T1m_count ; タイムカウンタ変数

    T20m_count         ; タイムカウンタ変数

    T100m_count         ; タイムカウンタ変数

    LP_count         ;ループカウンタ変数

    LP_countR ;ループカウンタ変数

    LP_kiban         ;ループカウンタ変数

    txdata ; 無線への送信データ(8ビット)格納用変数

    txdata2 ;無線受信データ2桁目の値

    txdata1 ;無線受信データ2桁目の値

    f_sig         ; 信号の状態を表す 1:Aセンサ通過済 2:Aセンサ補正済

        ;3:Bセンサ通過済, 4:Bセンサ補正済 5:RS232処理中

;6:donカウンタ作動

    kiban         ; 識別番号'000000**'下2桁が有効

    tx_bit         ;8ビットのシフト繰り返し用カウンタ

    txdatax         ;液晶へ送信する文字データ

    txdataq         ;液晶の制御信号用データ

    h_count ;液晶へのメッセージの送信数カウンタ

    MsgNO ;液晶へ送信するメッセージの位置番号

    COUNT1 ;タイマ用カウント

    COUNT4 ;汎用カウンタ

    COUNTSS ;don用カウンタ

 

    s_work ;割込み退避データ

    s_status ;割込み退避データ

    s_pclath ;割込み退避データ

 

    COUNT_INT ;割込みで使用する汎用カウンタ

 

    d000 ;時間データ

    d001

    d002

    d003

    d004

 

    da00 ;aの時間データ

    da01

    da02

    da03

    da04

 

    db00 ;bの時間データ

    db01

    db02

    db03

    db04

 

    e000 ;補正で使用する一時的時間データ

    e001

    e002

    e003

    e004

 

    A_00 ;センサ信号の変化記録変数(信号が0→1を見極めるため)

    A_count ;立ち上がり信号が入った時の時間の記録変数

    At_count ;a信号の最初のセンサ信号受信からの経過時間カウント

    B_00 ;センサ信号の変化記録変数(信号が0→1を見極めるため)

    B_count ;立ち上がり信号が入った時の時間の記録変数

    Bt_count ;a信号の最初のセンサ信号受信からの経過時間カウント

    E_count ;補正値(5ms×E_countが補正時間)

    ENDC

 

    org 0 ;プログラム開始アドレス

    goto main0

 

;*****割込処理(4MHz水晶発振,0.01s間隔用)*****

    org 4

    ;4   ;割込みによるステップ数=2

    ;+TMR0書き込み後のカウントアップなしステップ数=2

    bcf INTCON,TMR0IF     ;1    ;タイマ割込フラグを消す

;------退避

    movwf      s_work     ;1

    swapf      STATUS,w     ;1

    clrf        STATUS     ;1

    movwf      s_status     ;1

    movfw      PCLATH     ;1

    movwf      s_pclath     ;1

    clrf PCLATH     ;1 

    movlw D'14'     ;1

    movwf COUNT_INT   ;1 14 STEP

LOOP_INT

    nop ;1  1

    decfsz COUNT_INT,f ;1  2

    goto LOOP_INT    ;2  0  1+1+2=4 最後は 1+2+0=3 

 

    nop     ;1  

    movlw D'179'     ;1

    movwf TMR0     ;1 1+1+1=3step

    

    ; 1STEP=1/4000000*4*1000=.001ms

    ; プリスケーラ:64、TMR0入力値:179

    ; 64*(256-179)=4928

    ; 14+4*14-1+3=   72

    ; .001*64*(256-179)+.001*(14+4*14-1+3)=5ms=.005s

 

;------処理開始--------------

;-------タイマのカウント---------

    bsf PORTB,3 ;-----CK用----------------------

;A信号の補正処理

    btfsc f_sig,2 ;すでに処理済みの場合(=1)はBBに飛ぶ。

    goto BB

    btfss PORTA,4 ;センサ信号ありだったらスキップして次の処理。

    goto endA

    ;補正処理の開始

    bsf f_sig,1 ;「1回以上信号受信済」とする

    bsf A_00,0 ;信号ありとし、0ビット目を1にする

    btfsc A_00,1 ;1ビットが0だったら(前回5ms前信号がなしの場合)

;スキップして仮カウントのAt_countからA_countに記録

    goto endA

    movfw At_count ;センサ0⇒1だった場合At_countの値をA_countに代入

;(0⇒1の場合なら何回でも代入処理する)

    movwf A_count

endA

    bcf STATUS,C

    rlf A_00 ;Aを「左回り」して、0ビット目を1ビット目に移動する。

    btfsc f_sig,1 ;1度でも受信ある場合At_countをカウントアップ

    incf At_count ;At_countをカウントアップ

    btfss At_count,5 ;40(32+8)カウント(0.2s)経過したらタイムアップとし

    goto BB ;スキップして補正処理に移る

    btfss At_count,3 ;------------------------------------------------

    goto BB ;-------------------------------------------------    

 

    ;Aの補正処理

    bcf STATUS,C ;時間差を1/4にする(右シフトを2回する)。

    rrf A_count

    bcf STATUS,C

    rrf A_count

 

    movfw A_count

    BTFSC STATUS,Z ;A_countが0(Z=0)であれば、shoriAまでジャンプ

    goto shoriA

    movwf E_count ;A_countの値をE_countに代入

    movfw da00

    movwf e000

    movfw da01

    movwf e001

    movfw da02

    movwf e002

    movfw da03

    movwf e003

    movfw da04

    movwf e004

 

    call hosei ;補正計算(E_count分を+1する)

 

    movfw e000

    movwf da00

    movfw e001

    movwf da01

    movfw e002

    movwf da02

    movfw e003

    movwf da03

    movfw e004

    movwf da04

shoriA

    bsf f_sig,2 ;処理済みとする

 

BB

;B信号の補正処理

    btfsc f_sig,4 ;すでに処理済みの場合(=1)は、CCに飛ぶ。

    goto CC

    btfss PORTA,3 ;センサ出力確認 信号ありだったらスキップし次の処理

    goto endB

    ;補正処理の開始

    bsf f_sig,3 ;「1回以上信号受信済」とする

    bsf B_00,0 ;信号ありとし、0ビット目を1にする

    btfsc B_00,1 ;1bit目が0だったら(前回5ms前信号がなしの場合)

;スキップして、仮カウントのBt_countからB_countに記録する

    goto endB

    movfw Bt_count ;センサが0⇒1だった場合Bt_countの値をB_countに代入

;(0⇒1の場合なら何回でも代入処理する)

    movwf B_count

endB

    bcf STATUS,C

    rlf B_00 ;Aを「左回り」して、0ビット目を1ビット目に移動

    btfsc f_sig,3 ;1度でも受信あるのばあいはジャンプせず

    incf Bt_count ;Bt_countをカウントアップ

    btfss Bt_count,5 ;40カウント(0.20s)経過したらタイムアップでスキップ

    goto CC ;

    btfss Bt_count,3 ;-----------------------------------------------------

    goto CC ;-----------------------------------------------------

    

    ;Bの補正処理

    bcf STATUS,C ;時間差を1/4にする(右シフトを2回する)。

    rrf B_count

    bcf STATUS,C

    rrf B_count

 

    movfw B_count

    BTFSC STATUS,Z ;A_countが0(Z=0)であれば、shoriAまでジャンプ

    goto shoriB

    movwf E_count ;A_countの値をE_countに代入

    movfw db00

    movwf e000

    movfw db01

    movwf e001

    movfw db02

    movwf e002

    movfw db03

    movwf e003

    movfw db04     

    movwf e004

 

    call hosei ;補正計算(E_count分を+1する)

 

    movfw e000

    movwf db00

    movfw e001

    movwf db01

    movfw e002

    movwf db02

    movfw e003

    movwf db03

    movfw e004

    movwf db04

shoriB

    bsf f_sig,4 ;処理済みとする

 

CC

 

    bcf PORTB,3 ;--------------------CK用----------------------

 

;-------------------時間カウント処理---------------------------------------------

    incf d000 ;0005秒のカウント

    movfw d000

    sublw D'2'

    BTFSS STATUS,Z

    goto ENDCAL

    clrf d000

 

    incf d001 ;0.01秒のカウント

    movfw d001

    sublw D'3'

    BTFSS STATUS,Z

    bcf PORTB,6 ;LEDOFFとする(1秒カウントLEDを0.3秒後にOFFにする)

    movfw d001

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDCAL

    clrf d001

 

    incf d002 ;0.1秒のカウント

    movfw d002

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDCAL

    clrf d002

 

    bsf PORTB,6 ;LED ON

    incf d003 ;1秒のカウント

    movfw d003

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDCAL

    clrf d003

 

    incf d004 ;10秒のカウント

    movfw d004

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDCAL

    clrf d004

ENDCAL

 

    btfss f_sig,5 ;タイム表示オン(1)の場合スキップ。

    goto endTIMER

 

acheck

;A信号表示前処理

    BTFSC f_sig,1 ;A_OFFの場合スキップ

    goto bcheck ;  抜ける

    movfw d001 ;処理済みでなければ、元データをaデータにコピー

    movwf da01

    movfw d002

    movwf da02

    movfw d003

    movwf da03

    movfw d004

    movwf da04

 

bcheck

;B信号表示前処理

    BTFSC f_sig,3 ;B_OFFの場合スキップ

    goto ccheck ;  抜ける

    movfw d001 ;処理済みでなければ、元データをbデータにコピー

    movwf db01

    movfw d002

    movwf db02

    movfw d003

    movwf db03

    movfw d004

    movwf db04

 

ccheck

 

    btfsc PIR1,RCIF ;RSのデータがなければスキップ--------------------

    goto endTIMER

 

;A表示

    btfsc d000,0 ;0の場合、スキップしてAの表示処理

    goto bhyouji

 

    ;A表示のアドレス指定

    movlw B'10000000' ;制御指示

    movwf txdataq

    call TX

    movlw b'10000000' ;アドレス指定

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    call TIME10STEP ;10μs時間待ち

    call TIME10STEP ;10μs時間待ち

 

    ;表示

    ;4桁目表示

    movfw da04 ;4桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

    ;3桁目表示

    movfw da03 ;3桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

 

    btfsc PIR1,RCIF ;RSのデータがなければスキップ----------------------

    goto endTIMER

 

 

    ;"."のデータを処理

    movlw "." ;"."のデータを処理

    movwf txdatax

    call TXx

    ;2桁目表示

    movfw da02 ;2桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

    ;1桁目表示

    movfw da01 ;1桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

 

    ;補正値表示

    movfw A_count ;補正値データを表示------------------

    addlw 60H

    movwf txdatax

    call TXx

 

 

bhyouji

;b表示

    btfss d000,0 ;1の場合、スキップして表示処理

    goto endTIMER

    ;b表示のアドレス指定

    movlw B'10000000' ;制御指示

    movwf txdataq

    call TX

    ; movlw b'11000011' ;アドレス指定

    movlw b'11000010' ;アドレス指定

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    call TIME10STEP ;10μs時間待ち

    call TIME10STEP ;10μs時間待ち

 

    ;表示

    ;4桁目表示

    movfw db04 ;4桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

    ;3桁目表示

    movfw db03 ;3桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

 

    btfsc PIR1,RCIF ;RSのデータがなければスキップ---------------------

    goto endTIMER

 

    ;"."のデータを処理

    movlw "." ;"."のデータを処理

    movwf txdatax

    call TXx

    ;2桁目表示

    movfw db02 ;2桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

    ;1桁目表示

    movfw db01 ;1桁目のデータを処理

    addlw 30H

    movwf txdatax

    call TXx

    ;補正値表示

    movfw B_count ;補正値データを処理------------------

    addlw 60H

    movwf txdatax

    call TXx

 

endTIMER

    ;----退避戻し

    movfw s_pclath

    movwf PCLATH

    swapf s_status,w

    movwf STATUS

    swapf s_work,f

    swapf s_work,w

    RETFIE

;*******割込終わり********

 

 

main0

;**********************************

; ポートセット、初期化

;**********************************

 

    movlw b'00000111'

    movwf CMCON ;コンパレータを使用しない(RA0-RA4はデジタルピンで使用)

    bsf STATUS, RP0 ;◆RP0=1にして、バンク0→1にする

    movlw b'00011100' ;ポートAの入出力設定:2,3,4を入力(1)に その他(0)に

    movwf TRISA

    movlw b'00110010' ;ポートBの入出力設定:RB1,4,5は入力に

    movwf TRISB

 

    MOVLW B'00000101' ;210:16カウンタモード指定011:16 100:32 101:64 110:128 

;7: 0でプルアップ有効にする--RB0-RB7が全て

    MOVWF OPTION_REG ;プリセットカウンタへ出力

 

;RS232C設定---

    MOVLW B'00100110' ;送信の設定(非同期、高速モード等)

    MOVWF TXSTA ;

    MOVLW D'25' ;ボレートの設定 10Mは64--------------------------

    MOVWF SPBRG ;

    bcf STATUS, RP0 ;◆バンクを元に戻す

 

 

    movlw b'00000000' ;PORTA初期化

    movwf PORTA

    clrf PORTB ;PORTB初期化

    ;RS232C設定---

    MOVLW B'10010000' ;受信の設定(シリアルピン設定,,,連続受信等)

    MOVWF RCSTA

 

;液晶電源ON

    bsf PORTA,0 ;CLKHigh 最初からあげておかないと作動しない

    nop

    bsf PORTB,7 ;SDAHigh 

    nop

    bsf PORTA,1 ;電源をONにする 

    call T100mWAIT ;  

    call LCDstart ;約0.5秒かかる

 

;識別番号取得

    clrf kiban

    btfsc PORTB,5

    bsf kiban,0

    btfsc PORTB,4

    bsf kiban,1

    incf kiban ;0-3を1-4に変更

 

 ;REVを表示

    call gyou_1 ;1行目に"改訂符号記述---------------------

    movlw D'16'

    movwf MsgNO

    call MSG01   

 

 ;機番を表示

    call gyou_2

    movlw "N"

    movwf txdatax

    call TXx   

    movlw "O"

    movwf txdatax

    call TXx       

    movlw "."

    movwf txdatax

    call TXx       

    movfw kiban ;機番を表示

    addlw 30H

    movwf txdatax

    call TXx  

    

;変数初期値設定

    clrf d001

    clrf d002 

    clrf d003

    clrf d004

 

    clrf f_sig ;変数f_sigを0にしておく

; bsf f_sig, 1 ;Aの入力済信号のON

; bsf f_sig, 3 ;Bの入力済信号のON

    bcf f_sig,5 ;タイム表示はオフ

 

    ;割込開始----

    MOVLW D'179' ;カウント値ロード

    MOVWF TMR0 ;TMR0へ出力

    movlw B'11100000' ;GIE,PEIE,TMR0IEを1「割り込み許可」

    MOVWF INTCON ;

    ;-------------

 

;*******************************************************************************

;+++++++++++無線信号待ちと入力後の処理+++++++++++++++++++++++++++++++++++++++++++++

;********************************************************************************

 

SIGNAL1

 ;------スタート要求"20"受信時の処置------------------------------------   

    call T1mWAIT

    call RSreceivexx

 

    movfw txdata2

    sublw '2'

    btfss STATUS,Z ;引き算結果が0(Z=0)だったらスキップしてdata1確認

    goto nextjj1

    movfw txdata1

    sublw '0'

    btfsc STATUS,Z ;引き算結果が0でなかったら(Z=0)だったらスキップ   

    goto START1 ;START1に行く

    

;------送信要求信号"30"受信時の処理

nextjj1   

    movfw txdata2

    sublw '3'

    btfss STATUS,Z ;引き算結果が0(Z=0)だったらスキップしてdata1確認

    goto nextjj2

    movfw txdata1

    sublw '0'

    btfsc STATUS,Z ;引き算結果が0でなかったら(Z=0)だったらスキップ   

    goto DATA_SEND

 ;------------------------------

nextjj2   

    goto SIGNAL1

;------------------------------------------------------------------------------

    

    

;================================================

;            スタート要求信号受信時の処理

;================================================

START1

    ;割込停止----

    movlw B'11000000' ;GIE,PEIE,TMR0IEのTMR0IEを0

    MOVWF INTCON  ;

;-------------

 

;---------LED点滅---------------------

    movlw D'8'

    movwf LP_count

LOOPLED_S

    bsf PORTB,6 ;LED ONとする

    call T20mWAIT

    bcf PORTB,6

    call T20mWAIT

    decfsz LP_count,f

    goto LOOPLED_S

 

    bsf PORTB,6 ;LED ONとする

    call clear01 ;画面クリア

    call gyou_1 ;1行目に"スタートシレイ"と表示

    movlw D'0'

    movwf MsgNO

    call MSG01

    call gyou_2 ;2行目に"ジュシン"と表示

    movlw D'8'

    movwf MsgNO

    call MSG01

 

;4秒の時間待ち

    movlw D'200' ;この後、約20msecのスイッチチェックを250回ループ

    movwf LP_count ;LP_countに25を代入し、カウンタとして使う

LOOP11

    call RSreceive ;受信バッファをからにする---

    call T20mWAIT ;20msec時間待ち

    decfsz LP_count,f ;LP_countを1減らし0になったら次の命令をスキップす

    goto LOOP11 ;ループの先頭に戻る

 

    clrf d000 ;共通データをクリア

    clrf d001

    clrf d002 

    clrf d003

    clrf d004

 

    clrf da00 ;Aデータをクリア

    clrf da01

    clrf da02

    clrf da03

    clrf da04

 

    clrf db00 ;Bデータをクリア

    clrf db01

    clrf db02

    clrf db03

    clrf db04

 

    clrf A_count

    clrf At_count

    clrf A_00

 

    clrf B_count

    clrf Bt_count

    clrf B_00

    clrf f_sig

    bsf f_sig,5 ;タイム表示を有効にする

 

    call clear01 ;表示をクリアする

    bcf f_sig,6 ;スタートカウントを無効にする

 

 

;ドンの信号待ち------------------------------------------------------------------

LOOP12

    call T1mWAIT   

    btfss PIR1,RCIF ;RSのデータがあればスキップ--------------------

    call T1mWAIT   

    btfss PIR1,RCIF ;RSのデータがあればスキップ--------------------

    call T1mWAIT   

    call RSreceivexx ;:の次の2つのデータをtxdata2,txdata1にいれて戻ってくる

 

    ;"20"を確認

    ;2桁目 txdata2の確認   

    movfw txdata2

    sublw '2'

    btfss STATUS,Z ;引き算結果が0(Z=0)だったらスキップしてdata1確認

    goto nextjj3

    ;1桁目 txdata1の確認

    movfw txdata1

    sublw '0'

    btfsc STATUS,Z ;引き算結果が0でなかったら(Z=0)だったらスキップ   

    goto START1 ;引き算結果が0(Z=1)だったらSTART1に行く 

 

;-------------------140ms間隔での信号4回受信--------------------------------

nextjj3

    ;2桁目 txdata2の確認 "1"であることを確認

    movfw txdata2

    sublw '1'

    btfss STATUS,Z ;引き算結果が0(Z=0)だったらスキップしてdata1確認

    goto nextSS ;"1"でなければ最後までジャンプ

 

 ;  --------- 1桁目 txdata1の確認------------------------------------------------

    movfw txdata1

    sublw '6'

    btfss STATUS,Z ;引き算結果が0だったらスキップ

    goto next05 ;引き算結果が0(Z=1)だったらnext05に行く

    movlw D'246'

    movwf COUNTSS

    ;nop

    bsf f_sig,6

 

next05 

    movfw txdata1

    sublw '5'

    btfss STATUS,Z ;引き算結果が0だったらスキップ

    goto next04 ;引き算結果が0(Z=1)だったらnext04に行く

    movlw D'197'

    movwf COUNTSS

    ;nop

    bsf f_sig,6

 

next04

    movfw txdata1

    sublw '4'

    btfss STATUS,Z ;引き算結果が0だったらスキップ

    goto next03 ;引き算結果が0(Z=1)だったらnext03に行く

    movlw D'148' ;(4:213)

    movwf COUNTSS

    ;nop

    bsf f_sig,6

  

next03    

    movfw txdata1

    sublw '3'

    btfss STATUS,Z ;引き算結果が0だったらスキップ

    goto next02 ;引き算結果が0(Z=1)だったらnext02に行く

    movlw D'99' ;=(4:142)

    movwf COUNTSS   

    ;nop

    bsf f_sig,6

     

next02

    movfw txdata1

    sublw '2'

    btfss STATUS,Z ;引き算結果が0だったらスキップ

    goto next01 ;引き算結果が0(Z=1)だったらnext01に行く

    movlw D'50' ;=(4:72)

    movwf COUNTSS   

    ;nop

    bsf f_sig,6

    

next01

    movfw txdata1

    sublw '1'

    btfss STATUS,Z ;引き算結果が0だったらスキップ

    goto nextSS ;引き算結果が0(Z=1)だったらnextSSに行く

    movlw D'1'

    movwf COUNTSS

    ;nop

    bsf f_sig,6

    

nextSS

    btfsc f_sig,6 ;f_sig,6がセットされるかスタート準備信号が入るまでは無限ループ

    decfsz COUNTSS

    goto LOOP12 ;

 

;----------------------------------------------------------

don1

    bsf f_sig,2 ;0.1秒間センサ処理無効にする

    bsf f_sig,4

  ;計測開始

;割込開始----

    MOVLW D'179' ;カウント値ロード

    MOVWF TMR0 ;TMR0へ出力

    movlw B'11100000' ;GIE,PEIE,TMR0IEを1「割り込み許可」

    MOVWF INTCON ;-----------------------------------------------

    nop

    ;-------------

 

    ;LEDを消す

    bcf PORTB,6 ;LED OFFとする

    nop

;---------0.1秒待ち-----------

    movlw D'100'

    movwf LP_count

LOOP13

    call RSreceive ;受信バッファをからにする---

    call T1mWAIT

    decfsz LP_count,f

    goto LOOP13

    bcf f_sig,2 ;センサ処理有効にする

    bcf f_sig,4

    

    goto SIGNAL1 ;待ち状態に戻る。

 

 

;==========================================================================

;            送信要求信号受信時の処理

;==========================================================================

;------送信要求信号受信時の処理

DATA_SEND

;---------LED点滅---------------------

    movlw D'8'

    movwf LP_count

LOOPLED1

    bsf PORTB,6 ;LED ONとする

    call T20mWAIT

    bcf PORTB,6

    call T20mWAIT

    decfsz LP_count,f

    goto LOOPLED1

 

;--------- 0.3×識別番号秒待ち-----------

    movfw kiban

    movwf LP_kiban

LOOP103

    movlw D'15'

    movwf LP_count

LOOP93

    call RSreceive ;受信バッファをからにする---

    call T20mWAIT

    decfsz LP_count,f

    goto LOOP93

    decfsz LP_kiban

    goto LOOP103

 

;---------LED点滅---------------------

    movlw D'8'

    movwf LP_count

LOOPLED2

    bsf PORTB,6 ;LED ONとする

    call T20mWAIT

    bcf PORTB,6

    call T20mWAIT

    decfsz LP_count,f

    goto LOOPLED2

 

;---------------------------------------

;データ送信

    movlw 'T'

    movwf txdata ;文字データを転送用変数にいれて

    call RSsend ;RS232C出力ルーチン実行

    movlw 'X'

    movwf txdata ;文字データを転送用変数にいれて

    call RSsend ;RS232C出力ルーチン実行

    movlw 'D'

    movwf txdata ;文字データを転送用変数にいれて

    call RSsend ;RS232C出力ルーチン実行

    movlw 'A'

    movwf txdata ;文字データを転送用変数にいれて

    call RSsend ;RS232C出力ルーチン実行

 

    movlw '4' ;最初に'4'を送信

    movwf txdata

    call RSsend

    movfw kiban ;識別番号を送信(kiban=1?4)

    addlw 30H

    movwf txdata

    call RSsend

 

;a信号(左センサ)の時間データ送信

    movfw da04

    addlw 30H

    movwf txdata

    call RSsend

 

    movfw da03

    addlw 30H

    movwf txdata

    call RSsend

 

    movfw da02

    addlw 30H

    movwf txdata

    call RSsend

 

    movfw da01

    addlw 30H

    movwf txdata

    call RSsend

;B信号(右センサ)の時間データ送信

    movfw db04

    addlw 30H

    movwf txdata

    call RSsend

 

    movfw db03

    addlw 30H

    movwf txdata

    call RSsend

 

    movfw db02

    addlw 30H

    movwf txdata

    call RSsend

 

    movfw db01

    addlw 30H

    movwf txdata

    call RSsend

 

    movlw 0dh ;<CR>

    movwf txdata ;文字データを転送用変数にいれて

    call RSsend ;RS232C出力ルーチン実行

    movlw 0ah ;<LF>

    movwf txdata ;文字データを転送用変数にいれて

    call RSsend ;RS232C出力ルーチン実行

 

    goto SIGNAL1

 

 

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;----------------------------------------------------------------------

hosei

    incf e000 ;0005秒のカウント

    movfw e000

    sublw D'2'

    BTFSS STATUS,Z

    goto ENDhosei ;0.005経過であれば、最後までジャンプ

    clrf e000

 

    incf e001 ;0.01秒のカウント

    movfw e001

    movfw e001

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDhosei

    clrf e001

 

    incf e002 ;0.1秒のカウント

    movfw e002

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDhosei

    clrf e002

 

    incf e003 ;1秒のカウント

    movfw e003

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDhosei

    clrf e003

 

    incf e004 ;10秒のカウント

    movfw e004

    sublw D'10'

    BTFSS STATUS,Z

    goto ENDhosei

    clrf e004

ENDhosei

    decfsz E_count

    goto hosei

 

    return

 

 

;*************************************************************************

;***************LCDスタートシーケンス*******************************************

;*************************************************************************

LCDstart

    call BSTART

    movlw B'01111100'

    movwf txdataq

    call TX

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 38h ;FUNCTION SET テーブルは0セレクト

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 39h ;FUNCTION SET テーブル1セレクト(拡張コマンド選択)

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 14h ;作動周波数設定 380Hz(拡張コマンド選択後に設定)

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw B'01111111' ; 'XXXX1111'(コントラストC3,C2,C1,C0)

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw B'01010101' ;C5=0,C4=1 コントラストの一部等設定

    ;(拡張コマンド選択後に設定)

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 6Ch ;フォロワ制御設定(ON)(拡張コマンド選択後に設定)

    movwf txdataq

    call TX

    call T100mWAIT ;100ms時間待ち

    call T100mWAIT ;100ms時間待ち

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 38h ;FUNCTION SET テーブルは0セレクト

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 0Ch ;DISPLAY ON/OFF設定(表示オン、カーソルオフ、ブリンクオフ)

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

 

    call clear01 ;画面クリア

    return

 

;**************************************LCDEND*************************

LCDend

;表示終了処置

    movlw B'00000000'

    movwf txdataq

    call TX

    movlw 01h ;CLEAR DISPLAY

    movwf txdataq

    call TX

    call T1mWAIT ;2ms時間待ち

    call T1mWAIT ;2ms時間待ち

    call BSTOP ;ストップビットを送る

 

;液晶電源オフ

    bcf PORTA,1 ;液晶電源をオフとする

    nop

    bcf PORTA,0 ;clkをオフとする

    nop

    bcf PORTB,7 ;SDAをオフとする

    nop

    ;注電源終了までの待ち時間は別途確保する

    return

 

;画面クリア****************************************************************

clear01

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw 01h ;CLEAR DISPLAY

    movwf txdataq

    call TX

    call T1mWAIT ;2ms時間待ち

    call T1mWAIT

    return

 

;1行目を左端を指定********************************************************

gyou_1

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw B'10000000' ;アドレス指定

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

    return

 

;2行目左端を指定*********************************************************

gyou_2

    movlw B'10000000'

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    movlw B'11000000' ;アドレス指定

    movwf txdataq

    call TX

    call TIME100STEP ;100μs時間待ち

    return

 

 

; *** 簡易データ送信サブルーチン(表示後表示アドレスは右に一文字分ずれる)**********

TXx

    movlw B'11000000' ;データ継続でデータオペレーションするとの信号を送信

    ;(TXに対しこの部分を付加)

    movwf txdataq

    call TX

    movfw txdatax

    movwf txdataq

    call TX

    call TIME10STEP ;10μs時間待ち

    call TIME10STEP ;10μs時間待ち

    call TIME10STEP ;10μs時間待ち

    return

 

; ********* txdataを送信するサブルーチン ************************************

;---------------------------------------TX-----------------------------

TX

    movlw 08H

    movwf tx_bit ; 1バイト=8ビット繰り返し用カウンタ

;1.データの送信

TXLoop

;(1)SDA操作

    btfsc txdataq, 7 ; 書き込みデータ(7bit目)が0の場合スキップしてSDAをLOWに

    goto sdalow ; 

    bcf PORTB,7 ; 書き込みビットが0の場合SDAをLOW

    nop

    goto clkhigh ; クロック操作へジャンプ

sdalow

    bsf PORTB,7         ; 書き込みビットが1の場合:SDAをHIGHにする

    nop

    nop

;(2)CLC操作

clkhigh

    bsf PORTA,0 ; SCLをHighにする

    nop

    nop

    nop

    bcf PORTA,0 ; SCLをLowにする。

    nop

;(3)データ操作

    rlf txdataq, f ; 送信データバイトをシフトする

    decfsz tx_bit, f ; 8ビット送信終わったか?

    goto TXLoop ; 終わるまでループ

 

;2.ACKビット受信

    bsf STATUS, RP0

    bsf TRISB,7 ; SDAポートを入力にする---------------------

    bcf STATUS, RP0

    nop

    nop

    bsf PORTA,0 ; SCLをHighにする

    nop

    btfsc PORTB,7    ; SDAポートからの入力がlow(ACKした)場合スキップ

    bcf PORTA,1 ; ポート2(スピーカの出力を借用)をLOWにする 

    nop

    bcf PORTA,0    ; SCLをLowにする

    nop

    bsf STATUS, RP0

    bcf TRISB,7 ; SDAポートを出力に戻す--------------------

    bcf STATUS, RP0

    bcf PORTB,7 ; SDAをLowにする    20171001変更

    nop

    bsf PORTA,1 ; ポート2(スピーカの出力を借用)をhighにもどす

    nop

    return

 

;*************** スタートビット発生サブルーチン  *************************

BSTART

    bsf PORTB,7 ; まずSDAをHighにする

    nop

    nop

    nop

    nop

    bsf PORTA,0 ; SCLをHighにする

    nop

    nop

    nop

    nop

    bcf PORTB,7 ; SCLがHighの間にSDAをLowにする

    nop

    nop

    nop

    nop

    bcf PORTA,0 ; SCLをLowに戻す。

    nop

    nop

    nop

    nop

    return

 

;**************** ストップビット発生サブルーチン **************************

BSTOP

    bcf PORTB,7 ; まずSDAをLowにする

    nop

    nop

    nop

    nop

    bsf PORTA,0 ; SDAがLOWで安定してるときにSCLをHighにする

    nop

    nop    

    nop

    nop

    bsf PORTB,7 ; SCLがHighの間にSDAをHighにする。

    nop

    nop

    nop

    nop

    return

 

 

 

;================================================

;            RS232C 受信ルーチン

;              txdataに取り込み  

;================================================

; 2桁,1桁のデータを持って帰る-----------------------------------------------------

RSreceivexx

    movlw '/'

    movwf txdata2 ;データには/を入れておく

    movwf txdata1 ;データには/を入れておく   

    call RSreceive00 ; データを取得。 "/"か"":"後のデータが入る

    movfw txdata

    sublw "/"

    btfsc STATUS,Z ;"/"以外の値が入っていたらスキップして次の処理

    return ;"/"だったら戻る

    movfw txdata

    movwf txdata2 ;2桁目のデータをtxdata2に代入

    call RSreceive1 ;1桁目のデータを取得

    movfw txdata

    movwf txdata1 ;txdata1に代入

    return

 

 ;------------------------------------------------------------------------------

    

RSreceive00   ;”:”以外だったら/として直ちに戻る。

;":"だったら次の文字を持って帰る

    call RSreceive

    movfw txdata

    sublw ':'

    btfss STATUS,Z ;引き算結果が0(":"データ)だったらスキップ

    return

    call RSreceive1 ;":"の次のデータを持って帰る

    return

 

;---------------------------------------------------------------------------

RSreceive1 ;":"後の処理(データがあるはずなので、来るまで待つ。

;ただし6msまってもデータがこなければ戻る)

    movlw D'20'

    movwf COUNT4

    movlw '/'

    movwf txdata ;データには/を入れておく

cont01 ;0707誤記訂正------------------------------------

    btfsc PIR1,RCIF ;データがなければスキップ。あれば次の処理

    goto Tugi_shori

    call T01mWAIT

    call T01mWAIT

    call T01mWAIT

    decfsz COUNT4 ;count4が0になったらリターン。0でなければcont01

    goto cont01

    return

 

;----------------------------------------------------------------

RSreceive ;データがなければ、txdata="/"として戻る。あればTugi_shoriでデータ取得

    movlw '/'

    movwf txdata ;データには/を入れておく

    btfss PIR1,RCIF ;データがなければ戻る

    return

Tugi_shori

    btfss RCSTA,OERR ;データがあればオーバーランチェク

    goto next_ck

    bcf RCSTA,CREN ;エラーがあれば解除し戻る

    bsf RCSTA,CREN

    return

next_ck ;フレーミングエラーチェック

    btfss RCSTA,FERR

    goto receive_txdata

    movfw RCREG ;エラーがあれば解除し戻る

    return ;

receive_txdata

    movfw RCREG

    movwf txdata

 

    return

 

;================================================

;            RS232C 送信ルーチン

;              txdataの値を送信  

;================================================

RSsend

    btfss PIR1,TXIF

    goto RSsend

    movfw txdata

    movwf TXREG

    return

 

;================================================

;             タイマルーチン  

;================================================

;-----------0.1msecのタイムループ-------------------

T01mWAIT ;2

    movlw D'23' ;1

    movwf COUNT1 ;1

LOOP1

    nop ;1

    decfsz COUNT1,f ;1  2  最後は 2 

    goto LOOP1 ;2  0

    nop ;   1

    nop ;   1

    nop

    return   ;   2   4+4*23-1+5=100  μs

 

;----------- 1mS待つ

T1mWAIT ;2 call分

    movlw D'99' ;1

    movwf T1m_count ;1

LOOP1m

    goto $+1 ;2

    goto $+1 ;2

    goto $+1 ;2

    nop ;1

    decfsz T1m_count,f ;1 2  最後は 2

    goto LOOP1m ;2 0

    goto $+1 ;  2

    nop ;  1

    return ;  2

;  4+10*99-1+7=1000, 1000*1=1000usec=1msec

 

;----------- 約20ms待つ

T20mWAIT

    movlw D'20' ;

    movwf T20m_count ;

LOOP20m

    call T1mWAIT ;

    decfsz T20m_count,f

    goto LOOP20m

    return ;

 

;----------- 約100ms待つ

T100mWAIT

    movlw D'100' ;

    movwf T100m_count ;

LOOP100m

    call T1mWAIT ;

    decfsz T100m_count,f

    goto LOOP100m

    return ;

    ;

;----------- 約04s待つ

T04sWAIT

    call T100mWAIT ;

    call T100mWAIT ;

    call T100mWAIT ;

    call T100mWAIT ;

    return ;

 

;-----------10STEP待つ

;10STEP(10μs=0.01ms) 

TIME10STEP ;2 (call分)

    nop ;1

    nop ;1

    nop ;1

    nop ;1

    nop ;1

    nop ;1

    return ;2 

 

;-----------100STEP待つ

;100STEP(0.1ms) 

TIME100STEP ;2  (call分)

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    call TIME10STEP ;10

    nop ;1

    nop ;1

    nop ;1

    nop ;1

    nop ;1

    nop ;1

    return ;2 

 

 

 

;**********************文字列処理****************************************

;MsgNO番号に応じたメッセージを表示する-MgsNOに番号を入れてからコールする-----------

MSG01

    clrf h_count

loop_x01

    movfw MsgNO ;PCLに加算する数をワークレジスタに入れサブルーチンをコールする

    call MOJI_ALL

    movwf txdatax

    call TXx

    incf MsgNO

    incf h_count

    btfss h_count,3 ;8個データ処理したら戻る(文字数は8個ずつに限定)

    goto loop_x01

    return

 

 

;*******************************文字列***********************************

 

    org 0x390

MOJI_ALL

    clrf PCLATH

    bsf PCLATH,0

    bsf PCLATH,1

    addwf PCL,f

;0

    retlw "ス"

    retlw "タ"

    retlw "-"

    retlw "ト"

    retlw "シ"

    retlw "レ" 

    retlw "イ"

    retlw " "

;8

    retlw "シ"

    retlw "゙"

    retlw "ュ"

    retlw "シ"

    retlw "ン"

    retlw " "

    retlw " "

    retlw " "

;16

    retlw "v"

    retlw "1"

    retlw "8"

    retlw "0"

    retlw "7"

    retlw "1"

    retlw "6"

    retlw " "

 

    end