; GPS-Jupiter用時刻信号発生&データディスプレイ ; GPRMC、GPGGA入力用1PPSタイミング出力、GHSへ1PPMクリア信号を付加した。 ; 時間データーを数値に直し、2秒加算表示する。 ; 時間スーパーインポーズへの送信機能。 ; 表示切替機能を付け加えた。 ; 2000.09.22 (c) JJ3ZLA ; PIC16F84専用(16C84は不可) ; PA.EXE専用 .include 16f84.h .osc hs .wdt off .pwrt on .protect off ; ; RS232C用定数 btime equ 170 ;4800bps @10MHz stime equ 30 ;@10MHz スーパー用ICへの送信レート rxd equ rb.5 ;RS232C DATA入力 vsyo equ rb.2 txd equ rb.1 sw equ rb.0 ;表示切替 ; ; LCD用定数 E equ rb.6 ;制御出力 RS equ rb.7 ;制御出力 ; ; タイミング入出力設定 pps equ ra.4 ;1ppsタイミング入力 ppm equ rb.4 ;1ppmタイミング出力 ; ; GPS関連用変数 (size=41) org 0ch alt ds 4 ;アンテナ高度 altb ds 3 ;ジオイド高度 time ds 6 ;時刻 date ds 6 ;時間 lat ds 9 ;経度 lon ds 10 ;緯度 sta ds 1 ;ステータス dop ds 4 ;衛星配置状況 satz ds 2 ;衛星補足個数 ; ; 秒表示関連定数 sec ds 1 ;秒 min ds 1 ;分 hor ds 1 ;時間 flg ds 1 ; ; RS232C用変数 (size=3) ch ds 1 ;汎用データ受け渡し rsw ds 1 ;ウェイト時間調整用 rcn ds 1 ;ビット数 ; ; LCD用変数 (size=6) wait_cn ds 1 ;ウエイト用カウンタ1 wait_cn2 ds 1 ;ウエイト用カウンタ2 d4 ds 1 ;LCD DATA 出力(4bit) d8 ds 1 ;LCD DATA 出力(8bit) cn ds 1 ;汎用カウンタ poi ds 1 ;汎用ポインタ ; ; 時間文字変換用 hdc ds 1 ;hexdec 用使用変数 hd1c ds 1 hd1b ds 1 hd1a ds 1 ; ;============================================================================== ; ; プログラムスタート ; org 0 goto start org 4 error goto error ; ; NMEA-0183センテンス文字列 GPGGA jmp pc+w retw 0,'AGGPG$' ;$GPGGA GPRMC jmp pc+w retw 0,'CMRPG$' ;$GPRMC ; ;============================================================================== ; ; DATA MEMORY(EEPROM) 設定 ui01_tbl equ 0 eeorg ui01_tbl eedata 'GPS Data Display',0 ui02_tbl equ 32 eeorg ui02_tbl eedata 'Ver 1.0 by Dynic',0 ;============================================================================== start ; ポート初期化 mov !ra,#00010000b ;入力=RA4 他出力 mov !rb,#00100101b ;入力=RB5 RB2 RB0 他出力 clr ra clr rb call init_lcd ;LCD初期化 bsf ppm ;rb.4をH bsf txd ;rb.1をH call open ;オープニング表示 mov wait_cn,#200 call wait_ms ;200msのウエイト mov wait_cn,#200 call wait_ms ;200msのウエイト mov wait_cn,#200 call wait_ms ;200msのウエイト mov wait_cn,#200 call wait_ms ;200msのウエイト call lcd_clr ;オープニング表示OFF ; ;============================================================================== ; ; メインループ ; loop ; btfss sw ; ; goto loop0 ; ; mov txc,#1 ; bsf ppm loop0 call gapwait ; ; btfsc sw ; goto loop10 ; cje txc,#1,beacon ; ; ; GPSデータ取得 ; GPGGA検索 loop10 mov poi,#6 ; $GPGGA検索 loop11 call receive ; 1文字入力 jz loop ; error :jz addr9 if(zf==1) goto addr9 2 mov w,poi call GPGGA ; テーブル参照 subwf ch,0 ; テーブルと比較 jnz loop10 ; 違えば最初からやり直し:jnz addr9 if(zf==0) goto addr9 2 djnz poi,loop11 ; 6文字分比較する ; djnz fr,addr9 if(--fr!=0) goto addr9 2 frから1を引き0以外ならジャンプする mov poi,#7 ;7個分のパラメータをパス call tkscn jz loop ;error ; 受信可能衛星数 satsu call receive ; 1文字読み取り mov satz[0],ch ; 0chへコピー call receive ; 1文字読み取り mov satz[1],ch ; 1chへコピー call receive ; 1文字空読み ; HDOP取得 hdop call receive cje ch,#',',dop01 mov dop[0],ch call receive cje ch,#',',dop02 mov dop[1],ch call receive cje ch,#',',dop03 mov dop[2],ch call receive cje ch,#',',dop04 mov dop[3],ch goto htrec_1 dop01 mov dop[0],#'_' dop02 mov dop[1],#'_' dop03 mov dop[2],#'_' dop04 mov dop[3],#'_' ; アンテナ高度取得 htrec_1 call receive ; 1文字空読み call receive ; 1文字目 or -符号読み取り cje ch,#',',htr1 mov alt[0],ch call receive cje ch,#'.',htr2 mov alt[1],ch call receive cje ch,#'.',htr3 mov alt[2],ch call receive cje ch,#'.',htr4 mov alt[3],ch goto htre0 ; -10.0 -0.0 0.0 10.0 100.0 9999.9 htr1 mov alt[0],#'_' mov alt[1],#'_' mov alt[2],#'_' mov alt[3],#'m' goto htre1 htr2 mov alt[1],#'_' mov alt[2],#'_' mov alt[3],#'m' goto htre0 htr3 mov alt[2],#'_' mov alt[3],#'m' goto htre0 htr4 mov alt[3],#'m' htre0 call receive2 ; 1文字空読み & ',' htre1 call receive ; 1文字空読み 'M' call receive ; 1文字空読み ',' ; ジオイド高度取得 htrec_2 call receive ;1文字目 or -符号読み取り cje ch,#',',hts1 mov altb[0],ch call receive cje ch,#'.',hts2 mov altb[1],ch call receive cje ch,#'.',hts3 mov altb[2],ch goto loop20 hts1 mov altb[0],#'_' mov altb[1],#'_' mov altb[2],#'m' goto loop20 hts2 mov altb[1],#'_' mov altb[2],#'m' goto loop20 hts3 mov altb[2],#'m' ; GPRMC検索 loop20 mov poi,#6 ;$GPRMC検索 loop21 call receive ;1文字入力 jz loop ;error mov w,poi call GPRMC ;テーブル参照 subwf ch,0 ;テーブルと比較 jnz loop20 ;違えば最初からやり直し djnz poi,loop21 ;6文字分比較する call receive ; 1文字空読み "," ; 時間取得 1-6文字目読みとり mov fsr,#time ; FSRに変数のアドレス設定 mov poi,#6 ; 転送数は6バイト mltrecv2 call receive ; 1文字入力 mov indirect,ch ; FSRの指した変数に転送 inc fsr ; ポインタ+1:inc fr fr++ 1 djnz poi,mltrecv2 ; 指定転送数分繰り返し ; status取得 call receive2 ; 2文字空読み , & status mov sta,ch ; Status読みとり call receive ; 1文字空読み , ; latitude取得 1-9文字目読みとり mov fsr,#lat ; FSRに変数のアドレス設定 mov poi,#9 ; 転送数は9バイト mltrecv3 call receive ; 1文字入力 mov indirect,ch ; FSRの指した変数に転送 inc fsr ; ポインタ+1 djnz poi,mltrecv3 ; 指定転送数分繰り返し call receive2 ; 1文字空読み , & N/S call receive ; 1文字空読み , ; longitude取得 1-10文字目読みとり mov fsr,#lon ; FSRに変数のアドレス設定 mov poi,#10 ; 転送数は10バイト mltrecv4 call receive ; 1文字入力 mov indirect,ch ; FSRの指した変数に転送 inc fsr ; ポインタ+1 djnz poi,mltrecv4 ; 指定転送数分繰り返し call receive2 ; 1文字空読み , & E/W mov poi,#3 ; 3個分のパラメータをパス call tkscn jz loop ;error ; 日付取得 1-6文字目読みとり mov fsr,#date ; FSRに変数のアドレス設定 mov poi,#6 ; 転送数は6バイト mltrecv5 call receive ; 1文字入力 mov indirect,ch ; FSRの指した変数に転送 inc fsr ; ポインタ+1 djnz poi,mltrecv5 ; 指定転送数分繰り返し ; ;****************************************** ; 2秒加算ルーチン。 ;****************************************** sec01 sub time[4],#30h ;1バイト文字を数値に直す。 mov sec,time[4] mov poi,#9 ;10回加算して一桁上げる sec02 add sec,time[4] djnz poi,sec02 sub time[5],#30h ;1バイト文字を数値に直す。 add sec,time[5] ;2位と1位の加算 add sec,#2 ;2秒加算 cjae sec,#60,sec03 ;60秒以上なら-60sの処理 goto min01 sec03 sub sec,#60 ;-60の処理 add time[3],#1h ;1分加算処理 min01 sub time[2],#30h ;1バイト文字を数値に直す mov min,time[2] mov poi,#9 ;10回加算して一桁上げる min02 add min,time[2] djnz poi,min02 sub time[3],#30h ;1バイト文字を数値に直す。 add min,time[3] ;2位と1位の加算 cjae min,#60,min03 ;60分以上なら-60mの処理 goto hor01 min03 sub min,#60 ;-60の処理 add time[1],#1h ;1時間加算処理 hor01 sub time[0],#30h ;1バイト文字を数値に直す mov hor,time[0] mov poi,#9 ;10回加算して一桁上げる hor02 add hor,time[0] djnz poi,hor02 sub time[1],#30h ;1バイト文字を数値に直す。 add hor,time[1] ;2位と1位の加算 cjae hor,#24,hor03 ;24時間以上なら-24hの処理 goto timeout hor03 sub hor,#24 ; setb flg,0 ; ;************************************************************* ; 1PPSの信号を待って表示 ;************************************************************* timeout btfsc pps goto timeout ;1PPS信号データ待ち btfsc vsyo ;VSYN信号の重複チェック goto vsyochk ; syowait btfss vsyo goto syowait nop vsyochk btfsc vsyo ;スーパー用VSYO待ち goto vsyochk nop nop nop trans call transd ;スーパーPICへ時刻送信 mov cn,#40 twait nop ;1 スーパーPICの割り込み時間 djnz cn,twait ;2 調整用 trans2 call transd ;PICへ時刻送信 2回目 cje sec,#0,ppmtime ;秒の0判断 goto next ppmtime bcf ppm ;GHSへ1分クリアのタイミング出力L mov wait_cn,#1 call wait_ms ;1msのウエイト bsf ppm ;GHSへ1分クリアのタイミング出力H next btfss sw goto print2 ; スイッチoffなら経度緯度表示 nop goto print3 ; 緯度・経度表示 ; goto loop ; ;***************************************************************** ; トークンスキャン(区切り記号単位でパラメータをスキャンする) ; in : poi = パス数 ;***************************************************************** tkscn call receive jz tks1 ;error cjne ch,#',',tkscn ;cjne fr,#lite,addr9 if(fr!=lite) goto addr9 4 djnz poi,tkscn ;djnz fr,addr9 if(--fr!=0) goto addr9 2 clrb z ;clrb bit bit = 0 1 ret tks1 ret ;***************************************************************** ; スーパーインポーズコントロールPICへ時刻データ送信 ;***************************************************************** transd mov ch,hor call transmit mov ch,min call transmit mov ch,sec call transmit ret transmit clrb txd ;txd ビットクリア mov rsw,#stime ;スタートビット trn10 djnz rsw,trn10 mov rcn,#8 ;ビット位置 nop trn11 rr ch nop movb txd,c ;ポートに出力 mov rsw,#stime trn12 djnz rsw,trn12 ;1ビットのウエイト djnz rcn,trn11 ;8ビット分繰り返し nop nop nop nop nop nop setb txd ;txd を1に ストップビット mov rsw,#stime trn13 djnz rsw,trn13 ;1ビットのウエイト ret ;1文字送信終了、戻る ;*********************************** ;transmit bcf txd ; mov rsw,#stime ;trans10 djnz rsw,trans10 ; mov rcn,#8 ; nop ;transmit0 rr ch ; nop ; movb txd,c ; データ出力(LSBから) ; ; mov rsw,#stime ;trans11 djnz rsw,trans11 ; ; djnz rcn,transmit0 ; nop ; nop ; nop ; nop ; nop ; nop ; bsf txd ; mov rsw,#stime ;trans12 djnz rsw,trans12 ; STOPビット分ウェイト ; ret ; ;******************************************** ; 緯度経度表示 2ページ目に変更 ;******************************************** print3 call line2 ;LCD 2行目にカーソルセット mov d4,#'N' ;北緯のNを表示 call write_lcd4 ; latitude表示 mov fsr,#lat ;FSRに変数のアドレス設定 mov poi,#9 ;転送数は10バイト mltrecv6 mov d4,indirect ;FSRの指した変数から転送 ; cje d4,#'.',mltrecv7 ;"."なら表示しない:cje fr,#lite,addr9 if(fr==lite) goto addr9 4 call write_lcd4 ;表示 mltrecv7 inc fsr ;ポインタ+1:inc addr9 if(cf==0) goto addr9 2 djnz poi,mltrecv6 ;指定回数繰り返し mov d4,#' ' call write_lcd4 ; アンテナ高度表示 altrec1 mov d4,#'H' ;アンテナ高度ヘッダーのHを表示 call write_lcd4 ;表示 mov d4,alt[0] call write_lcd4 ;表示 mov d4,alt[1] call write_lcd4 ;表示 mov d4,alt[2] call write_lcd4 ;表示 mov d4,alt[3] call write_lcd4 ;表示 call line1 ;LCD 1行目にカーソルセット mov d4,#'E' ;東経のE表示 call write_lcd4 ; longitude表示 mov fsr,#lon ;FSRに変数のアドレス設定 mov poi,#10 ;転送数は10バイト mltrecv8 mov d4,indirect ;FSRの指した変数から転送 ; cje d4,#'.',mltrecv9 ;"."なら表示しない call write_lcd4 ;表示 mltrecv9 inc fsr ;ポインタ+1 djnz poi,mltrecv8 ;指定回数繰り返し ; データの有効性表示 cje sta,#'V',p3skp1 ;データ無効ならp3skp1へ mov d4,#' ' goto p3skp2 p3skp1 mov d4,#'x' ;無効なら"x"を表示 p3skp2 call write_lcd4 ; ジオイド高度表示 altrec2 mov d4,#'G' ;ジオイド高度ヘッダーのGを表示 call write_lcd4 ;表示 mov d4,altb[0] call write_lcd4 ;表示 mov d4,altb[1] call write_lcd4 ;表示 mov d4,altb[2] call write_lcd4 ;表示 goto loop ;********************************************* ; LCD 時刻表示 一ページ目に表示 ;********************************************* print2 call line2 ;;LCD 2行目にカーソルセット mov d4,#'U' call write_lcd4 mov d4,#'T' call write_lcd4 mov hdc,hor ;時間表示 call hexdec ;数値−文字変換へ mov d4,hd1b call write_lcd4 mov d4,hd1a call write_lcd4 mov d4,#':' call write_lcd4 ;"h" mov hdc,min ;分表示 call hexdec ;数値−文字変換へ mov d4,hd1b call write_lcd4 mov d4,hd1a call write_lcd4 mov d4,#':' ;"m" call write_lcd4 mov hdc,sec ;秒表示 call hexdec ;数値−文字変換へ mov d4,hd1b call write_lcd4 mov d4,hd1a call write_lcd4 mov d4,#' ' call write_lcd4 ; 衛星受信数 mov d4,#'S' call write_lcd4 mov d4,#'a' call write_lcd4 mov d4,#'t' call write_lcd4 mov d4,satz[0] call write_lcd4 mov d4,satz[1] call write_lcd4 call line1 ;LCD 1行目にカーソルセット ; 日付表示 mov d4,#'2' call write_lcd4 ;表示 mov d4,#'0' call write_lcd4 ;表示 mov d4,date[4] call write_lcd4 ;表示 mov d4,date[5] call write_lcd4 ;表示 mov d4,#'/' call write_lcd4 ;表示 mov d4,date[2] call write_lcd4 ;表示 mov d4,date[3] call write_lcd4 ;表示 mov d4,#'/' call write_lcd4 ;表示 mov d4,date[0] call write_lcd4 ;表示 mov d4,date[1] call write_lcd4 ;表示 ; データ有効性の表示 cje sta,#'V',p4skp1 ;データ無効ならp3skp1へ mov d4,#' ' goto p4skp2 p4skp1 mov d4,#'x' ;無効なら"x"を表示 p4skp2 call write_lcd4 ; HDOP値の表示 mov d4,#'D' call write_lcd4 mov d4,dop[0] call write_lcd4 mov d4,dop[1] call write_lcd4 mov d4,dop[2] call write_lcd4 mov d4,dop[3] call write_lcd4 goto loop ; ;********************************************************************* ; 1バイト値を10進数文字列に変換する 0-255 ; 変換する数を hdc にセットして呼ぶ ; hd1c(100位),hd1b(10位),hd1a(1位) に変換した文字のアスキーコードが返る ;********************************************************************* ; hexdec mov hd1a,#30h mov hd1b,#30h mov hd1c,#30h hd1_1 cjb hdc,#100,hd1_2 add hd1c,#1 sub hdc,#100 goto hd1_1 hd1_2 cjb hdc,#10,hd1_3 add hd1b,#1 sub hdc,#10 goto hd1_2 hd1_3 add hd1a,hdc ret ; ;********************************************* ; RS232C受信サブルーチン ;********************************************* ; gapwait gapw3 btfss rxd goto gapw3 ;START検出するまで待つ ret ; ; 受信処理 receive4 call receive ;3バイト空読みして受信する receive3 call receive ;2バイト空読みして受信する receive2 call receive ;1バイト空読みして受信する receive btfss rxd goto receive ;START検出するまで待つ ; mov rsw,#btime/2 ;1/2ビット分待つ recv01 djnz rsw,recv01 ; mov rcn,#8 ;繰り返しは8回 nop recv10 mov rsw,#btime ;1ビット分待つ recv11 djnz rsw,recv11 ; nop movb c,rxd ;データ入力 rr ch ;バッファにシフトする djnz rcn,recv10 ;8ビット分繰り返す ; nop mov rsw,#btime ;1ビット分待つ recv12 djnz rsw,recv12 ; comf ch,1 btfss rxd ;STOPビット読みとり ret ;NO-ERROR Z=1 ; clr ch ;STOPビットエラー ret ;ERROR Z=0 ;============================================================================== ; ; 液晶初期化ルーチン(16桁x2行用) ; init_lcd mov wait_cn,#15 ;起動時ウエイト 15ms call wait_ms ; 4Bit-mode初期化 clrb RS ;RS='L' mov d8,#0011b ;Function set call write_lcd8 mov wait_cn,#5 ;wait 4.1ms call wait_ms mov d8,#0011b ;Function set call write_lcd8 mov wait_cn,#100 ;wait 100us call wait_us mov d8,#0011b ;Function set call write_lcd8 mov d8,#0010b ;Function set 4Bit-mode call write_lcd8 ; mov d4,#00101000b ;duty,font set9 call write_lcd4 ; ; 画面消去 lcd_clr clrb RS ;RS='L' mov d4,#00000001b ;画面消去コマンド call write_lcd4 mov wait_cn,#2 ;クリアが終わるまで待つ call wait_ms mov d4,#00000110b ;entry mode set call write_lcd4 mov d4,#00001111b ;display on,cursor on,blink on call write_lcd4 ret ; ; ライン先頭ジャンプ line1 mov d4,#10000000b ;1行目にカーソル移動コマンド goto line line2 mov d4,#10000000b+64 ;2行目にカーソル移動コマンド line clrb RS ;カーソル移動コマンド発行 call write_lcd4 setb RS ret ; ; 8ビットモード専用液晶ライトルーチン ; (in : d8(8bit)) write_lcd8 mov ra,d8 ;データをポートへ出力 nop setb E ;EをHi nop clrb E ;EをLow mov wait_cn,#40 ;wait call wait_us ret ; ; 4ビットモード専用液晶ライトルーチン(80uS) ; (in : d4) write_lcd4 mov d8,d4 ;上位ビットが先 swap d8 ;上位・下位ビットを反転 call write_lcd8 mov d8,d4 ;下位ビットは後 call write_lcd8 ret ; ; msオーダーのウェイト wait_ms wait_ms0 mov wait_cn2,#0 wait_ms1 nop nop nop nop nop nop nop djnz wait_cn2,wait_ms1 djnz wait_cn,wait_ms0 ret ; ; μsオーダーのウェイト wait_us wait_us0 djnz wait_cn,wait_us0 ret ; ;============================================================================== ; オープニング画面 open call lcd_clr ;液晶画面消去 call line1 ;LCD 1行目にカーソルセット call messp ;タイトル表示 call line2 ;LCD 2行目にカーソルセット call messq ;バージョン情報表示 ret ; ;============================================================================= ; メッセージ表示 messp mov poi,#ui01_tbl ;ポインタ設定 mess1 mov w,poi call eeREAD ;EEPROMから読み出し jz mess2 ;0なら表示終了 mov d4,w call write_lcd4 ;表示 inc poi ;ポインタ+1 goto mess1 ;繰り返し mess2 ret ;終了 messq mov poi,#ui02_tbl ;ポインタ設定 mess3 mov w,poi call eeREAD ;EEPROMから読み出し jz mess4 ;0なら表示終了 mov d4,w call write_lcd4 ;表示 inc poi ;ポインタ+1 goto mess1 ;繰り返し mess4 ret ;終了 ; ;============================================================================== ; ; データメモリ読み書き ; ; EEPROM READ (in:address(w) out:data(w)) eeREAD mov eeadr,w setb rp0 ;page1 setb rd ;EEPROM READ FLAG clrb rp0 ;page0 mov w,eedata ret