R8C A/D変換

R8CのA/D変換も出来ました。

ただ、別の部分で、工夫が必要な事が判りました。

工夫と言うのは、バイナリーサイズが肥大化しているのです・・
問題になってるのは「format」クラスです。
このクラスは、「printf」に代わるものとして実装した物ですが、16キロバイトにもなります。
フラッシュメモリーは32キロまで使えるとは言え、流石に半分も消費するのでは問題です。
RXマイコンで実装した物をほとんどそのまま使っているのですがー、RXマイコンではそこそこのサイズでしたが、R8Cでは巨大になるのです・・

動作は、設計の通りですが、小さくする工夫をする必要があります。

しばしば、小さな組み込みでは、libc の printf が巨大になるので、縮小版を作る人が多いですが、自分もその口です。
そもそも、printf は、引数がスタックベースなので、フォーマットと、引数が食い違う場合に簡単にクラッシュするか、
意図しない微妙な動きになる場合があります。
コンパイラーが整合性をチェックしますが、完全ではありません。
C++では、そんな危険を冒さなくても、安全な方法が色々あります。
「format.hpp」は、オペレーターの機能を使って、boost::format のような実装を行った物です、boost::format 版は、std::cout が必要な為、バイナリーが肥大化して使えませんので、縮小版です。

  int i = 123;
  printf("%d\n", i);

が、

  uint32_t i = 123;
  format("%d\n") % i;

のように書けます。
※R8Cでは「int」が16ビットなので、in32_t、uint32_t を使います。
※「%」オペレーターをオーバーロードしています。

調べると、現在の実装では、文字の出力や、定型サイズなどをテンプレートの引数として受け取るのですが、これが肥大化の要因のようです。
そこで、テンプレートをやめ、通常のクラスとして定義しなおし、エラーレポートもオフにしてみました、その結果、半分以下になりました。
これなら、許容範囲と思いますと言いたいのですが、もう少し何とかしないと駄目な感じです・・
R8C の gcc はメンテされていないのと、基本16ビットのCPUなので、コンパイラのコード生成に問題があるのかもしれません・・
※R8Cでは、フラッシュは64キロ以内なので、64キロを超えてジャンプする機構は必要無いのですが、コンパイル
されたマシンコードには、そのキックコードが含まれています、コンパイラのスイッチで排除出来ると思いますが、少し調べた限りでは判りませんでした・・

さて、本題はA/D変換です、R8Cに内臓されているA/Dコンバーターは10ビットの分解能で、2チャネル、アナログ入力は6チャネルあります。
変換速度は高速で、最大で2.3uSです。
アナログ用電源はピン数の制限から、デジタル電源と共通ですが、ルネサス系のCPUは電源ノイズも少なく、A/D変換の精度もAVR系より優れている感覚があります。
※AVR系ではサンプルホールドが無い為、変換結果に誤差が乗り易く、正確な変換を行うのが難しいと思えます。

format クラスには、A/D変換などの表示に適した、固定小数点表示「%y」を実装してあります。
A/D変換結果は大抵、電圧や電流などですが、表示する場合、小数点付きで10進表記で表示した方が判りやすい
ですが、通常だと実数と少数部を分けて、別々に計算をする必要があり、多少面倒です。

固定少数点表記機能を使うと、例えば、1023を5Vとすると、実数1桁、小数2桁、小数点以下8ビットの精度としてー

  uint16_t v = adc_.get_value();
  format("%1.2:8y") % static_cast(((v + 1) * 10) >> 3);

とすれば、v が1023の場合に「5.00」と表示できます。

A/D変換のサンプルコード

浮動小数点の計算は、リソースを食うし、FPUが無いとスピードも出ませんので、固定小数点の計算を簡単に行えると便利だと思います。
※何故10倍して8で割っているのか、良く考えれば判ります。

現在の「format.hpp」は「float、double」の実装がまだで、中途です、IEEE754 の表示を浮動少数点を使わずに整数計算だけで実装したいのですが、苦労しています、道まだ半ばです・・・

型指定子にどんなものが使えるか、「format.hpp」を観れば直ぐに解ると思います。
※8進数は、通常あまり使わないので、オプションとしています。