; GM38用データディスプレイ ; ナビトラ・ビーコン送信機能付き ; 1999.12.13 (c) JS1RSV ; PIC16F84専用(16C84は不可) ; PA.EXE専用 .include 16f84.h .osc hs .wdt off .pwrt on .protect off ; ; AX25用ポート設定 outp equ rb ;RB0-3 WAVE OUT ptt equ rb.4 ;PTT OUT sw equ ra.4 ;SW入力(起動時:パラメータ登録) ; (動作時:ビーコン送信) ; ; RS232C用定数 btime equ 170 ;4800bps @10MHz rxd equ rb.5 ;RS232C DATA入力 ; ; LCD用定数 ; ra.0-4 ;データ出力 E equ rb.6 ;制御出力 RS equ rb.7 ;制御出力 ; ; AX25用定数 Htone equ 18 ;2200Hz = 28.41uS x 16 Ltone equ 37 ;1200Hz = 52.08uS x 16 Hloop equ 29 ;833uS(1200bps) / 28uS Lloop equ 16 ;833uS(1200bps) / 52uS txcnt equ 60 ;送信周期(単位S) ; ; キー設定 esc equ 27 ;エスケープ(ESC) can equ 8 ;キャンセル(BS) ; ; GPS関連用変数 (size=41) org 0ch alt ds 5 ;海抜高度 spd ds 3 ;対地速度 dir ds 3 ;移動方向 time ds 6 ;時刻 date ds 6 ;時間 lat ds 8 ;経度 lon ds 9 ;緯度 sta ds 1 ;ステータス ; ; RS232C用変数 (size=3) ch ds 1 ;汎用データ受け渡し tcn ; AX25用 rsw ds 1 ;ウェイト時間調整用 bcn ; AX25用 rcn ds 1 ;ビット数 ; ; LCD用変数 (size=6) wait_cn ds 1 ;ウエイト用カウンタ1 wait_cn2 ds 1 ;ウエイト用カウンタ2 tpo ; AX25用 d4 ds 1 ;LCD DATA 出力(4bit) outb ; AX25用 d8 ds 1 ;LCD DATA 出力(8bit) cn ds 1 ;汎用カウンタ poi ds 1 ;汎用ポインタ ; ; AX25用変数 (size=5) ;tcn ds 1 ;FSK発生カウンタ ;tpo ds 1 ;FSK波形ポインタ ;outb ds 1 ;NRZI変換バッファ ;bcn ds 1 ;ビット数カウンタ hcn ds 1 ;HDLCビットカウンタ crcH ds 1 ;CRC計算用バッファ(UPPER) crcL ds 1 ;CRC計算用バッファ(LOWER) ssid ;SSIDワーク sum ds 1 ;PNTSチェックサム txc ds 1 ;送信周期カウンタ ;============================================================================== ; ; プログラムスタート ; org 0 goto start org 4 error goto error ; ; スタート確認用文字列 inkey_tbl jmp pc+w retw 'PUSH [ESC] KEY' ;14文字 ; ; NMEA-0183センテンス文字列 GPGGA jmp pc+w retw 0,'AGGPG$' ;$GPGGA GPRMC jmp pc+w retw 0,'CMRPG$' ;$GPRMC ; ; サイン波テーブル wave_tbl jmp pc+w retw 18h,1Bh,1Dh,1Eh,1Fh,1Eh,1Dh,1Bh retw 18h,15h,12h,11h,10h,11h,12h,15h ; ; UIパケット文字列定義 pac02 equ 00000011b ;制御(UI) pac03 equ 11110000b ;PID ui01_tbl jmp pc+w retw '$PNTS,1,0,' ;10文字 ui03_tbl jmp pc+w retw ',000,1*' ;7文字 MARK equ '0' ;MARK設定 ; ; 16進数字変換用 hex jmp pc+w retw '0123456789ABCDEF' ;============================================================================== ; ; DATA MEMORY(EEPROM) 設定 ; ; UIパケット文字列定義 pac01 equ 0 eeorg pac01 eedata 08eh,0a0h,0a6h,040h,040h,040h,01100000b ;GPS eedata 09ch,09eh,086h,082h,098h,098h,11100000b ;NOCALL-0 eedata 094h,098h,062h,0b4h,09ah,0b0h,01100001b ;JL1ZMX-0 ui02_tbl equ 43 eeorg ui02_tbl eedata 'GM38 DataDisplay',0 ;============================================================================== start ; ポート初期化 mov !rb,#00100000b ;入力=RB5 他出力 mov !ra,#00010000b ;入力=RA4 他出力 clr ra clr rb call init_lcd ;LCD初期化 ; ; パラメータ登録モード・チェック btfsc sw goto next ;SW OFFならnextへ call inkey ;ESC入力待ち call open ;オープニング表示 call input ;パラメータ入力 next call open ;オープニング表示 clr wait_cn ;起動時ウエイト(256mS x2) call wait_ms call wait_ms mov hcn,#5 ;HDLCビットカウンタ初期化 mov txc,#0 ;送信周期カウンタ最大時間(250s) ;============================================================================== ; ; メインループ ; loop btfss sw ;SW-OFFなら送信周期カウンタを goto loop0 ;即時送信可能状態にする mov txc,#1 loop0 call gapwait ;GPSデータの区切り待ち btfsc sw ;SW-OFFなら位置表示へ goto loop10 cje txc,#1,beacon ;送信準備可能なら送信する ; ; GPSデータ取得 ; loop10 mov poi,#6 ;$GPGGA検索 loop11 call receive ;1文字入力 jz loop ;error mov w,poi call GPGGA ;テーブル参照 subwf ch,0 ;テーブルと比較 jnz loop10 ;違えば最初からやり直し djnz poi,loop11 ;6文字分比較する ; mov poi,#9 ;9個分のパラメータをパス call tkscn jz loop ;error ; 高度取得 call receive ;1文字目 +/-符号読み取り mov alt[0],ch ; 符号保存 call receive ;2文字目 空読み ;3-6文字目読みとり mov FSR,#alt+1 ; FSRに変数のアドレス設定 mov poi,#4 ; 転送数は4バイト mltrecv1 call receive ; 1文字入力 mov INDIRECT,ch ; FSRの指した変数に転送 inc FSR ; ポインタ+1 djnz poi,mltrecv1 ; 指定転送数分繰り返し call receive2 ;7-8文字目 空読み ; 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 ; 転送数は4バイト mltrecv2 call receive ; 1文字入力 mov INDIRECT,ch ; FSRの指した変数に転送 inc FSR ; ポインタ+1 djnz poi,mltrecv2 ; 指定転送数分繰り返し ; status取得 call receive2 ;2文字空読み , & status mov sta,ch ;Status読みとり call receive ;1文字空読み , ; latitude取得 1-8文字目読みとり mov FSR,#lat ; FSRに変数のアドレス設定 mov poi,#8 ; 転送数は4バイト mltrecv3 call receive ; 1文字入力 mov INDIRECT,ch ; FSRの指した変数に転送 inc FSR ; ポインタ+1 djnz poi,mltrecv3 ; 指定転送数分繰り返し call receive4 ;4文字空読み 8,N/S, ; longitude取得 1-9文字目読みとり mov FSR,#lon ; FSRに変数のアドレス設定 mov poi,#9 ; 転送数は4バイト mltrecv4 call receive ; 1文字入力 mov INDIRECT,ch ; FSRの指した変数に転送 inc FSR ; ポインタ+1 djnz poi,mltrecv4 ; 指定転送数分繰り返し call receive4 ;4文字空読み 9,E/W, ; 速度取得 call receive ;1文字目読みとり cjne ch,#',',skip1 ;データが有効ならskip1へ mov w,#'-' ;データ無効時には'---'表示 mov spd[0],w mov spd[1],w mov spd[2],w goto skip2 skip1 mov spd[0],ch ;1文字目保存 call receive ;2文字目読みとり mov spd[1],ch call receive ;3文字目読みとり mov spd[2],ch call receive3 ;4-5文字目 空読み , skip2 ; 移動方向取得 call receive ;1文字目 移動方向 cjne ch,#',',skip3 ;データが有効ならskip3へ mov w,#'-' ;データ無効時には'---'表示 mov dir[0],w mov dir[1],w mov dir[2],w goto skip4 skip3 mov dir[0],ch ;1文字目保存 call receive ;2文字目読みとり mov dir[1],ch call receive ;3文字目読みとり mov dir[2],ch call receive3 ;4-5文字目 空読み , skip4 ; 日付取得 1-6文字目読みとり mov FSR,#date ; FSRに変数のアドレス設定 mov poi,#6 ; 転送数は4バイト mltrecv5 call receive ; 1文字入力 mov INDIRECT,ch ; FSRの指した変数に転送 inc FSR ; ポインタ+1 djnz poi,mltrecv5 ; 指定転送数分繰り返し ; call print3 ;緯度経度表示 call print1 ;高度・速度・方向表示 ; ; ビーコン送信許可 ; beacon btfsc sw ;SW-OFFならループ先頭へ goto loop djnz txc,loop ;送信周期カウンタ=0で送信 mov txc,#txcnt ;カウンタ初期化 ;============================================================================== ; ; AX25フレーム発生 ; ; 送信インジケータ表示 mov d4,#10000000b+64+15 ;2行+15桁目 call line ;カーソル設定 mov d4,#'*' ;インジケータON call write_lcd4 ;LCD表示 clr sum ;チェックサム初期化 clr tpo ;波形ポインタ初期化 clr outb ;NZRIバッファ初期化 setb ptt ;PTT ON ; ; TXDELAYウエイト ; mov cn,#75 ;TXDELAY=500ms send0 call flag ;フラグ発生 djnz cn,send0 ;フラグを75回発生 ; ; UIフレーム発生 ; mov crcH,#0ffh ;CRCバッファの初期化 mov crcL,#0ffh call flag ;フレーム最初のフラグ ; ヘッダ送信 mov poi,#pac01 ;EEPROMアドレス設定 send1 mov w,poi call eeREAD ;EEPROMからデータ取得 mov ch,w call HDLC ;データ送信 inc poi ;アドレス+1 btfss eedata.0 ;終了フラグを見て goto send1 ;終了するまで繰り返し mov ch,#pac02 ;制御バイト送信 call HDLC mov ch,#pac03 ;PID送信 call HDLC ; データ送信(ナビトラ・ビーコン送信開始) mov cn,#10 ;$PNTS文字列送信 clr poi ;テーブルポインタ初期化 send2 mov w,poi call ui01_tbl ;テーブル取得 mov ch,w call send ;送出 inc poi ;テーブルポインタ+1 djnz cn,send2 ;指定文字数繰り返し ; 日付送信 mov ch,date[0] ;1文字目 call send mov ch,date[1] ;2文字目 call sepa2 ;セパレータ送信 mov ch,date[2] ;3文字目 call send mov ch,date[3] ;4文字目 call sepa2 ;セパレータ送信 mov ch,date[4] ;5文字目 call send mov ch,date[5] ;6文字目 call sepa2 ;セパレータ送信 ; 時間送信 mov FSR,#time ;FSRに変数のアドレス設定 mov poi,#6 ;送信数は6文字 send3 mov ch,INDIRECT ;FSRの指した変数から転送 call send ;送信 inc FSR ;ポインタ+1 djnz poi,send3 ;指定転送数分繰り返し call sepa ;セパレータ送信 ; latitude送信 mov FSR,#lat ;FSRに変数のアドレス設定 mov poi,#8 ;送信数は8文字 send4 mov ch,INDIRECT ;FSRの指した変数から転送 call send ;送信 inc FSR ;ポインタ+1 djnz poi,send4 ;指定転送数分繰り返し call sepa ;セパレータ送信 mov ch,#'N' ;"N"を送信 call sepa2 ;セパレータ送信 ; longitude送信 mov FSR,#lon ;FSRに変数のアドレス設定 mov poi,#9 ;送信数は9文字 send5 mov ch,INDIRECT ;FSRの指した変数から転送 call send ;送信 inc FSR ;ポインタ+1 djnz poi,send5 ;指定転送数分繰り返し call sepa ;セパレータ送信 mov ch,#'E' ;"E"を送信 call sepa2 ;セパレータ送信 ; 方向送信 mov ch,dir[0] ;1文字目 cje ch,#'-',send51 ;データが無効なら空白 call send mov ch,dir[1] ;2文字目 call send mov ch,dir[2] ;3文字目 call send send51 call sepa ;セパレータ送信 ; 速度送信 mov ch,spd[0] ;1文字目 cje ch,#'-',send52 ;データが無効なら空白 call send mov ch,spd[1] ;2文字目 call send mov ch,spd[2] ;3文字目 call send send52 call sepa ;セパレータ送信 ; マーク送信 mov ch,#MARK ;マーク送信 call sepa2 ;セパレータ送信 ; メッセージ送信 mov poi,#ui02_tbl ;ポインタにテーブルアドレス設定 send6 mov w,poi call eeREAD ;EEPROMからデータを読み出す mov ch,w call HDLC ;送信 inc poi ;ポインタ+1 cjne eedata,#0,send6 ;データ終了まで繰り返し ; グループ・ステータス送信 mov cn,#7 ;グループ・ステータス文字列送信 clr poi ;テーブルポインタ初期化 send7 mov w,poi call ui03_tbl ;テーブル取得 mov ch,w call send ;送出 inc poi ;テーブルポインタ+1 djnz cn,send7 ;指定文字数繰り返し ; チェックサム送信 swapf sum,0 ;チェックサムの上位バイトを andlw 15 ;hexテーブルを使い文字化する call hex mov ch,w call HDLC ;下位バイト送信 mov w,sum ;チェックサムの下位バイトを andlw 15 ;hexテーブルを使い文字化する call hex mov ch,w call HDLC ;下位バイト送信 ; mov ch,#13 call HDLC ;改行コード送信 ; ; CRC・フラグ送信(AX25フレーム) call CRC ;CRC送信 call flag ;フラグ送信 ; clrb ptt ;PTT OFF ; 送信インジケータ消去 mov d4,#10000000b+64+15 ;2行+15桁目 call line mov d4,#' ' call write_lcd4 goto loop ;============================================================================== ; ; チェックサム計算(ナビトラビーコン用) send xor sum,ch goto HDLC ; ; セパレータ送信(区切り記号) sepa2 call send ;通常送信後セパレータ送信 sepa mov ch,#',' ;セパレータのみ送信 goto HDLC ; ; トークンスキャン(区切り記号単位でパラメータをスキャンする) ; in : poi = パス数 tkscn call receive jz tks1 ;error cjne ch,#',',tkscn djnz poi,tkscn clrb z ret tks1 ret ;============================================================================== ; ; 高度、速度、方向の表示 ; print1 call line2 ;LCD 2行目にカーソルセット ; 高度表示 mov d4,alt[0] cje d4,#'-',prt11 ;負数なら"-"を表示 mov d4,alt[1] ;1桁目表示 prt11 call write_lcd4 mov d4,alt[2] ;2桁目表示 call write_lcd4 mov d4,alt[3] ;3桁目表示 call write_lcd4 mov d4,alt[4] ;4桁目表示 call write_lcd4 mov d4,#'m' ;単位は"m" call write_lcd4 mov d4,#' ' call write_lcd4 ; 速度表示 mov d4,spd[0] ;1桁目表示 call write_lcd4 mov d4,spd[1] ;2桁目表示 call write_lcd4 mov d4,spd[2] ;3桁目表示 call write_lcd4 mov d4,#'k' ;単位は"km/h" call write_lcd4 mov d4,#' ' call write_lcd4 ; 方向表示 mov d4,dir[0] ;1桁目表示 call write_lcd4 mov d4,dir[1] ;2桁目表示 call write_lcd4 mov d4,dir[2] ;3桁目表示 call write_lcd4 mov d4,#0dfh ;単位は"度" call write_lcd4 mov d4,#' ' call write_lcd4 ret ; ; 緯度経度表示 ; print3 call line1 ;LCD 1行目にカーソルセット ; latitude表示 mov FSR,#lat ;FSRに変数のアドレス設定 mov poi,#8 ;転送数は8バイト mltrecv6 mov d4,INDIRECT ;FSRの指した変数から転送 cje d4,#'.',mltrecv7 ;"."なら表示しない call write_lcd4 ;表示 mltrecv7 inc FSR ;ポインタ+1 djnz poi,mltrecv6 ;指定回数繰り返し ; データの有効性表示 cje sta,#'V',p3skp1 ;データ無効ならp3skp1へ mov d4,#' ' goto p3skp2 p3skp1 mov d4,#'x' ;無効なら"x"を表示 p3skp2 call write_lcd4 ; longitude表示 mov FSR,#lon ;FSRに変数のアドレス設定 mov poi,#9 ;転送数は8バイト mltrecv8 mov d4,INDIRECT ;FSRの指した変数から転送 cje d4,#'.',mltrecv9 ;"."なら表示しない call write_lcd4 ;表示 mltrecv9 inc FSR ;ポインタ+1 djnz poi,mltrecv8 ;指定回数繰り返し ret ;============================================================================== ; ; オープニング画面・パラメータ表示 ; open call lcd_clr ;液晶画面消去 call line1 ;LCD 1行目にカーソルセット mov d4,#'M' ;"MY:"を表示 call write_lcd4 mov d4,#'Y' call write_lcd4 mov d4,#':' call write_lcd4 mov poi,#pac01+7 ;ポインタに自局アドレス設定 call callp ;CALL表示 call line2 ;LCD 2行目にカーソルセット call messp ;メッセージ表示 ret ; ; コール表示 callp mov cn,#6 ;表示文字数は6文字 call1 mov w,poi call eeREAD ;EEPROMから読み出し mov d4,w clc rr d4 ;右シフトしてASCII文字に戻す call write_lcd4 ;表示 inc poi ;ポインタ+1 djnz cn,call1 ;指定文字数繰り返し ; SSIDの表示 mov d4,#'-' ;"-"を表示 call write_lcd4 mov w,poi call eeREAD ;EEPROMから読み出し andlw 00011110b ;SSID部分だけ抜き出す addlw 60h ;ASCII文字化するための準備 mov d4,w rr d4 ;右シフトしてASCII文字に戻す call write_lcd4 ;表示 ret ; ; メッセージ表示 messp mov poi,#ui02_tbl ;ポインタ設定 mess1 mov w,poi call eeREAD ;EEPROMから読み出し jz mess2 ;0なら表示終了 mov d4,w call write_lcd4 ;表示 inc poi ;ポインタ+1 goto mess1 ;繰り返し mess2 ret ;終了 ;============================================================================== ; ; パラメータ書き換え用文字入力 ; ; スタート確認用ESC入力 inkey call line1 ;LCD 1行目にカーソルセット mov cn,#14 ;表示文字数設定 inkey1 mov w,poi call inkey_tbl ;テーブル参照 mov d4,w call write_lcd4 ;表示 inc poi ;ポインタ+1 djnz cn,inkey1 ;指定回数繰り返し ; inkey2 call receive ;1文字入力 cjne ch,#esc,inkey2 ;ESC入力待ち ret ; ; MY CALL入力 input mov d4,#10000000b+3 ;LCD 1行+3桁目にカーソルセット call line mov poi,#pac01+7 ;ポインタ設定 mov ssid,#11100000b ;SSIDパラメータ設定 call cinput ;CALL入力 jnz input ;キャンセルなら最初に戻る ; ; DIGI CALL表示 call line1 ;LCD 1行目にカーソルセット mov d4,#'D' ;"DG;"を表示 call write_lcd4 mov d4,#'G' call write_lcd4 mov d4,#':' call write_lcd4 mov poi,#pac01+14 ;デジCALL表示 call callp ; ; DIGI CALL入力 input2 mov d4,#10000000b+3 ;1行+3桁目 call line mov poi,#pac01+14 mov ssid,#01100001b call cinput jnz input2 ;キャンセル ; ; MESSAGE書き換え inp1 call line2 ;LCD 2行目にカーソルセット mov poi,#ui02_tbl ;ポインタ設定 mov cn,#20 ;入力文字数設定 inp2 call cget ;1文字入力 cje ch,#can,inp1 ;キャンセルなら最初に戻る mov eeadr,poi ;EEPROMアドレス設定 cje ch,#13,inp3 ;改行なら終了する mov eedata,ch ;EEPROMに文字書き込み call eeWRITE ;書き込み実行 inc poi ;ポインタ+1 djnz cn,inp2 ;指定文字数分繰り返し ret inp3 mov eedata,#0 ;最後に"0"を書き込んで終了 call eeWRITE ret ; ; CALL書き換え(6文字入力) cinput mov cn,#6 ;入力文字数設定 cinp1 call cget ;1文字入力 cje ch,#can,cinp3 ;キャンセルなら最初に戻る clc rl ch ;左シフトしてLSBを空ける mov eedata,ch ;EEPROMに文字書き込み mov eeadr,poi ;EEPROMのアドレス設定 call eeWRITE ;書き込み実行 inc poi ;ポインタ+1 djnz cn,cinp1 ;指定回数分繰り返し mov d4,#'-' ;"-"表示 call write_lcd4 ; SSID入力 cinp2 call cget ;1文字入力 cje ch,#can,cinp3 ;キャンセルなら最初に戻る rl ch ;左シフトしてLSBを空ける mov w,ch andlw 00011110b ;SSIDに無関係なビットを削除 iorwf ssid,0 mov eedata,w ;EEPROMに文字書き込み mov eeadr,poi ;EEPROMのアドレス設定 call eeWRITE ;書き込み実行 setb z ;正常終了ならz-flagセット ret cinp3 clrb z ;キャンセルならz-flagクリア ret ; ; 1文字入力 (out:ch) cget call receive ;1文字入力 jz cget ;エラーがあれば繰り返し mov d4,ch goto write_lcd4 ;入力文字を表示 ret ;============================================================================== ; ; CRC計算 ; (CRC-CCITT ... P(x) = X^16 + X^12 + X^5 + 1/実際のbit並びは逆) ; 実行時間 CRCC1 ; 新規に1を加える時のコール先 xor crcL,#00000001b ;2 X^16と1をEXORする CRCC0 ; 新規に0を加える時のコール先 rr crcL ;1 結果をcfへ転送 btfss c ; goto crcc01 ;2/1+2 cf=0ならcrcc01へ ; crcc00 ; 結果が"1"だった時 rl crcL ;1 crcLを元に戻す stc ;1 rr crcH ;1 "1"をcrcバッファへシフトする rr crcL ;1 xor crcL,#00001000b ;2 X^5と1をEXORする xor crcH,#00000100b ;2 X^12と1をEXORする ret ;2(15) ; crcc01 ; 結果が"0"だった時 nop ;3 計算終了時間調整用ウエイト nop ; nop ; rl crcL ;1 crcLを元に戻す clc ;1 rr crcH ;1 "0"をcrcバッファへシフトする rr crcL ;1 ret ;2(12+3) ; ; CRC出力 ; (HDLC変換するとCRC計算もされてしまうのでcrcHを一時退去する) CRC mov cn,crcH ;crcHを一時退去 mov ch,crcL xor ch,#0ffh call HDLC ;CRC下位バイト送信 mov ch,cn ;crcHを復帰 xor ch,#0ffh call HDLC ;CRC上位バイト送信 ret ;============================================================================== ; ; HDLC変換("1"が5個以上連続したら"0"を挿入) ; (in : ch) HDLC ;実行時間 mov bcn,#8 ; 8ビット分出力 HDLC1 rr ch ;1 シリアル変換 btfsc c ; goto HDLC2 ;2/1+2 "1"ならHDLC2へ call NRZI ;2+*6 "0"を出力 call CRCC0 ;2+12 CRCも"0"で計算 nop ;4 時間調整用ウエイト nop ; nop ; nop ; mov hcn,#5 ;2 HDLCビットカウンタ初期化 djnz bcn,HDLC1 ;3(30+4) 8ビット分繰り返し ret HDLC2 ; 出力が"1"だった時 dec hcn ;1 HDLCビットカウンタ-1 jz HDLC3 ;2/3 "1"が連続5個越えたらHDLC3へ call NRZI ;2+*6 "1"を出力 call CRCC1 ;2+14 CRCも"1"で計算 djnz bcn,HDLC1 ;3(34) 8ビット分繰り返し ret HDLC3 ; "1"が5個連続した時 stc ;1 call NRZI ;2+*6 "1"を出力 mov wait_cn,#5 ;2 少しウエイトを入れる call wait_us ;4+5*3(21) clc ;1 call NRZI ;2+*6 "0"を挿入 call CRCC1 ;2+14 CRCは"1"で計算 mov hcn,#5 ;2 HDLCビットカウンタ初期化 djnz bcn,HDLC1 ;3(47+21/2) 8ビット分繰り返し ret ;============================================================================== ; ; フラグ出力(07ehの出力) ; flag ;実行時間 mov ch,#07eh ; フラグデータは7eh mov bcn,#8 ; 8ビット分出力 flag1 rr ch ;1 call NRZI ;2+*6 データ出力 nop ;1 mov wait_cn,#5 ;2 フラグ出力ルーチンは短いので call wait_us ;4+5*3(22) ウエイトを入れる djnz bcn,flag1 ;3(12+22) 8ビット分繰り返し ret ;============================================================================== ; ; NRZI変換(cf=0なら反転、cf=1ならそのまま) ; (in : cf) NRZI ;実行時間 btfsc c ; c=1ならそのまま出力 goto NRZIend ;2/1+2 xor outb,#1 ;2 c=0なので反転して出力 NRZIend btfsc outb.0 ; 出力が0ならLowへ goto Low ;2/1+2(5/7) ;============================================================================== ; ; トーン発生(1200bps出力) ; ; 2200Hzを1200bps発生 Hi ;実行時間 mov tcn,#Hloop-1 ;2 繰り返し数設定 Hi1 movf tpo,0 ;1 波形ポインタ取得 andlw 15 ;1 call wave_tbl ; 波形テーブル参照 movwf rb ;1 波形データ出力 mov wait_cn,#Htone ;2 波形データ出力間隔設定 call wait_us ;4+n ウエイトルーチン inc tpo ;1 波形ポインタ+1 djnz tcn,Hi1 ; 1200bps分繰り返し ; movf tpo,0 ;1 最後の波形データ出力後の andlw 15 ;1 ウエイト時間を減らして、 call wave_tbl ; 他の処理の時間を稼ぐ。 movwf rb ;1 mov wait_cn,#Htone-11 ; 2 11ループ分時間を減らす call wait_us ;4+n inc tpo ;1 ret ; 1200Hzを1200bps発生 Low ;時間実行 mov tcn,#Lloop-1 ;2 繰り返し数設定 Low1 movf tpo,0 ;1 波形ポインタ取得 andlw 15 ;1 call wave_tbl ; 波形テーブル参照 movwf rb ;1 波形データ出力 mov wait_cn,#Ltone ;2 波形データ出力間隔設定 call wait_us ;4+n ウエイトルーチン inc tpo ;1 波形ポインタ+1 djnz tcn,Low1 ; 1200bps分繰り返し ; movf tpo,0 ;1 最後の波形データ出力後の andlw 15 ;1 ウエイト時間を減らして、 call wave_tbl ; 他の処理の時間を稼ぐ。 movwf rb ;1 mov wait_cn,#Ltone-11 ; 2 11ループ分時間を減らす call wait_us ;4+n inc tpo ;1 ret ;============================================================================== ; ; RS232C受信サブルーチン ; ; フレーム間検出 データの10キャラクタ以上の切れ目を探す gapwait mov ch,#200 ;200bit gapw1 mov rsw,#btime/4 ;1/2ビット分待つ gapw2 djnz rsw,gapw2 ; btfsc sw ;SWチェック goto gapw4 cjne txc,#1,gapw4 ;送信準備状態でなければキャンセル ret gapw4 btfsc rxd goto gapwait ;時間内にHIが来たらリセット ; djnz ch,gapw1 ;指定ビット数以上のギャップ検出 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 ;============================================================================== ; ; データメモリ読み書き ; ; 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 ; ; EEPROM WRITE (in:address(eeadr),data(eedata)) eeWRITE setb rp0 ;page1 setb wren ;EEPROM WRITE ENABLE mov eecon2,#055h mov eecon2,#0aah setb wr ;EEPROM WRITE FLAG eeWRITE1 btfss eeif ;EEPROM WRITED COMPLETE goto eeWRITE1 clrb wren ;EEPROM WRITE disENABLE clrb rp0 ;page0 mov wait_cn,#10 call wait_ms ret