三角関数を使うための基礎知識が揃ったので、実際に三角関数を使ってみます。
関連:
三角関数 基本編、
ラジアンって何?、
浮動小数点型とは処理を高速化するために三角関数を自作することもありますが、とりあえず標準
で用意されている三角関数を使うことを考えます。
授業で習うプログラムの場合
#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.c、
hwsetup_rx220.hAD変換設定:
ADconv_rx220.c、
ADconv_rx220.h
タイマ設定:
intCMT_rx220.c、
intCMT_rx220.hシリアル通信設定:
intSCI_rx220.c、
intSCI_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
と正常に計算できていることが分かります。