GPS 経緯度&時計表示器 16F877A版

<B>
<font COLOR="blue" >
・---------------------------------------------------------------------------------------・<BR>
・GPSに興味があり<a href="https://akizukidenshi.com/catalog/">秋月電子</A>のGPS受信機で作ってみました。<BR>
・時刻の表示も可能です。(衛星からは時刻データも送られてくる)<BR>
・GPSって何? という時代にGP-22というICOM製のレシーバ(数値しか出ない)を<BR>
・大枚はたいて買った事があり。持ち歩て経緯度が変わるのをみて感動してました。<BR>
・---------------------------------------------------------------------------------------・</B></FONT>

<font COLOR="blue" >

### 1.取り敢えず受信してみる
</FONT>

![P1160305.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/fda3f694-c5dc-20d7-8d92-8f1e3960e228.jpeg)
レベルコンバータが内蔵されいるのでシリアルに接続するだけでGPSデータが得られる。

![P1160299.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/e4817253-f0a7-8d67-1935-3f1cca0302a3.jpeg)
* これだけでデータが受信できる。10分位で完成。

![P1160303.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/4b6fe413-ec60-5b18-4bbd-15d39ab79b3f.jpeg)
* 2本は未使用なのでカット。

![P1160306.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/423e9f14-61ad-f78b-8b21-71e69c4884e5.jpeg)
補足している衛星、経緯度、標高、日付と時刻、利用可能な衛星、最小構成の航法、針路/速度情報等のデータが流れてくる。初めは見てて面白いがすぐ飽きる。

<HR>
<font COLOR="blue" >

### 2.LCDに表示してみる</FONT>
・データの羅列ではどうしようもないので必要データを抽出してLCDに出力させる
[使用した主な部品一覧]
GPS -> <a href="https://akizukidenshi.com/catalog/faq/goodsfaq.aspx?goods=M-02711">RS232Cレベルコンバータ内蔵GPSモジュール GT-720F</A>
LCD -> <a href="https://akizukidenshi.com/catalog/g/gP-00038/">SC1602</A>
PIC -> <a href="https://akizukidenshi.com/catalog/g/gI-00266/">16F877A</A>

##### ブレッドボードに組み込んだ様子　左の四角いものがレシーバ
</font>

![P1160314.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/bf7db7b8-feb6-845b-4248-3ccb7ab9512f.jpeg)

* 時計(JST)表示中。衛星の原子時計のデータなので正確。SATは捕捉している衛星数。
![P1160469.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/df95f5f2-f4be-cb79-9fcd-a953f051bcc3.jpeg)


* 時刻データはUTCなのでプログラムでJST(+9H)に変換している。
日付はUTC15:00で日付を+1している。
* ただし、JST30日、31日の場合は+1して表示はせず、「+1」と表示されるので自分で1日プラスして読んでもらいたい。
というのも30日、31日の時、単純に+1とすると実際と異なる場合があるため。(月によって30日や31日の月がある為)
* その他、12/31 UTC15:00の場合は年を+1して01/01 00:00と計算する必要がある。その他、閏年など面倒な処理が必要となる。途中までコード書いたがテストが面倒なので削除。


* データの流れはGPSモジュール -> RS232Cドライバ -> PICマイコン -> LCD。
経緯度は＄GPGGAに入っているので　$GPGGA　の文字がくるまでスルーして、
経緯度のデータなど必要な文字を取得してLCDに表示している。

下記のリンク先で衛星から来るデータの詳細が確認できる。
<a href="https://www.hiramine.com/physicalcomputing/general/gps_nmeaformat.html">ナブスター衛生からのデータフォーマット</A> OSI-APP層辺りまで昇格してるので扱いが楽です。<BR>
<HR>
<font COLOR="blue" >

### 3.回路図 PIC 16F877A版</FONT>

![新しいビットマップ イメージ (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/30bae067-e8ae-4add-2116-ba32a79cb286.jpeg)

<font COLOR="blue" >

### 4.ASM形式 ソースコード</FONT>

```armasm
;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GPSモジュール GT-720F 16F877A データ表示器 (c) inf102
; XTAL 3.58MHz RS232C=9600BPS N81
; CQ出版社 はじめてのPICアセンブラ入門のコード流用 LCD,シリアル http://mycomputer.cqpub.co.jp/pic004/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	LIST	P=16F877A		
	#INCLUDE P16F877A.INC
	__CONFIG _XT_OSC & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF

#define	LCD_E		PORTD,0
#define	LCD_RS		PORTD,1
#define	LCD_RW		PORTD,2
#define LCD_PORT	PORTB
#define LCD_PORT_	PORTB_

TRISB_LCD_OUT	equ	B'00001111'
TRISB_LCD_IN	equ	B'11111111'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	CBLOCK	020H
	TMP	

	STR_LOOP	
	CT_DELAY100US
	CT_DELAY1MS	
	LCD_DAT
	LCD_TMP
	LCD_PORT_TMP
	LCD_RDAT	
	HEX_TMP	
	PORTB_	
	T1
	T2
	T3
	T4

	H1
	H2

	SWFLG

	DAY1
	DAY2
	DAY3
	DAY4
	DAY5
	DAY6

	DAYFLG

	ENDC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org	0x000

	; BK0 ;;;;;;;;;;;;;
	BCF		STATUS, RP0
	BCF		STATUS, RP1

	CLRF	INTCON		; 割り込み禁止
	CLRF	PORTA
	CLRF	PORTB
	CLRF	PORTC		
	CLRF	PORTD		
	CLRF	PORTE	

	; 232C
	MOVLW	B'10010000'
	MOVWF	RCSTA

	; BK1 ;;;;;;;;;;;;;
	BSF		STATUS, RP0

	; NO A/D
	MOVLW	B'00000110'
	MOVWF	ADCON1

	MOVLW	TRISB_LCD_OUT
	MOVWF	TRISB
	BCF		OPTION_REG, NOT_RBPU ; ポートBのウィーク・プルアップを有効に
	
	MOVLW	B'00000001'
	MOVWF	TRISA

	MOVLW	B'10000000'
	movwf	TRISC
	CLRF	TRISD		

	; RS232C 9600BPS
	movlw	B'00100010'
	MOVWF	TXSTA
	MOVLW	D'5'
	MOVWF	SPBRG

	BCF		STATUS, RP0

	;;;;;;;;;;;;;;;;;;;;
	; INIT LCD
	CALL	LCD_INI	

	; CLEAR COMMAND
	MOVLW	01H		
	CALL	LCD_CMD

	; COUROSR ON /BLANK OFF
	MOVLW	B'00001100'
	CALL	LCD_CMD
	
	; HOME POSISION
	MOVLW	0X80 			
	CALL	LCD_CMD
	
	CLRF	SWFLG
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MAIN
	CLRF	DAYFLG

	BTFSC	PORTB,0
	GOTO	TIME
	
	; CLEAR COMMAND
	MOVLW	01H		
	CALL	LCD_CMD

	; ADDRES No
	GOTO	ADR

; TIME AND USE STATION COUNT
TIME
	; $GPGGA,060306.00,4344.77894,N,14223.38857,E,2,11,0.9,128.4,M,28.8,M,5.0,0129*4C
	CALL	RECV
	SUBLW	'$'

	BTFSS	STATUS,Z
	GOTO	MAIN

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z	
	GOTO	MAIN

	CALL	RECV
	SUBLW	'P'
	BTFSS	STATUS,Z
	GOTO	MAIN

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z
	GOTO	MAIN

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z
	GOTO	MAIN

	CALL	RECV
	SUBLW	'A'
	BTFSS	STATUS,Z
	GOTO	MAIN

	CALL	RECV

	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; HOME POSISION
	MOVLW	0X80 			
	CALL	LCD_CMD

	CALL	RECV
	MOVWF	H1
	MOVLW	30H
	SUBWF	H1,F
	
	CALL	RECV
	MOVWF	H2
	MOVLW	30H
	SUBWF	H2,F	

; UTC -> JST
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UTC 0X:00  
	MOVF	H1,F		
	BTFSC	STATUS,Z
	CALL	ZERO

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UTC 10:00
	MOVFW	H1
	SUBLW	1H
	BTFSS	STATUS,Z
	GOTO	E5
	
	MOVF	H2,F
	BTFSS	STATUS,Z
	GOTO	E5

	MOVLW	31H
	MOVWF	H1

	MOVLW	39H 
	MOVWF	H2

	GOTO	FR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UTC 15:00 
E5
	MOVFW	H1
	SUBLW	1
	BTFSS	STATUS,Z
	GOTO	E2
	
	MOVFW	H2
	SUBLW	5
	BTFSS	STATUS,Z
	GOTO	E2

	MOVLW	30H
	MOVWF	H1

	MOVLW	30H 
	MOVWF	H2

	MOVLW	1
	MOVWF	DAYFLG

	GOTO	FR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UTC 11:00 TO 14:00
E2
	MOVLW	1
	XORWF	H1,W
	BTFSS	STATUS,Z
	GOTO	E7

	MOVLW	5
	subwf	H2,W
	btfsC	STATUS,C
	goto	E7

	MOVLW	32H
	MOVWF	H1

	MOVFW	H2 
	ADDLW	2FH
	MOVWF	H2

	GOTO	FR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UTC 20:00 TO 23:00
E7
	MOVFW 	H1
	SUBLW	2
	BTFSS	STATUS,Z
	GOTO	E4

	MOVLW	30H
	MOVWF	H1

	MOVFW	H2
	ADDLW	35H
	MOVWF	H2

	MOVLW	1
	MOVWF	DAYFLG

	GOTO	FR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UTC 16:00 TO 19:00
E4	
	MOVLW	0AH
	SUBWF	H2,W
	BTFSC	STATUS,C
	GOTO	FR

	MOVLW	30H
	MOVWF	H1

	MOVFW	H2 
	ADDLW	2BH
	MOVWF	H2

	MOVLW	1
	MOVWF	DAYFLG

	GOTO	FR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FR

	MOVFW	H1
	CALL	LCD_DATA

	MOVFW	H2
	CALL	LCD_DATA

	MOVLW	':'
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	MOVLW	':'
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA
	
	MOVLW	' '
	CALL	LCD_DATA

	; 衛星数;;;;;;;;;;;
	MOVLW	D'32'
	MOVWF	TMP
RR
	CALL	RECV
	DECFSZ	TMP,F
	GOTO	RR
	
	MOVLW	'['
	CALL	LCD_DATA

	MOVLW	'S'
	CALL	LCD_DATA

	MOVLW	'A'
	CALL	LCD_DATA

	MOVLW	'T'
	CALL	LCD_DATA
	
	CALL	RECV	
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	MOVLW	']'
	CALL	LCD_DATA

; GET DATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DFR
	;$GPRMC,060309.00,A,4344.77571,N,14223.38879,E,0.03,210.32,190808,06.2,W,D*51
	CALL	RECV
	SUBLW	'$'
	BTFSS	STATUS,Z
	GOTO	DFR

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z	
	GOTO	DFR

	CALL	RECV
	SUBLW	'P'
	BTFSS	STATUS,Z
	GOTO	DFR

	CALL	RECV
	SUBLW	'R'
	BTFSS	STATUS,Z
	GOTO	DFR

	CALL	RECV
	SUBLW	'M'
	BTFSS	STATUS,Z
	GOTO	DFR

	CALL	RECV
	SUBLW	'C'
	BTFSS	STATUS,Z
	GOTO	DFR

	; DATE;;;;;;;;;;;
	MOVLW	0C0H
	CALL	LCD_CMD

	MOVLW	D'51'
	MOVWF	TMP
RR4
	CALL	RECV
	DECFSZ	TMP,F
	GOTO	RR4

	CALL	RECV
	MOVWF	DAY1

	CALL	RECV
	MOVWF	DAY2

	CALL	RECV
	MOVWF	DAY3

	CALL	RECV
	MOVWF	DAY4

	CALL	RECV
	MOVWF	DAY5

	CALL	RECV
	MOVWF	DAY6

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	; YEAR
	MOVFW	DAY5
	CALL	LCD_DATA
	MOVFW	DAY6
	CALL	LCD_DATA

	;;;;;;;;;;;;;;;;;;;;;
	MOVLW	'/'
	CALL	LCD_DATA
	;;;;;;;;;;;;;;;;;;;;;
	; MONTH
	MOVFW	DAY3
	CALL	LCD_DATA
	MOVFW	DAY4
	CALL	LCD_DATA

	;;;;;;;;;;;;;;;;;;;;
	MOVLW	'/'
	CALL	LCD_DATA
	;;;;;;;;;;;;;;;;;;;;
	; DAY
	MOVFW	DAY1
	CALL	LCD_DATA

	SUBLW	33H
	BTFSS	STATUS,Z
	GOTO	N30

	MOVFW	DAY2
	CALL	LCD_DATA
	MOVLW	'+'
	CALL	LCD_DATA
	MOVLW	'1'
	CALL	LCD_DATA
	GOTO	MAIN

N30
	MOVFW	DAY2
	BTFSC	DAYFLG,0
	ADDLW	1H
	CALL	LCD_DATA

;;;;;;;;;;;;;;;;;;;
	GOTO	MAIN


ADR
;	BTFSS	PORTA,0
	BTFSS	PORTB,0
	GOTO	ADR2

	; CLEAR COMMAND
	MOVLW	01H		
	CALL	LCD_CMD
	GOTO 	MAIN

ADR2
	; $GPGGA
	CALL	RECV
	SUBLW	'$'
	BTFSS	STATUS,Z
	GOTO	ADR

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z
	GOTO	ADR

	CALL	RECV
	SUBLW	'P'
	BTFSS	STATUS,Z
	GOTO	ADR

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z
	GOTO	ADR

	CALL	RECV
	SUBLW	'G'
	BTFSS	STATUS,Z
	GOTO	ADR

	CALL	RECV
	SUBLW	'A'
	BTFSS	STATUS,Z
	GOTO	ADR

	CALL	RECV
	SUBLW	','
	BTFSS	STATUS,Z
	GOTO	ADR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HOME POSISION
	MOVLW	0X80 		
	CALL	LCD_CMD

	MOVLW	D'11'
	MOVWF	TMP
RR2
	CALL	RECV
	DECFSZ	TMP,F
	GOTO	RR2

	MOVLW	' '
	CALL 	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA
	
	MOVLW	0A1H
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA
;;;;;;;;;;;;;;;;;;;;;;;


	MOVLW	0C0H
	CALL	LCD_CMD

	CALL	RECV

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	MOVLW	0A1H
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	CALL	RECV
	CALL	LCD_DATA

	GOTO	ADR


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


RECV
	; 1バイト受信するまで待つ
	BTFSS	PIR1, RCIF
	GOTO	$-1

	; エラーかチェックする
	BTFSS	RCSTA, OERR
	GOTO	CHK_FERR
	bcf		RCSTA, CREN		; オーバラン・エラーを消す
	BSF		RCSTA, CREN
	GOTO	RECV
	
CHK_FERR
	BTFSS	RCSTA, FERR	
	GOTO	ASX

	movfw	RCREG		; フレーミング・エラーを消して、次の受信を行う
	GOTO	MAIN
	
	
ASX
	movfw	RCREG		; フレーミング・エラーを消して、次の受信を行う
	RETURN


TXCHR
	BTFSS	PIR1, TXIF		; CHECK IF THE BUFFER IS EMPTY
	GOTO	$-1
	MOVWF	TXREG
	RETURN

;***************************************************
;       液晶関連サブルーチン
;***************************************************
;　初期化サブルーチン
LCD_INI
	bcf	LCD_E
	bcf	LCD_RW		;R/W (write)
	bcf	LCD_RS		;RS  (CMD)

	call	delay5ms	; 5[ms]待つ
	call	delay5ms	; 5[ms]待つ
	call	delay5ms	; 5[ms]待つ

	movlw	0x30		;Function set 8bits
	call	LCD_8BIT_SEND_NOCHK

	call	delay5ms	; 5[ms]待つ
	movlw	0x30		;Function reset 8bits
	call	LCD_8BIT_SEND_NOCHK

	call	delay100us	; 100[us]待つ
	movlw	0x30		;Function reset 8bits
	call	LCD_8BIT_SEND_NOCHK

	call	delay100us	;  100[us]待つ
	movlw	0x20		;Function set 4bits mode
	call	LCD_8BIT_SEND_NOCHK

	;From here 4bits mode
	;; ここではBUSYチェックをしてはいけない
	call	delay100us
	movlw	0x2C		;function DL=0 4bit mode
	call	LCD_CMD_NOCHK

	;; ここからはBUSYチェックあり
	movlw	0x08		;Display off D=C=B=0
	call	LCD_CMD
	
	movlw	0x0f		;Display on D=1 C=B=0
	call	LCD_CMD
	
	movlw	0x06		;Entry I/D=1 S=0
	call	LCD_CMD
	
	return

;;　データを書く(RS=1)
LCD_DATA
	movwf	LCD_DAT	; wレジスタの内容を保存
	call	LCD_BUSY
	bsf	LCD_RS		;RS high (DATA)
	goto	LCD_SEND_BYTE
;;　コマンドを書く(RS=0)、ビジー・チェックなし
LCD_CMD_NOCHK
	movwf	LCD_DAT	; wレジスタの内容を保存
	bcf	LCD_RS		;RS low (CMD)
	goto	LCD_SEND_BYTE
;;　コマンドを書く(RS=0)、ビジー・チェックあり
LCD_CMD
	movwf	LCD_DAT	; wレジスタの内容を保存
	call	LCD_BUSY
	bcf	LCD_RS		;RS low (CMD)
;;  4ビット・モードで1バイト送る
LCD_SEND_BYTE
	movfw	LCD_DAT	; 上位4ビットを送る
	call	LCD_SEND_4BITS; 
	swapf	LCD_DAT, w	; 下位4ビットを送る
	call	LCD_SEND_4BITS;

	return

;;  液晶にwレジスタの上位4ビットを送る
LCD_8BIT_SEND_NOCHK
LCD_SEND_4BITS
	andlw	B'11110000'	; 下位4ビットは0にする
	movwf	LCD_PORT_TMP
	movfw	LCD_PORT_	; 現在のポート出力を読む
	andlw	B'00001111'	; 上位4ビットを0にする
	iorwf	LCD_PORT_TMP, w	; 上位と下位を結合する
	movwf	LCD_PORT	; ポートに書く

	bsf		LCD_E	; E high
	bcf		LCD_E	; E low

	return


;;  液晶から1バイト読む
LCD_READ
	movlw	B'11110000'	; 下位4ビットを0にするため
	bsf	LCD_E	;E high
	andwf	LCD_PORT, w	; 上位4ビットを読む
	bcf	LCD_E	;E low
	
	movwf	LCD_RDAT
	
	bsf	LCD_E	;E high
	swapf	LCD_PORT, w	; 下位4ビットを読む
	bcf	LCD_E	;E low
	
	andlw	B'00001111'	; 上位4ビットを0にする
	iorwf	LCD_RDAT, f	; 上位と下位を結合する

	return

;;  液晶のビジー・チェック・サブルーチン
LCD_BUSY
	bsf		STATUS,RP0	;バンク 1
	movlw		TRISB_LCD_IN ; D5からD7のつながったピンを入力にする
	movwf		TRISB
	bcf		STATUS,RP0	;バンク0

	bcf		LCD_RS		;RS low (CMD)
	bsf		LCD_RW		;R/W high (read)
LCD_BUSY_1
	call		LCD_READ
	BTFSC		LCD_RDAT,7	;ビジー・フラグのチェック
	goto		LCD_BUSY_1	;ビジーなので再読み込み

	bcf		LCD_RW		;R/W low (write)

	bsf		STATUS,RP0	;バンク1
	movlw		TRISB_LCD_OUT ; D5からD7のつながったピンを出力にする
	movwf		TRISB		;LCD_PORT
	bcf		STATUS,RP0	;バンク0

	return

;;　10[us]待ちサブルーチン
delay10us:
	goto	$+1		; 2
	goto	$+1		; 2
	goto	$+1		; 2
	goto	$+1		; 2
	goto	$+1		; 2

	goto	$+1		; 2
	goto	$+1		; 2
	goto	$+1		; 2
	goto	$+1		; 2
	goto	$+1		; 2

	nop			; 1
	return			; 2

;;　100[us]待ちサブルーチン
delay100us:
	movlw		D'9'
	movwf		CT_DELAY100US
T_LP1	call		delay10us	;2＋(25＋3)*9－1＝253
	decfsz		CT_DELAY100US, f
	goto		T_LP1
	return				;254*0.4＝100[us]

;;　1[ms]待ちサブルーチン
delay1ms:
	movlw	D'89'		; 1
	movwf	CT_DELAY1MS	; 1
delay1msl1:
	call	delay10us
	decfsz	CT_DELAY1MS, f	; 1(次の行を実行)、2(次の行はとばす)
	goto	delay1msl1	; 2

	nop			; 1
	goto	$+1		; 2

	return			; 2

;;　5[ms]待ちサブルーチン
delay5ms:
	call	delay1ms
	call	delay1ms
	call	delay1ms
	call	delay1ms
	call	delay1ms
	return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ZERO
	; UTC 00:00 CHK
	MOVF	H2,F
	BTFSS	STATUS,Z
	GOTO	NONE
	
	MOVLW	30H ;0
	MOVWF	H1	
	MOVLW	39H ;9
	MOVWF	H2
	RETURN

;UTC 00でないので UTC 01:00 TO 09:00 CHK
NONE	
	MOVLW	0AH
	SUBWF	H2,W
	BTFSS	STATUS,C
	GOTO	ER		; 01 TO 09
	RETURN

; UTC 01:00 TO 09:00 だった
ER
	MOVLW 	31H
	MOVWF	H1

	MOVFW	H2
	ADDLW	2FH
	
	MOVWF	H2

	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	END

```