;DS18S20携帯温度計 Ver 1.00		NAO TECHUNOHUT		2004-02-27(金)
;
;[プログラム概要]
; ･DS18S20温度センサー使用の携帯型温度計｡
; ･DS18S20のリセットエラー及びCRCエラーはEとして回数カウント表示する｡
; ･CR2032電池(3V)x1を5Vに昇圧する｡
; ･電池電圧をA/D比較して､約2.1～2.2V以下で警告表示する｡
; ･ウォッチドックタイマーを使用して省電力を図る｡
;　　プリスケーラ1:32設定で約0.5秒くらい｡
; ･オシレーターは内部RC4MHzを使用する｡
;　　タイマー2のプリスケーラを1:1設定にして1カウント当たり1μsにする｡
;　　タイマー1もプリスケーラを1:1設定にして1カウント当たり1μsで使用する｡
; ･LCDは16文字x2行を4ビットモードでビジーチェックする｡
; ･LCD濃度を濃く設定できるようにする｡
; ･ハードOFFスイッチを無効にする設定ができるようにする｡
; ･OFFタイマーは通常約10分として､約4時間の延長設定もできるようにする｡
;　　ただし､ハードOFFスイッチを無効にした場合は延長設定無しとする｡
;	  1234567890123456
;	┌────────┐
;	│Now -00.5ﾟC(51)*│
;	│Mem -00.5ﾟC * E0│
;	└────────┘
;[PIC選定その他仕様]
; ･PIC16F819-I/P使用｡(秋月電子通商で350円/個)
; ･MCLRは外配線を簡略するため内部接続モードとする｡
;			     ┌─┰─┐
;	電源スイッチ	 RA2 ┥	     ┝ RA1	DS18S20温度センサー
;	LCD_濃		 RA3 ┥	     ┝ RA0	電池 A/D
;	未使用		(#03)┥	     ┝(#16)	未使用
;	未使用		(#04)┥PIC16 ┝(#15)	未使用
;			 Vss ┥  F819┝ 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???:変数  ★:調整箇所など
;
; CVASM16アセンブラ用記述
;-------PICコンフィギュレーション設定---;

	include	'16f819.inc'

	fuses _intrc_io			;オシレーター設定→内蔵､ピンはra6設定
	fuses _wdt_on			;ウォッチドックタイマー→有効
	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	'0100'			;Ver1.00

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

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

v1MIN	=	51			;★約1分カウントの調整用

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桁目
mSOUSIN	=	2Ah			;DS18S20送信データー用
mDS18_L	=	2Bh			;DS18S20温度データー下位バイト
mDS18_H	=	2Ch			;DS18S20温度データー上位バイト
mDATA_2	=	2Dh			;(THレジスタまたはユーザー･バイト1)
mDATA_3	=	2Eh			;(TLレジスタまたはユーザー･バイト2)
mDATA_4	=	3Fh			;(予約済み)
mDATA_5	=	30h			;(予約済み)
mDATA_6	=	31h			;(温度変換カウンタ(COUNT REMAIN))
mDATA_7	=	32h			;(温度変換カウンタ(COUNT PERﾟC))
mDS_CRC	=	33h			;CRC
mSHR1	=	34h			;計算で得たCRC

mCOUNTs	=	35h			;約1秒カウンター
mAUTOFF	=	36h			;約1分カウンター(OFFタイマー用)
mERROR	=	37h			;エラーカウンター
m_0or5	=	38h			;小数点第一位の温度表示用
mST_BIT	=	39h			;電源ON直後の初期設定用
;3bit…OFFタイマー
;2bit…ハードOFF無効
;1bit…LCD濃
;0bit…電源ON直後の隙間

mMY_BIT	=	3Ah			;各種ビット
;7bit…1ならCRCエラー
;6bit…1なら電圧低下
;3bit…1ならOFFタイマー延長
;2bit…1ならハードOFF無効
;1bit…未使用
;0bit…未使用

;=======プログラムスタート設定==========;

	clr	wdt			;ウォッチドックタイマークリア
	mov	mCOUNTs,#3		;
	clr	mAUTOFF			;
	clr	mERROR			;
	mov	mST_BIT,#00001111b	;電源ON直後の初期設定用
	clr	mMY_BIT			;
	setb	ra.1			;DS18S20準備

	clr	rb			;
	mov	t1con,#00000001b	;プリスケール1:1
	mov	t2con,#00000100b	;プリスケール1:1
	mov	adcon0,#11000000b	;A/Dクロック設定(内蔵RC)

	setb	rp0			;ページ変更(Bank 1へ)
;Bank 1
	mov	option_reg,#11111101b	;WDT用プリスケーラ1:32に設定(約0.5秒)
	clrb	trisa.1			;RA.1(温度センサー)のみ出力ピンに設定
	mov	trisb,#00000000b	;RBをすべて出力に設定
;	mov	osccon,#01110000b	;内蔵オシレーター周波数を8MHzに設定
	mov	osccon,#01100000b	;内蔵オシレーター周波数を4MHzに設定
;	mov	osccon,#01010000b	;内蔵オシレーター周波数を2MHzに設定
	mov	adcon1,#00001110b	;RA.0のみA/Dに設定､基準電圧はVdd､8bit
	clrb	rp0			;ページ変更(Bank 0へ戻す)
;Bank 0

;-------LCD初期表示---------------------;

	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		;(8MHzの場合で計算すると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自作キャラクター登録
	mov	mLCD_44,#01000000b	;アドレスセット №0-0
	call	sLCD_E_			;
;下左矢印(Enter風)
	mov	mLCD_44,#00000001b	;0-0ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000101b	;0-1ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00001001b	;0-2ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00011111b	;0-3ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00001000b	;0-4ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000100b	;0-5ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;0-6ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;0-7ドットデーター
	call	sLCD_RE			;
;電池空
	mov	mLCD_44,#00001110b	;1-0ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00011111b	;1-1ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00010001b	;1-2ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00010001b	;1-3ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00010001b	;1-4ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00010001b	;1-5ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00011111b	;1-6ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;1-7ドットデーター
	call	sLCD_RE			;
;｢ﾟ｣の右寄せ
	mov	mLCD_44,#00000111b	;2-0ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000101b	;2-1ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000111b	;2-2ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;2-3ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;2-4ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;2-5ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;2-6ドットデーター
	call	sLCD_RE			;
	mov	mLCD_44,#00000000b	;2-7ドットデーター
	call	sLCD_RE			;

;[LCD配置表] (16進)    10000000b(80h)加算済
;	   |01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;	01 |80|81|82|83|84|85|86|87|88|89|8A|8B|8C|8D|8E|8F|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;	02 |C0|C1|C2|C3|C4|C5|C6|C7|C8|C9|CA|CB|CC|CD|CE|CF|
;	---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
;キャラクターコード送信(表示)
;1行目
	mov	mLCD_44,#80h		;1行目1桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'N'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'o'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'w'		;
	call	sLCD_RE			;
	mov	mLCD_44,#87h		;1行目8桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'.'		;
	call	sLCD_RE			;
	mov	mLCD_44,#89h		;1行目10桁目
	call	sLCD_E_			;
	mov	mLCD_44,#2		;キャラクター登録№2
	call	sLCD_RE			;｢ﾟ｣の右寄せ
	mov	mLCD_44,#'C'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'('		;
	call	sLCD_RE			;
	mov	mLCD_44,#8Eh		;1行目15桁目
	call	sLCD_E_			;
	mov	mLCD_44,#')'		;
	call	sLCD_RE			;
;2行目
	mov	mLCD_44,#0C0h		;2行目1桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'M'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'e'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'m'		;
	call	sLCD_RE			;
	mov	mLCD_44,#0C7h		;2行目8桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'.'		;
	call	sLCD_RE			;
	mov	mLCD_44,#0C9h		;1行目10桁目
	call	sLCD_E_			;
	mov	mLCD_44,#2		;キャラクター登録№2
	call	sLCD_RE			;｢ﾟ｣の右寄せ
	mov	mLCD_44,#'C'		;
	call	sLCD_RE			;
	mov	mLCD_44,#0CCh		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#0		;キャラクター登録№0
	call	sLCD_RE			;下左矢印
	mov	mLCD_44,#0CEh		;1行目15桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'E'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'0'		;
	call	sLCD_RE			;



;↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ;
;***[ メインループ ]********************;

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

;電池電圧低下点滅用
	jb	mMY_BIT.6,rBAT_L1	;電池電圧低下なら｢ ｣(空白)表示へ
rJBACK_1
	sleep				;WDTによる約0.5秒の待ち時間(変換待ち他)

;A/D電池電圧チェック(110で警告表示)
	setb	adon			;A/D有効(A/D変換準備)
	clrb	mMY_BIT.6		;
	mov	mFREE_A,#10		;暖機運転必要?!
	djnz	mFREE_A,$		;nop2～3回では足りない!
	setb	go_done			;A/D変換開始
	jb	go_done,$		;A/D変換終了まで待つ
	clrb	adon			;省電力化

	cjb	adresh,#110,rBAT_L0	;110未満なら｢電池空｣表示へ
rJBACK_0
	sleep				;WDTによる約0.5秒の待ち時間(変換待ち他)

	call	sDRESET			;DS18S20/RESET送信
	mov	mSOUSIN,#0CCh		;スキップROMコード(CCh)送信
	call	sSOUSIN			;11001100b
	mov	mSOUSIN,#0BEh		;リード･スクラッチ･パッド･コード(BEh)
	call	sSOUSIN			;10111110b
	call	sREAD_9			;スクラッチ･パットのデーターを読む
	call	s9BCRC			;CRC計算とエラー判定
	jb	mMY_BIT.7,rERROR	;CRCエラーがあった場合｢---.-｣表示へ

;-------温度計算と表示------------------;
;小数点第一位表示
	mov	m_0or5,#'0'		;とりあえず｢0｣を入れる
	jnb	mDS18_L.0,$+4		;1ビット目判定
	mov	m_0or5,#'5'		;
;マイナス判定と処理
	jb	mDS18_H.0,rMINUS	;1ビット目でマイナス判定､表示へ
rJBACK_2
;÷2計算
	clc				;クリアキャリー
	rr	mDS18_L			;÷2
	mov	mBINA08,mDS18_L		;温度計測データーをBCD化
	call	sBCDCAL			;BCD計算へ
	jnb	mDS18_H.0,$+4		;1ビット目でマイナス判定
	mov	mBCD_3,#'-'		;マイナス表示
rCRC_E
	mov	mLCD_44,#84h		;1行目5桁目
	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,#88h		;1行目9桁目
	call	sLCD_E_			;
	mov	mLCD_44,m_0or5		;
	call	sLCD_RE			;
;2行目の更新表示
	cje	mCOUNTs,#0,rMEMORY	;カウントゼロになったら更新表示へ
rJBACK_3

;-------[ 初期設定変更 ]----------------;
	jb	mST_BIT.0,r03		;(電源ON直後の隙間)
	jb	mST_BIT.1,rL3		;LCD濃度設定
	jb	mST_BIT.2,rS3		;ハードOFF有効無効設定
	jb	mST_BIT.3,rT3		;OFFタイマー時間設定
;---------------------------------------;

;ダウンカウント表示
	mov	mBINA08,mCOUNTs		;カウンターをBCD化
	call	sBCDCAL			;BCD計算へ
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,mBCD_2		;10進化2桁目表示
	call	sLCD_RE			;
	mov	mLCD_44,mBCD_1		;10進化1桁目表示
	call	sLCD_RE			;

	dec	mCOUNTs			;-1
	cjbe	mCOUNTs,#v1MIN,rCONT_E	;★設定値以下ならジャンプ
	mov	mCOUNTs,#v1MIN		;★カウントリセット
rCONT_E
;エラー(E)回数表示と1桁補正
	jb	mMY_BIT.7,rERR_CT	;エラーがあった場合表示へ
rJBACK_4

;-------電源OFFチェック-----------------;
;オートOFFカウントと判定
	test	mCOUNTs			;ゼロか?
	snz				;約1分で1カウントUP
	inc	mAUTOFF			;+1
	jb	mMY_BIT.3,_rTM_L	;長時間設定か?
	cjae	mAUTOFF,#14,rPW_OFF	;約10分(初期設定で｢4｣消費)
;	cjae	mAUTOFF,#5,rPW_OFF	;★約1分テスト(初期設定で｢4｣消費)
_rTM_L
	cjae	mAUTOFF,#244,rPW_OFF	;約4時間
;	cjae	mAUTOFF,#7,rPW_OFF	;★約3分テスト(初期設定で｢4｣消費)
;ハードOFF判定
	jb	mST_BIT.3,rREPEAT	;初期設定中?
	jb	mMY_BIT.2,rREPEAT	;設定によりハードOFFなし!
	jnb	ra.2,rPW_OFF		;ハードOFF操作中?
	jmp	rREPEAT			;∞繰り返し


;***[ メインループここまで ]************;
;↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ;





rBAT_L1
	mov	mLCD_44,#8Fh		;1行目16桁目
	call	sLCD_E_			;
	mov	mLCD_44,#' '		;電池電圧低下点滅用
	call	sLCD_RE			;
	jmp	rJBACK_1		;ジャンプリターン
rBAT_L0
	mov	mLCD_44,#8Fh		;1行目16桁目
	call	sLCD_E_			;
	mov	mLCD_44,#1		;キャラクター登録№1表示
	call	sLCD_RE			;電池電圧低下
	setb	mMY_BIT.6		;
	jmp	rJBACK_0		;ジャンプリターン
rMINUS
	clr	mFREE_A			;ゼロ化
	sub	mFREE_A,mDS18_L		;0-mDS18_L
	mov	mDS18_L,mFREE_A		;
	jmp	rJBACK_2		;ジャンプリターン
rERROR
	mov	mBCD_3,#'-'		;CRCエラーがあった場合｢---.-｣表示
	mov	mBCD_2,#'-'		;
	mov	mBCD_1,#'-'		;
	mov	m_0or5,#'-'		;
	jmp	rCRC_E			;ジャンプリターン
rMEMORY
	mov	mLCD_44,#0C4h		;2行目5桁目(2行目の更新表示)
	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,#0C8h		;2行目9桁目
	call	sLCD_E_			;
	mov	mLCD_44,m_0or5		;
	call	sLCD_RE			;
	jmp	rJBACK_3		;ジャンプリターン
rERR_CT
	clrb	mMY_BIT.7		;エラー(E)回数表示と1桁補正
	cjbe	mERROR,#9,$+6		;9以下ならジャンプ
	mov	mERROR,#1		;リセット
	mov	mLCD_44,#0CFh		;2行目16桁目
	call	sLCD_E_			;
	mov	mLCD_44,mERROR		;
	add	mLCD_44,#48		;エラー数をアスキーコード変換
	call	sLCD_RE			;
	jmp	rJBACK_4		;ジャンプリターン

;初期設定変更
;(電源ON直後の隙間)
r03
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'0'		;
	call	sLCD_RE			;
	mov	mLCD_44,mCOUNTs		;
	add	mLCD_44,#48		;アスキーコード変換
	call	sLCD_RE			;
	dec	mCOUNTs			;-1
	jnb	mCOUNTs.7,rCONT_E	;負の判定
	clrb	mST_BIT.0		;
	mov	mCOUNTs,#3		;
	jmp	rCONT_E			;ジャンプリターン
;LCD濃度濃設定
rL3
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'L'		;
	call	sLCD_RE			;
	mov	mLCD_44,mCOUNTs		;
	add	mLCD_44,#48		;アスキーコード変換
	call	sLCD_RE			;

	jb	ra.2,_rL3_1		;
	clrb	ra.3			;
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.3			;◆出力ピンに変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'*'		;
	call	sLCD_RE			;
_rL3_1
	dec	mCOUNTs			;-1
	jnb	mCOUNTs.7,rCONT_E	;負の判定
	clrb	mST_BIT.1		;
	mov	mCOUNTs,#3		;
	jmp	rCONT_E			;ジャンプリターン

;ハードOFF無効設定
rS3
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'S'		;
	call	sLCD_RE			;
	mov	mLCD_44,mCOUNTs		;
	add	mLCD_44,#48		;アスキーコード変換
	call	sLCD_RE			;

	jb	ra.2,_rS3_1		;
	setb	mMY_BIT.2		;
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'*'		;
	call	sLCD_RE			;
_rS3_1
	dec	mCOUNTs			;-1
	jnb	mCOUNTs.7,rCONT_E	;負の判定
	clrb	mST_BIT.2		;

	jb	mMY_BIT.2,_rT3_Z	;ハードOFFにした場合は長時間OFF無し

	mov	mCOUNTs,#3		;
	jmp	rCONT_E			;ジャンプリターン


;OFFタイマー延長設定
rT3
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'T'		;
	call	sLCD_RE			;
	mov	mLCD_44,mCOUNTs		;
	add	mLCD_44,#48		;アスキーコード変換
	call	sLCD_RE			;

	jb	ra.2,_rT3_1		;
	setb	mMY_BIT.3		;
	mov	mLCD_44,#8Ch		;1行目13桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'*'		;
	call	sLCD_RE			;
_rT3_1
	dec	mCOUNTs			;-1
	jnb	mCOUNTs.7,rCONT_E	;負の判定
_rT3_Z
	clrb	mST_BIT.3		;
	mov	mCOUNTs,#v1MIN		;★
	jmp	rCONT_E			;ジャンプリターン





;sssssss RESET送信及びエラーチェック sss;DS18S20
sDRESET
	clrb	ra.1			;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.1			;◆入力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

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

;---Waits計測開始(15-60μs)
	clr	tmr2			;タイマー2の値クリア
	clrb	tmr2if			;タイマー2のオーバーフロー旗クリア
	jb	ra.1,$			;ビット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.1,$			;ビット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.1			;あらかじめHiにしておく
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.1			;◆出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

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


;RESETエラー処理
_rERROR
	inc	mERROR			;+1
	setb	ra.1			;あらかじめHiにしておく
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.1			;◆出力に変更
	clrb	rp0			;ページ変更(Bank 0へ戻す)

	jmp	sDRESET			;


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

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

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

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

	rr	mSOUSIN			;
	djnz	mFREE_A,_rSOUSI		;

	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.1			;

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

	nop				;
	nop				;
	nop				;

	clc				;クリアキャリー
	snb	ra.1			;
	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.1,$			;ビット立つまで待つ

;｢1｣だった場合(共通)
rNZERO
	setb	ra.1			;
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.1			;◆出力に変更
	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			;
;CRCエラー判定
	mov	mFREE_A,mDS_CRC		;
	sub	mFREE_A,mSHR1		;CRC-計算CRC
	jz	$+4			;
	inc	mERROR			;+1
	setb	mMY_BIT.7		;

	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				;リターン(サブルーチン終わり)


;***************************************;
;****** 電源OFF終了 ********************;
;***************************************;
rPW_OFF
	mov	mLCD_44,#1		;表示クリア
	call	sLCD_E_			;
	mov	mLCD_44,#'P'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'o'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'w'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'e'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'r'		;
	call	sLCD_RE			;
	mov	mLCD_44,#' '		;
	call	sLCD_RE			;
	mov	mLCD_44,#'O'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'F'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'F'		;
	call	sLCD_RE			;
	mov	mLCD_44,#0C7h		;2行目8桁目
	call	sLCD_E_			;
	mov	mLCD_44,#'S'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'.'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'N'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'a'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'o'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'y'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'u'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'k'		;
	call	sLCD_RE			;
	mov	mLCD_44,#'i'		;
	call	sLCD_RE			;

	clr	wdt			;ウォッチドッククリア
	jnb	ra.2,$-1		;スイッチ離すまで待つ

	clrb	ra.2			;
	setb	rp0			;ページ変更(Bank 1へ)
	clrb	trisa.2			;◆出力に変更
	jmp	$			;
;	clrb	rp0			;ページ変更(Bank 0へ戻す)
