PICで浮動小数点ウェイトルーチン2015年05月26日 00:00
ふと思いついたので書いてみた。
呼び出すと、Wレジスタの値を浮動小数点数として見た量だけウェイトを掛ける。
具体的には、指数部3bit、仮数部5bitで、
1.仮数×2^(指数+4)
または指数部が0の時
0.仮数×2^(1+4)
で表される値×80。
最小が1の時の80、最大が255の時の322560…かと思いきやちょうど上手く0の時に327680になっている。
グラフにするとこうだ。

さて、ふと思いついて面白そうだったので書いてみたのだが、使い道が思いつかない。
思いついたきっかけは液晶モジュールの初期化時に27μsと1msと200msのようなウェイト量を要求されたからなのだが、数回使うくらいなら固定値のウェイトルーチンで済むし、10回程度までは単純な2バイトのウェイトルーチンを作った方がよいだろう。
役立てるには数十回のダイナミックレンジの広いウェイトを要求される必要があるが、そのような状況が思いつかない。
まあ書いてて楽しかったので特に問題はない。
何か使い道を思いついた方はご自由に使ってください。
呼び出すと、Wレジスタの値を浮動小数点数として見た量だけウェイトを掛ける。
具体的には、指数部3bit、仮数部5bitで、
1.仮数×2^(指数+4)
または指数部が0の時
0.仮数×2^(1+4)
で表される値×80。
最小が1の時の80、最大が255の時の322560…かと思いきやちょうど上手く0の時に327680になっている。
グラフにするとこうだ。

さて、ふと思いついて面白そうだったので書いてみたのだが、使い道が思いつかない。
思いついたきっかけは液晶モジュールの初期化時に27μsと1msと200msのようなウェイト量を要求されたからなのだが、数回使うくらいなら固定値のウェイトルーチンで済むし、10回程度までは単純な2バイトのウェイトルーチンを作った方がよいだろう。
役立てるには数十回のダイナミックレンジの広いウェイトを要求される必要があるが、そのような状況が思いつかない。
まあ書いてて楽しかったので特に問題はない。
何か使い道を思いついた方はご自由に使ってください。
fwait:
;使用レジスタ:
;cnth, cntl, exp
;cnthは事前にゼロクリアのこと。
;浮動小数点数を分解して適切な場所に置いたりケチ表現解除
movwf cntl
andlw 0xE0
movwf exp
btfss STATUS,Z
bsf cnth,1
btfss cnth,1
bsf exp,5
btfsc cntl,4
bsf cnth,0
swapf cntl,F
movlw 0xF0
andwf cntl,F
bcf STATUS,C
;指数部が1xxなら4bit左シフト
btfss exp,7
goto f1x4
swapf cnth,F
swapf cntl,F
movf cntl,W
andlw 0x0F
iorwf cnth,F
movlw 0xF0
andwf cntl,F
f1:
;指数部がx1xなら2bit左シフト
btfss exp,6
goto f2x1
rlf cntl
rlf cnth
rlf cntl
rlf cnth
f2:
;指数部がxx1でなければ1bit右シフト
btfss exp,5
rrf cnth,F
btfss exp,5
rrf cntl,F
;素通りに掛かる時間分の調整
movlw .8 ;40/5
subwf cntl,F
btfsc STATUS,C
incf cnth,F ;繰り下がり処理しつつ+1
b0:
;時間待ち処理本体
;ここにウェイトを入れ、上の調整部分も合わせると、全体のウェイト量を定数倍できる
decf cntl,F
btfsc STATUS,Z
decfsz cnth,F
goto b0
nop ;時間調整
retlw 0
;分岐の時間合わせ
f2x1:
nop
goto f2
f1x4:
goto $+1
goto $+1
goto f1
;使用レジスタ:
;cnth, cntl, exp
;cnthは事前にゼロクリアのこと。
;浮動小数点数を分解して適切な場所に置いたりケチ表現解除
movwf cntl
andlw 0xE0
movwf exp
btfss STATUS,Z
bsf cnth,1
btfss cnth,1
bsf exp,5
btfsc cntl,4
bsf cnth,0
swapf cntl,F
movlw 0xF0
andwf cntl,F
bcf STATUS,C
;指数部が1xxなら4bit左シフト
btfss exp,7
goto f1x4
swapf cnth,F
swapf cntl,F
movf cntl,W
andlw 0x0F
iorwf cnth,F
movlw 0xF0
andwf cntl,F
f1:
;指数部がx1xなら2bit左シフト
btfss exp,6
goto f2x1
rlf cntl
rlf cnth
rlf cntl
rlf cnth
f2:
;指数部がxx1でなければ1bit右シフト
btfss exp,5
rrf cnth,F
btfss exp,5
rrf cntl,F
;素通りに掛かる時間分の調整
movlw .8 ;40/5
subwf cntl,F
btfsc STATUS,C
incf cnth,F ;繰り下がり処理しつつ+1
b0:
;時間待ち処理本体
;ここにウェイトを入れ、上の調整部分も合わせると、全体のウェイト量を定数倍できる
decf cntl,F
btfsc STATUS,Z
decfsz cnth,F
goto b0
nop ;時間調整
retlw 0
;分岐の時間合わせ
f2x1:
nop
goto f2
f1x4:
goto $+1
goto $+1
goto f1
ファミコンディスクシステム用ソフトの作成
CDのピットの数
6段のカレンダーが好きだ
PIC16のDhrystone MIPSを測ろうとしてみた
Twitterの画像の扱いがやっとまともになって嬉しい
ファミコンで9×9ドット文字表示(ほか)
CDのピットの数
6段のカレンダーが好きだ
PIC16のDhrystone MIPSを測ろうとしてみた
Twitterの画像の扱いがやっとまともになって嬉しい
ファミコンで9×9ドット文字表示(ほか)