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などのタイマ機能が充実しているそうだ。
使いこなすにはもう少し慣れる必要がありそう。