TODOPIC
Microcontroladores PIC => Primeros pasos - Iniciación a los microcontroladores => Mensaje iniciado por: Damianga en 04 de Octubre de 2010, 08:51:49
-
Hola. Soy nuevo en el foro, y en el tema microcontroladores. Estos dias arme un proyecto que bajé de Internet y cuando cargo el .hex en WinPIC800 me tira un error: "direccion inválida para dispositivo seleccionado", pero aún asi el proyecto armado parece funcionar correctamente. Pero mi problema radica en el .asm. Lo quiero modificar pero no reconozco las instrucciones. Ahi va parte del programa.
;
; ’e‘¬Œvƒ\[ƒX bb_speed.asm 1.4
;
; for PIC16F84@20MHz
;
; –{ƒvƒƒOƒ‰ƒ€‚̓gƒCƒKƒ“‚Å”ŽË‚³‚ê‚éBB’e‚̉‘¬‚¨‚æ‚јAŽË‘¬“x‘ª’èŠí—p‚Å‚·B
; ‚Ü‚½‚Ü‚½‚Ü‚½—á‚Ì‚²‚Æ‚–{ƒ\[ƒX‚ÍHŒŽ‚ÌPA.EXEŠg’£ƒCƒ“ƒXƒgƒ‰ƒNƒVƒ‡ƒ“‚ðŽg—p‚µ‚Ä
; ‚¨‚è‚Ü‚·‚̂ł ‚µ‚©‚炸B 2000.11 (c) RUU
;
; •ÏX—š—ð
; 2002.04 (1.4) ‘ª’踓x‚ÌŒüã(ƒJƒEƒ“ƒgŽüŠú=1.8us‚É•ÏX)
; 2002.02 (1.3) ‘ª’踓x‚ÌŒüã(ƒJƒEƒ“ƒgŽüŠú=3.2us‚É•ÏX)
; 2002.02 (1.2) ˜AŽË‘¬“x‚Ì‘ª’è‹@”\’ljÁA‚»‚Ì‘¼‰ü—ÇB
; 2000.12 (1.1) ƒvƒŠƒXƒP[ƒ‰‚ðŽg—p‚µ‚ăJƒEƒ“ƒgŽüŠú‚ð12.8us‚É‚·‚éB
; ‚±‚ê‚É‚æ‚èTMR0Š„‚螂݂ð‚â‚ß‚Ämain“à‚ÅŒo‰ßŽžŠÔƒJƒEƒ“ƒg‚É•ÏXB
; 2000.11 (1.0) ʼn‚̃o[ƒWƒ‡ƒ“
;
.include 16F84.h
.osc hs
.wdt off
.pwrt on
.protect off
PT1 equ ra.3 ; “üŒû‘¤ƒtƒHƒgƒgƒ‰
PT2 equ ra.4 ; oŒû‘¤
CNT_MIN equ 45 ; Å’áƒJƒEƒ“ƒg’l = 45 (Œv‘ªÅ‘å 987m/s)
CNT_MAX0 equ 64 ; ˜AŽËƒJƒEƒ“ƒgÅ‘å(high byte) = 4000h(Å‘å 5.24•b)
WAIT_CNT equ 162 ; 100us‚ÌwaitƒJƒEƒ“ƒg
BB_MIN equ 10 ; BB’eÅ’ád—Ê(=0.10g)
BB_MAX equ 50 ; BB’eÅ‘åd—Ê(=0.50g)
BB_CNT_MIN equ 2 ; Å’á˜AŽË’e”
BB_CNT_MAX equ 20 ; Å‘å˜AŽË’e”
org 0ch
res ds 1 ; ƒŠƒUƒ‹ƒgƒR[ƒh
SW2 equ res.0 ; •\Ž¦Ø‚è‘Ö‚¦/UP
SW3 equ res.1 ; ’ed—ÊSET/DOWN
SW1 equ res.2 ; RESET/OK
led_opt ds 1 ; LED•\ަƒIƒvƒVƒ‡ƒ“ Šebit=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(10i)Ši”[ƒGƒŠƒA 5bytes
disp_buf ds 1 ; •\ަ—pƒoƒbƒtƒ@
keta_cnt ds 1 ; •\ަŒ…ƒJƒEƒ“ƒ^
count ds 2 ; PT1-PT2’ʉߎžŠÔƒJƒEƒ“ƒ^(16bit)
work ds 1 ; ˆêŽžŽg—pƒ[ƒN
cnt ds 1 ; 32bit‰‰ŽZ‚¨‚æ‚Ñwait—pƒJƒEƒ“ƒ^
xd64 ds 4 ; 64bit‰‰ŽZ—p(xd64+xd32=64bit)
xd32 ds 4 ; 32bit‰‰ŽZ—p
xs32 ds 4 ; V
y32 ds 4 ; V
bb_weight ds 1 ; BB’ed—Ê(*100g)
bb_cnt_num ds 1 ; ˜AŽË‘ª’è’e”
bb_cnt ds 1 ; ˜AŽË’e”ƒJƒEƒ“ƒ^
wsave ds 1 ; WƒŒƒWƒXƒ^‘Þ”ð
stsave ds 1 ; STATUS‘Þ”ð
eeorg 0
eedata 25,10 ; EEPROM‰Šú’l(BB’ed—Ê=0.25g, ˜AŽË‘ª’è’e”=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 ; ˜AŽË‘¬“x‘ª’è‚̃JƒEƒ“ƒgƒAƒbƒv—pŠ„‚螂݈—
mov wsave,w ; WƒŒƒWƒXƒ^‘Þ”ð
mov stsave,status ; STATUS‘Þ”ð
sub tmr0,#100 - 2 ; tmr0ÄÝ’è(3.2us*100=0.32msŠÔŠu‚ÅŠ„‚èž‚Ý)
clrb t0if
incsz count[1] ; ƒJƒEƒ“ƒgƒAƒbƒv
goto int_end
inc count[0] ; High byte‚ÖŒ…オ‚è
int_end
mov status,stsave ; STATUS–ß‚·
mov w,wsave ; W–ß‚·
retfie ; •œ‹A
;;;;;;;;;;;; main ;;;;;;;;;;;;
main
;; ‰Šú‰»
init
;; I/Oƒ|[ƒgÝ’è
mov !ra,#00011000b ; PT1,PT2‚ðIN‚ÉASEG1`3select‚ðOUT‚É
mov !rb,#00000111b ; RB0`2(SW)‚ð“ü—ÍARB3,RB4`7(BCDo—Í)‚ðo—Í‚É
clr ra
clr rb
;; OPTIONƒŒƒWƒXƒ^Ý’è
setb rp0
mov option,#00000011b ; ƒ|[ƒgBƒvƒ‹ƒAƒbƒvAƒvƒŠƒXƒP[ƒ‰(1:16)
clrb rp0
;; Š„‚èž‚ÝÝ’è
mov intcon,#00100000b ; ƒ^ƒCƒ}0Š„‚螂݋–‰ÂAƒOƒ[ƒoƒ‹Š„‚螂݋֎~
;; EEPROMƒf[ƒ^(BB’eŽ¿—Ê,˜AŽË‘ª’è’e”)ƒ[ƒh
clr eeadr
call eeprom_read
mov bb_weight,eedata
inc eeadr
call eeprom_read
mov bb_cnt_num,eedata
call get_key ; SW1‚ð‰Ÿ‚µ‚È‚ª‚ç“dŒ¹ON‚È‚ç˜AŽË‘ª’胂[ƒh‚Ö
jb SW1,mode_single
;; -------- ˜AŽË‘¬“x‘ª’胂[ƒh --------
Algien me puede decir como transformar al .asm de Microchip. o cuales son las equivalencias de las instrucciones y/o como compilarlo?
Desde ya muchas gracias.
-
.
Eso no es asm para PIC :? .. y no creo que sea posible pasarlo directamente, porque cada marca de uC tiene un juego de instrucciones específicas (a veces también difieren dentro de una misma marca entre distintas familias) y encima los PICs tienen un conjunto de instrucciones reducido (con lo que probablemente no haya un equivalente para cada instrucción).
La solución más sencilla (a mi parecer) es crear un código totalmente nuevo, usando instrucciones de asm para PIC, pero siguiendo el programa que ya tenés. ¿Sabés cuál es el uC que usa ese programa?
Y una duda inevitable.. ¿Qué significa eso de disparar balas? :mrgreen:
¡Saludos!
-
El proyecto esta basado en un pic 16f84a. (por eso mi duda). Es un cronografo para medir la velocidad de balas de airsoft. Esta tomado de este lugar http://www.mars.dti.ne.jp/~ogura/e_hobby/bbspeed.html.
Parecieran ser las mismas instrucciones, pero 'escritas de otra forma'. Quiza no las entienda porque están en japonés ;-)
-
Puede que sean macros. Mejor hacerlo desde cero :D
-
Ahora edite el primer mensaje, agregando un fragmento mas largo del programa y en su version original. Espero que se entienda mejor.
-
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
-
El código es definitivamente para un PIC, pero no se compila con MPLAB. Acá un foro en donde dicen que probablemente esté compilado con Parallax.
http://www.microchip.com/forums/tm.aspx?high=&m=114791&mpage=1#114797
Acá una descarga del compilador ASM Parallax SPASM.
http://www.sxlist.com/techref/scenix/languages.htm
-
Gracias por las respuestas! Con esto creo estar ya encaminado.
Saludos