Talvez te sirva de algo el programa bien copiado en japonés y su traducción a inglés.
; 弾速計ソース bb_speed.asm 1.4
;
; for PIC16F84@20MHz
;
; 本プログラムはトイガンで発射されるBB弾の初速および連射速度測定器用です。
; またまたまた例のごとく本ソースは秋月のPA.EXE拡張インストラクションを使用して
; おりますのであしからず。 2000.11 (c) RUU
;
; 変更履歴
; 2002.04 (1.4) 測定精度の向上(カウント周期=1.8usに変更)
; 2002.02 (1.3) 測定精度の向上(カウント周期=3.2usに変更)
; 2002.02 (1.2) 連射速度の測定機能追加、その他改良。
; 2000.12 (1.1) プリスケーラを使用してカウント周期を12.8usにする。
; これによりTMR0割り込みをやめてmain内で経過時間カウントに変更。
; 2000.11 (1.0) 最初のバージョン
;
.include 16F84.h
.osc hs
.wdt off
.pwrt on
.protect off
PT1 equ ra.3 ; 入口側フォトトラ
PT2 equ ra.4 ; 出口側
CNT_MIN equ 45 ; 最低カウント値 = 45 (計測最大 987m/s)
CNT_MAX0 equ 64 ; 連射カウント最大(high byte) = 4000h(最大 5.24秒)
WAIT_CNT equ 162 ; 100usのwaitカウント
BB_MIN equ 10 ; BB弾最低重量(=0.10g)
BB_MAX equ 50 ; BB弾最大重量(=0.50g)
BB_CNT_MIN equ 2 ; 最低連射弾数
BB_CNT_MAX equ 20 ; 最大連射弾数
org 0ch
res ds 1 ; リザルトコード
SW2 equ res.0 ; 表示切り替え/UP
SW3 equ res.1 ; 弾重量SET/DOWN
SW1 equ res.2 ; RESET/OK
led_opt ds 1 ; LED表示オプション 各bit=1で点灯
MSLED equ led_opt.0 ; m/s表示
JLED equ led_opt.1 ; J表示
P1 equ led_opt.2 ; 小数点1桁目
P2 equ led_opt.3 ; 小数点2桁目
bcdbuf ds 5 ; BCD(10進)格納エリア 5bytes
disp_buf ds 1 ; 表示用バッファ
keta_cnt ds 1 ; 表示桁カウンタ
count ds 2 ; PT1-PT2通過時間カウンタ(16bit)
work ds 1 ; 一時使用ワーク
cnt ds 1 ; 32bit演算およびwait用カウンタ
xd64 ds 4 ; 64bit演算用(xd64+xd32=64bit)
xd32 ds 4 ; 32bit演算用
xs32 ds 4 ; 〃
y32 ds 4 ; 〃
bb_weight ds 1 ; BB弾重量(*100g)
bb_cnt_num ds 1 ; 連射測定弾数
bb_cnt ds 1 ; 連射弾数カウンタ
wsave ds 1 ; Wレジスタ退避
stsave ds 1 ; STATUS退避
eeorg 0
eedata 25,10 ; EEPROM初期値(BB弾重量=0.25g, 連射測定弾数=10)
eedata 'BB_Speed 1.4 by RUU -- http://www.mars.dti.ne.jp/~ogura/'
org 0
goto main
org 4
goto intproc
;;;;;;;;;;;; 割り込み処理 intproc ;;;;;;;;;;;;
intproc ; 連射速度測定のカウントアップ用割り込み処理
mov wsave,w ; Wレジスタ退避
mov stsave,status ; STATUS退避
sub tmr0,#100 - 2 ; tmr0再設定(3.2us*100=0.32ms間隔で割り込み)
clrb t0if
incsz count[1] ; カウントアップ
goto int_end
inc count[0] ; High byteへ桁上がり
int_end
mov status,stsave ; STATUS戻す
mov w,wsave ; W戻す
retfie ; 復帰
;;;;;;;;;;;; main ;;;;;;;;;;;;
main
;; 初期化
init
;; I/Oポート設定
mov !ra,#00011000b ; PT1,PT2をINに、SEG1~3selectをOUTに
mov !rb,#00000111b ; RB0~2(SW)を入力、RB3,RB4~7(BCD出力)を出力に
clr ra
clr rb
;; OPTIONレジスタ設定
setb rp0
mov option,#00000011b ; ポートBプルアップ、プリスケーラ(1:16)
clrb rp0
;; 割り込み設定
mov intcon,#00100000b ; タイマ0割り込み許可、グローバル割り込み禁止
;; EEPROMデータ(BB弾質量,連射測定弾数)ロード
clr eeadr
call eeprom_read
mov bb_weight,eedata
inc eeadr
call eeprom_read
mov bb_cnt_num,eedata
call get_key ; SW1を押しながら電源ONなら連射測定モードへ
jb SW1,mode_single
;; -------- 連射速度測定モード --------
mode_series
clr count[0] ; カウンタクリア
clr count[1]
mov bb_cnt,#1
clr res ; リザルトコードクリア
loop_0
jnb PT1,keychk_0 ; 弾発射?
mov tmr0,#155 ; TMR0初期設定(100カウント=0.32ms)
setb gie ; グローバル割り込み許可
goto strt_count_0 ; 通過時間のカウント開始
keychk_0
call get_key ; SW3が押されたら連射数設定を行う
jb SW3,loop_0
clrb gie
wait_off_0
call get_key
jnb SW3,wait_off_0 ; SW3が離されるまで待つ
call set_bb_count
goto mode_series
strt_count_0 ; 連射数のカウント
jb PT2,next_loop ; 弾の通過待ち
cja count[0],#CNT_MAX0,err_0 ; 経過時間チェック
goto strt_count_0
next_loop
jnb PT1,chk_count_0 ; 次の弾待ち
inc bb_cnt
cje bb_cnt,bb_cnt_num,end_count_0 ; 測定連射数に達したらカウント終了
goto strt_count_0
chk_count_0
cja count[0],#CNT_MAX0,err_0 ; 経過時間チェック
goto next_loop
end_count_0
;; 連射速度(発/sec)表示
clrb gie
clr xd32[0]
mov xd32[1],#04h ; xd32=312500
mov xd32[2],#0c4h
mov xd32[3],#0b4h
clr y32[0] ; y32=連射数
clr y32[1]
clr y32[2]
mov y32[3],bb_cnt_num
call mul64 ; xd32=312500*連射数
clr y32[0] ; y32=count
clr y32[1]
mov y32[2],count[0]
mov y32[3],count[1]
call div32 ; 発/sec(*100)=312500*連射数/count
call conv_bcd
mov fsr,#bcdbuf
mov led_opt,#1 ; 単位=発/sec
call disp_num
jnb SW3,wait_off_0 ; SW3が押されたら連射数設定を行う
goto mode_series
err_0
clrb gie
call disp_err
goto mode_series
;; -------- 単発・弾速測定モード --------
mode_single
clr count[0] ; カウンタクリア
clr count[1]
clr res ; リザルトコードクリア
loop
jb PT1,strt_count ; 弾発射?
keychk
call get_key ; SW3が押されたらBB弾重量設定を行う
jb SW3,loop
wait_off
call get_key
jnb SW3,wait_off ; SW3が離されるまで待つ
call set_weight
goto loop
strt_count ; 通過時間のカウント
jb PT2,end_count ; 2
inc count[1] ; 1
snz ; 1(2)
inc count[0] ; 1
snz ; 1(2)
goto err ; (1) カウンタオーバーフロー
goto strt_count ; 2 計9cycle=1.8us
end_count
cjne count[0],#0,disp_ms ; カウント値の範囲チェック
cjb count[1],#CNT_MIN,err
;; 速度(m/s)表示
disp_ms
clr xd32[0] ; xd32=4444444
mov xd32[1],#043h
mov xd32[2],#0d1h
mov xd32[3],#01ch
clr y32[0] ; y32=count
clr y32[1]
mov y32[2],count[0]
mov y32[3],count[1]
call div32 ; m/s(*100)=4444444/count
call conv_bcd
mov fsr,#bcdbuf
mov led_opt,#1 ; 単位=m/s
call disp_num
jnb SW1,mode_single
jnb SW2,disp_j
call set_weight
goto disp_ms
;; パワー(J)表示
disp_j
clr xd32[0] ; xd32=count
clr xd32[1]
mov xd32[2],count[0]
mov xd32[3],count[1]
clr y32[0] ; y32=count
clr y32[1]
mov y32[2],count[0]
mov y32[3],count[1]
call mul64 ; xd32=count^2
mov xs32[0],xd32[0] ; xd32を待避
mov xs32[1],xd32[1]
mov xs32[2],xd32[2]
mov xs32[3],xd32[3]
clr xd32[0] ; xd32=987654
mov xd32[1],#00fh
mov xd32[2],#012h
mov xd32[3],#006h
clr y32[0] ; y32=bb_weight
clr y32[1]
clr y32[2]
mov y32[3],bb_weight
call mul64 ; xd32=987654*bb_weight
mov y32[0],xs32[0] ; y32=count^2
mov y32[1],xs32[1]
mov y32[2],xs32[2]
mov y32[3],xs32[3]
call div32 ; J(*100)=(987654*bb_weight)/(count^2)
call conv_bcd
mov fsr,#bcdbuf
mov led_opt,#2 ; 単位=J
call disp_num
jnb SW1,mode_single
jnb SW2,disp_ms
call set_weight
goto disp_j
err
call disp_err
goto mode_single
;;;;;;;;;;;; disp_err ;;;;;;;;;;;;;;
disp_err ; エラー('0.00' を表示、単位消灯)
clr xd32[0]
clr xd32[1]
clr xd32[2]
clr xd32[3]
call conv_bcd
mov fsr,#bcdbuf
clr led_opt
call disp_num
ret
;;;;;;;;;;;; set_weight ;;;;;;;;;;;;;;
set_weight ; BB弾の重量設定を行う
clr xd32[0]
clr xd32[1]
clr xd32[2]
mov xd32[3],bb_weight
call conv_bcd
mov fsr,#bcdbuf
mov led_opt,#3 ; 単位=g
call disp_num
jnb SW1,write_weight
jnb SW2,up_cnt
down_cnt
cje bb_weight,#BB_MIN,set_weight
dec bb_weight
goto set_weight
up_cnt
cje bb_weight,#BB_MAX,set_weight
inc bb_weight
goto set_weight
write_weight ; EEPROMに書き込む
clr eeadr
mov eedata,bb_weight
call eeprom_write
ret
;;;;;;;;;;;; set_bb_count ;;;;;;;;;;;;;;
set_bb_count ; 連射測定時の弾数設定を行う
clr xd32[0]
clr xd32[1]
clr xd32[2]
mov xd32[3],bb_cnt_num
clr y32[0]
clr y32[1]
clr y32[2]
mov y32[3],#100
call mul64
call conv_bcd
mov fsr,#bcdbuf
mov led_opt,#3 ; 単位=発
call disp_num
jnb SW1,write_count
jnb SW2,up_cnt0
down_cnt0
cje bb_cnt_num,#BB_CNT_MIN,set_bb_count
dec bb_cnt_num
goto set_bb_count
up_cnt0
cje bb_cnt_num,#BB_CNT_MAX,set_bb_count
inc bb_cnt_num
goto set_bb_count
write_count ; EEPROMに書き込む
mov eeadr,#1
mov eedata,bb_cnt_num
call eeprom_write
ret
;;;;;;;;;;;; conv_bcd ;;;;;;;;;;;;;;
conv_bcd ; xd32をBCD変換してbcdbuf(5桁)に格納する
mov fsr,#bcdbuf+4 ; 注:xd32,xs32,y32いずれも変更される
clr y32[0]
clr y32[1]
clr y32[2]
mov y32[3],#10 ; y32 = 10
conv_loop
call div32 ; xd32÷10の余りをbcdbufの5桁目から逆順に格納
mov indirect,xs32[3]
cje fsr,#bcdbuf,conv_end ; 5桁分変換
dec fsr
goto conv_loop
conv_end
ret
;;;;;;;;;;;; get_key ;;;;;;;;;;;;;;
get_key
mov res,rb
and res,#00000111b
ret
get_key2
mov !rb,#00000111b ; RB0~2(SW1~3)を入力に切り替え
mov cnt,#10 ; SW入力ポート安定のためのWait
call wait100
mov res,rb
and res,#00000111b
mov !rb,#00000000b ; RB0~2(LED)を出力にする
ret
;;;;;;;;;;;; disp_num ;;;;;;;;;;;;;;
disp_num ; fsrから5桁分のBCD(3桁+小数点以下2桁)を有効3桁で表示する
mov !rb,#00000000b ; RB0~2(LED)を出力にする
and led_opt,#00000011b
cjne indirect,#0,disp_3_0 ; 小数点位置決定
inc fsr
cje indirect,#0,disp_1_2
disp_2_1
setb P2
goto disp_3_0
disp_1_2
setb P1
inc fsr
disp_3_0
clc
mov keta_cnt,#1
disp_loop ; 3桁分表示
mov disp_buf,indirect
swap disp_buf
or disp_buf,led_opt
clr ra
mov rb,disp_buf
mov ra,keta_cnt
mov cnt,#50
call wait100
jb keta_cnt.2,key_chk
inc fsr
rl keta_cnt
goto disp_loop
key_chk ; SW押下でリターンする
clr ra
call get_key2
cjne res,#07h,disp_end
sub fsr,#2
goto disp_3_0
disp_end
mov !rb,#00000111b ; RB0~2(SW1~3)を入力に切り替え
mov work,res
wait_key_off
call get_key
cjne res,#07h,wait_key_off
mov res,work ; 結果はresに入っている
clr ra
clr rb
ret
;;;;;;;;;;;; div32 ;;;;;;;;;;;;;;
div32 ; xd32 ÷ y32 の商を xd32に、余りをxs32に格納する
clr xs32[0]
clr xs32[1]
clr xs32[2]
clr xs32[3]
mov cnt,#32
div32_loop
clc ; キャリーをクリア
rl xd32[3] ; xd32<<1 bitシフト
rl xd32[2]
rl xd32[1]
rl xd32[0]
rl xs32[3] ; 桁あふれはxs32に納める
rl xs32[2]
rl xs32[1]
rl xs32[0]
mov W,y32[0] ; xs32 >= yd32か?
subwf xs32[0],0
jnc div32_nxt
jnz div32_sub
mov W,y32[1]
subwf xs32[1],0
jnc div32_nxt
jnz div32_sub
mov W,y32[2]
subwf xs32[2],0
jnc div32_nxt
jnz div32_sub
mov W,y32[3]
subwf xs32[3],0
jnc div32_nxt
div32_sub ; then xs32 = xs32 - y32
call sub32
setb xd32[3].0 ; xd32[3].0のビットを立てる
div32_nxt ; else
djnz cnt,div32_loop ; 32bit分ループ
ret
;;;;;;;;;;;; sub32 ;;;;;;;;;;;;;;
sub32 ; xs32 から y32 を減算し、結果をxs32に格納する
sub xs32[3],y32[3] ; xs-y [3] 最終桁の計算
jc sub32_2 ; 結果が正なら[2]桁計算へ
sub xs32[2],#1 ; 負なら前の桁から1引く(残念ながらdecfは使えない)
jc sub32_2
sub xs32[1],#1
jc sub32_2
dec xs32[0]
sub32_2
sub xs32[2],y32[2] ; [2]桁の計算
jc sub32_1
sub xs32[1],#1
jc sub32_1
dec xs32[0]
sub32_1
sub xs32[1],y32[1] ; [1]桁の計算
jc sub32_0
dec xs32[0]
sub32_0
sub xs32[0],y32[0] ; [0]桁の計算
ret
;;;;;;;;;;;; mul64 ;;;;;;;;;;;;;;
mul64 ; xd32[0,1,2,3](32bit)とy32[0,1,2,3](32bit)の積をxd64[0,1,2,3,4,5,6,7](64bit)に格納する
clr xd64[0]
clr xd64[1]
clr xd64[2]
clr xd64[3]
mov cnt,#32
mul64_loop
clc
jnb xd32[3].0,mul64_nxt
add xd64[3],y32[3]
jnc mul64_2
inc xd64[2]
jnz mul64_2
inc xd64[1]
snz
inc xd64[0]
mul64_2 add xd64[2],y32[2]
jnc mul64_1
inc xd64[1]
snz
inc xd64[0]
mul64_1 add xd64[1],y32[1]
snc
inc xd64[0]
add xd64[0],y32[0]
mul64_nxt
rr xd64[0]
rr xd64[1]
rr xd64[2]
rr xd64[3]
rr xd32[0]
rr xd32[1]
rr xd32[2]
rr xd32[3]
djnz cnt,mul64_loop ; 32bit分ループ
ret
;;;;;;;;;;;; wait100;;;;;;;;;;;;
wait100 ; 100μs * cnt 時間を消費
loop_n
mov work,#WAIT_CNT
loop100
decsz work
goto loop100
decsz cnt
goto loop_n
ret
;;;;;;;;;;;; eeprom_read;;;;;;;;;;;;
eeprom_read
setb rp0
setb eecon1.0
clrb rp0
ret
;;;;;;;;;;;; eeprom_write;;;;;;;;;;;;
eeprom_write
setb rp0
setb eecon1.2
mov eecon2,#55h
mov eecon2,#0aah
setb eecon1.1
writeloop
snb eecon1.1
goto writeloop
clrb rp0
ret
;;;;;;;;;;;;;;;;;;; おしまい ;;;;;;;;;;;;;;;;;;;;;;
Inglés
; Source chronoscope bb_speed.asm 1.4
;
; For PIC16F84 @ 20MHz
;
; The program is being launched in Toigan Instrument BB bullet muzzle velocity and rate of fire.
; Again as usual this is also the source of instruction used to extend PA.EXE Akizuki
; So we Sorry. 2000.11 (c) RUU
;
; Change History
; 2002.04 (1.4) Improvement of measurement accuracy (count = 1.8us cycle changes)
; 2002.02 (1.3) Improvement of measurement accuracy (count = 3.2us cycle changes)
; 2002.02 (1.2) Measurement of enhancement rate of fire, and other improvements.
; 2000.12 (1.1) using the counting period to 12.8us prescaler.
; This TMR0 interrupt to stop the elapsed time count in the main change.
; 2000.11 (1.0), first version
;
. Include 16F84.h
. Osc hs
. Wdt off
. Pwrt on
. Protect off
PT1 equ ra.3; the inlet tiger photo
PT2 equ ra.4; outlet
CNT_MIN equ 45; minimum count of 45 (measured up to 987m / s)
CNT_MAX0 equ 64; largest blaze count (high byte) = 4000h (up to 5.24 seconds)
WAIT_CNT equ 162; 100us wait for the count
BB_MIN equ 10; BB bullets minimum weight (= 0.10g)
BB_MAX equ 50; BB bullets up to the weight (= 0.50g)
BB_CNT_MIN equ 2; minimum number of bullets blazing
BB_CNT_MAX equ 20; the maximum number of bullets blazing
org 0ch
res ds 1; result code
SW2 equ res.0; Toggle / UP
SW3 equ res.1; weight bullet SET / DOWN
SW1 equ res.2; RESET / OK
led_opt ds 1; LED lights on each display option bit = 1
MSLED equ led_opt.0; m / s show
JLED equ led_opt.1; J Show
P1 equ led_opt.2; the first digit decimal
P2 equ led_opt.3; 2 digit decimal point
bcdbuf ds 5; BCD (decimal), storage area 5bytes
disp_buf ds 1; buffer for display
keta_cnt ds 1; digit counter display
count ds 2; PT1-PT2 transit time counter (16bit)
work ds 1; work Temporary Use
cnt ds 1; 32bit counter and wait for operator
xd64 ds 4; 64bit arithmetic (xd64 xd32 = 64bit)
xd32 ds 4; 32bit arithmetic
xs32 ds 4; 〃
y32 ds 4; 〃
bb_weight ds 1; BB bullet weight (* 100g)
bb_cnt_num ds 1; number of bullets blazing measurement
bb_cnt ds 1; rapid-fire ammo counter
wsave ds 1; W registers are saved
stsave ds 1; STATUS evacuation
eeorg 0
eedata 25,10; EEPROM default (BB bullet weight = 0.25g, measuring the number of bullets blazing-10)
eedata 'BB_Speed 1.4 by RUU - http://www.mars.dti.ne.jp/ ~ ogura /'
org 0
goto main
org 4
goto intproc
Interrupt ;;;;;;;;;;;; intproc ;;;;;;;;;;;;
intproc; interrupt count for the measurement of rate of fire
mov wsave, w; W registers are saved
mov stsave, status; STATUS evacuation
sub tmr0, # 100 - 2; tmr0 reset (3.2us * 100 = 0.32ms interval interrupt)
clrb t0if
incsz count [1]; Count
goto int_end
inc count [0]; High byte to carry
int_end
mov status, stsave; STATUS back
mov w, wsave; W back
retfie; return
;;;;;;;;;;;; Main ;;;;;;;;;;;;
main
;; Initialization
init
;; I / O port setting
mov! ra, # 00011000b; PT1, PT2 to the IN, SEG1 ~ 3select to the OUT
mov! rb, # 00000111b; RB0 ~ 2 (SW) input, RB3, RB4 ~ 7 (BCD output) output
clr ra
clr rb
;; OPTION register set
setb rp0
mov option, # 00000011b; Port B pull-up, the prescaler (1:16)
clrb rp0
;; Interrupt settings
mov intcon, # 00100000b; Timer0 interrupt, the global interrupt disabled
;; EEPROM data (BB bullet mass, measuring the number of bullets blazing) Road
clr eeadr
call eeprom_read
mov bb_weight, eedata
inc eeadr
call eeprom_read
mov bb_cnt_num, eedata
call get_key; SW1 to ON power while pressing the automatic fire mode, if the measurement
jb SW1, mode_single
;; -------- -------- Blazing speed measurement mode.
mode_series
clr count [0]; counter clear
clr count [1]
mov bb_cnt, # 1
clr res; Rizarutokodokuria
loop_0
jnb PT1, keychk_0; firing bullets?
mov tmr0, # 155; TMR0 default (count 100 = 0.32ms)
setb gie; global interrupt
goto strt_count_0; start counting transit time
keychk_0
call get_key; SW3 to set the number of fire when pressed
jb SW3, loop_0
clrb gie
wait_off_0
call get_key
jnb SW3, wait_off_0; SW3 wait is released
call set_bb_count
goto mode_series
strt_count_0; count of the number of fire
jb PT2, next_loop; awaiting passage of the bullet
cja count [0], # CNT_MAX0, err_0; check the elapsed time
goto strt_count_0
next_loop
jnb PT1, chk_count_0; waiting for the next bullet
inc bb_cnt
cje bb_cnt, bb_cnt_num, end_count_0; count reaches the end of the measurement of fire
goto strt_count_0
chk_count_0
cja count [0], # CNT_MAX0, err_0; check the elapsed time
goto next_loop
end_count_0
;; Rate of fire (from / sec) display
clrb gie
clr xd32 [0]
mov xd32 [1], # 04h; xd32 = 312500
mov xd32 [2], # 0c4h
mov xd32 [3], # 0b4h
clr y32 [0]; y32 = number of fire
clr y32 [1]
clr y32 [2]
mov y32 [3], bb_cnt_num
call mul64; xd32 = 312500 * The number of fire
clr y32 [0]; y32 = count
clr y32 [1]
mov y32 [2], count [0]
mov y32 [3], count [1]
call div32; development / sec (* 100) = 312500 * Number of fire / count
call conv_bcd
mov fsr, # bcdbuf
mov led_opt, # 1; unit = From / sec
call disp_num
jnb SW3, wait_off_0; SW3 to set the number of fire when pressed
goto mode_series
err_0
clrb gie
call disp_err
goto mode_series
;; -------- -------- Shot muzzle velocity measuring mode
mode_single
clr count [0]; counter clear
clr count [1]
clr res; Rizarutokodokuria
loop
jb PT1, strt_count; firing bullets?
keychk
call get_key; SW3 weight when pressed to set the BB bullet
jb SW3, loop
wait_off
call get_key
jnb SW3, wait_off; SW3 wait is released
call set_weight
goto loop
strt_count; count of passing time
jb PT2, end_count; 2
inc count [1]; 1
snz; 1 (2)
inc count [0]; 1
snz; 1 (2)
goto err; (1) counter
goto strt_count; total of 2 9cycle = 1.8us
end_count
cjne count [0], # 0, disp_ms; count range check
cjb count [1], # CNT_MIN, err
;; Velocity (m / s) display
disp_ms
clr xd32 [0]; xd32 = 4444444
mov xd32 [1], # 043h
mov xd32 [2], # 0d1h
mov xd32 [3], # 01ch
clr y32 [0]; y32 = count
clr y32 [1]
mov y32 [2], count [0]
mov y32 [3], count [1]
call div32; m / s (* 100) = 4444444/count
call conv_bcd
mov fsr, # bcdbuf
mov led_opt, # 1; unit = m / s
call disp_num
jnb SW1, mode_single
jnb SW2, disp_j
call set_weight
goto disp_ms
;; Power (J) show
disp_j
clr xd32 [0]; xd32 = count
clr xd32 [1]
mov xd32 [2], count [0]
mov xd32 [3], count [1]
clr y32 [0]; y32 = count
clr y32 [1]
mov y32 [2], count [0]
mov y32 [3], count [1]
call mul64; xd32 = count ^ 2
mov xs32 [0], xd32 [0]; xd32 a shelter
mov xs32 [1], xd32 [1]
mov xs32 [2], xd32 [2]
mov xs32 [3], xd32 [3]
clr xd32 [0]; xd32 = 987654
mov xd32 [1], # 00fh
mov xd32 [2], # 012h
mov xd32 [3], # 006h
clr y32 [0]; y32 = bb_weight
clr y32 [1]
clr y32 [2]
mov y32 [3], bb_weight
call mul64; xd32 = 987654 * bb_weight
mov y32 [0], xs32 [0]; y32 = count ^ 2
mov y32 [1], xs32 [1]
mov y32 [2], xs32 [2]
mov y32 [3], xs32 [3]
call div32; J (* 100) = (987654 * bb_weight) / (count ^ 2)
call conv_bcd
mov fsr, # bcdbuf
mov led_opt, # 2; units = J
call disp_num
jnb SW1, mode_single
jnb SW2, disp_ms
call set_weight
goto disp_j
err
call disp_err
goto mode_single