2017年7月10日月曜日

Nucleo F303K8でDAC 3ch出力できた。(mbed 2のみ)

以前やったときは1chずつしか出力できなかったが、改めてやり直したらDAC 3ch同時出力できた。

mbed repository:
https://developer.mbed.org/users/ryood/code/Nucleo_sinewave_output/ Revision:1

<main.cpp>

#include "mbed.h"

AnalogOut my_output1(A5);
AnalogOut my_output2(A4);
AnalogOut my_output3(A3);

#define PI        (3.141592653589793238462)
#define AMPLITUDE (1.0)    // x * 3.3V
#define PHASE     (PI * 1) // 2*pi is one period
#define RANGE     (0x7FFF)
#define OFFSET    (0x7FFF)

// Configuration for wave output
#define BUFFER_SIZE (360)
uint16_t buffer_sine[BUFFER_SIZE];
uint16_t buffer_cosine[BUFFER_SIZE];
uint16_t buffer_saw[BUFFER_SIZE];

void calculate_sinewave(void);
void calculate_cosinewave(void);
void calculate_sawwave(void);

int main() {
    printf("Multi-channel DAC example\n");
    calculate_sinewave();
    calculate_cosinewave();
    calculate_sawwave();
    while(1) {      
        // wave output
        for (int i = 0; i < BUFFER_SIZE; i++) {
            my_output1.write_u16(buffer_sine[i]);
            my_output2.write_u16(buffer_cosine[i]);
            my_output3.write_u16(buffer_saw[i]);
        }
    }
}

// Create the wave buffer
void calculate_sinewave(void){
  for (int i = 0; i < BUFFER_SIZE; i++) {
     double rads = (PI * i)/180.0; // Convert degree in radian
     buffer_sine[i] = (uint16_t)(AMPLITUDE * (RANGE * (sin(rads + PHASE))) + OFFSET);
  }
}

void calculate_cosinewave(void) {
  for (int i = 0; i < BUFFER_SIZE; i++) {
     double rads = (PI * i)/180.0; // Convert degree in radian
     buffer_cosine[i] = (uint16_t)(AMPLITUDE * (RANGE * (cos(rads + PHASE))) + OFFSET);
  }
}

void calculate_sawwave(void) {
    for (int i = 0; i < BUFFER_SIZE; i++) {
        buffer_saw[i] = i * 0xFFFF / BUFFER_SIZE;
    }
}

3chそれぞれにサイン波、コサイン波(90度位相遅れ)、ノコギリ波のテーブルを作って出力している。予めテーブルを作っているので出力ループ内では単純にバッファの値を出力しているので、どの波形でも処理はいっしょ。

PeripheralPins.cを見ると

A3 DAC1 OUT1
A4 DAC1 OUT2
A5 DAC2 OUT1

となっている。

1ch


DAC 1chだけに出力するようにして比較してみた。

A3

A4

A5

2ch


DAC 2chを同時出力

A3+A4

ch1:A3 ch2:A4

A4+A5

ch1:A5 ch2:A4

A3+A5

ch1:A5 ch2:A3

3ch


DAC 3chを同時出力

A3+A4+A5

ch1:A5 ch2:A4

DAC 周波数(Hz) サンプリングレート(kHz) サンプリング周期(us)
A3 1080 388.8 2.572016461
A4 1081 389.16 2.569637167
A5 1068 384.48 2.600915522
A3+A4 577.4 207.864 4.810837856
A4+A5 577.4 207.864 4.810837856
A3+A5 577.4 207.864 4.810837856
A3+A4+A5 389.1 140.076 7.138981696

※サンプリングレートは周波数×360で計算

出力波形の歪

WaveSpectraでFFTして歪を見てみた。(3ch出力時)


12bitDACなので、歪は結構多い。

mbed 2のrtos


Nucleo F303K8はmbed 2のrtosには対応していないようだ。コンパイルすると

Error: #error directive: "no target defined" in "mbed-rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c", Line: 54, Col: 4

というエラーが返ってきてコンパイルできない。

mbed OS 5


mbedのNucleo F303K8のページを見ると

mbed Enabled
mbed OS 2

となっていて、mbed OS 5対応の表示はない。

Nucleo F401REのベージを見ると

mbed Enabled
mbed OS 2
mbed OS 5.4
mbed OS 5.5

となっている。

mbedのオンラインコンパイラーにmbed OS 5のAnalog OutのExampleをオンラインコンパイラーにインポートして、TargetにNucleo F303K8を指定するとコンパイル可能で、Lチカ及びUART出力は動作するが、AnalogOutに指定したPinから信号は出力されなかった。

コンパイル時に以下のようなWarningが出る。