製作モジュール一覧

ラベル Nucleo F303K8 の投稿を表示しています。 すべての投稿を表示
ラベル Nucleo F303K8 の投稿を表示しています。 すべての投稿を表示

2017年12月18日月曜日

Nucleo F446REとNucleo F303K8の一部ピンは5Vトレラントではない模様

Nucleoで使われているSTM32は3.3V駆動で、基本的には5VトレラントだがF446、F303では一部ピンは5Vトレラントになっていないようだ。

F446RE


STM32F446xC/EのDATASHEET(en.DM00141306.pdf)を見てみると、一部ピンは絶対定格で最大4.0Vとなっている。


VinのFTとFTfピンは最大値が「VDD+4.0|V」となっているが、TTaピンやその他のピンは「4.0|V」となっている。

ピンの仕様の略称は、


となっていて、FT/FTfは「5V tolerant I/O」、TTaは「3.3V tolerant I/O directly connected to ADC」となっている。

F446の場合、電源系とBOOT0以外は基本的にFT/FTfだが、


PA4、PA5は「TC」となっている。「TC」の説明はざっと見た感じでは見当たらないが、FT/FTfピン以外は5Vトレラントではない

F303K8


STM32F303x6/x8のDATASHEET(en.DM00092070.pdf)より。

絶対定格

こちらもTTaやその他のピンは最大「4.0|V」となっている。

ピンの略称

こちらはTCの説明があり、「Standard 3.3V I/O」となっている。

各ピンの仕様はTable14にあり、5VトレラントのFT/FTfとなっているピンは多くはない。Nucleo F303K8は基本的に5Vトレラントではないと思って取り扱ったほうが良さそうだ。

5V系からのレベルシフトが必要になった時に、FT/FTfピンを(よく考えて)使うのが良さそう。

出力ピンの短絡


出力ピンをGNDに短絡した場合の保護については、DATASHEETの分量が多いので読み切れない。

少なくとも出力系(特にアナログ出力)に設定したピンは短絡についても注意が必要だと思う。

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が出る。



2017年6月29日木曜日

SPI Digital PotのAD8403の処理速度を調べてみた。

KIK01で使うかもしれないので、Analog DevicesのSPI接続のデジタル・ポテンショメータのAD8403の処理速度をArduinoとNucleoで調べてみた。

Arduino Uno


配線は「Arduinoでデジタル・ポテンショメータメーター(AD8403)を使ってみた」のものと同じ。

スケッチ
<AD8403_Control.ino>

// inslude the SPI library:
#include <SPI.h>

// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;

void setup() {
  // set the slaveSelectPin as an output:
  pinMode(slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop() {
  // go through the four channels of the digital pot:
  for (int channel = 0; channel < 4; channel++) {
    // change the resistance on this channel from min to max:
    digitalPotWrite(channel, 255);
    digitalPotWrite(channel, 0);
  }
}

void digitalPotWrite(int address, int value) {
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin, LOW);
  //  send in the address and value via SPI:
  SPI.transfer(address);
  SPI.transfer(value);
  // take the SS pin high to de-select the chip:
  digitalWrite(slaveSelectPin, HIGH);
}


AD8403への出力はノーウェイトで0と255を切り替えている。slaveSelectPin(CS)がアクティブ(L)の時間を見ればAD8403に値を送るのにかかった時間がわかる。

CS

ch1:CS ch2:SCK

CSがアクティブな時間は9.680us。SPIクロック(SCK)は3.538MHzとなっているが、拡大してオシロのカーソルで測ると約4MHzだった。

2回目のSPI.transfer()の後、CSをHiにするまでに結構時間がかかっているようだ。

W1

ch1:CS ch2:W1

W1はAD8403のchannel 1のWiperの出力電圧で、プログラムでここの電圧値を制御している。CSがL->H、つまりSPI通信が終了したタイミングでほぼ遅延なく送った設定値が反映されている。

Nucleo F446RE


配線はArduinoと同じ。(NucleoのArduino Headerで配線した)

プログラム

/*
 * Digital Potentiometer AD8304のテスト
 *
 * 2017.06.28
 *
 */

#include "mbed.h"

#define SPI_CLOCK   (16000000)

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

// address: 0..4
// value:   0..255
void outDigiPot(uint8_t address, uint8_t value)
{
    Cs = 0;
    SpiM.write(address);
    SpiM.write(value);
    Cs = 1;
}

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

    for (;;) {
        for (int channel = 0; channel < 4; channel++) {
            outDigiPot(channel, 255);
            wait_us(1);
            outDigiPot(channel, 0);
            wait_us(1);
        }
    }
}

メインループ内でwait_us(1)を入れているが、これは処理が速すぎてオシロで信号が見辛かったため。

AD8403の最大クロックは10MHzなので、SPI_CLOCKを1MHz、6MHz、12MHzにして測定してみた。

1MHz CS

ch1:CS ch2:SCK

CSがアクティブな時間は26.240us。SPIクロックは597.0kHz

1MHz W1

ch1:CS ch2:W1

Arduinoと同じくCSがインアクティブになってからほぼ遅延なく設定した値が出力されている。

6MHz CS

CS:7.820us。SCKは拡大して測ると5.627MHz。

12MHz CS

CS:6.220us。SCKは拡大して測ると11.25MHz。(AD8403の仕様外)

Nucleo F303K8


F303K8はSPIクロックを1MHz、8MHz、16MHzにして測定。


1MHz CS

CS:34.6us。SCKは拡大して測ると約1MHz。

8MHz CS

CS:20.8us。SCKは拡大して測ると約8MHz。

16MHz CS

CS:20.84us。SCKは拡大して測ると約16MHz。(AD8403)

比較表


Device SCK(設定値) SCK(実測値) CS
Arduino 4MHz 4MHz 9.680us
F446RE 1MHz 597.0kHz 26.24us
F446RE 6MHz 5.627MHz 7.820us
F446RE 12MHz 11.25MHz 6.22us
F303K8 1MHz 1MHz 34.6us
F303K8 8MHz 8MHz 20.8us
F303K8 16MHz 16MHz 20.84us

比較してみると、Arduino Unoがかなり健闘している。SPIクロックが同程度ならNucleoF446REと同じぐらいかもしれない。NucleoF303K8はSPI通信前後のオーバーヘッドが大きく、SPIクロックを上げてもArduino Unoよりも悪い結果となってしまった。

F446もF303もコアは同じCortex-M4だが処理能力はかなり差がある。

Interface2016年12月号に「定番ARMマイコンSTM32便利帳2016」 という付録がついているので見てみると、F3はADC、DACなどのアナログ機能やPWMなどのタイマ機能が充実しているそうだ。



使いこなすにはもう少し慣れる必要がありそう。

2017年6月23日金曜日

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

サイズの小さいNucleo F303K8でも内蔵DACとMCP4922の処理時間を比較してみた。

ブレッドボード配線図


プログラムはNucleoF446REの場合と同じです。

SPIクロックに16MHzを指定した場合



ch1:D2 ch2:SPI_SCK

MCP4922に出力完了するまで、21.04usかかっている。


ch1:SPI_MOSI ch2:SPI_SCK

SPIクロックに16MHz指定した場合、SCKの周波数は表示では15.98MHzとなっているが測定誤差で16MHzだと思う。

SPIクロックの指定を変えて測定


SPIクロック設定値 SPIクロック実測値 D2(MCP4922の処理時間) D3(内蔵DACの処理時間)
1MHz 1.0MHz 34.8us 2.8us
2MHz 2.0MHz 27.3us 2.8us
4MHz 4.0MHz 23.5us 2.8us
8MHz 8.0MHz 21.04us 2.8us
16MHz 16.0MHz 21.04us 2.8us
32MHz 32.0MHz 19.8us 2.8us
64MHz 32.0MHz 19.8us 2.8us

32MHzまでは設定値通りのSPIクロックが出力される。やはりNucleo F303は64MHz駆動で、SPIクロックはマスタークロックの1/2まで設定できるんだと思う。

MCP4922の仕様ではSPIクロックは20MHzまでだが、32MHzでも動作した。

NucleoF446REと比べると、SPIクロックを上げてもSPI通信の処理時間はあまり短縮されない。

2017年6月14日水曜日

NucleoF303K8を買ってみた。


(左)Nucleo F401RE、(右上)Arduino Pro Mini、(右下)Nucleo F303K8

画像の通りかなりコンパクトで、USBシリアル変換基板も不要。基板は両面実装でメインMPUのSTM32F303のほかに裏面にSTM32F103が載っている。

STMF303はCorete-M4ベースでDACも2つ(3ch)搭載されている。

内蔵DAC


mbedでプログラムを書いてDACの出力を見てみた。

main.cpp

#include "mbed.h"

AnalogOut my_output1(PA_4);
//AnalogOut my_output2(PA_5);
//AnalogOut my_output3(PA_6);

#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 sinewave output
#define BUFFER_SIZE (360)
uint16_t buffer[BUFFER_SIZE];

void calculate_sinewave(void);

int main() {
    printf("Sinewave example\n");
    calculate_sinewave();
    while(1) {      
        // sinewave output
        for (int i = 0; i < BUFFER_SIZE; i++) {
            my_output1.write_u16(buffer[i]);
            //my_output2.write_u16(buffer[i]);
            //my_output3.write_u16(buffer[i]);
        }
    }
}

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

mbed repository:
https://developer.mbed.org/users/ryood/code/Nucleo_sinewave_output/ revision:0

3chあるということで、3つAnalgOutを作ってみたがmbedでは同時に2つ以上使えないようだ。いろいろ組み合わせてみたがうまくいかなかった。それぞれ1chだけなら利用可能。

出力波形

PA_4

F:922.5Hz

PA_5

F:932.8Hz

PA_6

F:924.2Hz

各chで出力された周波数が若干異なる。

PA_4では922.5Hzのサイン波が出力された。以前Nucleo F446REでテストした時は、6.4kHzのサイン波が出力されたので、比較するとかなり遅い。

1周期のサンプル数(BUFF_SIZE)が360なので、サンプリング周波数は約332kHz(3u秒)となる。

F446REの時に見られた波形のつぶれはなく、フルレンジできれいなサイン波が出力されている。

単精度浮動小数点数点演算


駆動クロックははっきりしないが、回路図と基板を見比べてみるとF303用の外付けのクリスタル(X1)が実装されていない。内蔵RCで動作しているとすると、PLLで逓倍して最大64MHzとなっているので、64MHzとして比較してみた。

No Device No2 Op time(us) clock(MHz) period(us) clock:op
3 Nucleo F303K8 1 div 0.357 64 0.015625 22.848
3 Nucleo F303K8 2 sinf 2.011 64 0.015625 128.704
3 Nucleo F303K8 3 cosf 1.922 64 0.015625 123.008
3 Nucleo F303K8 4 expf 3.202 64 0.015625 204.928
3 Nucleo F303K8 5 logf 2.506 64 0.015625 160.384
3 Nucleo F303K8 6 sqrtf 0.739 64 0.015625 47.296

単精度浮動小数点数の割り算


1処理あたりの実行時間

1処理あたりのクロック数

単精度浮動小数点数のsinf()


1処理あたりの実行時間

1処理あたりのクロック数

FPUが載っているので単精度浮動小数点演算は十分速いと思う。

メモ:


NucleoF303K8の駆動クロックはわからないが、STM F4もSTM F3もFPUの割り算の性能が変わらないとすると64MHzなのかも?