; fll 2006/07/30 7n4kyg
; dllに改名 2006/09/16 一応それなりに、動く!!
; 2006/10/01差の周波数表示としたが、いまいち上手く行かない。結果、設定周波数にした。
; 2006/10/21周波数カウント回路のポート入れ替えを削除 フリッカーノイズ対策
; 2006/10/29周波数偏差20HZ以下でも、多少調整(20hz調整すると、音質が変化する為)
; 2006/10/30 VFO-CONTを割り込み不許可にした。
; 2006/11/12 pa-3.0にて、エラー発生アリ 土台を修正(新規のファイルに貼付、変な属性あったかも?
; 他にエラー6点発生修正済み
; OPTIONで文法エラー、FCOUNTで文法エラー,freq_to_oscでエラー有り修正済み
; カウンター部127以上繰り上がり禁止でカウンター正常になった。可也苦労3週間悩んだ!!
; 2007/01/30訂正 btfsc freq[0],7;繰上りミス防止上記内容
; 2007/03/24 RITプログラム追加 rit動作ok
; 2007/05/28 RIT初期記憶追加 RIT ONで立ち上げると送信Fが違いすぎる。
; 2007/06/06 ハムフェアーに提出 落選
; 2008/08/23 ステップ50hzに変更、RIT,送信表示、周波数誤差12khz修正
; 2010/02/07 RIT、TX信号入れ替え
; 2010/03/15 フォトカプラー信号入れ替え
; 2010/06/06 7mhz拡張の為中心周波数を7.075Mhzに変更
; 2010/07/30 7mhzやっぱり中心周波数を7.050Mhzの方がイイ
; 2010/08/14 チューニング中でも周波数補正させる。 良好
; 2010/12/05 クロック20mhz&クリスタルにする。周波数カウント時間50ms最高測定5Mhz計測、プリスケーラ2倍削除
; 2011/01/22 if 10.24mhzに変更 if12だと、北京放送入るので!!
; 2011/01/23 プリスケーラをなし、前はX2 ステップ20hzに、ダイアル回しても周波数変化遅いので!。
; 2012/02/15  ritスイッチ、tx表示逆なので修正&rit周波数表示
; 2012/09/08  周波数ずれを修正 周波数誤差12khz修正この処理削除


;***** at Clock=20.00mhz *****
wait_10us equ 164   ;100 usec の定数
wait_4us equ 64   ;40 usec の定数
;***** at Clock=12.80mhz *****
;wait_10us equ 105   ;100 usec の定数
;wait_4us equ 41   ;40 usec の定数
;LCDに関する定数の定義
;***** at Clock=10MHz *****
;WAIT_10US equ 82    ;100 usec の定数
;WAIT_4US equ 32   ;40 usec の定数
;***** at Clock=4.00MHz *****
;WAIT_10US equ 32   ;100 usec の定数
;WAIT_4US equ 12   ;40 usec の定数
 
;**************************
lcd_line1 equ 0   ;LCDの1行目の先頭アドレス
lcd_line2 equ 64   ;LCDの2行目の先頭アドレス
;******************
;システム構成の定義
;******************
  .include 16f84.h  ;CPUに16F84を指定する
  .osc  hs  ;外部発信機
  .wdt  off  ;ウォッチドッグを使用しない
  .pwrt  off  ;パワーアップタイマを使用しない
  .protect off  ;プロテクトはしない

;************************************************
;送受信に関するパラメータ群
;発信周波数 osc
;表示周波数 freq
;add_xy x=x+y
;sub_xy x=x-y
;long_to_asc asc=ltoa( x )
;************************************************
step3  equ 00000000b ;周波数ステップ=40Hz               最初から40HZでした。
step2  equ 00000000b ;=0x00000004x10倍
step1  equ 00000000b ;
step0  equ 00000100b ;初期値

;iff3  equ 00000000b ;中間周波数12.000MHz
;iff2  equ 00010010b ;
;iff1  equ 01001111b ;
;iff0  equ 10000000b ;

iff3  equ 00000000b ;中間周波数10.24MHz
iff2  equ 00001111b ;
iff1  equ 10100000b ;
iff0  equ 00000000b ;

;iff3  equ 00000000b ;中間周波数11.000MHz
;iff2  equ 00010000b ;
;iff1  equ 11001000b ;
;iff0  equ 11100000b ;

;setf3 equ 00000000b ;設定(目標)周波数4.95MHz
;setf2 equ 00000111b ;初期中心周波数7.050を表示する
;setf1 equ 10001101b ;
;setf0 equ 10011000b ;

setf3 equ 00000000b ;設定(目標)周波数3.19MHz
setf2 equ 00000100b ;初期中心周波数7.050を表示する
setf1 equ 11011110b ;
setf0 equ 00011000b ;

;setf3 equ 00000000b ;設定(目標)周波数3.95MHz
;setf2 equ 00000110b ;初期中心周波数7.050を表示する
;setf1 equ 00000110b ;
;setf0 equ 11111000b ;

;***************************************
;ロータリーエンコーダーに用いる H/W 定義
;***************************************
rea  equ rb.0  ;A相
reb  equ rb.1  ;B相
;******************************************
;ロータリーエンコーダで使用するメモリー定義
;******************************************
rodat  ds 1
ropas  ds 1
;****************************
;システムに用いるメモリー定義
;****************************
  org 0ch
cn  ds 1 ;カウンタ
cnnn ds 1  ;カウンタ
wrk  ds 1 ;ワーク
rewrk ds 1  ;エンコーダ用ワーク
osc  ds 4 ;発振周波数
freq ds 4  ;現在の周波数
kstep ds 4  ;早送り記憶 110129追加
stfreq ds 4  ;設定周波数
iffreq ds 4  ;中間周波数
txfreq ds 4  ;送信周波数
rxfreq ds 4  ;受信周波数
x  ds 4 ;long 計算ワーク
y  ds 4 ;long 計算ワーク
asc  ds 10 ;アスキーデータ
asc_end
;**********************
;システムで使用する変数
;**********************
wrks  ds 1  ;ステータスの退避メモリ
wrkw  ds 1  ;アキュムレータ退避メモリ
timecnt0 ds 1  ;割込みサービス変数
waitnss0 ds 1 
waitnss1 ds 1
waitnss2 ds 1
par  ds 1  ;関数間の受渡しデータ
parr  ds 1  ;関数間の受渡しデータ
d8  ds 1  ;関数間の補助受渡しデータ
os_wrk1  ds 1  ;μsec wait カウンタ
os_wrk2  ds 1  ;1msec wait カウンタ
rbddr  ds 1  ;rb の設定データ
pa  ds 1  ;ポートの読込みデータ
os_flg  ds 1  ;フラグ用メモリ
lpcnt1  ds 1
lpcnt2  ds 1
;**************************
;LCD コントロールピンの定義
;各種フラグの定義
;**************************
timeup equ os_flg.0  ;タイムアップフラグ
rs  equ os_flg.1 ;論理ポート
rrs  equ rb.2  ;物理ポート
ee  equ rb.3  ;
count_in equ ra.4  ;tmr0のポート             tmr0のポートの開け閉めつけました。
vup  equ ra.1  ;vco+チャージ。 
vdown equ ra.0   ;vco-チャージでない。 
rit_sw equ ra.3   ;ritがon。  名前on→sw
tx_sw equ ra.2   ;送信時。 **********名前on→sw ************************
;*****  プログラムセクション  *****
;**********************************
;****************
;システムの初期化
;****************
  org 0  ;
  goto start  ;

  org 4  ;エンコーダーの割り込み
  goto enco_in  ;割り込み処理へ
;**************
;スタートアップ
;**************
start  
  bsf status,5   ;set page 1
  mov option,#01100000b  ;ra4(tmr0)の設定 プリスケーラを含む
       ;prescaler 1/2 set ;RBプルアップ; 立ち下がりカウント
  bcf status,5   ;set page 0
  clr tmr0    ;Clear TMR0
  mov !ra,#00011100b   ;ra2,3,4を入力,ra0,1をOUT に
  mov !rb,#00000011b   ;rb0,1 以外を全部 OUT に
  mov ra, #00000000b   ;ポート初期化
  mov rb, #00000000b   ;ポート初期化
  call lcdopen    ;LCD初期化
  mov stfreq[3],#setf3  ;エンコーダの初期周波数を入力(495.000khz)
  mov stfreq[2],#setf2  ;尚、表示は、10倍にする(左へ一桁シフトさせる)
  mov stfreq[1],#setf1
  mov stfreq[0],#setf0
  mov iffreq[3],#iff3   ;中間周波数10.2400MHz
  mov iffreq[2],#iff2   ;
  mov iffreq[1],#iff1   ;
  mov iffreq[0],#iff0   ;
  mov kstep[3],#step3   ;ステップ
  mov kstep[2],#step2   ;
  mov kstep[1],#step1
  mov kstep[0],#step0
  mov txfreq[0], stfreq[0] ;最初に送信周波数を記憶して置く
  mov txfreq[1], stfreq[1] ;rit、onのままだと、とんでもない数値を記憶する為
  mov txfreq[2], stfreq[2] ;リセットを掛ける。
  mov txfreq[3], stfreq[3] ;最初に送信周波数を記憶して置く
  mov intcon,#10010000b ;rb0割り込みを許可する
  mov cnnn,#1   ;表示回数の設定 初期値の設定 

;**************+       
;メインルーチン
;**************
main
  call f_count   ;カウンター 
  call vfo_cont  ;vfo制御 
  djnz cnnn,main  ;ループ中は、表示は、10回ループに1回
  call hyouji_ue  ;現在/設定差の周波数の表示
  mov cnnn,#10  ;表示回数の設定 一秒に一回では、ちらつき過ぎ
  goto  main   ;メインに戻る
;**************+       
;周波数補正ルーチン 割込より呼ばれる。
;**************
fcont_enc
  call f_count   ;カウンター 
  call vfo_cont  ;vfo制御 
  call hyouji_ue  ;現在/設定差の周波数の表示
  ret    ;メインに戻る

;*********************************************************
;周波数カウンター初期設定
;オーバーフロー監視、カウントアップ、一定時間の確保(25msec) 後で5mhz迄測定不可能  ここの処理おかしい
;59*163*2.6=(25msec)1命令時間 1/20MHz*4*13Step=2.6                  ここの処理おかしい       
;118*163*2.6=(50msec)1命令時間 1/20MHz*4*13Step=2.6 これ OK 6khzの誤差      ここの処理おかしい
;98*157*2.6=(40msec) =25hz最小周波数 これわ 駄目!!                 ここの処理おかしい
;*********************************************************fcount 

f_count 
  clr freq[0]   ;周波数カウントの前処理
  clr freq[1]   ;
  clr freq[2]   ;
  clr freq[3]   ;
                bsf count_in  ;ゲートを開ける 120907追加      tmr0の開く指令
  clr tmr0   ;counter reset
  bcf intcon,2  ;reset T0IF
  mov lpcnt1,#125  ;loop counter 1           回数変更
meslp1
  mov lpcnt2,#133  ;loop counter 2           回数変更
meslp2
  btfss intcon,2  ;13 steps loop   
  goto dumy1
  bcf intcon,2  ;reset T0IF
  movlw 1   ;カウントアップ
  goto  next
dumy1
  nop    ;dumy NOP
  nop    ;同じステップ数にするため
  movlw 0   ;カウントアップ無し
next
  nop    ;ステップ調整  120907追加              
  nop   ;ステップ調整  120907追加
  addwf freq[1],1 ;freq[1]+T0IF
  rlf freq[1],0 ;carry to d0
  andlw 1  ;mask
  addwf freq[2],1 ;BYTE2+Carry
  decfsz lpcnt2,1 ;check loop end
  goto meslp2  ;loop
  decfsz lpcnt1,1 ;
  goto meslp1  ;  (15*LPCNT2 133 +5)*LPCNT1 125 ==2500000ステップ
  bcf count_in ;ゲートを閉める 120907追加                        0.05の計測時間でした

  nop   ;50msループから脱出
  movf tmr0,0  ;TMR0をfreq[0]に取り出し
  movwf freq[0]  ;061112()と[]間違え有った
  btfss intcon,2 ;オーバーフロー確認   
  goto tobu1  ;オーバーフローで無いなら
  bcf intcon,2 ;reset T0IF
  btfsc freq[0],7 ;繰上りミス防止 '070130訂正
  goto tobu1
  movlw 1
  addwf freq[1],1 ;freq[1]+T0IF
  rlf freq[1],0 ;carry to d0
  andlw 1  ;mask
  addwf freq[2],1 ;freq[2]+Carry
tobu1
     ;プリスケーラーで1/2したので最後にデーターを4倍する。50mSなので!
  bcf status,0
  rlf freq[0],1 ;2倍にする
  rlf freq[1],1
  rlf freq[2],1
  rlf freq[3],1
  bcf status,0
  bcf status,0
  rlf freq[0],1 ;2倍にする
  rlf freq[1],1
  rlf freq[2],1
  rlf freq[3],1
  bcf status,0
  ret 

;********************************************************************
;vfo制御 stfreq-freq(セット周波数-現在の周波数)で引き算して、差があるとき
;周波数が+又は-に成るように、制御信号を出す。
;********************************************************************
vfo_cont 
  mov intcon,#00000000b  ;rb0割り込みを許可しない。ここで、割込発生すると、チャージ、デチャージし続ける為。
  mov rxfreq[0], stfreq[0]  ;ritコントロール  変数に記憶する
  mov rxfreq[1], stfreq[1]  ;最初に受信周波数を記憶して置く。
  mov rxfreq[2], stfreq[2]  ;最後に受信周波数をsetする。
  mov rxfreq[3], stfreq[3]  ;

  btfss rit_sw    ;rit onなら
  goto ritsww    ;実際は、rit onの時は、ジャンプする。
  mov txfreq[0], stfreq[0]  ;ritがoffならば、送信周波数を記憶して置く
  mov txfreq[1], stfreq[1]  ;(逆に云うと、rit、onの時は、送信周波数は、固定させる。
  mov txfreq[2], stfreq[2]  ;
  mov txfreq[3], stfreq[3]  ;
ritsww  
  btfsc tx_sw    ;tx on?(送信中?)
  goto txsww
  mov stfreq[0], rxfreq[0]  ;現在の周波数を受信周波数に代入
  mov stfreq[1], rxfreq[1]  ;
  mov stfreq[2], rxfreq[2]  ;
  mov stfreq[3], rxfreq[3]  ;
  goto rxon
txsww
  mov stfreq[0], txfreq[0]  ;現在の周波数を受信周波数に代入
  mov stfreq[1], txfreq[1]  ;
  mov stfreq[2], txfreq[2]  ;
  mov stfreq[3], txfreq[3]  ;
rxon
  mov x[0], freq[0]    ;現在の周波数
  mov x[1], freq[1]    ;
  mov x[2], freq[2]    ;
  mov x[3], freq[3]    ;
  mov y[0], stfreq[0]    ;設定周波数
  mov y[1], stfreq[1]    ;
  mov y[2], stfreq[2]    ;
  mov y[3], stfreq[3]    ;
          ;*************
  call sub_xy     ;現在の周波数-設定周波数
  btfss x[3].7     ;+-の振り分け、正なら代入、負なら逆数にを整数に変換
  goto purasu     ;整数は、そのまま代入
;******周波数マイナスの時の処理*******
  mov y[0], x[0]     ;引き算の準備
  mov y[1], x[1]     ;-は逆ビット数なので整数にする。
  mov y[2], x[2]     ;
  mov y[3], x[3]     ;
  clr x[0]       ;マイナスを整数に変換、notを使わず0より引く
  clr x[1]       ;
  clr x[2]       ;
  clr x[3]      ;
  call sub_xy      ;マイナスを整数へ変換のための引き算
;******バリキャップの印加時間、マイナスの時の動作時間作り*******
;*****周波数プラスの時は、電圧up******** 
syuuseim
  ;mov kstep[0],#250   ;普通に回すとステップが遅い  いい感じぢゃないので、中止
  ;cjb x[0],#64,stepmm   ;cja== if fr<<#lite then jmp
  ;mov kstep[0],#2   ;早くダイアル回すと早送りする
;stepmm 
  bcf vdown    ;ra1-off コンデンサ電圧放電やめ、インターロック
  cje x[1],#0,jpm0   ;cje== if fr==<#lite then jmp
  bsf vup    ;ra0-on コンデンサへ電圧印加
  mov par,#10    ;mswait 1ms=1000ループ  最大3万回
  call waitnms    ;
  goto jpm02
jpm0
  cjb x[0],#32,jpm01   ;cjb== if fr<<#lite then jmp
  bsf vup    ;ra0-on コンデンサへ電圧印加
  mov par,#1    ;wait 1ms=1000ループ
  call waitnms    ;
  goto jpm02
jpm01
  cjb x[0],#1,jpm02   ;20hz以内は、不感帯
  bsf vup    ;ra0-on コンデンサへ電圧印加
  mov parr,x[0]   ;cへのチャージ時間に代入
  call wait_nss   ;
jpm02
  bcf vup    ;ra0-off コンデンサへ電圧印加やめ
  goto dainyuu    ;変数に代入して表示する

;*****バリキャップの印加時間、周波数プラスの時の動作時間作り********
;*****周波数マイナスの時は、電圧down********
purasu
  ;mov kstep[0],#250   ;普通に回すとステップが遅い。いい感じぢゃないので、中止
  ;cjb x[0],#64,steppp   ;cjb== if fr<<#lite then jmp
  ;mov kstep[0],#2   ;早くダイアル回すと早送りする
;steppp       ;プラスの処理
  bcf vup    ;ra0-off コンデンサへ電圧印加やめ、インターロック
  cje x[1],#0,jpp0   ;cjb== if fr<<#lite then jmp
  bsf vdown    ;ra1-on コンデンサ電圧放電へ
  mov par,#10    ;wait 1ms=1000ループ
  call waitnms    ;
  goto jpp02
jpp0
  cjb x[0],#32,jpp01   ;cjb== if fr<<#lite then jmp
  bsf vdown    ;ra0-on コンデンサへ電圧印加
  mov par,#1    ; wait 1ms
  call waitnms    ;
  goto jpp02    ;
jpp01 
  cjb x[0],#1,jpp02   ;20hz以内は、不感帯
  bsf vdown    ;ra1-on コンデンサ電圧放電へ
  mov parr,x[0]   ;cへのチャージ時間に代入
  call wait_nss   ;
jpp02 
  bcf vdown    ;ra1-off コンデンサ電圧放電やめ
dainyuu

  mov stfreq[0], rxfreq[0] ;070325 rit追加に依り変更
  mov stfreq[1], rxfreq[1] ;最後に受信周波数をsetする。
  mov stfreq[2], rxfreq[2] ;
  mov stfreq[3], rxfreq[3] ;
  mov intcon,#10010000b ;rb0割り込みを許可する
  ret
;*******************************
;lcdに表示する。(1行目)
;*******************************
hyouji_ue 
  mov intcon,#00000000b ;rb0割り込みを許可しない。変な文字が出る為;lcd表示中に割込が入ると、表示が乱れてしまう。
      ;if周波数-発振周波数=現在(表示)周波数 2007/01/30追加)
  mov x[0], iffreq[0]  ;現在の周波数
  mov x[1], iffreq[1]  ;
  mov x[2], iffreq[2]  ;
  mov x[3], iffreq[3]  ;
  mov y[0], freq[0]  ;設定周波数
  mov y[1], freq[1]  ;
  mov y[2], freq[2]  ;
  mov y[3], freq[3]  ;
  call sub_xy   ;xが引算結果      
  call long_to_asc  ;周波数をアスキー変換
  movlw lcd_line1  ;表示位置の指定(1行目)
  call locate   ;
  movlw 'f'   ; 1桁目
  call print   ;
  movlw 'r'   ; 2桁目
  call print   ;
  movlw 'e'   ; 3桁目
  call print   ;
  movlw 'q'   ; 4桁目
  call print   ;
  movlw ' '   ; 5桁目
  call print   ;
  mov w, asc[4]  ;  6桁目
  call print   ;
  movlw '.'   ; 7桁目
  call print   ;
  mov w, asc[5]  ; 8桁目
  call print   ;
  mov w, asc[6]  ; 9桁目
  call print   ;
  mov w, asc[7]  ; 10桁目
  call print   ;
  movlw '.'   ; 11桁目
  call print   ;
  mov w, asc[8]  ; 12桁目
  call print   ;
  mov w, asc[9]  ; 13桁目
  call print   ;
  movlw 'M'   ; 14桁目
  call print   ;
  movlw 'h'   ; 15桁目
  call print   ;
  movlw 'z'   ; 16桁目
  call print   ;
  mov intcon,#10010000b ;rb0割り込みを許可する
      ;ret表示上と指示すると、下も表示させる、よってretを削除してある

;************************************************************************
;lcdに表示する。(2行目) 割込中の処理-表示中は、割り込み禁止にしたほうが、いい
;************************************************************************
hyouji_sita     ;ここは、割込中なので、問題ない。
  mov intcon,#00000000b ;rb0割り込みを許可しない。変な文字が出る為;lcd表示中に割込が入ると、表示が乱れてしまう。
  
  ;mov x[0], iffreq[0]  ;ifの周波数
  ;mov x[1], iffreq[1]  ;
  ;mov x[2], iffreq[2]  ;
  ;mov x[3], iffreq[3]  ;
  ;mov y[0], freq[0]  ;現在周波数
  ;mov y[1], freq[1]  ;
  ;mov y[2], freq[2]  ;
  ;mov y[3], freq[3]  ;
  ;call sub_xy   ;xが引算結果      
  ;call long_to_asc  ;周波数をアスキー変換

  movlw lcd_line2  ;表示位置の指定(2行目)
  call locate   ;

  btfsc tx_sw   ;TX ONなら
   goto  okuri   ;送信表示

uke  
  movlw 'r'   ; 1桁目
  call print   ;
  movlw 'e'   ; 2桁目
  call print   ;
  movlw 'c'   ; 3桁目
  call print   ;
  movlw ' '   ; 4桁目
  call print   ;
  goto hyoujiff
okuri
  movlw 's'   ; 1桁目
  call print   ;
  movlw 'n'   ; 2桁目
  call print   ;
  movlw 'd'   ; 3桁目
  call print   ;
  movlw ' '   ; 4桁目
  call print   ;
hyoujiff  
  movlw 'R'   ;  5桁目
  call print   ;
  movlw 'I'   ;  6桁目
  call print   ;
  movlw 'T'   ;  7桁目
  call print   ;
  movlw '='   ;  8桁目
  call print   ;
  
  btfss rit_sw   ;rit onなら
  goto ritonnn  
ritofff 
  movlw 'o'   ;9 区切りの表示
  call print   ;
  movlw 'f'   ;10 区切りの表示
  call print   ;
  movlw 'f'   ;11 区切りの表示
  call print   ;
  movlw ' '   ;12 区切りの表示
  call print   ;

  goto  mokuhyou             
ritonnn
  movlw 'o'   ;9 区切りの表示
  call print   ;
  movlw 'n'   ;10 区切りの表示
  call print   ;
  movlw ' '   ;11 区切りの表示
  call print   ;
  movlw ' '   ;12 区切りの表示
  call print   ;
mokuhyou 
 
  movlw ' '   ;13 区切りの表示
  call print   ;
  movlw ' '   ;14 区切りの表示
  call print   ;
  movlw ' '          ;15 区切りの表示
  call print   ;
  movlw ' '       ;16 区切りの表示
  call print   ;
  mov intcon,#10010000b ;rb0割り込みを許可する
      ;ret表示上と指示すると、下も表示させる、よってretを削除して
  ret
;************************************
;8ビット****************************
write_lcd8 
  and d8,#0f0h ;下位マスク(rb用に編集) 
  mov rb, d8  ;Bポートに出力
  movb rrs, rs  ;rs 情報書込み
  nop
  setb ee  ;Eピンを'H'(ストローブ)
  nop   ;時間かせぎ
  clrb ee  ;ストローブ終了
  call waitus0  ;100usecウエイト
  call waitus4  ;40usec wait
  ret
;************************************
;4ビットモード専用液晶ライトルーチン
;
;W で書込みデータを指定する
;************************************
print 
  movwf par  ;
  mov d8,par  ;上位書込み
  call write_lcd8 ;
  mov d8,par  ;下位書込み
  swap d8  ;
  call write_lcd8 ;
  ret
;******************
;液晶初期化ルーチン
;;LCD では Rb5-Rb0 を使用します。このため、Rb5-Rb0は必ず出力に
;設定して下さい。各ピンの接続方法は以下のとおりです。
;PIC-LCD
;Rb7-D7;Rb6-D6;Rb5-D5;Rb4-D4;GND-D3;GND-D2;GND-D1;GND-D0;Rb3-E;Rb2-rs;GND-R/~W
;******************
;液晶初期化ルーチン
;******************
lcdopen
        mov par,#20    ; wait 15ms
  call waitnms   ;
  clrb rs   ; rs='L'
  mov d8,#00110000b  ;8bit 指定
  call write_lcd8  ;
  mov par,#10   ; wait 4.1ms
  call waitnms   ;
  mov d8,#00110000b  ;8bit 指定
  call write_lcd8  ;
  call waitus0   ; wait 100μsec
  mov d8,#00110000b  ;8bit 指定
  call write_lcd8  ; 0 0 0011 (3)
  mov d8,#00100000b  ;4bit 指定
  call write_lcd8  ; 0 0 0010 (4bit)
  mov par,#00101000b  ;4bit/duty,font set9
  call print   ;
  mov par,#00000001b  ; クリアコマンド
  call print   ;
  mov par,#2   ; クリアが終わるまで待つ
  call waitnms   ;
  mov par,#00000110b  ; entry mode set
  call print   ;
  mov par,#00001100b  ; display on,cursor off
  call print   ;
  ret
;********************
;LCD の表示位置の指定
;W で位置を指定
;1行目 0-
;2行目 64-
;********************
locate
  movwf par
  setb par.7   ;LCD 固有のコマンド
  clrb rs   ;コマンド指定
  movf par, 0   ;
  call print   ;書込み
  setb rs   ;
  ret
;**************************************
;ロータリーエンコーダーから読込の割り込み
;**************************************
enco_in
  ;bcf intcon,7  ;割り込み禁止
  call wait1ms   ;1msウエイト
  movb rodat.1, reb  ;B 入力
  btfss rodat.1   ;rb1が1か確認する   
  goto setp   ;
setm
  call dec_freq  ;周波数を減算する
  jmp setf   ;
setp
  call inc_freq  ;周波数を加算する
setf
  ;call freq_to_osc  ;発振周波数を求める
  ;call SendFreq  ;DDS に周波数を書き込む
  nop    ;ちょっと時間稼ぎ
  ;call hyouji_sita  ;lcdに表示
  call fcont_enc  ;割り込み中でも周波数補正させる。
  nop    ;ちょっと時間稼ぎ
  ;mov intcon,#10010000b ;rb0割り込みを許可する
  goto main   ;メインに復帰
  ;retfie    ;割り込み終了
;****************
;周波数を ++ する
;****************
inc_freq
  mov x[0], stfreq[0]  ;もとの周波数
  mov x[1], stfreq[1]  ;
  mov x[2], stfreq[2]  ;
  mov x[3], stfreq[3]  ;
  mov y[0], kstep[0]  ;周波数の変位量
  mov y[1], kstep[1]  ;
  mov y[2], kstep[2]  ;
  mov y[3], kstep[3]  ;
  call add_xy   ;x = 現在周波数+ステップ
  mov stfreq[0], x[0]  ;結果の受け取り
  mov stfreq[1], x[1]  ;
  mov stfreq[2], x[2]  ;
  ret
;****************
;周波数を -- する
;****************
dec_freq
  mov x[0], stfreq[0] ;もとの周波数
  mov x[1], stfreq[1] ;
  mov x[2], stfreq[2] ;
  mov x[3], stfreq[3] ;
  mov y[0], kstep[0] ;周波数の変位量
  mov y[1], kstep[1] ;
  mov y[2], kstep[2] ;
  mov y[3], kstep[3] ;
  call sub_xy  ;x = 現在周波数-ステップ
  mov stfreq[0], x[0] ;結果の受け取り
  mov stfreq[1], x[1] ;
  mov stfreq[2], x[2] ;
  mov stfreq[3], x[3] ;
  ret
;***************************
;long 型式の引き算プログラム
;***************************
sub_xy 
  sub x[0],y[0]
  movlw 1
  btfss c
  subwf x[1],1
  btfss c
  subwf x[2],1
  btfss c
  subwf x[3],1
  sub x[1],y[1]
  movlw 1
  btfss c
  subwf x[2],1
  btfss c
  subwf x[3],1
  sub x[2],y[2]
  movlw 1
  btfss c
  subwf x[3],1
  sub x[3],y[3]
  ret
;***************************
;long 型式の足し算プログラム
;***************************
add_xy 
  add x[0],y[0]
  movlw 1
  btfsc c
  addwf x[1],1
  btfsc c
  addwf x[2],1
  btfsc c
  addwf x[3],1
  add x[1],y[1]
  movlw 1
  btfsc c
  addwf x[2],1
  btfsc c
  addwf x[3],1
  add x[2],y[2]
  movlw 1
  btfsc c
  addwf x[3],1
  add x[3],y[3]
  ret
;****************************
;long 型式の x を Asci に変換
;****************************
long_to_asc
  mov fsr,#asc_end ; 格納場所初期値
  call dev10  ; 最下位変換
  call dev10
  call dev10
  call dev10
  call dev10
  call dev10
  call dev10
  call dev10
  call dev10
  call dev10  ; 最上位変換
  ret
;***************
;/10サブルーチン
;***************
dev10
  mov cn,#32  ; 32ビットくり返し
  clr wrk
dev1001
  clrb c  ;キャリーリセット
  rl x[0]
  rl x[1]
  rl x[2]
  rl x[3]
  rl wrk
  movlw 0F6h  ;W=-10
  addwf wrk,0  ;W=wrk-10
  btfsc c
  mov wrk,w
  btfsc c
  inc x[0]
  djnz cn,dev1001
  dec fsr  ;格納ポインタ
  and wrk, #0Fh ;不要部分のマスク
  or wrk, #30h ;アスキーコード変換
  mov indirect,wrk ; 余り
  ret
;**************
;1msec ウェイト
;**************
wait1ms
  mov os_wrk2,#10
wm_lxh2
  call waitus0
  djnz os_wrk2, wm_lxh2
  ret
;****************
;100usec ウェイト
;****************
waitus0
  mov os_wrk1,#wait_10us
wu_lxh 
  djnz os_wrk1,wu_lxh
  ret
;****************
;40usec ウェイト
;****************
waitus4
  mov os_wrk1,#wait_4us
wu_lxh4
  djnz os_wrk1,wu_lxh4
  ret
;***********************
;n msec ウェイト
;n は par にセットします
;***********************
waitnms
  call wait1ms
  djnz par, waitnms
  ret
;****************
;2乗タイマ ウェイト
;****************
wait_nss
  
  cjb parr,#0,jmpwait1 ;誤動作防止マイナス計算される。
  mov waitnss2,parr
  ; add parr,#2
wait_nss2
  mov waitnss1,parr
wait_nss1
  djnz waitnss1,wait_nss1
  djnz waitnss2,wait_nss2
jmpwait1
  ret

end




TOPに戻る