;DS18S20温度表示TEST-04 Ver 1.00	NAO TECHUNOHUT		2004-02-15(日)
;
;[プログラム概要]
; ･DS18S20温度センサーのﾟC温度とCRC計算比較をLCDに表示させてみるテスト｡
; ･オシレーターは内部RC4MHzを使用する｡
;　　タイマー2のプリスケーラを1:1設定にして1カウント当たり1μsにする｡
;　　タイマー1もプリスケーラを1:1設定にして1カウント当たり1μsで使用する｡
; ･LCDは20文字x4行を4ビットモードでビジーチェックする｡
;	  12345678901234567890
;	┌──────────┐
;	│DS18S20 T4.         │
;	│thermometer  -00.5ﾟC│
;	│mDS_CRC:255--255    │
;	│                    │
;	└──────────┘
;[PIC選定その他仕様]
; ･PIC16F819-I/P使用｡(秋月電子通商で350円/個)
; ･MCLRは外配線を簡略するため内部接続モードとする｡
;			     ┌─┰─┐
;	未使用		(#01)┥	     ┝(#18)	未使用
;	未使用		(#02)┥	     ┝ RA0	DS18S20
;	未使用		(#03)┥	     ┝(#16)	未使用
;	未使用		(#04)┥PIC16F┝(#15)	未使用
;			 Vss ┥  819 ┝ Vdd	5.0V
;	LCD_電源	 RB0 ┥	     ┝ RB7	LCD_DB7
;	LCD_RS		 RB1 ┥	     ┝ RB6	LCD_DB6
;	LCD_R/W		 RB2 ┥	     ┝ RB5	LCD_DB5
;	LCD_E		 RB3 ┥	     ┝ RB4	LCD_DB4
;			     └───┘
;-------PIC初期状態確認-----------------;(▲:変更必要)
;Bank 0
;	tmr0		xxxxxxxx	;　タイマー0の状態
;	status		00011xxx	;　Bankセレクト設定､各旗の状態
;	porta		xxx00000	;　RAピン出力状態(xは不定)
;	portb		xxxxxxxx	;▲RBピン出力状態(xは不定)
;	intcon		0000000x	;　割り込み他､設定
;	pir1		-0--0000	;　旗状態(A/D､タイマー､
;	pir2		---0----	;　EEメモリー､他)
;	tmr1l		xxxxxxxx	;　タイマー1下位8bitの状態
;	tmr1h		xxxxxxxx	;　タイマー1上位8bitの状態
;	t1con		--000000	;▲タイマー1コントロール関係設定
;	tmr2		00000000	;　タイマー2の状態
;	t2con		-0000000	;▲タイマー2コントロール関係設定
;	sspbuf		xxxxxxxx	;　装置内通信SPI通信機能
;	sspcon		00000000	;　
;	ccpr1l		xxxxxxxx	;　
;	ccpr1h		xxxxxxxx	;　
;	ccp1con		--000000	;　キャプチャ/コンペア/PWM
;	adresh		xxxxxxxx	;　A/D変換値9､10bit？
;	adcon0		000000-0	;　A/Dコントロール関係設定
;Bank 1
;	option_reg	11111111	;　プルアップ､プリスケーラー比率他､設定
;	trisa		11111111	;▲RAピンI/O制御設定(1は入力)
;	trisb		11111111	;▲RBピンI/O制御設定(1は入力)
;	pie1		-0--0000	;　A/D､CCP､タイマー､EEメモリーの
;	pie2		---0----	;　割り込み使用するしない設定
;	pcon		------qq	;　パワーオン､低電圧リセットの？
;	osccon		-000-0--	;▲内部RCオシレーター周波数設定
;	osctune		--000000	;　内蔵RCオシレーター微調整？
;	pr2		11111111	;　
;	sspadd		00000000	;　
;	sspstat		00000000	;　
;	adresl		xxxxxxxx	;　A/D変換値0～8bit
;	adcon1		00--0000	;▲A/Dピン設定
;Bank 2
;	eedata		xxxxxxxx	;　EEメモリーの状態 Lo？
;	eeadr		xxxxxxxx	;　EEメモリーのアドレス位置 Lo
;	eedath		--xxxxxx	;　EEメモリーの状態 Hi？
;	eeadrh		-----xxx	;　EEメモリーのアドレス位置 Hi
;Bank 3
;	eecon1		x--xx000	;　EEメモリー関係設定
;	eecon2		--------	;　EEメモリー関係設定？
;
;[凡例] (自分で分かりやすいように目印を付ける)
; m???:メモリー  r???:ラベル  s???:サブルーチン  v???:変数  ★:調整箇所など
;
;-------PIC基本設定---------------------;
; CVASM16アセンブラ用記述

	include	'16f819.inc'

	fuses _intrc_io			;オシレーター設定→内蔵､ピンはra6設定
	fuses _wdt_off			;ウォッチドックタイマー→無効
	fuses _pwrte_on			;電源投入72ms間リセット→有効
	fuses _mclr_off			;MCLR端子(リセット)→設定しない
	fuses _boden_off		;低電圧リセット(約4V以下)→無し
	fuses _lvp_off			;低電圧プログミング(5V)→無効
	fuses _cpd_off			;eepromのコードプロテクト→無効
	fuses _wrt_enable_off		;eeconのFlashメモリ可能→しない
	fuses _debug_off		;インサーキットデバックモード→無効
	fuses _ccp1_rb2			;？
	fuses _cp_off			;コードプロテクト→無効

	id	'0004'			;★DS18S20TESTの№0004

;-------プログラム開始(初期設定他)------;

LCD_PW	=	rb.0			;LCD電源
LCD_RS	=	rb.1			;
LCD_RW	=	rb.2			;
LCD_E	=	rb.3			;

mFREE_A	=	20h			;汎用カウンターなど
mFREE_B	=	21h			;　　〃
mFREE_C	=	22h			;　　〃
mLCD_44	=	23h			;汎用メモリー(LCD表示用)
mBINA08	=	24h			;BCD計算用
mBINAXX	=	25h			;　　〃
mSHOW08	=	26h			;　　〃
mBCD_1	=	27h			;B→Dの1桁目
mBCD_2	=	28h			;B→Dの2桁目
mBCD_3	=	29h			;B→Dの3桁目
mCOMMA	=	2Ah			;動作中確認｢.｣表示用
mSOUSIN	=	2Bh			;DS18S20送信データー用
mDS18_L	=	2Ch			;DS18S20温度データー下位バイト
mDS18_H	=	2Dh			;DS18S20温度データー上位バイト
mDATA_2	=	2Eh			;(THレジスタまたはユーザー･バイト1)
mDATA_3	=	2Fh			;(TLレジスタまたはユーザー･バイト2)
mDATA_4	=	30h			;(予約済み)
mDATA_5	=	31h			;(予約済み)
mDATA_6	=	32h			;(温度変換カウンタ(COUNT REMAIN))
mDATA_7	=	33h			;(温度変換カウンタ(COUNT PERﾟC))
mDS_CRC	=	34h			;CRC

mSHR1	=	35h			;計算で得たCRC

	clr	rb			;
	mov	t1con,#00000001b	;プリスケール1:1
	mov	t2con,#00000100b	;プリスケール1:1

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	clrb	trisa.0			;◆RA.0を出力に設定
	mov	trisb,#00000000b	;RBをすべて出力に設定
;	mov	osccon,#01110000b	;内蔵オシレーター周波数を8MHzに設定
	mov	osccon,#01100000b	;内蔵オシレーター周波数を4MHzに設定
;	mov	osccon,#01010000b	;内蔵オシレーター周波数を2MHzに設定
	mov	adcon1,#00000110b	;A/Dをすべてデジタルに設定
	clrb	rp0			;ページ変更(Bank 0へ戻す)
;Bank 0


;=======メイン==========================;

	setb	ra.0			;DS18S20準備

	setb	LCD_PW			;LCD電源 ON

	clr	mFREE_A			;
	mov	mFREE_B,#64		;★(4MHzなので128x0.5)
rWAIT00	djnz	mFREE_A,rWAIT00		;LCD受付OKになる頃まで待つ
	djnz	mFREE_B,rWAIT00		;(約0.05秒)

	mov	rb,#00101001b		;4ビットモード､+E+PW
	clrb	LCD_E			;これで4ビットモードになる
;↓4
	mov	mLCD_44,#00101000b	;(6)ファンクションセット設定
	call	sLCD_E_			;N=1(1/16)にすること

	mov	mLCD_44,#00001100b	;(4)表示オン/オフコントロール
	call	sLCD_E_			;

;[LCD配置表] (16進)    10000000b(80h)加算済
;	   |01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;	01 |80|81|82|83|84|85|86|87|88|89|8A|8B|8C|8D|8E|8F|90|91|92|93|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;	02 |C0|C1|C2|C3|C4|C5|C6|C7|C8|C9|CA|CB|CC|CD|CE|CF|D0|D1|D2|D3|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;	03 |94|95|96|97|98|99|9A|9B|9C|9D|9E|9F|A0|A1|A2|A3|A4|A5|A6|A7|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;	04 |D4|D5|D6|D7|D8|D9|DA|DB|DC|DD|DE|DF|E0|E1|E2|E3|E4|E5|E6|E7|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;キャラクターコード送信(表示)
	mov	mLCD_44,#'D'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'S'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'1'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'8'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'S'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'2'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'0'		;
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;
	call	sLCD_RE			;
	mov	mLCD_44,#'T'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'4'		;
	call	sLCD_RE			;

	mov	mLCD_44,#0C0h		;2行目1桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'t'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'h'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'e'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'r'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'m'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'o'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'m'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'e'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'t'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'e'		;
	call	sLCD_RE			;

	mov	mLCD_44,#0D0h		;2行目17桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'.'		;
	call	sLCD_RE			;

	mov	mLCD_44,#0D2h		;2行目19桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'ﾟ'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'C'		;
	call	sLCD_RE			;

	mov	mLCD_44,#94h		;3行目1桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'m'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'D'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'S'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'_'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'C'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'R'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'C'		;
	call	sLCD_RE			;
	mov	mLCD_44,#':'		;
	call	sLCD_RE			;

	mov	mLCD_44,#9Fh		;3行目12桁目
	call	sLCD_E_			;
	mov	mLCD_44,#01111111b	;｢←｣
	call	sLCD_RE			;
	mov	mLCD_44,#01111110b	;｢→｣
	call	sLCD_RE			;

;=======================================;
;***[ DS18S20 ]*************************;
rREPEAT
	call	sDRESET			;RESET送信
	mov	mSOUSIN,#0CCh		;スキップROMコード(CCh)送信
	call	sSOUSIN			;11001100b
	mov	mSOUSIN,#44h		;コンバートTコード(44h)送信
	call	sSOUSIN			;01000100b

	call	sWAIT_1			;約1秒の待ち時間(変換待ち他)

	call	sDRESET			;RESET送信
	mov	mSOUSIN,#0CCh		;スキップROMコード(CCh)送信
	call	sSOUSIN			;11001100b
	mov	mSOUSIN,#0BEh		;リード･スクラッチ･パッド･コード(BEh)
	call	sSOUSIN			;10111110b

	call	sREAD_9			;スクラッチ･パットのデーターを読む

	call	s9BCRC			;CRC計算


;キャラクターコード送信(表示)
;(温度計算と表示)
;---小数点第一位表示
	mov	mLCD_44,#0D1h		;1行目15桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'0'		;とりあえずゼロを入れる
	jnb	mDS18_L.0,$+3		;
	mov	mLCD_44,#'5'		;
	call	sLCD_RE			;

;---プラスマイナス判定と処理
	jnb	mDS18_H.0,rHALF		;1ビット目でマイナス判定
	clr	mFREE_A			;ゼロ化
	sub	mFREE_A,mDS18_L		;0-mDS18_L
	mov	mDS18_L,mFREE_A		;
;---÷2
rHALF
	clc				;クリアキャリー
	rr	mDS18_L			;
	
	mov	mBINA08,mDS18_L		;温度計測データーをBCD化
	call	sBCDCAL			;BCD計算へ

	jnb	mDS18_H.0,$+3		;1ビット目でマイナス判定
	mov	mBCD_3,#'-'		;マイナス表示

	mov	mLCD_44,#0CDh		;2行目14桁目
	call	sLCD_E_			;
	mov	mLCD_44,mBCD_3		;10進化3桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_2		;10進化2桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_1		;10進化1桁目表示
	call	sLCD_RE			;
;(mDS_CRC表示)
	mov	mBINA08,mDS_CRC		;計測CRCをBCD化
	call	sBCDCAL			;BCD計算へ
	mov	mLCD_44,#9Ch		;3行目9桁目
	call	sLCD_E_			;
	mov	mLCD_44,mBCD_3		;10進化3桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_2		;10進化2桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_1		;10進化1桁目表示
	call	sLCD_RE			;
;(CRC計算値表示)
	mov	mBINA08,mSHR1		;計算CRCをBCD化
	call	sBCDCAL			;BCD計算へ
	mov	mLCD_44,#0A1h		;3行目14桁目
	call	sLCD_E_			;
	mov	mLCD_44,mBCD_3		;10進化3桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_2		;10進化2桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_1		;10進化1桁目表示
	call	sLCD_RE			;
;動作中確認表示
	mov	mLCD_44,#8Ah		;1行目11桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'.'		;動作中確認｢.｣表示
	inc	mCOMMA			;+1
	jb	mCOMMA.0,$+3		;偶数､奇数判定
	mov	mLCD_44,#' '		;(点滅用)
	call	sLCD_RE			;

	jmp	rREPEAT			;∞繰り返し


;***************************************;
;=======================================;





;sssssss RESET送信及びエラーチェック sss;DS18S20
sDRESET
	clrb	ra.0			;RA.0→Lo
	mov	tmr1h,#0FDh		;480μs x1.5=720μsの待ちを作る
	mov	tmr1l,#30h		;(16ビットで0-720(10進)=FD30(16進))
	clrb	tmr1if			;
	jnb	tmr1if,$		;

	setb	rp0			;ページ変更(Bank 1へ)
	setb	trisa.0			;◆RA.0を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	mov	tmr1h,#0FDh		;(16ビットで0-720(10進)=FD30(16進))
	mov	tmr1l,#30h		;
	clrb	tmr1if			;480μs x1.5=720μs設定

;---Waits計測開始(15-60μs)
	clr	tmr2			;タイマー2の値クリア
	clrb	tmr2if			;タイマー2のオーバーフロー旗クリア
	jb	ra.0,$			;ビット0まで待つ
	mov	mFREE_A,tmr2		;タイマー2の値をメモリーに格納
	jb	tmr2if,rERROR		;リセットエラー判定
	cjbe	mFREE_A,#15,rERROR	;　　　〃
	cjae	mFREE_A,#60,rERROR	;　　　〃

;---pulse計測開始(60-240μs)
	clr	tmr2			;タイマー2の値クリア
	clrb	tmr2if			;タイマー2のオーバーフロー旗クリア
	jnb	ra.0,$			;ビット1まで待つ
	mov	mFREE_A,tmr2		;タイマー2の値をメモリーに格納
	jb	tmr2if,rERROR		;リセットエラー
	cjbe	mFREE_A,#60,rERROR	;　　　〃
	cjae	mFREE_A,#240,rERROR	;　　　〃

	jb	tmr1if,$		;設定しておいた720μsになるまで待つ

	setb	ra.0			;あらかじめHiにしておく
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.0			;◆RA.0を出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	ret				;リターン(サブルーチン終わり)

;RESETエラー処理
rERROR
	mov	mLCD_44,#0D4h		;4行目1桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'R'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'E'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'S'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'E'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'T'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'/'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'E'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'R'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'R'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'O'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'R'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'!'		;
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;
	call	sLCD_RE			;
	mov	mLCD_44,#'('		;
	call	sLCD_RE			;
	mov	mLCD_44,#'T'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'_'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'T'		;
	call	sLCD_RE			;
	mov	mLCD_44,#')'		;
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;
	call	sLCD_RE			;
	sleep				;スリープ状態にしてプログラム終了


;sssssss 送信パターン｢0｣か｢1｣ ssssssssss;DS18S20

sSOUSIN
	mov	mFREE_A,#8		;8ビット分
_rSOUSI
	jb	mSOUSIN.0,_rWRIT1	;｢0｣か｢1｣の判定
;｢0｣だった場合
	clrb	ra.0			;
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ
	setb	ra.0			;送信終わりの合図
	rr	mSOUSIN			;
	djnz	mFREE_A,_rSOUSI		;

	ret				;リターン(サブルーチン終わり)

;｢1｣だった場合
_rWRIT1
	clrb	ra.0			;
	setb	ra.0			;
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ

	rr	mSOUSIN			;
	djnz	mFREE_A,_rSOUSI		;

	ret				;リターン(サブルーチン終わり)

;sssssss 約1秒の待ち時間 sssssssssssssss;DS18S20
sWAIT_1
	clr	mFREE_A			;約0.98秒
	clr	mFREE_B			;
	mov	mFREE_C,#5		;
_r1WAIT	djnz	mFREE_A,_r1WAIT		;
	djnz	mFREE_B,_r1WAIT		;
	djnz	mFREE_C,_r1WAIT		;

	ret				;リターン(サブルーチン終わり)

;sssssss データー受信 ssssssssssssssssss;DS18S20
sREAD_9
	call	ssREAD9			;
	mov	mDS18_L,mFREE_A		;温度データー下位バイト
	call	ssREAD9			;
	mov	mDS18_H,mFREE_A		;温度データー上位バイト
	call	ssREAD9			;
	mov	mDATA_2,mFREE_A		;(THレジスタまたはユーザー･バイト1)
	call	ssREAD9			;
	mov	mDATA_3,mFREE_A		;(TLレジスタまたはユーザー･バイト2)
	call	ssREAD9			;
	mov	mDATA_4,mFREE_A		;(予約済み)
	call	ssREAD9			;
	mov	mDATA_5,mFREE_A		;(予約済み)
	call	ssREAD9			;
	mov	mDATA_6,mFREE_A		;(温度変換カウンタ(COUNT REMAIN))
	call	ssREAD9			;
	mov	mDATA_7,mFREE_A		;(温度変換カウンタ(COUNT PERﾟC))
	call	ssREAD9			;
	mov	mDS_CRC,mFREE_A		;CRC

	ret				;リターン(サブルーチン終わり)

;サブルーチンのサブルーチン
ssREAD9
	mov	mFREE_B,#8		;8ビット分
_rREAD9
	clrb	ra.0			;

	setb	rp0			;ページ変更(Bank 1へ)
	setb	trisa.0			;◆RA.0を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	nop				;
	nop				;
	nop				;

	clc				;クリアキャリー
	snb	ra.0			;
	stc				;セットキャリー
	rr	mFREE_A			;データーを7ビット目に入れる
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	nop				;
	jb	mDS18_L.7,rNZERO	;

;｢0｣だった場合
	mov	tmr2,#196		;(256-60=196)
	clrb	tmr2if			;
	jnb	tmr2if,$		;60μs待つ

	jnb	ra.0,$			;ビット立つまで待つ

;｢1｣だった場合(共通)
rNZERO
	setb	ra.0			;
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.0			;◆RA.0を出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	djnz	mFREE_B,_rREAD9		;

	ret				;リターン(サブルーチン終わり)

;sssssss CRC計算 sssssssssssssssssssssss;DS18S20
;
;CRCの計算方法についてはよく分からないので､この部分は､
;｢トラ技2003年12月号の272P～280P PIC16F84を使った温度コントローラの製作
;<前編>DS18S20を使いこなそう! 軸丸 哲也 氏作成｣
;を､ほぼそのまま転用した｡
;
;8バイトデーターからCRCを計算
s9BCRC
	clr	mSHR1			;
	mov	w,mDS18_L		;
	call	ssCRC			;
	mov	w,mDS18_H		;
	call	ssCRC			;
	mov	w,mDATA_2		;
	call	ssCRC			;
	mov	w,mDATA_3		;
	call	ssCRC			;
	mov	w,mDATA_4		;
	call	ssCRC			;
	mov	w,mDATA_5		;
	call	ssCRC			;
	mov	w,mDATA_6		;
	call	ssCRC			;
	mov	w,mDATA_7		;
	call	ssCRC			;

	ret				;

ssCRC
	mov	mFREE_A,w		;
	mov	mFREE_C,#8		;(汎用回数カウント)
_rCRC_L
	mov	w,mFREE_A		;
	xor	w,mSHR1			;mSHR1 = 計算で得たCRC
	mov	mFREE_B,w		;
	jnb	mFREE_B.0,_rZCRC	;
	xor	mSHR1,#11000b		;0001 1000(生成多項式による)
_rZCRC
	rr	mFREE_B			;
	rr	mSHR1			;
	rr	mFREE_A			;
	djnz	mFREE_C,_rCRC_L		;
	ret





;sssssss LCD E 送信関係 ssssssssssssssss;
sLCD_E_
	call	sBUSY7			;LCD受付OKになるまで待つ

	setb	LCD_E			;
	and	rb,#00001111b		;RB4～7クリア
	snb	mLCD_44.7		;
	setb	rb.7			;
	snb	mLCD_44.6		;
	setb	rb.6			;
	snb	mLCD_44.5		;
	setb	rb.5			;
	snb	mLCD_44.4		;
	setb	rb.4			;
	clrb	LCD_E			;

	setb	LCD_E			;
	and	rb,#00001111b		;RB4～7クリア
	snb	mLCD_44.3		;
	setb	rb.7			;
	snb	mLCD_44.2		;
	setb	rb.6			;
	snb	mLCD_44.1		;
	setb	rb.5			;
	snb	mLCD_44.0		;
	setb	rb.4			;
	clrb	LCD_E			;

	ret				;リターン(サブルーチン終わり)

;sssssss LCDキャラクター表示 sssssssssss;
sLCD_RE
	call	sBUSY7			;LCD受付OKになるまで待つ

	setb	LCD_RS			;
	setb	LCD_E			;
	and	rb,#00001111b		;RB4～7クリア
	snb	mLCD_44.7		;
	setb	rb.7			;
	snb	mLCD_44.6		;
	setb	rb.6			;
	snb	mLCD_44.5		;
	setb	rb.5			;
	snb	mLCD_44.4		;
	setb	rb.4			;
	clrb	LCD_E			;
	clrb	LCD_RS			;

	setb	LCD_RS			;
	setb	LCD_E			;
	and	rb,#00001111b		;RB4～7クリア
	snb	mLCD_44.3		;
	setb	rb.7			;
	snb	mLCD_44.2		;
	setb	rb.6			;
	snb	mLCD_44.1		;
	setb	rb.5			;
	snb	mLCD_44.0		;
	setb	rb.4			;
	clrb	LCD_E			;
	clrb	LCD_RS			;

	ret				;リターン(サブルーチン終わり)

;sssssss LCDビジーチェック sssssssssssss;
sBUSY7
	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	mov	trisb,#10000000b	;RB7を入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	setb	LCD_RW			;
	setb	LCD_E			;
	jb	rb.7,$			;ビジー信号が消えるまでここで待つ
	clrb	LCD_E			;
	clrb	LCD_RW			;

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	mov	trisb,#00000000b	;RB7を出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	ret				;リターン(サブルーチン終わり)

;sssssss BCD割り算(8bit÷10) ssssssssss;
sBCDCAL
	call	sBCDZAN			;1桁目
	mov	mBCD_1,mBINAXX		;余りを入れる

	mov	mBINA08,mSHOW08		;商を入れる
	call	sBCDZAN			;2桁目
	mov	mBCD_2,mBINAXX		;余りを入れる
	mov	mBCD_3,mSHOW08		;商を入れる

;---アスキーコード変換---
	add	mBCD_1,#48		;1桁目のアスキーコード変換
	add	mBCD_2,#48		;2桁目　　　　〃
	add	mBCD_3,#48		;3桁目　　　　〃

	ret				;リターン(サブルーチン終わり)

;---桁移動比較---
sBCDZAN
	mov	mFREE_A,#8		;ループ数設定
	clr	mBINAXX			;
rBCD_0	rl	mBINA08			;
	rl	mBINAXX			;

	jc	rBCD_2			;比較8ビット超判定
	cjae	mBINAXX,#10,rBCD_1	;勝ち負け判定
	clrb	c			;キャリー0
	jmp	rWARI_4			;
rBCD_1	sub	mBINAXX,#10		;引き算(余りはここに残る)
	jmp	rBCD_3			;
rBCD_2	clr	mFREE_B			;0にする
	sub	mFREE_B,#10		;
	add	mBINAXX,mFREE_B		;
rBCD_3	setb	c			;キャリー1

;---計算結果入れ---
rWARI_4	rl	mSHOW08			;計算結果を入れる
	djnz	mFREE_A,rBCD_0		;ループ継続判定

	ret				;リターン(サブルーチン終わり)

