みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

PICでルックアップテーブルを使ってみた

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

PICでルックアップテーブルを使ってみた

投稿記事 by みけCAT » 10年前

302.PICの命令とレジスタ一覧
PICのプログラミングは、これだけの命令を組み合わせてプログラムを作るパズルです。
入出力などの機能の呼び出しは、それぞれ決められたレジスタの読み書きで表現します。

さて、A/D変換で得られた0~255の数値から待ち時間(0~255の数値で表す)を決定する処理で、
これらの命令で表現しやすい計算式ではない表現をしたいと思いました。

そこで、複雑な計算をしなくても済むように、ルックアップテーブルで実装しようと考えました。
しかし、PICには256バイトもの巨大なテーブルを格納でき、ランダムアクセスできるようなメモリはありません。
(EEPROMを使えば出来るかもしれませんが、もったいない気がしますし、機種によってはEEPROMが無いものもあります)
ということは、テーブルをコード中に埋め込む必要があります。

さて、どのようなコードを書けばいいでしょうか。
普通に線型探索?でもそれだと重そうです。
そこで二分探索です。
今回は、このような感じの制御を直接コードで表現します。
nibutan_example.png
二分探索の例
nibutan_example.png (1.99 KiB) 閲覧数: 782 回
指定したビットが1かで分岐する命令があるので、このような2の非負整数乗との比較は簡単です。

とはいえ、こんなコードを直接手で書くのは修行でしかないので、プログラムでコードを吐かせます。

CODE:

#!/usr/bin/perl

use strict;

my $min=5;
my $max=75;

my $lut_reg="ADRES";
my $goto_label="LUT_EXIT";

print "; CW speed lookup table\n\n";

for(my $i=0;$i=0) {
		print "    BTFSC LUT_REG,$digit\n";
		print "    GOTO LUT_BINSEARCH_".substr($valuestr."1XXXXXXXX",0,8)."\n";
		print "LUT_BINSEARCH_".substr($valuestr."0XXXXXXXX",0,8)."\n";
		&gen_binsearch($value,$valuestr."0",$digit-1);
		print "LUT_BINSEARCH_".substr($valuestr."1XXXXXXXX",0,8)."\n";
		&gen_binsearch($value|(1<<$digit),$valuestr."1",$digit-1);
	} else {
		print "    MOVLW LUT_VALUE_$value\n";
		print "    GOTO $goto_label\n";
	}
}
前半でルックアップテーブルの値を生成し、後半でテーブルを引くプログラムを生成しています。
再帰を使えば、こんなに簡単に書けるのですね。

そして、こちらが実際に生成したコードです。
► スポイラーを表示
一応、最初のテーブルと参照するレジスタを変えれば、テーブルを引くプログラムは使いまわせるようになっています。
テーブルから取り出した値はワーキングレジスタに格納されます。

1ビットあたり2命令で8ビットあり、最後だけGOTOがあるので、
2*7+3 = 17サイクルでテーブルから値を取得することができます。

このコードなら最悪時の計算時間(サイクル数)が線型探索より大幅に抑えられるし、
どの値でも同じ時間(サイクル数)で値を取り出せる、という利点もあります。

みなさんも、PICのプログラムでルックアップテーブルが必要な場面に遭遇したら、このテクニックを使用してみてはいかがですか?

naohiro19
記事: 256
登録日時: 13年前

Re: PICでルックアップテーブルを使ってみた

投稿記事 by naohiro19 » 10年前

Perlで書いてPICマイコンプログラムを生成している感じですね。

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 13年前

Re: PICでルックアップテーブルを使ってみた

投稿記事 by Hiragi(GKUTH) » 10年前

低レイヤー過ぎて話がわけわかりません。
そういう所から理解したいなぁ、とは思っているのですが。
そもそもDxLibであるとかSDLとか言う高級なモノばかり弄っているからこうなるんですかね。