R8C で AD9851を試してみる

以前に、周波数シンセサイザ、AD9833 を試していたが、より高い周波数に対応した、AD9851も試してみた。
※最近RXマイコンばかりで久しぶりにR8Cを触った、このような実験には、小回りが利いて便利だ。

値段はかなり高く、モジュールで3500円程だった。

買ってから気がついたが、このICはサイン波のみで、三角波はサポートしていない。
※矩形波はコンパレーターがあるので作れるだろうか・・

ただ、内部は最大180MHzで駆動できる為、出力できる周波数を高く設定でき、周波数ステップも細かく設定可能。
※AD9850は最大125MHz
※AD9833は最大25MHz
※AD9851では、電源電圧により、最大動作周波数が異なる

モジュールでは、出力にLCRを使ったローパスフィルタが組んであるのだが、出力する周波数によって振幅が小さくなるので、結構扱いが面倒だ・・
※10MHzだと減衰がかなり大きい。
この手のICを実用的に使うとなると、一番ネックになるのが、出力の扱いだと思う。
中心をGNDにして、+-で振幅させたいとか、出力振幅やオフセットを設定したいとかするには、外部に何らかの回路を付けたいが、マイコンで制御できるようにするには、意外と単純では無い。

いつものようにテンプレートライブラリとしたが、周波数の計算で、倍精度の浮動小数点を使っている。
本来整数計算だけで出来ると思うが、参考にしたライブラリの手法をそのまま流用した、時間がある時にでも考えてみたい。

ICの制御は基本4本の制御線が必要で、外部基準発信器をどのようにするかを設定出来るようにしてある。

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
    @brief  AD985X テンプレートクラス
    @param[in]  D7      ポート・クラス
    @param[in]  W_CLK   ポート・クラス
    @param[in]  FQ_UD   ポート・クラス(FQ_UpdDate)
    @param[in]  RESET   ポート・クラス
    @param[in]  BASEC   ベースクロック(AD9850:125, AD9851:180)
*/    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
template <class D7, class W_CLK, class FQ_UD, class RESET, uint32_t BASEC>
class AD985X {

...
public:
    //-----------------------------------------------------------------//
    /*!
        @brief  レジスターを設定
        @param[in]  w0      W0 レジスター値
        @param[in]  freq    周波数
     */
    //-----------------------------------------------------------------//
    void set_reg(uint8_t w0, float freq)


};

サンプルでは、外部OSCが30MHzで、内部の6倍PLLを有効にする。

    // P1_0(20):
    typedef device::PORT<device::PORT1, device::bitpos::B0> D7;
    // P1_1(19):
    typedef device::PORT<device::PORT1, device::bitpos::B1> W_CLK;
    // P1_2(18):
    typedef device::PORT<device::PORT1, device::bitpos::B2> FQ_UP;
    // P1_3(17):
    typedef device::PORT<device::PORT1, device::bitpos::B3> RESET;

    // 180MHz
    typedef chip::AD985X<D7, W_CLK, FQ_UP, RESET, 180> AD9851;
    AD9851  ad9851_;



    {  // AD9851 開始
        ad9851_.start();
        ad9851_.reset();
    }




    char tmp[32];
    command_.get_word(1, sizeof(tmp), tmp);
    float a = 0.0f;
    if((utils::input("%f", tmp) % a).status()) {
        ad9851_.set_reg(0b00001001, a);  // Phase: 1, PLL 6x
    } else {
        error = true;
    }

市販の周波数ジェネレーターはそれなりに高いので、安価な実験用発信器が欲しかったのだが、実用的な物にするにはそれなりの工夫が必要で、それなりに考える必要がある。
AD9851は内部180MHz動作なのだが、三角波も出せないので、AD9833の方が良いのかもしれない・・・

AD985X.hpp
github AD9851_sample