忍者ブログ

Fグループ電子工作講座

秋月電子SH7125ボードで始めるマイコン開発

RX220で三角関数を使う

三角関数を使うための基礎知識が揃ったので、実際に三角関数を使ってみます。
関連:三角関数 基本編ラジアンって何?浮動小数点型とは

処理を高速化するために三角関数を自作することもありますが、とりあえず標準
で用意されている三角関数を使うことを考えます。

授業で習うプログラムの場合
#include <math.h>

#include <mathf.h>
とさえ書けば三角関数が利用可能になるのですが、ルネサスマイコンの場合は
プロジェクトの設定を変更しないと三角関数が使えません。

試しにプロジェクトの設定変更せずに三角関数を使おうとすると・・・

HEWだと
L2310 (E) Undefined external symbol "_sin" referenced in "プロジェクトの場所"

CS+だと
(E)    E0562310    E0562310:Undefined external symbol "_sinf" referenced in "プロジェクトの場所"

とエラーが出てビルドできません。
ちなみにincludeするだけなら設定変更しなくてもビルドが通ります

ビルドを通すには


方法①プロジェクト作成時にmath.hを使えるようにする(HEWのみ?)




方法②プロジェクトのオプションを変更する(HEWの場合)
ビルド> RX Standard Toolchain

SH7125の場合は「SuperH RISC engine Standerd Toolchain」

プロジェクトの標準ライブラリのタブ>標準ライブラリ



方法②プロジェクトのオプションを変更する(CS+の場合)
ビルド・ツールを右クリックしてプロパティー


ライブラリ・ジェネレート・オプションのタブ

で設定を変更します。

math.hとmathf.hの違い

math.hとmathf.hの違いは計算精度計算時間です。
 math.h:double型で計算(精度が高く計算時間が長い
 mathf.h:float型で計算(精度が低く計算時間が短い
となるはずですが、浮動小数点型で説明した通りオプション設定を変更しないと
double型でもfloat型の精度で計算してしまいます。

実際に計算時間を比較してみました。
sinとsinfでそれぞれ100万回計算するのに要する時間を測って計算1回あたりの処理時間を計算してみます。
※2019/5/23補足 32MHz動作の場合

標準設定で100万回計算させた場合
 sin:8221ms 計算1回⇒約8.2μs
 sinf:8220ms 計算1回⇒約8.2μs
差がありません。

double型を8Byteに設定して100万回計算させた場合
 sin:99191ms 計算1回⇒約100μs
 sinf:8221ms 計算1回⇒約8.2μs
計算時間に10倍以上の差が出ました。

どちらを使うかは使用目的によって異なりますが、とりあえず使ってみる分には
mathf.h(float型)で良いと思います。
精度が欲しい場合はdouble型を8Byteに設定したうえでmath.hを使う必要があります。

ちなみにビルド後の*.motファイルの容量はmath.hをincludeしただけでは変化せず、
使った関数の種類に応じて変化する様です。

4Byte設定
math.h sinのみ使用⇒2KB増
math.h cosのみ使用⇒2KB増
math.h sinとcos使用⇒2KB増

mathf.h sinfのみ使用⇒2KB増
mathf.h cosfのみ使用⇒2KB増
mathf.h sinfとcosf使用⇒2KB増

sin,cos,sinf,cosf4種使用⇒2KB増
⇒ 4Byte設定だとmath.hはmathf.h扱いになっている。

8Byte設定
math.h sinのみ使用⇒6KB増
math.h cosのみ使用⇒6KB増
math.h sinとcos使用⇒7KB増

mathf.h sinfのみ使用⇒2KB増
mathf.h cosfのみ使用⇒3KB増
mathf.h sinfとcosf使用⇒3KB増

sin,cos,sinf,cosf4種使用⇒9KB増
⇒ 8Byte設定だとmath.hはmathf.h別扱いになる。

mathf.hを使ってみる

マイコン内の計算結果を確認するために
クロック設定:hwsetup_rx220.chwsetup_rx220.h
AD変換設定:ADconv_rx220.cADconv_rx220.h
タイマ設定:intCMT_rx220.cintCMT_rx220.h
シリアル通信設定:intSCI_rx220.cintSCI_rx220.h
を使うものとします。
当ブログで公開してあるRX220用サンプルプログラムの使い方はこちら

<設定>
#include "hwsetup_rx220.h"
#include "ADconv_rx220.h"
#include "intCMT_rx220.h"
#include "intSCI_rx220.h"
#include <stdio.h>    //sprintf用
#include <mathf.h>    //三角関数

#define PI 3.1415923    //円周率8桁まで

void main(void)
{
    char trans_buf[255];    //送信バッファ
    float in,out;            //入出力変数

    //各機能の初期化
    HardwareSetup();    //クロックの設定
    init_ADC();            //AD変換の初期化(今回不要)
    init_CMT0(1);        //タイマー機能初期化
    init_SCI1();    //シリアル通信初期化

    in=PI/4;        //入力 π/4rad(45deg)
    out=sinf(in);    //計算

    sprintf(trans_buf,"%f=sinf(%f)\n",out,in);    //送信文字列組み立て
    write_sci1(trans_buf);                        //送信

    while(1){    //無限ループ
    }//end while

}//end main

<解説>
プロジェクトの設定を変更してmathf.hを使えるようにしてからmathf.hをインクルードします。

計算結果をシリアル通信(38400,8,E,1)で出力します。
Tmz等で受信すると


0.707107=sinf(0.785398)
と出てくれば成功です。

0.707107 ⇒ 1/√2
と正常に計算できていることが分かります。

PR

コメント

プロフィール

HN:
ぼんどF博士
性別:
男性

最新コメント