;**********************
;加速度ロガーVer5(232C)
;**********************
; BASEはVer4_14_232c.asm
; RS232C垂れ流し版
;
;Ver.5_1('08/09/28)
; 232C出力にペダル情報追加
; 車速PICからのペダル情報受信追加
;
;Ver.5_2('08/09/28)
;車速変換見直し→失敗
;
;Ver.5_3('08/09/30)
;車速8bit+ペダル4bitを受信する仕様
;
;Ver.5_4('08/10/01)
;ペダル出力値オフセット
;
;Speed_Ver4_4.asmと対応
;**********************
;
;PIC16F84A:4MHz用(1cycle=1μs)
;
;電源を入れて,SW1を押すとデータ送信モード,SW2を押すとデータ計測モード
;SW両方押しで停止モード
;
;⇒データ計測モードSW2
; 計測開始,0.1secごとに**分間まで(メモリいっぱい使用)
; X下位,X上位,Y下位,Y上位の順に4バイトずつ書き込み
; 12000ポイント×4バイト=48000バイト
; 中断操作(ボタンを二つ1秒以上押す)まで繰り返す。
;
;⇒データ送信モードSW1
; 9600bps,8bit,1stopbit
; パリティなし,フロー制御なし
; SW1を押すと,テキストデータが順に流れてくる
;
;
;
; ピン・アサイン
; RA0 →CLK(ADコンバータ)
; RA1 →CS(ADコンバータ)
; RA2 ⇔EEPROM SDA
; RA3 →EEPROM SCLK
; RA4 ←SP_CLK(車速用PIC)
; RB0 ←SP_DATA(車速用PIC)
; RB1 →RS232C送信
; RB2 ←D-OUT(ADコンバータ)
; RB3 →D_IN(ADコンバータ)
; RB4 →SP_REQ車速要求信号(車速用PICへ)
; RB5 ←プッシュSW2;データ記録開始モード
; RB6 →LED(0でOFF,1でON)
; RB7 ←プッシュSW1;データ送信モード
;
;
;***************************************
LIST P=PIC16F84A
INCLUDE "P16F84A.INC"
;****************
; 変数レジスタ定義 0CH〜7FHが汎用レジスタ
;****************
;---------EEPROM関連----------
eeprom equ 0CH ; eeprom ビット書き込み/読み込み用レジスタ
addrl equ 0EH ; eeprom アドレス(下位)
addrh equ 0FH ; eeprom アドレス(上位)
datai equ 10H ; eeprom 読み込み用データ
datao equ 11H ; eeprom 書き込み用データの1バイト目
datao2 equ 12H ; eeprom 書き込み用データの2バイト目
datao3 equ 13H ; eeprom 書き込み用データの1バイト目
datao4 equ 14H ; eeprom 書き込み用データの2バイト目
txbuf equ 16H ; eeprom 変数受け渡し用
count equ 17H ; eeprom ビット・カウンタ
;--------時間待ちループ用----------
counta equ 19H ; 時間待ち用のカウンタ
countb equ 1AH
countc equ 1BH
countd equ 1CH
counte equ 1DH ; 汎用カウンタ
countf equ 1EH
;---------RS-232C用--------
sendt equ 1FH ; RS232C通信ウエイト時間の調整用
bitw equ 20H ; 送信中ビット数のカウント
txdata equ 21H ; 送信データ(8バイト)格納用変数
;---------パルスカウント-----
xplsh equ 2AH ; X軸パルス・カウンタ上位
xplsl equ 2BH ; X軸パルス・カウンタ下位
yplsh equ 2CH ; Y軸パルス・カウンタ上位
yplsl equ 2DH ; Y軸パルス・カウンタ下位
datao5 equ 22H ; eeprom 書き込み用データの1バイト目
datao6 equ 23H ; eeprom 書き込み用データの2バイト目
;--------10進数変換用--------
hexh equ 31H ; 16進数上位
hexl equ 32H ; 16進数下位
decxhh equ 3CH ; 10進数・千の位
decxh equ 2EH ; 10進数・百の位
decxm equ 2FH ; 10進数・十の位
decxl equ 30H ; 10進数・一の位
decyhh equ 43H ; 10進数・千の位
decyh equ 44H ; 10進数・百の位
decym equ 45H ; 10進数・十の位
decyl equ 46H ; 10進数・一の位
decshh equ 47H ; 10進数・千の位
decsh equ 48H ; 10進数・百の位
decsm equ 49H ; 10進数・十の位
decsl equ 4AH ; 10進数・一の位
dechh equ 4BH ; 10進数・千の位
dech equ 4CH ; 10進数・百の位
decm equ 4DH ; 10進数・十の位
decl equ 4EH ; 10進数・一の位
;--------メイン・ルーチン用--------
stepl equ 33H ; ステップ数カウンタ下位(960分カウンタ)
steph equ 34H ; ステップ数カウンタ上位
OUTBUF equ 35H ;
INBUFH equ 36H ;
INBUFL equ 37H ;
COUNT equ 38H ;
COUNT2 equ 3BH ;
Pedal equ 3CH ; ペダル情報
old_plsl equ 3DH ; 前回車速パルス下位
old_plsh equ 3EH ; 前回車速パルス上位
;**********ADコンバータ************
ADCS equ 0x02 ; chip select line A/D
plsl equ 40H ; 車速信号受信データ下位
plsh equ 41H ; 車速信号受信データ上位
countg equ 42H ; 汎用カウンタ
ch_cntl equ 26H ; アナログ入力CH切り替え
d_data1 equ 27H ; AD変換データ格納先
d_data2 equ 28H ; AD変換データ格納先
data_buf equ 29H ;
;*******************
;ビット定義など
;*******************
di equ 7 ; eeprom入力はeepromレジスタの7ビット目
do equ 6 ; eeprom出力はeepromレジスタの6ビット目
sdata equ 2 ; SDA接続ポートはRA2
sclk equ 3 ; SCL接続ポートはRA3
ackf equ 6 ; EEPROM警告LEDはRB4
btime equ D'31' ; RS232C通信速度設定用変数 9600bps@4MHz
; btime=((オシレータ周波数(Hz)/転送スピード(bps)/4)-10)/3
org 0
;**********************
; ポート・セット,初期化
;**********************
bsf STATUS,RP0 ; TRIS設定のためバンクを切り替える
movlw b'00010000' ; PORTA入出力設定:RA4を入力(1)ほかは出力(0)に設定
movwf TRISA
movlw b'10100101' ; PORTB入出力設定:RB0,RB2,RB5,RB7が入力(1),ほかは出力(0)に設定
movwf TRISB
bcf STATUS,RP0 ; TRIS設定が終了したのでバンクを元にもどす
movlw b'00000010' ; PORTA初期化(5V=1,0V=0)
movwf PORTA
movlw b'00000010' ; PORTB初期化(5V=1,0V=0)
movwf PORTB
;****************************
;メインルーチン
;****************************
; SWが押されたか監視,SW1(RB7)でデータ送信モード
; SW2(RB5)でデータ記録開始
; その間,LEDが400ms周期で点滅
MENU1
movlw 0C8H ; カウンタを200にセット
movwf counte
bsf PORTB,6 ; LED点灯
bcf PORTB,4 ; SP_REQ=RB4をLO(初期化)
MENU2
call WAIT_1M ; 1ms時間待ち
; btfss PORTB,7 ; SW1が1(OFF)だったらスキップ
; goto DATATR ; onだったらデータ送信モードへ
btfss PORTB,5 ; SW2が1(OFF)だったらスキップ
goto LOG ; onだったらデータ計測モードへ
decfsz counte,f
goto MENU2 ; 200回ループ
movlw 0C8H ; カウンタを200にセット
movwf counte
bcf PORTB,6 ; LED消灯
MENU3
call WAIT_1M ; 1ms時間待ち
; btfss PORTB,7 ; SW1が1(OFF)だったらスキップ
; goto DATATR ; onだったらデータ送信モードへ
btfss PORTB,5 ; SW2が1(OFF)だったらスキップ
goto LOG ; onだったらデータ計測モードへ
decfsz counte,f
goto MENU3 ; 200回ループ
goto MENU1
;********************************
; データ計測モード
;********************************
;**********初期化***********
LOG
; movlw 060H ; ステップ・カウンタのリセット,計測可能時間の制限
; movwf stepl ; 4バイト(65536(0000H))-12000ステップ(20分,1ステップ0.1s)
; movlw 073H ; 1ずつ加算していき,0になったら記録終了
; movwf steph
; clrf addrl ; eeprom書き込みアドレスリセット
; clrf addrh
;*******データ計測********
LOG0
call Speed ; 車速データ受信
call Gmeas ; 加速度センサ・パルス計測
;*******データの記録********
; movf xplsl,w ; X軸データを前ターン用変数にセット
; movwf datao
; movf xplsh,w
; movwf datao2
; movf yplsl,w ; Y軸データを前ターン用変数にセット
; movwf datao3
; movf yplsh,w
; movwf datao4
; movf plsl,w ; 車速データを前ターン用変数にセット
; movwf datao5
; movf plsh,w
; movwf datao6
call DATATR ;RS232C出力へ
; call EEPWT ;EEPROM書き込み
;
; incfsz addrl,f ;書き込みアドレス+6加算,0なら次をスキップ
; goto skip1
; incf addrh,f
;skip1
; incfsz addrl,f
; goto skip2
; incf addrh,f
;skip2
; incfsz addrl,f
; goto skip3
; incf addrh,f
;skip3
; incfsz addrl,f
; goto skip4
; incf addrh,f
;skip4
; incfsz addrl,f
; goto skip5
; incf addrh,f
;skip5
; incfsz addrl,f
; goto LOG2
; incf addrh,f
;*******カウンタ処理*********
;LOG2
; incfsz stepl,f ;ステップカウンタ加算
; goto LOG3
; incfsz steph,f
; goto LOG4
; goto LOGend
;LOG3
; nop
; nop
;*******SW入力(中断処理)********
LOG4
btfsc PORTB,7
goto LOG5
btfsc PORTB,5
goto LOG6
goto LOGend
LOG5
nop
nop
;********LED点滅**********
LOG6
; bsf PORTB,6 ;LEDを5ms光らせる
; movlw 005H
; movwf countc
LOG7
; call WAIT_1M
; decfsz countc,f
; goto LOG7
; bcf PORTB,6
;********時間あわせループ**********
; movlw 050H ;全体の計測時間の余りをここで消費する
; movwf countc ;50H=80回
;LOG8
; call WAIT_1M
; decfsz countc,f
; goto LOG8
; nop
goto LOG0
;********計測終了(中断)********
LOGend ; 記録終了:停止マーカ(7373H)を書き込む
; call WAIT_50M ; EEPROMに書き込んだばかりなので少し待つ
; movlw 073H
; movwf datao
; movwf datao2 ; 7373Hをセットして
; movwf datao3
; movwf datao4
; movwf datao5
; movwf datao6
; call EEPWT ; EEPROM書き込み
bsf PORTB,6 ; LED1s点灯
call WAIT_500M
call WAIT_500M
bcf PORTB,6
goto MENU1
;********************************
; データ送信モード
;********************************
DATATR
; movlw 060H ;計測モードの値にあわせること
; movwf stepl
; movlw 073H
; movwf steph
;
; clrf addrl
; clrf addrh
DATATR1
; call EEPRD ;X下位データ読み出し
movf xplsl,w
movwf hexl
; incf addrl,f ; アドレス下位を+1加算
; goto DATATR12 ; 繰り上がらなかったらDATATR12へジャンプ
; incf addrh,f ; 上位繰上げ
DATATR12
; call EEPRD ; X上位データ読み出し
movf xplsh,w
movwf hexh ; 10進変換用上位レジスタへ代入
; データが7373Hでないかチェック
; movlw 073H
; subwf hexh,w ; hexh-w→w
; btfss STATUS,Z ; Zフラグが1だったら(=演算結果が0だったら)次をステップ
; goto DATATR15
; movlw 073H
; subwf hexl,w ; hexl-w→w
; btfss STATUS,Z ; Zフラグが1だったら(=演算結果が0だったら)次をステップ
; goto DATATR15
; データが7373Hだった
; goto DATATR3 ; 送信終了
DATATR15
; incfsz addrl,f ; アドレス下位を+1加算
; goto DATATR4 ; 繰り上がらなかったらDATATR4へジャンプ
; incf addrh,f ; 上位繰上げ
DATATR4
call DECTR ; 10進変換ルーチン
movlw "X"
movwf txdata ; 文字データを転送用変数に入れて
call RSTRANS ; RS232C出力ルーチン実行
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf dechh,w
movwf txdata
call RSTRANS ; RS-232C送信
movlw 030H ; ASCiiコードに変換(+30H)して
addwf dech,w
movwf txdata
call RSTRANS ; RS-232C送信
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decm,w
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decl,w
movwf txdata
call RSTRANS
; movf dechh,w
; movwf decxhh
; movf dech,w
; movwf decxh
; movf decm,w
; movwf decxm
; movf decl,w
; movwf decxl
; call EEPRD ; Y下位データ読み出し
movf yplsl,w
movwf hexl ; 10進変換用下位レジスタへ代入
; incf addrl,f ; アドレス下位を+1加算
; goto DATATR13 ; 繰り上がらなかったらDATATR13へジャンプ
; incf addrh,f ; 上位繰上げ
DATATR13
; call EEPRD ; Y上位データ読み出し
movf yplsh,w
movwf hexh ; 10進変換用上位レジスタへ代入
; incfsz addrl,f ;
アドレス下位を+1加算
; goto DATATR2 ; 繰り上がらなかったらDATATR2へジャンプ
; incf addrh,f ; 上位繰上げ
DATATR2
call DECTR ; 10進変換ルーチン
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw "Y"
movwf txdata ; 文字データを転送用変数に入れて
call RSTRANS ; RS232C出力ルーチン実行
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf dechh,w
movwf txdata
call RSTRANS ; RS-232C送信
movlw 030H ; ASCiiコードに変換(+30H)して
addwf dech,w
movwf txdata
call RSTRANS ; RS-232C送信
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decm,w
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decl,w
movwf txdata
call RSTRANS
movf plsl,w
movwf hexl ; 10進変換用下位レジスタへ代入
DATATR14
movlw 00H ; ダミー
; movf plsh,w
movwf hexh ; 10進変換用上位レジスタへ代入
DATATR16
call DECTR ; 10進変換ルーチン
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw "S"
movwf txdata ; 文字データを転送用変数に入れて
call RSTRANS ; RS232C出力ルーチン実行
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
; movlw 030H ; ASCiiコードに変換(+30H)して
; addwf dechh,w
; movwf txdata
; call RSTRANS ; RS-232C送信
movlw 030H ; ASCiiコードに変換(+30H)して
addwf dech,w
movwf txdata
call RSTRANS ; RS-232C送信
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decm,w
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decl,w
movwf txdata
call RSTRANS
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw "B"
movwf txdata ; 文字データを転送用変数に入れて
call RSTRANS ; RS232C出力ルーチン実行
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
clrf hexh
btfsc Pedal,3 ;Brk=0?
goto Brk_ON
movlw 0AH
movwf hexl ; 10進変換用下位レジスタへ代入
goto DATATR17
Brk_ON
movlw 0CH
movwf hexl ; 10進変換用下位レジスタへ代入
DATATR17
call DECTR ; 10進変換ルーチン
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decm,w
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decl,w
movwf txdata
call RSTRANS
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw "P"
movwf txdata ; 文字データを転送用変数に入れて
call RSTRANS ; RS232C出力ルーチン実行
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
btfsc Pedal,2 ;P_Brk=0?
goto P_Brk_ON
movlw 14H
movwf hexl ; 10進変換用下位レジスタへ代入
goto DATATR18
P_Brk_ON
movlw 16H
movwf hexl ; 10進変換用下位レジスタへ代入
DATATR18
call DECTR ; 10進変換ルーチン
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decm,w
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decl,w
movwf txdata
call RSTRANS
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
movlw "A"
movwf txdata ; 文字データを転送用変数に入れて
call RSTRANS ; RS232C出力ルーチン実行
movlw "," ;
カンマで区切る
movwf txdata
call RSTRANS
btfss Pedal,1 ;Accel=1?
goto Accel_ON
movlw 1EH
movwf hexl ; 10進変換用下位レジスタへ代入
goto DATATR19
Accel_ON
movlw 20H
movwf hexl ; 10進変換用下位レジスタへ代入
DATATR19
call DECTR ; 10進変換ルーチン
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decm,w
movwf txdata
call RSTRANS
movlw 030H ; ASCiiコードに変換(+30H)して
addwf decl,w
movwf txdata
call RSTRANS
movlw 00DH
movwf txdata
call RSTRANS
movlw 00AH ; 0D,0Aで「改行」
movwf txdata
call RSTRANS
movlw 021H ;時間調整用
movwf countc
bsf PORTB,6 ;確認用LED点滅
DATATR33
call WAIT_1M
decfsz countc,f
goto DATATR33
bcf PORTB,6
call WAIT_1M
return ;LOG0に戻る
;*********************************
;RS-232C送信ルーチン
;txdataの値を送信
;*********************************
RSTRANS
bcf PORTB,1 ; スタートビット送信開始,送信ポートRB1をLOWに
movlw btime ;
転送中時間待ち用カウンタ
movwf sendt ; btimeはあらかじめ転送速度にあわせて定義しておく必要がある。
TRANS10
decfsz sendt,f
goto TRANS10 ; 転送速度(ここでは9600bps)に合わせて時間待ち
movlw 08H
movwf bitw ; 送信の単位は8ビットで1データ,bitwは8ビットカウント用変数
nop
TRANS0
rrf txdata,f ; txdata(送信データ)の最下位ビットをC(キャリ・ビット)に。
nop ; その他のビットはそれぞれ1桁ずつ下位の方(右側)にシフト。
btfss STATUS,C ; Cビットが1だったら送信ポートRB1をHighに,0だったらLowにする。
bcf PORTB,1 ; 下位ビット側から送信することになる。
btfsc STATUS,C
bsf PORTB,1
movlw btime
movwf sendt
TRANS11
decfsz sendt,f
goto TRANS11 ; 転送速度(ここでは9600bps)に合わせて時間待ち
decfsz bitw,f ;
ビットカウントを1減らす
goto TRANS0 ; まだ8ビット送信していなかったら次のビットを送信
nop ;nopで時間調整
nop
nop
nop
nop
nop
bsf PORTB,1 ; 最後にストップビットを送信
movlw btime
movwf sendt
TRANS12
decfsz sendt,f ; ストップビット分ウエイト
goto TRANS12
return
;*****************************
;時間待ち用タイマサブルーチン
; WAIT_100U :100μs
; WAIT_1M :1ms
; WAIT_50M :50ms
; WAIT_500M :0.5s
;*****************************
WAIT_100U
movlw 20H
movwf counta
W_LOOP1
decfsz counta,f ; 2+3*32-1=97
goto W_LOOP1
nop
return ; 97+3=100(μs)
WAIT_1M
movlw 0AH ; 10回ループ
movwf countb
W_LOOP2
call WAIT_100U ; 2+(100+5)*10-1=1051
decfsz countb,f
goto W_LOOP2
return ; 1051+2=1053(=1.053ms)
WAIT_50M
movlw 32H ; 50回ループ
movwf countc
W_LOOP3
call WAIT_1M
decfsz countc,f
goto W_LOOP3
return
WAIT_500M
movlw 0AH ; 10回ループ
movwf countd
W_LOOP4
call WAIT_50M
decfsz countd,f
goto W_LOOP4
return
;******************************
;EEPROMデータ書き込みサブルーチン(1度に2バイト書き込む)
; アドレス:addrh,addrl
; データ : datao〜datao6
;******************************
EEPWT
call BSTART ; スタートビット発生
movlw b'10100000' ;
コントロールバイト送信
movwf txbuf
call TX
movf addrh,w ; 書き込みアドレス上位を送信
movwf txbuf
call TX
movf addrl,w ; 書き込みアドレス下位を送信
movwf txbuf
call TX
movf datao,w ; X軸下位データバイトの1バイト目を送信
movwf txbuf
call TX
movf datao2,w ; X軸上位データバイトの2バイト目を送信
movwf txbuf
call TX
movf datao3,w ; Y軸下位データバイトの1バイト目を送信
movwf txbuf
call TX
movf datao4,w ; Y軸上位データバイトの2バイト目を送信
movwf txbuf
call TX
movf datao5,w ; 車速上位データバイトの2バイト目を送信
movwf txbuf
call TX
movf datao6,w ; 車速上位データバイトの2バイト目を送信
movwf txbuf
call TX
call BSTOP ; ストップビット発生,書き込み処理終了
return
;******************************
;EEPROMデータ読み込みサブルーチン
; アドレス:addrh,addrl
; データ : datai
;******************************
EEPRD
call BSTART ; スタートビット発生
movlw b'10100000' ;
コントロールバイト送信(書き込みモード)
movwf txbuf
call TX
movf addrh,w ; 読み込みアドレス上位を送信
movwf txbuf
call TX
movf addrl,w ; 読み込みアドレス下位を送信
movwf txbuf
call TX
call BSTART ; スタートビット発生
movlw b'10100001' ;
コントロールバイト送信(読み込みモード)
movwf txbuf
call TX
call RX
call BSTOP ; ストップビット発生
return
;*********バイトデータ送信サブルーチン*********
TX
movlw 008H
movwf count ; 1バイト=8ビット繰り返し用カウンタ
TXLP
bcf eeprom,do ; eeprom書き込み用ビットを0にしておく
btfsc txbuf,7 ; 書き込みデータは本当に0か?
bsf eeprom,do ; 書き込み用データが1だったので,書き込み用ビットを1にする
btfss eeprom,do ; 書き込み用データビットは1か?
goto bitlow
bsf PORTA,sdata ; 書き込み用ビットが1の場合:SDAをHighにする
goto clkout ; クロック操作へジャンプ
bitlow
bcf PORTA,sdata ; 書き込み用ビットが0の場合:SDAをLowにする
nop
clkout
bsf PORTA,sclk ; SCLをHighにする
nop
nop
nop
nop
bcf PORTA,sclk ; SCLをLowにする。ここまででビット書き込み完了
rlf txbuf,f ; 送信データバイトをシフトする
decfsz count,f ; 8ビット送信終わったか?
goto TXLP ; 終わるまでループ
;***ACKビット送信****
bsf eeprom,di ; eeprom読み込み用ビットを1にしておく
bsf STATUS,RP0
bsf TRISA,sdata ; SDAポートを入力にする
bcf STATUS,RP0
bsf PORTA,sclk ; SCLをHighにする
nop
nop
nop
nop
nop
btfss PORTA,sdata ; SDAポートからの入力をチェック
bcf eeprom,di ; ポートがLowの場合,読み込みビットを0に変更
bcf PORTA,sclk ; SCLをLowにする。
nop
bsf STATUS,RP0
bcf TRISA,sdata ; SDAポートを出力にもどす
bcf STATUS,RP0
nop
btfsc eeprom,di ; 読み込みビットをチェックして失敗(1)していたら
bsf PORTB,ackf ; LEDを点灯する
return
;*******バイトデータ受信サブルーチン*********
RX
clrf datai ; 読み込み用レジスタのクリア
movlw .8 ; set#bits to 8
movwf count
bcf STATUS,0 ; キャリビットを0にする
RXLP
rlf datai,f ; 読み込み用レジ下を左シフト,最下位は0になる
bsf eeprom,di ; eeprom読み込み用ビットを1にする
bsf STATUS,RP0
bsf TRISA,sdata ; SDAポートを入力にする
bcf STATUS,RP0
bsf PORTA,sclk ; SCLをHighにする
nop
nop
nop
nop
nop
btfss PORTA,sdata ; SDAポートからの入力をチェック
bcf eeprom,di ; ポートがLowの場合,読み込みビットを0に変更
bcf PORTA,sclk ; SCLをLowにする。
nop
bsf STATUS,RP0
bcf TRISA,sdata ; SDAポートを出力にもどす
bcf STATUS,RP0
btfsc eeprom,di ; 読み込みビットが1だったら
bsf datai,0 ; 読み込みようレジスタの最下位を1にする
decfsz count,f ; 8ビット受信終わったか?
goto RXLP ; 終わるまでループ
;***ACKビット送信****
bsf eeprom,do ; ACK出力用ビットを1にする
bsf PORTA,sdata ; SDAポートをhighにする
bsf PORTA,sclk ; SCLをhighにする
nop
nop
nop
nop
bcf PORTA,sclk ; SCLをLowにする
return
;********スタートビット発生サブルーチン********
BSTART
bsf PORTA,sdata ; SDAポートをhighにする
nop
nop
nop
bsf PORTA,sclk ; SCLをhighにする
nop
nop
nop
bcf PORTA,sdata ; SDAポートをLowにする。SCLがHighの間にSDAがLowになるとスタートビットと認識される
nop
nop
nop
bcf PORTA,sclk ; SCLをLowにする
nop
nop
nop
nop
return
;********ストップビット発生サブルーチン********
BSTOP
bcf PORTA,sdata ; SDAポートをLowにする。
nop
nop
nop
bsf PORTA,sclk ; SCLをhighにする
nop
nop
nop
bsf PORTA,sdata ; SDAポートをhighにする。SCLがHighの間にSDAがHighになるとストップビットと認識される
nop
nop
nop
bcf PORTA,sclk ; SCLをLowにする
nop
nop
nop
nop
return
;***********************************************
;10進数に変換するルーチン
;16進データhexh(上位),hexl(下位)の値をdec4(万の位)〜dec0(一の位)に変換する。
;***********************************************
DECTR
clrf dechh
clrf dech
clrf decm
clrf decl
movf hexh,w ; 入力データが0でないか調べる
btfss STATUS,Z ; hexhが0だった場合,Zフラグが1になっている。
goto DEC4 ; hexh(上位データ)が0でなかったら処理開始へ
movf hexl,w ;hexhが0だったのでhexlをチェック
btfss STATUS,Z
goto DEC1 ; hexl(下位データ)が0でなかったら処理開始へ
return ; hexhもhexlも0だったので出力データ0のまま復帰
DEC4 ;hexhが0じゃなかったのでhexlをチェック
movf hexl,w
btfss STATUS,Z ;0だったら次スキップ
goto DEC1 ;hexlが0じゃないのでカウントアップ
goto DEC3 ;0だったのでhexh減算へ
DEC1
call DECUP ;10進データカウントアップ
decfsz hexl,f ;下位データが0でなかったら繰り返す
goto DEC1
DEC3
movf hexh,w ;上位データが0でないか調べる
btfsc STATUS,Z ; Z=0(結果が正)の場合,次をスキップ
goto DEC2 ; Z=1(結果が0)の場合,下位バイト処理へ
decf hexh,f ;hexhを減算して
goto DEC1 ;下位の減算を再開
DEC2
return ;上位も0になったので処理終了
;*******カウントアップサブルーチン****************
DECUP
incf decl,f
movf decl,w
sublw 00AH
btfss STATUS,Z
return
;*****2桁目カウントアップサブルーチン*****
clrf decl
incf decm,f
movf decm,w
sublw 00AH
btfss STATUS,Z
return
;*****3桁目カウントアップサブルーチン*****
clrf decm
incf dech,f
movf dech,w
sublw 00AH
btfss STATUS,Z
return
;*****4桁目カウントアップサブルーチン*****
clrf dech
incf dechh,f
movf dechh,w
sublw 00AH
btfss STATUS,Z
return
;*****4桁目もオーバーフロー*****
clrf dechh
return
;*********************************************
;加速度センサ・パルス計測サブルーチン
; 消費時間:50μs(50.004μs)
; データ :X軸xplsh(上位)xplsl(下位)
; :Y軸yplsh(上位)yplsl(下位)
; :単位10μs
;*********************************************
Gmeas
clrf xplsh
clrf xplsl
clrf yplsh
clrf yplsl
clrf OUTBUF ;reset output buffer
call x_ad_conv
call y_ad_conv
; call WAIT_50M ;100ms周期時間あわせ
return
;**********X軸のADコンバータ通信************
x_ad_conv
clrf INBUFH ;reset input buffer
clrf INBUFL
BEGIN_AD_X
bcf PORTA,1 ;CS=RA1をLO select A/D converter
bsf PORTB,3 ;D_IN=RB3がHI 開始ビット
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bsf PORTB,3 ;D_IN=RB3がHI シングルエンド
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bcf PORTB,3 ;D_IN=RB3がLO D2無視
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bcf PORTB,3 ;D_IN=RB3がLO D1
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bsf PORTB,3 ;D_IN=RB3がHI D0
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
call IN_DATA ;read data from
A/D converter
bsf PORTA,1 ;CS=RA1をHI de-select A/D converter
movlw 00FH ;load MSB mask
andwf INBUFH,W ;mask out MSB’s and put result in W
movwf xplsh ;output MSB’s
movf INBUFL,W ;load LSB’s into W
movwf xplsl ;output LSB’s
return ;finished, return to caller
;**********Y軸のADコンバータ通信************
y_ad_conv
clrf INBUFH ;reset input buffer
clrf INBUFL
BEGIN_AD_Y
bcf PORTA,1 ;CS=RA1をLO select A/D converter
bsf PORTB,3 ;D_IN=RB3がHI 開始ビット
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bsf PORTB,3 ;D_IN=RB3がHI シングルエンド
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bcf PORTB,3 ;D_IN=RB3がLO D2
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bcf PORTB,3 ;D_IN=RB3がLO D1
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
bcf PORTB,3 ;D_IN=RB3がLO D0
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
call IN_DATA ;read data from
A/D converter
bsf PORTA,1 ;CS=RA1をHI de-select A/D converter
movlw 0FH ;load MSB mask
andwf INBUFH,W ;mask out MSB’s and put result in W
movwf yplsh ;output MSB’s
movf INBUFL,W ;load LSB’s into W
movwf yplsl ;output LSB’s
return ;finished, return to caller
;**********ADコンバータ共通************
OUT_CONTROL
movlw 04H
movwf COUNT ;init bit counter
bsf PORTB,3 ;D_IN=RB3がHI 開始ビット
bsf PORTA,0 ;CLK=RA0をHI generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
BIT_OUT
rlf OUTBUF,W ;rotate bit into carry
movwf OUTBUF
bcf PORTB,3 ;D_IN=RB3がLO pre-clear data out
btfsc STATUS,C ;check if bit should be set
bsf PORTB,3 ;D_IN=RB3がHI set data out
bsf PORTA,0 ;CLK=RA0をHI
generate clock pulse
bcf PORTA,0 ;CLK=RA0をLO
decfsz COUNT ;decrement bit
counter
goto BIT_OUT ;output next bit
return ;finished, return to caller
IN_DATA
clrf INBUFL
clrf INBUFH ;reset input buffer
movlw 0DH
movwf COUNT ;init bit counter
bsf PORTA,0 ;CLK=RA0をHI 1サイクル待ち(前回のLOと合計して1.5サイクル)
bcf PORTA,0 ;CLK=RA0をLO
BIT_IN
bsf PORTA,0 ;CLK=RA0をHI set clock to latch bit
bcf STATUS,C ;pre-clear carry
btfsc PORTB,2 ;D_OUT=RB2を check for high or low bit
bsf STATUS,C ;set carry bit
rlf INBUFL,f
rlf INBUFH,f ;rotate bit into position
bcf PORTA,0 ;CLK=RA0をLO drop clock for next bit
decfsz COUNT ;decrement bit
counter
goto BIT_IN ;get next bit
return ;return to caller
;*********************************************
;車速データ受信サブルーチン
; データ:plsh(上位)plsl(下位)
; SP_CLK受信ポート=RA4
; SP_REQ送信ポート=RB4
; SP_DATA受信ポート=RB0
;*********************************************
Speed
movlw 0CH ;実車速化に伴い8bit+ペダル4bit
movwf countf ;init bit counter
bcf STATUS,C
bcf PORTB,4 ;SP_REQ=RB4をLO(初期化)
movlw 078H ;C423H=50210μs-DATATR時間220H544μS=C203H
movwf counte ;C203H/2(ワード数で約半分以下)=6978H
movlw 069H ;オーバーフロー用(0km/h判定)
movwf countg ;ただし,車速PICの返答時間までとし,残りの余りは別でWAIT処理する
clrf plsh ;車速
clrf plsl ;車速
clrf Pedal
clrf COUNT
SP_REQ1
btfss PORTA,4 ;SP_CLKがHIなら次をスキップ
goto WAIT_BEFOR ;LOなのでHIになるまで規定時間待つ
bsf PORTB,4 ;SP_REQ=RB4をHI,車速PICはDATATRに移行
;今はCLKはHI,車速応答はHI
SP_REQ2 ;車速PICはBIT_OUT_HI
btfsc PORTA,4 ;SP_CLKがLOなら次をスキップ
goto SP_REQ2 ;HIなのでLOになるまで待つ
;今はCLKはLO,車速応答はHI
btfsc PORTB,0 ;SP_DATAがLOなら次をスキップ
bsf STATUS,C ;set carry bit
rlf plsl,f
; rlf plsh,f
rlf Pedal,f ;ペダル情報受信結果格納
bcf PORTB,4 ;SP_REQ=RB4をLO
CHECK ;今はCLKはLO,車速応答はLO
btfss PORTA,4 ;SP_CLKがHIなら次をスキップ
goto CHECK ;LOなのでHIになるまで待つ
bsf PORTB,4 ;SP_REQ=RB4をHI
decfsz countf ;decrement bit
counter
goto SP_REQ2
bcf PORTB,4 ;SP_REQ=RB4をLO
;*********残りWaitTime消費*******
movf COUNT,w ;wait回数を引き算する
andlw 2 ;wait回数とカウントワード分
addwf counte,f
DOWN1
decfsz counte,f
goto DOWN1
movlw 0FFH
movwf counte
decfsz countg,f
goto DOWN1
;*********固定WaitTime消費*******
movlw 0ACH ;DATATR時間と同じ時間(544μs)をここで消費する
movwf counte ;220H-70H-4H=1ACh=428
movlw 001H ;データ転送時間を引き算する
movwf countg ;14ワード×8回=112ワード=70H
DOWN2
decfsz counte,f
goto DOWN2
movlw 0FFH
movwf counte
decfsz countg,f
goto DOWN2
movf plsh,w
movwf old_plsh
movf plsl,w
movwf old_plsl
return
WAIT_BEFOR
incf COUNT ;wait回数カウンタ
decfsz counte,f ;0になったら次をスキップ
goto SP_REQ1
movlw 0FFH
movwf counte
decfsz countg,f
goto SP_REQ1
;******0km/h処理*********
SPEED_ZERO ;カウントオーバフローなので前回のデータを使用する
movf old_plsh,w
movwf plsh
movf old_plsl,w
movwf plsl
return ;カウントオーバフローなので戻る
end