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