2017年6月22日木曜日

Nucleo F446RE(mbed)の内蔵DACとSPI DACのMCP4922の速度を比較する

結論から言うと、内蔵DACの方が圧倒的に速かった。

mbedでプログラムを書いて、SPI DACのMCP4922とNucleo F446RE内蔵DACの処理時間を比較してみた。

どちらも12bit。

/*
 * 内蔵DACとMCP4922に出力するテスト
 *
 * 2017.06.21
 *
 */

#include "mbed.h"
#include "rtos.h"

#define SPI_CLOCK   (24000000)

SPI SpiM(SPI_MOSI, SPI_MISO, SPI_SCK);  // mosi, miso, sclk
DigitalOut Cs(D10, 1);

AnalogOut InternalDac(PA_4);

DigitalOut CheckPinD2(D2);
DigitalOut CheckPinD3(D3);

// v: 0..0x0fff
void OutMCP4922(uint16_t v)
{
    //v &= 0x0fff;

    // Channel A
    Cs = 0;
    SpiM.write(v >> 8 | 0x30);    // 0x30: DAC_A(0) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1)
    SpiM.write(v & 0xff);
    Cs = 1;
}


// v: 0..0xffff
void OutInternalDac(uint16_t v)
{
    InternalDac.write_u16(v);
}

int main()
{
    SpiM.format(8, 0);
    SpiM.frequency(SPI_CLOCK);

    uint16_t count = 0;
    for (;;) {
        uint16_t v12 = count >> 4;
        uint16_t v16 = count;
        
        CheckPinD2 = 1;
        OutMCP4922(v12);
        CheckPinD2 = 0;

        CheckPinD3 = 1;
        OutInternalDac(v16);
        CheckPinD3 = 0;
        
        count += 0x100;

        Thread::wait(1);
    }
}

Nucleoをmbedで使って、SPIの周波数設定をするとちょうどの周波数にはならない。おそらくマスタークロックの分周比なのだと思う。

こういうハードウェア寄りの使い勝手はmbedの弱点ではあります。

SPI::frequency()でSPIクロックの周波数を変えて測定してみた。

ブレッドボード配線図


MCP4922にはLDAC pinがあって、これをH→LするとA ChannelとB Channelが同期して
同時に電圧が出力されるが、LDACをL(GND)に落としておくと、CSのアクティブ/インアクティブで制御できるようだ。配線や処理時間のコストがシビアな場合は役に立つと思う。(A Channelだけしか試してないです)

1MHz

ch1:MCP4922 ch2:内蔵DAC

MCP4922から出力すると、27.3usかかる。一方内蔵DACは700ns(0.7us)で済む。


ch1:MCP4922 ch2:SPI_SCK

1MHzを設定した場合はMCP4922との通信に使っているSPIのクロック周波数は643kHz

24MHz

ch1:MCP4922 ch2:内蔵DAC

SPIのクロック周波数を上げるとMCP4922でも6.8us(≒147kHz)で済む。


ch1:MCP4922 ch2:SPI_SCK

SPIのクロック周波数は22.44MHz。クロックが高周波数になるとダンピング抵抗を入れていても波形が怪しくなる。

MCP4922の最大周波数は20MHzなので仕様外だが、VOUTAから波形は出力される。

Zoom Out

ch1:MCP4922 ch2:SPI_SCK

高クロックになると、8bitずつのSPI通信の間隔が開くようだ。

<追記:2017.06.25>
間隔が開くと言うより、SPI::write()のオーバーヘッドが2~3us程度ある?
</追記>

設定値と出力周波数


設定値 SPIクロック 処理時間
1MHz 643.8kHz 27.3us
2MHz 1.154MHz 16.76us
4MHz 2.810MHz 11.32us
6MHz 5.762MHz 8.76us
12MHz 11.29MHz 7.36us
24MHz 22.44MHz 6.74us