;********************************************************************* ; FIT (GD1) 瞬間燃費計 ; (c)るきへな 2001-2002 ;********************************************************************* ; ; 開発開始 2001/12/22 ; 配線決定 2001/12/23 ; ケース組み込み 2001/12/24 ; 中途半端だけどリリース 2002/01/08 ; ; 使用環境 ; PIC PIC16F84-10/P ; 液晶 M1632,M1672,SC1602B等 ; クロック 10.0MHz ; アセンブラ 秋月の PA.EXE (http://www.akizuki.ne.jp/ashop/picdev.htm#K-00038) ; ; ピンアサイン: ; ; PIC LCD FIT etc. ; -------------------------------------------------------------------- ; GND DB0 ; GND DB1 ; GND DB2 ; GND DB3 ; RA0(17) DB4 LED_0 (電流制限抵抗を介してLED_COMへ) ; RA1(18) DB5 LED_1 (電流制限抵抗を介してLED_COMへ) ; RA2(17) DB6 LED_2 (電流制限抵抗を介してLED_COMへ) ; RA3(18) DB7 LED_3 (電流制限抵抗を介してLED_COMへ) ; RA4(17) ; GND R/~W ; RB0() speed(E25)青/黄 ; RB1() RS ; RB2() E(ENABLE) ; RB3() LED_COM (LED_0-3 のコモン。計25mAに気をつけよう) ; RB4() fup(E5)緑/白 ; RB5() nep(E26)青 ; RB6() ndr(C7)赤/青 ; RB7() ndn(C15)白 ; ; ☆ 電源・クリスタル・コントラスト調整VR等の配線は省略 ; ☆ 対車両IFは、単にダイオードを通して信号線へ直結。プルアップはPIC内蔵を使用。 ; ☆ 車両への接続のピンアサインは流動的です。本体プログラム参照のこと。 ; ☆ LED は液晶バスを使っていないときにドライブする。ダイナミック点灯の応用。 ; ☆ でも LED は使ってません。(デバッグ用かも) ; ☆ 変速比計計画のなごりコードが残ってます。 .include 16f84.h ; ここでは16F84を選択 .osc xt ; オシレータXT .wdt off ; ウォッチドッグOFF .pwrt on ; パワーアップタイマON .protect off ; プロテクトOFF RS equ rb.1 ; LCD の RS ピン E equ rb.2 ; LCD の RS ピン LED_COM equ rb.3 ; ステータス表示 (@@@予定) tmr0_reset equ 103 ; @@@適当 org 0ch ; 定石 timer_cn ds 2 ; タイマカウンタ odometer_cn ds 3 ; 走行距離カウンタ fuel_cn ds 3 ; 燃料パルスカウンタ igp_cn ds 2 ; エンジン回転パルスカウンタ ndr_cn ds 2 ; ドライブプーリースピード パルスカウンタ ndn_cn ds 2 ; ドリブンプーリースピード パルスカウンタ speed_tm_la ds 2 ; スピード・時間 speed_tm_lb ds 2 ; スピード・時間 speed_tm ds 2 ; スピード・時間 speed_flow ds 1 ; スピード・0km/hチェック fuel_tm_la ds 2 ; 燃料パルス・時間 fuel_tm_lb ds 2 ; 燃料パルス・時間 fuel_tm ds 2 ; 燃料パルス・時間 fuel_flow ds 1 ; 燃料パルス・fuel cut チェック speed ds 2 ; スピード fuel ds 2 ; 瞬間燃費[km/l] fuel_t ds 2 ; 瞬間燃費[cc/min] fuel_tr ds 2 ; 区間燃費[cc/min] w_save ds 1 ; 割込 退避用 status_save ds 1 ; 割込 退避用 ra_save ds 1 ; 通常時のra rb_now ds 1 ; 割込時のrb(割り込み期間だけ保存) rb_temp ds 1 ; 割込時のrb(処理ワーク) rb_save ds 1 ; 割込時のrb(次回まで保存) lcd_data ds 1 ; LCDデータ lcd_raw_data ds 1 ; LCDデータ(生) src1 ds 4 ; 計算用 引数 src2 ds 4 ; 計算用 引数 res ds 4 ; 計算用 戻り値 mod ds 4 ; 計算用 戻り値 diverr ds 1 ; 計算用 戻り値 dec ds 5 ; 10進格納場所(5バイト) dec_top calc_cn ds 1 ; カウンタのワーク calc_cn2 ds 1 ; カウンタのワーク org 0 goto start org 4 ; //////////////////////////////////////////////////////////////////// ; いきなりですが、割り込み処理。 ; //////////////////////////////////////////////////////////////////// interrupt movwf w_save ;レジスタ退避(定石) swapf status,w movwf status_save snb t0if ; t0if (タイマ) はどうよ call int_t0if ; t0if の処理 snb intf ; intf (RB0/INT) はどうよ call int_rb0 ; intf の処理 jnb rbif,skip_rbif ; rbif (RB4-7) はどうよ ; 以下 rbif の処理 mov rb_now,rb ; 現在の rb をゲット mov rb_temp,rb_now ; 計算tempにコピ xor rb_temp,rb_save ; 変化があったもの and rb_temp,rb_now ; かつ、現在 1 のもの snb rb_temp.4 ; rb4 はどうよ call int_rb4 ; rb4 の処理 snb rb_temp.5 ; rb5 はどうよ call int_rb5 ; rb5 の処理 snb rb_temp.6 ; rb6 はどうよ call int_rb6 ; rb6 の処理 snb rb_temp.7 ; rb7 はどうよ call int_rb7 ; rb7 の処理 mov rb_save,rb_now ; 次回のために現在の rb を保存 ; ★ rb から直接ゲットすると、既に変化している恐れあり。 skip_rbif swapf status_save,w ;レジスタ復帰(定石) movwf status swapf w_save swapf w_save,w clr t0if clr intf clr rbif retfie ; 割り込み処理終わり ; //////////////////////////////////////////////////////////////////// ; 割り込み処理のサブルーチン各種 ; //////////////////////////////////////////////////////////////////// int_t0if inc timer_cn[0] ; 2バイト inc btfsc 3.2 inc timer_cn[1] sb speed_flow.7 ; 0km/h と判断したら inc しない inc speed_flow sb fuel_flow.7 ; fuel cut と判断したら inc しない inc fuel_flow ret int_rb0 inc ndr_cn[0] ; 2バイト inc btfsc 3.2 inc ndr_cn[1] clr fuel_cn[0] ; 2バイト inc clr fuel_cn[1] clr fuel_cn[2] clr odometer_cn[0] ; 2バイト inc clr odometer_cn[1] clr odometer_cn[2] ret int_rb4 inc ndn_cn[0] ; 2バイト inc btfsc 3.2 inc ndn_cn[1] clr fuel_cn[0] ; 2バイト inc clr fuel_cn[1] clr fuel_cn[2] clr odometer_cn[0] ; 2バイト inc clr odometer_cn[1] clr odometer_cn[2] ret int_rb5 inc igp_cn[0] ; 2バイト inc btfsc 3.2 inc igp_cn[1] clr fuel_cn[0] ; 2バイト inc clr fuel_cn[1] clr fuel_cn[2] clr odometer_cn[0] ; 2バイト inc clr odometer_cn[1] clr odometer_cn[2] ret int_rb6 inc odometer_cn[0] ; 2バイト inc btfsc 3.2 inc odometer_cn[1] btfsc 3.2 inc odometer_cn[2] mov speed_tm_lb[0],speed_tm_la[0] mov speed_tm_lb[1],speed_tm_la[1] mov speed_tm_la[0],tmr0 mov speed_tm_la[1],timer_cn[0] clr speed_flow ; 0km/h チェックフラグクリア ret int_rb7 inc fuel_cn[0] ; 2バイト inc btfsc 3.2 inc fuel_cn[1] btfsc 3.2 inc fuel_cn[2] mov fuel_tm_lb[0],fuel_tm_la[0] mov fuel_tm_lb[1],fuel_tm_la[1] mov fuel_tm_la[0],tmr0 mov fuel_tm_la[1],timer_cn[0] clr fuel_flow ; fuel cut チェックフラグクリア ret ; //////////////////////////////////////////////////////////////////// ; メイン ; //////////////////////////////////////////////////////////////////// start ; OUT:0 IN:1 mov !ra,#00000000b ; RA? は全部OUT mov !rb,#11110001b ; RB1-RB3ピンをOUT clr ra clr rb ;[OPTIONレジスタの設定] ;7 RBPU   0 :PORTBのPullUp = 0:あり 1:なし ;6 INTEDGE  1 :INT割込み信号のエッジ = 0:立ち下がり 1:立ち上がり ;5 TOCS 0 :TMR0ソース選択 = 0:RA4ピン 1:内部 ;4 TOSE 0 :TMR0のカウントエッジ = 0:立ち上がり 1:立ち下がり ;3 PSA 0 :プリスケーラ割当 = 0:TMR0 1:WDT ;2 PS0〜2 6 :プリスケーラ値 = (TMR0)0:2 1:4 2:8 3:16 4:32 5:64 6:128 7:256 ; PS0〜2 :プリスケーラ値 = (WDT )0:1 1:2 2:4 3:8 4:16 5:32 6:64 7:128 mov option,#01000110b ; RAM初期化 ; 0c 〜 3f クリア mov fsr,#0ch ram_init_loop1 clr indirect inc fsr jnb fsr.6,ram_init_loop1 ; 続いて 40 〜 4f クリア ram_init_loop2 clr indirect inc fsr jnb fsr.4,ram_init_loop2 mov ra_save,#77h mov ra,w ; w には 11h が入っているハズ mov rb_save,#0ffh ; ------------------------------------------------------------------- ; 液晶初期化 開始 ; ------------------------------------------------------------------- ;;init_lcd mov calc_cn,#15 ; wait 15ms call wait_ms clrb RS ; RS='L' mov lcd_raw_data,#00000011b call write_lcd_raw mov calc_cn,#5 ; wait 4.1ms call wait_ms mov lcd_raw_data,#00000011b call write_lcd_raw mov calc_cn,#100 ; wait 100us call wait_us mov lcd_raw_data,#00000000b call write_lcd_raw ; 0 0 0011 (3) mov lcd_raw_data,#00000010b call write_lcd_raw ; 0 0 0010 (4bit) mov lcd_data,#00101000b ; duty,font set9 call write_lcd_data mov lcd_data,#00000001b ; クリアコマンド call write_lcd_data mov calc_cn,#2 ; クリアが終わるまで待つ call wait_ms mov lcd_data,#00000110b ; entry mode set call write_lcd_data mov lcd_data,#00001110b ; display on,cursor on call write_lcd_data ; ------------------------------------------------------------------- ; 液晶初期化 終了 ; ------------------------------------------------------------------- mov intcon,#11111000b ; 割り込みレジスタ初期設定 ; ------------------------------------------------------------------- ; メインループ ; ------------------------------------------------------------------- mainloop clr speed[1] clr speed[0] clrb rbie ; rb割込禁止 ; 速度計算(通常走行時) mov speed_tm[0],speed_tm_la[0] mov speed_tm[1],speed_tm_la[1] sub speed_tm[0],speed_tm_lb[0] sc dec speed_tm[1] sub speed_tm[1],speed_tm_lb[1] setb rbie ; rb割込許可 mov src2[0],speed_tm[0] mov src2[1],speed_tm[1] mov src1[1],#07dh ;32201=7DC9 mov src1[0],#0c9h ;32201=7DC9 call div16 mov speed[1],res[1] mov speed[0],res[0] clr fuel[1] clr fuel[0] ; 瞬間燃費計算 clrb rbie ; rb割込禁止 mov fuel_tm[0],fuel_tm_la[0] mov fuel_tm[1],fuel_tm_la[1] sub fuel_tm[0],fuel_tm_lb[0] sc dec fuel_tm[1] sub fuel_tm[1],fuel_tm_lb[1] setb rbie ; rb割込許可 mov src1[0],fuel_tm[0] mov src1[1],fuel_tm[1] mov src2[0],speed_tm[0] mov src2[1],speed_tm[1] call div16 mov fuel[1],res[1] mov fuel[0],res[0] mov src1[0],#38h ;11832=2e38 mov src1[1],#2eh ;11832=2e38 mov src2[0],fuel_tm[1] mov src2[1],#0 call div16 mov fuel_t[1],res[1] mov fuel_t[0],res[0] ; 区間燃費計算 clrb rbie ; rb割込禁止 mov src1[0],odometer_cn[0] mov src1[1],odometer_cn[1] mov src1[2],odometer_cn[2] mov src2[0],fuel_cn[0] mov src2[1],fuel_cn[1] mov src2[2],fuel_cn[2] setb rbie ; rb割込許可 clr src1[3] clr src2[3] call div32 mov fuel_tr[1],res[1] mov fuel_tr[0],res[0] ; LED mov ra_save,odometer_cn[0] mov ra,ra_save call print sb timer_cn[0].4 goto $-1 ; wait snb timer_cn[0].4 goto $-1 ; wait goto mainloop ; 無限ループ ;title_tbl jmp pc+w ; テーブル参照 ;title_mes retw '[16x2LCD Sample]' ; retw '「Microchip PIC」 ' print ; カーソルを0行目に移動 clrb RS mov lcd_data,#10000000b call write_lcd_data setb RS ; RS=1 : 以後のコマンドは文字表示 ; 区間燃費表示 mov src1[0],fuel_tr[0] mov src1[1],fuel_tr[1] call bin16tobcd call print_dec3 mov lcd_data,#' ' call write_lcd_data ; 走行距離カウント表示 mov src1[0],odometer_cn[0] mov src1[1],odometer_cn[1] call bin16tobcd call print_dec3 mov lcd_data,#' ' call write_lcd_data ; 燃料パルスカウント表示 mov src1[0],fuel_cn[0] mov src1[1],fuel_cn[1] call bin16tobcd call print_dec3 mov lcd_data,#' ' call write_lcd_data ; 速度表示 jb speed_flow.7,sp_print_0 ; 0km/h と判断されたら、0のまま、計算しない mov src1[0],speed[0] mov src1[1],speed[1] call bin16tobcd call print_dec3 goto sp_print_e sp_print_0 mov lcd_data,#'i' call write_lcd_data mov lcd_data,#'d' call write_lcd_data mov lcd_data,#'l' call write_lcd_data sp_print_e ; カーソルを1行目に移動 clrb RS mov lcd_data,#11000000b call write_lcd_data setb RS ; RS=1 : 以後のコマンドは文字表示 ; エンジン回転パルスカウント表示 mov src1[0],igp_cn[0] mov src1[1],igp_cn[1] call bin16tobcd ; call print_dec3 mov lcd_data,#' ' ; call write_lcd_data ; プーリーパルスカウント表示 mov src1[0],speed_tm[0] mov src1[1],speed_tm[1] call bin16tobcd call print_dec5 mov lcd_data,#' ' call write_lcd_data ; プーリーパルスカウント表示 mov src1[0],fuel_tm[0] mov src1[1],fuel_tm[1] call bin16tobcd call print_dec5 mov lcd_data,#' ' call write_lcd_data ; 燃費表示 jb speed_flow.7,fu_print_0 ; 0km/h と判断されたら jb fuel_flow.7,fu_print_fc ; fuel cut と判断されたら mov src1[0],fuel[0] mov src1[1],fuel[1] call bin16tobcd call print_dec3 mov lcd_data,#'k' call write_lcd_data mov lcd_data,#'m' call write_lcd_data goto fu_print_e fu_print_0 mov src1[0],fuel_t[0] mov src1[1],fuel_t[1] call bin16tobcd call print_dec3 mov lcd_data,#'c' call write_lcd_data mov lcd_data,#'c' call write_lcd_data goto fu_print_e fu_print_fc mov lcd_data,#'f' call write_lcd_data mov lcd_data,#'-' call write_lcd_data mov lcd_data,#'c' call write_lcd_data mov lcd_data,#' ' call write_lcd_data mov lcd_data,#' ' call write_lcd_data ;goto fu_print_e fu_print_e ret ; ; dec をLCDに表示 ; print_dec5 mov lcd_data,dec[0] call write_lcd_data print_dec4 mov lcd_data,dec[1] call write_lcd_data print_dec3 mov lcd_data,dec[2] call write_lcd_data print_dec2 mov lcd_data,dec[3] call write_lcd_data print_dec1 mov lcd_data,dec[4] call write_lcd_data ret ; ; 4ビット液晶ライト ; write_lcd_data mov lcd_raw_data,lcd_data ; 引数を読んで、 swap lcd_raw_data ; まず上位データを call write_lcd_raw ; 出力 mov lcd_raw_data,lcd_data ; 引数を読んで call write_lcd_raw ;; 姑息な最適化 ret ;; 姑息な最適化 ; ; 液晶ライト ; write_lcd_raw setb LED_COM ; LED コモン 消灯 and lcd_raw_data,#00001111b ; 念のため、マスクする mov ra,lcd_raw_data ; RAポートへ出力 nop ; ちょこっとwait setb E ; Eピンを'H' nop ; ちょこっとLOVE clrb E ; Eピンを'L' nop ; ぷっち以下略 mov ra,ra_save ; RA の出力を元に戻す mov calc_cn,#40 ; wait clrb LED_COM ; LED コモン 点灯 call wait_us ret ; ; 16ビットバイナリ→10進変換サブルーチン ; 1997 by M.Ochiai ; in src1 16ビットデータ ; (src1[1]:src1[0]) ; out dec ; (dec[4]:dec[3]:...:dec[0]) ; dec[0]が最下位桁でdec[4]が最上位桁です。 ; ; 変換後src1は破壊されます。(必要なら、コールする前に待避して下さい) ; ; sample: ; src1 = 00:00:04:D2 h ; dec = 00:00:00:00:00:00:01:02:03:04 bin16tobcd mov fsr,#dec_top ; 格納場所初期値 call devideby10 ; 最下位変換 call devideby10 call devideby10 call devideby10 call devideby10 ; 最上位変換 add dec[0],#'0' add dec[1],#'0' add dec[2],#'0' add dec[3],#'0' add dec[4],#'0' ret ; ; ÷10サブルーチン ; 10で除算します ; devideby10 mov calc_cn,#16 ; 16ビットくり返し clr mod devideby10_0 clc rl src1[0] rl src1[1] rl mod movlw 10 subwf mod,0 btfsc c mov mod,w btfsc c inc src1[0] djnz calc_cn,devideby10_0 dec fsr mov indirect,mod ; 余り ret ;********************************************************************* ;--------------------------------------------------------------------- div16: ;16ビットの割り算ルーチン ;秋月 PA (PICアセンブラ) 用 ;参考 http://www.sikasenbey.or.jp/~enaga/pic/pic.html ;-------------------- div16 での使用変数 ;src1 ds 2 ;割られる数 (終了時には0になって戻る) ;src2 ds 2 ;割る数 (変化せず戻る) ;res ds 2 ;答え    (答えが返る) ;mod ds 2 ;余り    (余りが返る、内部ワークにも使用) ;calc_cn ds 1 ;内部ループ用 ;calc_cn2 ds 1 ;内部ループ用 ;diverr ds 1 ;割る数が0であった場合に1をセットして戻る ;-------------------- 使用例 ; mov src1[1],#0ffh ;割られる数上位 (ffffh=65535) ; mov src1[0],#0ffh ;割られる数下位 ; mov src2[1],#027h ;割る数上位 (2710h=10000) ; mov src2[0],#010h ;割る数下位 ; call div16 ;答えは res[2] 、余りは mod[2] に返る ;-------------------- 主ルーチン mov calc_cn,#16 mov mod[0],src2[0] ;割る数下位をワークにコピー mov mod[1],src2[1] ;割る数上位をワークにコピー di1601: rl mod[0] ;左シフトする rl mod[1] jc di1602 ;割る数の上位ビット位置を探す djnz calc_cn,di1601 mov diverr,#1 ;割る数が0である、エラー ret di1602: clr res[0] ;答え下位をクリアしておく clr res[1] ;上位 clr mod[0] ;ワーク下位をクリアしておく clr mod[1] ;上位 mov calc_cn2,#16 sub calc_cn2,calc_cn ;残り、実ループの回数 di1603: clc ;キャリフラグを0に rl src1[0] ;有効位置までシフトする rl src1[1] rl mod[0] ;押し出されたビットをワークに rl mod[1] djnz calc_cn,di1603 ;割られる数を初期位置までシフトしておく di1604: ;現位置での減算が可能かチェック cjb mod[1],src2[1],di1606 cja mod[1],src2[1],di1605 ;上位が= cjb mod[0],src2[0],di1606 di1605: sub mod[0],src2[0] ;ワークから下位を引く sc ;キャリフラグが 1(正)なら次をスキップ dec mod[1] ;上位 -1 sub mod[1],src2[1] ;ワークから上位を引く stc ;キャリフラグを1に goto di1607 di1606: clc ;キャリフラグを0に di1607: rl res[0] ;キャリフラグの内容を答えにシフトしてゆく rl res[1] cje calc_cn2,#0,di1608 ;最下位まで処理したなら終了 dec calc_cn2 ;ビット位置を1つ下げる(右へ) clc ;キャリフラグを0に rl src1[0] ;ワークへ1ビット左シフト rl src1[1] rl mod[0] rl mod[1] goto di1604 di1608: clr diverr ;正常終了 ret ;--------------------------------------------------------------------- ;********************************************************************* ;********************************************************************* ;--------------------------------------------------------------------- div32: ;32÷32ビット=32ビットの割り算ルーチン ;秋月 PA (PICアセンブラ) 用 ;src1[3] ÷ src1[3] = 結果 res[4] 余り mod[4] ;演算後、式の左項(割られる数)は壊れる ;割る数が0(エラー)なら diverr に1を代入して戻る ;エラーの場合、引き数は変化しない ;正常終了の場合は diverr=0 で戻る ;32ビットで扱える数の最大は 4294967295 (42億9496万7295) ;-------------------- div32 での使用変数 ;src1 ds 4 ;割られる数 (終了時には0になって戻る) ;src2 ds 4 ;割る数 (変化せず戻る) ;res ds 4 ;答え    (答えが返る) ;mod ds 4 ;余り    (余りが返る、内部ワークにも使用) ;calc_cn ds 1 ;内部ループ用 ;calc_cn2 ds 1 ;内部ループ用 ;diverr ds 1 ;割る数が0であった場合に1をセットして戻る ;-------------------- 使用例 ; mov src1[3],#0ffh ;割られる数上位 (ffffffffh=4294967295) ; mov src1[2],#0ffh ; 〜 ; mov src1[1],#0ffh ; 〜 ; mov src1[0],#0ffh ;下位 ; mov src2[3],#00h ;割る数上位 (989680h=10000000) ; mov src2[2],#098h ; 〜 ; mov src2[1],#096h ; 〜 ; mov src2[0],#080h ;下位 ; call div32 ;答えは res[3] 、余りは mod[3] に返る ;-------------------- 主ルーチン mov calc_cn,#32 mov mod[1],src2[0] ;割る数をワークにコピー mov mod[1],src2[1] mov mod[2],src2[2] mov mod[3],src2[3] di3201: rl mod[1] ;左シフトする rl mod[1] rl mod[2] rl mod[3] jc di3202 ;割る数の上位ビットが見付かったなら di3202 へ djnz calc_cn,di3201 mov diverr,#01 ;割る数が0である、エラー ret di3202: clr res[0] ;答えのクリア clr res[1] clr res[2] clr res[3] clr mod[1] ;ワークのクリア(ワークには余りが残る) clr mod[1] clr mod[2] clr mod[3] mov calc_cn2,#32 sub calc_cn2,calc_cn ;残り、実ループの回数 di3203: clc ;キャリフラグを0に rl src1[0] ;有効位置までシフトする rl src1[1] rl src1[2] rl src1[3] rl mod[1] ;押し出されたビットをワークに rl mod[1] rl mod[2] rl mod[3] djnz calc_cn,di3203 ;割られる数を初期位置までシフトしておく di3204: movf src2[3],0 ;src2[2] を w にコピー subwf mod[3],0 ;比較 btfsc 3,2 ;結果が=なら di3205 へ goto di3205 btfsc 3,0 ;引くことが可なら di3210 へ goto di3210 btfss 3,0 ;引くことは不可なら di3211 へ goto di3211 di3205: movf src2[2],0 subwf mod[2],0 btfsc 3,2 goto di3206 btfsc 3,0 goto di3210 btfss 3,0 goto di3211 di3206: movf src2[1],0 subwf mod[1],0 btfsc 3,2 goto di3207 btfsc 3,0 goto di3210 btfss 3,0 goto di3211 di3207: movf src2[0],0 subwf mod[1],0 btfsc 3,2 goto di3210 btfss 3,0 goto di3211 di3210: sub mod[1],src2[0] ;ワークから下位を引く movlw 1 ;ワークには余りが残る btfss 3,0 subwf mod[1],1 btfss 3,0 subwf mod[2],1 btfss 3,0 subwf mod[3],1 sub mod[1],src2[1] ;ワークから2位を引く movlw 1 btfss 3,0 subwf mod[2],1 btfss 3,0 subwf mod[3],1 sub mod[2],src2[2] ;ワークから3位を引く btfss 3,0 dec mod[3] ;4上位 -1 sub mod[3],src2[3] ;ワークから上位を引く stc ;キャリフラグを1に goto di3212 di3211: clc ;キャリフラグを0に di3212: rl res[0] ;キャリフラグの内容を答えにシフトしてゆく rl res[1] rl res[2] rl res[3] cje calc_cn2,#0,di3213 ;最下位まで処理したなら終了 dec calc_cn2 ;ビット位置を1つ下げる(右へ) clc ;キャリフラグを0に rl src1[0] ;ワークへ1ビット左シフト rl src1[1] rl src1[2] rl src1[3] rl mod[1] rl mod[1] rl mod[2] rl mod[3] goto di3204 di3213: mov diverr,#00 ;正常終了 ret ;--------------------------------------------------------------------- ;********************************************************************* ; ; msオーダーのウェイト ; wait_ms wait_ms0 mov calc_cn2,#0 wait_ms1 nop nop nop nop nop nop nop djnz calc_cn2,wait_ms1 djnz calc_cn,wait_ms0 ret ; ; μsオーダーのウェイト ; wait_us wait_us0 djnz calc_cn,wait_us0 ret ; end of lcd.asm