2016年9月30日金曜日

Nucleo F401同士でSPI通信してみる。

Arduino Master <-> Nucleo Slaveで実験してみたので、MasterもNucleo F401RE(mbed)にしてSPI通信してみた。

ほんとはNucleo F401REではなく、Nucleo F446REが欲しかったのだが秋月で売り切れていたのでF401REをもうひとつ仕入れた。F446REは動作クロックが最大180MHzで12bit DAC他周辺機能も大幅に強化されていて1600円。mbedで使ってもメリットはいろいろありそう。またいずれ購入する予定。

配線図


Slave側のファームウェアは前回のまま。

Nucleo(Master)のプログラム(mbed)

https://developer.mbed.org/users/ryood/code/Nucleo_rtos_SPI_Master_Test/

mbed: Revision 121
mbed-rtos Revision 117

main.cpp

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

#define SPI_SPEED   (10000000)

BusOut Leds(PA_8, PB_10, PB_4, PB_5);
BusIn Switches(PA_0, PA_1, PA_4, PB_0, PC_1, PC_0);

SPI SpiM(PA_7, PA_6, PA_5); // mosi, miso, sclk
DigitalOut SpiMCs(PB_6);

InterruptIn stepChangeInterrupt(PC_7);

volatile bool isStepChanged = false;
uint8_t prevSendVal = 0x00;

void setChangeStep()
{
    isStepChanged = true;
}

int main()
{
    printf("\r\n\nNucleo rtos SPI Master Test..\r\n");
    
    // LED Check
    for (int i = 0; i <  5; i++) {
        Leds.write(0x0f);
        Thread::wait(100);
        Leds.write(0x00);
        Thread::wait(100);
    }
    
    // Setup Switches
    Switches.mode(PullUp);
    /*
    while(1) {
        printf("%x\r\n", ~Switches.read() &0x3f);
        Thread::wait(100);
    }
    */
    
    // Setup Interrupt
    stepChangeInterrupt.fall(&setChangeStep);
    
    // Setup SPI
    SpiMCs = 1;
    SpiM.format(8, 0);
    SpiM.frequency(SPI_SPEED);
    
    for (;;) {
        uint8_t sendVal = ~Switches.read();
        
        if (prevSendVal != sendVal || isStepChanged) {
            SpiMCs = 0;
            uint8_t receivedVal = SpiM.write(sendVal);
            SpiMCs = 1;
            
            prevSendVal = sendVal;
            
            if (isStepChanged) {
                Leds.write(receivedVal & 0x0f);
                isStepChanged = false;
            }
        }
    }
}

メモ:


この回路では関係ないが、タクトスイッチでInterruptInのテストをすると、以前やった時と同じようにmbedのInterruptIn::mode()でPullUpを指定しても内部PullUpされなかった。(参考:「Nucleo F401REでmbedのInterruptInが動作しない。」) VDD(3.3V)に抵抗でPull Upすれば動作する。

割り込み信号を立ち上がりで補足するInterruptIn::rise()でISRを指定すると割り込みがかからない。立ち下がりで捕捉するInterrupt::fall()だと割り込みがかかった。

割り込み信号

Vonが120nsぐらい。

2016年9月28日水曜日

ダイオードで電源の逆接続に対策する実験

電源の逆接続にダイオード1本でなんとか対策できないか調べてみた。電源は過電流でシャットダウンする対策が取られている3端子レギュレータを想定。

3.3V LDOのTA48M033Fで実験してみた。


1) 電源ラインにダイオードを入れる

これは負荷のRLに逆電圧がかかったらダイオードに逆方向電圧がかかるのでRLに電流が流れないという回路

2) 電源ラインからGNDにダイオードを逆接続


これは逆電圧がかかった場合ダイオードに電流を流してRLに流れる電流をなくすという回路

1)の電源ラインにダイオードを入れるとダイオードの順電圧Vf分(0.6V程度)電圧降下してしまうので「電源ラインにダイオードを入れる」作戦は不採用。もしできるなら3端子レギュレータの前に入れるべきだと思う。

なので、2) の電源ラインからGNDにダイオードを逆方向で入れて実験してみた。




電源は5V/3.3V安定化電源 Ver.2 を使って5Vを出力し、TA48M033Fで3.3Vに降圧&安定化。RLは220Ωの酸金にした。

Irl = 3.3V / 220Ω = 15mA

ダイオードをショットキーダイオード(1S4)にした場合


1S4 Vrl(V) Irl(mA)
正電圧 2.76 15.06
逆電圧 -0.3 -2.5

ダイオードを整流用ダイオード(1N4007)にした場合


1N4007
Vrl(V) Irl(mA)
正電圧 2.7 15.03
逆電圧 -0.6 -4.2

ダイオードがショットキーダイオードの場合も整流用の場合も逆電圧をかけると、5V電源の赤色LEDが点滅。

電源は5V/3.3V安定化電源 Ver.2は出力電圧が5V以下になると赤色LEDが点灯するようにしているのでLDOのTA48M033Fの出力過多を抑止する機能が働いているんだと思う。

メモ:


実験の結果、15mAを負荷に流すと2)の回路でも3.3Vの電源が2.7V~2.8V程度にまで電圧が落ちてしまうようだ。

ダイオードの逆方向電圧だと0.6Vの電圧降下は大きすぎると思うけどよくわからない。

逆電圧をかけた場合も、ショットキーダイオードの方が保護に役立っていそう。

<追記:2016.09.29>

正電圧の場合の0.6V程度の電圧降下は電流計(テスタ)による電圧降下だった。結構でかい。

電流計を外して(ショートして)測り直した。

ショットキー


1S4 Vrl(V) Vrl_max(V)
正電圧 3.32 3.32
逆電圧 -0.3 -0.5

整流用

1N4007 Vrl(V) Vrl_max(V)
正電圧 3.32 3.32
逆電圧 - -1

どちらの場合も逆電圧にした場合、ブレッドボード上の三端子レギュレータがかなり発熱したので計測中止。徐々に電圧が下がって落ち着くが整流用ダイオードの場合は発熱のため落ち着くまで計測しなかった。

ダイオード1本の逆電圧対策にはショットキーダイオードの方がよさそうで、正常時には電圧降下はほとんどない。

</追記>

2016年9月27日火曜日

Arduino UnoをSPI Master、Nucleo F401REをSPI Slaveにして通信してみる。


配線図

Nucleo(Slave)のCSピンはArduinoのようにD10にすると実行時にSerial経由でエラーが表示される。Nucleo F401REのピンアウトを見ると、A2がSPI1_NSSとなっているので、こちらに設定したら動作した。NSSのNはたぶんActive Lowの意味でSS(Slave Select)に前置しているんだと思う。

<追記:2016.10.01>

シリアル経由のエラーメッセージ


</追記>


SPIの信号線だけではSlaveからアクションを起こせないので、SPIとは別に外部割込みを配線(Nucleo:PC_7→Arduino:D2)し、Nucleo(Slave)からArduino(Master)に割込みをかけてMasterからSPI通信を開始するようにした。

また、秋月のNucleo F401REの商品説明によると「GPIO数:50(5Vトレラント、一部を除く)」となっているので5V→3.3Vのレベルシフトはしないで直結した。除かれる「一部」がどこのピンか調べてないがAruduinoヘッダは5Vトレラントだろうと憶測(^q^;

<追記:2016.09.29>

STM32 F401のDATASHEET(DM00102166.pdf 「STM32F401xD STM32F401xE」)の「4 Pinouts and pin description」の「Table 8. STM32F401xD/xE pin definitions」にどのピンが5Vトレラントなのか載っていた。「Pin type」がFTとなっているピンが5Vトレラントで、LQFP64パッケージのI/Oピンはすべて5Vトレラントのようです。

VREFとBOOT0(何をするピンかはよく調べてない)は5Vトレラントではないので要注意です。

</追記>

動作概要


1   タクトスイッチの読み取り(Master→Slave送信)


1.1 Arduino(SPI Master)でタクトスイッチ×6の押し下げ状態を取得。

1.2 タクトスイッチの押し下げ状態に変化があった場合に、SPIで読み取り値をNucleo(SPI Slave)に送信。Nucleoからの返値は無視。

1.3 NucleoはSPI受信した読み取り値をLED×6に表示

2.  一定間隔でカウンタをインクリメント(Slave→Master送信)


2.1 NucleoはmbedのRtosTimerで一定間隔でカウンタをインクリメントし、SPI通信の返値にセット。カウンタをインクリメントした時に一度だけArduinoに外部割込みをかける。

2.2 Arduinoは外部割込みがかかったときNucleoにSPI送信(Master→Slave)し、返値にセットされているカウンタ値をLEDx4に表示。

Arduino(Master)のスケッチ

SPI_Master_for_Nucleo_SPI_Slave.ino

#include <SPI.h>

const int SpiCsPin = 10;
const int SpiSpeed = 10000000;

const int InterruptPin = 2;

volatile bool isStepChanged = false;
uint8_t prevSendVal = 0x00;

void setup()
{
  // PD4 - PD7: Output
  DDRD  = 0xF0;
  
  // LED Check
  for (int i = 0; i < 5; i++) {
    PORTD = 0xF0;
    delay(100);
    PORTD = 0x00;
    delay(100);
  }
  
  // PORTC: Input Pullup
  DDRC  = 0x00;
  PORTC = 0xFF;
  
  // Setup Interrupt Pin
  pinMode(InterruptPin , INPUT);
  attachInterrupt(digitalPinToInterrupt(InterruptPin), setStepChange, RISING);  
  
  // Setup SPI
  pinMode(SpiCsPin, OUTPUT);
  digitalWrite(SpiCsPin, HIGH);
  SPI.begin();
  SPI.beginTransaction(SPISettings(SpiSpeed, MSBFIRST, SPI_MODE0));
}

void loop()
{
  uint8_t sendVal = ~PINC & 0x3f;
  
  if (prevSendVal != sendVal || isStepChanged) {
    digitalWrite(SpiCsPin, LOW);
    uint8_t recievedVal = SPI.transfer(sendVal);
    digitalWrite(SpiCsPin, HIGH);
    
    prevSendVal = sendVal;
    
    if (isStepChanged) {
      PORTD = recievedVal << 4;
      isStepChanged = false;
    }
  }
}

void setStepChange() {
  isStepChanged = true;
}

Nucleo(Slave)のプログラム(mbed)

https://developer.mbed.org/users/ryood/code/Nucleo_rtos_SPISlave_Test/

mbedのLibraryは個人的に動作実績のあるRevisionを使うことにした。

mbed: Revision 121
mbed-rtos Revision 117

main.cpp

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

#define SPI_SPEED   (10000000)

BusOut Leds(PA_10, PB_3, PB_5, PB_4, PB_10, PA_8);
DigitalOut StepChangePin(PC_7);

SPISlave SpiS(PA_7, PA_6, PA_5, PA_4);    // mosi, miso, sclk, ssel

unsigned int step = 0;

void stepUp(void const* arg)
{
    step++;
   
    // Masterにinterruptをかける。
    StepChangePin.write(1);
    StepChangePin.write(0);
}

int main()
{
    printf("\r\n\nNucleo rtos SPISlave Test..\r\n");
   
    // Setup LED
    for (int i = 0; i < 5; i++) {
        Leds.write(0x3f);
        Thread::wait(100);
        Leds.write(0x00);
        Thread::wait(100);
    }

    // Setup SPISlave
    SpiS.format(8, 0);
    SpiS.frequency(SPI_SPEED);

    // RtosTimer
    RtosTimer stepTimer(stepUp, osTimerPeriodic, (void *)0);
    stepTimer.start(250);   // BPM:60
   
    SpiS.reply(0);
    while(1) {
        if(SpiS.receive()) {
            int v = SpiS.read();   // Read byte from master
            Leds.write(v);
            SpiS.reply(step % 16);
        }
    }
}

SPI通信のようす。


MOSI(タクトスイッチの押し下げ状態)


ch1:MOSI ch2:SCK

MISO(カウンタ)


ch1:MISO ch2:SCK

CS


ch1:CS ch2:SCK

Interrupt


ch1:Interrupt ch2:SCK

Arduinoへの外部割込み信号とSPIのSCK信号の間隔は最大5マス程度で変動する。

MISO/MOSI


ch1:MOSI ch2:MISO

SPIのMOSIとMISOは同時にデータを送り合っている。

2016年9月25日日曜日

ベースマシンの音出し動画

プログラムや配線を大幅にいじる予定なので動かなくなったりしたら悲しいので、現状で音出しした動画を作ってみた。



Webカムとライン撮りの方法がよくわからないので、スピーカーから音を出してWebカムのマイクで録音した。

LME49600のヘッドホンアンプを仮のケースに収めてみた。



秋月のポリカーボネート・ケースの大きいバージョンの「大型ポリカーボネート・ケース 140」に入れてみた。



コネクタがフタと干渉するのでやすりで削ってみたが、巨大な電解コンデンサが邪魔をしてちゃんとフタが閉まらない。

ケースへの組み込みは仮組なのでフタは適当にセロテープとかで固定しておくことにする。

特性の測定の準備


自作の可変両電源PCM5102A利用のファンクションジェネレータ、USB Audio I/F+WaveSpectraで測定してみたがAudio I/Fがボロいせいなのか環境ノイズのせいなのかよくわからないので突き詰めた計測はできなさそうだ。

ステップ応答は自作の矩形波だけのファンクションジェネレータとOWONのオシロを使って測定できるかもしれない。

メモ:


基板設計の甘さとかノイズ対策のいい加減さもあるが、TASCAM US-144MKIIのヘッドフォン出力よりかなり低音がタイトな感じがする(音量をあげても低音が気持ちいい)。LME49600 HPAにはUSB A/IFのヘッドホン端子から出してるのだが。

そもそももう10年近く使っているヘッドホンがヘタっててあやしい気がするが、それもまた相性。

クラシックよりEDMの方が聴いてて楽しい(^q^/

Eagleでユニバーサル基板の部品面でジャンパー配線を作図する (メモ)

Bot Thoughts: Eagle Tips: Jumper Wires





ポリウレタン線のはんだ面配線をやめても、まだユニバーサル基板で頑張れそうだ(^q^/

PSoC 4 Prototyping Kitでサーミスタを使ってみる。(LCD表示)

サーミスタ(SEMITEC 103AT)の測定回路をPSoC 4 Prototyping Kitに移植してみた。

UART通信に加えて、キャラクタLCDに値を表示するようにしてみた。

配線図(Pioneer Kit)


配線図(Prototyping Kit)


Github:
https://github.com/ryood/PSoC_4_Thermistor/tree/master/PSoC/PSoC%204%20Pioneer%20Temp%20Meas/PSoC%204%20Prototyping%20Temp%20Meas.cydsn

メモ:


Putty、CPLTではソフトウェアの起動後にPSoC 4 Prototyping KitをUSB接続しないとシリアル通信がうまくいかない。PSoC 4のResetではだめで、USB-Serial BridgeをResetしないとダメなのかも?

Teratermは接続しなおさなくてもシリアル出力を読み取れるようだ。

2016年9月23日金曜日

PSoC 4 Pioneer Kitでサーミスタ(SEMITEC 103AT)を使ってみる。

素子の温度を測りたいのでサーミスタを使ってみた。

以前、I2C出力のHDC1000を使って温度湿度を測定する実験をしてみたが、形状が素子の温度測定には使いにくそうなので(貼りつけられなさそう)、部品箱で眠っていたサーミスタの103ATが使えるかどうか実験してみた。

要件としては

1.素子に貼りつけて、素子の温度を測定できる
2.素子が高温になる場合もあるので100℃ぐらいまでは測定できる
3.1秒ごと程度にサンプリングしてロギングできる
4.手持ちの部品を使ってなるべくお金をかけない

PSoC 4 Pioneer Kit


高機能テスタだと熱電対というセンサーを使って、PCにもロギングできるようだ。(OWON DMM B35など)。

いずれは買うかもしれないとして、なるべくお金をかけないように手持ちの部品で考えてみた。

ロギングで一番楽なのはPCとUART通信すること。UARTでCSV形式のデータを出力できれば、CPLT(http://www.datatecno.co.jp/cplt/cplt-download.htm)を使ってロギングやグラフ化が簡単にできる。

Arduinoがいちばん使い慣れてるが、UART通信しようと思うとArduinoをまるまる使わないといけない。aitendoのあちゃんでいいのは安いけどUART通信には別途それ用の回路が必要。

PSoC 4 Prototyping KitだとUARTも使えるし値段も安いのでPSoC 4を使ってみることにした。

が、Prototyping Kitは何かと実験しにくいのでまずはPioneer Kitでテストしてみた。

TopDesign

PSoCにはThermistorCalcというコンポーネントがあってサーミスタの抵抗値->温度を変換してくれるので使ってみた。ソースをチラ見するとSteinhart-Hart式の定数を生成して計算してくれるマクロのようだ。

Thermitor CalculatorのDATASHEETを見ると、抵抗値によってインスタンスを分割したほうがいいようなことが書いてあるのでlow、mid、highの3つに分けてみた。

D_1のZennerで2.5Vの定電圧源とし(ツェナーは正確な電圧を出力できないので、実際は基準電圧を作るのにTL431を使った)、Opamp_1のボルテージフォロワーで基準電圧の出力を増強。

R_2のサーミスタとR_refで分圧してそれぞれの電位差を差動モードのADCに読み込ませた。

ThermistorCalcのGetResitance()はこういう分圧と測定の仕方で電圧値を与えてサーミスタの抵抗値を算出しているようだ。

配線図


Github:
https://github.com/ryood/PSoC_4_Thermistor

2016年9月22日木曜日

PSoC 4でCharLCD(HD44780)を使う

HD44780互換の普通のキャラクタLCDをPSoC 5LPで使うとPinによって動いたり動かなかったりしたので、PSoC 4でも確認してみた。PSoC 4 Pioneer KitとPSoC 4 Prototyping Kitを持っているので両方試してみた。

PSoCは割と自由にPin配置が決められるが、完全に自由と言うわけではなく機能によって使えるPinが決まっている。

PSoC 4 Pioneer Kit(3000円@秋月)とPSoC 4 Prototyping Kit(600円@秋月)は同じCY8C4245AXI-483を使っている。

CharLCDの割り当て可能なPinは
P0[6:0]
P0[7:1]
P1[6:0]
P1[7:1]
P2[6:0]
P2[7:1]

PSoC 4 Pioneer Kit


配線図


プログラムはPSoC CreatorのExampleの「CharLCD_CustomFont」プロジェクトをベースに、DWRエディターで割り当てるPinを変更しながら実験した。


PSoC 4 Pioneer KitではP1[6]がヘッダに引き出されていないのでPort P1は使えないようだ。

PSoC 4 Prototyping Kit






Prototyping Kitの方はP1[6]もヘッダに引き出されているが、CharLCD用にP1[7:1]を割り当てるとちゃんと表示されなかった。


信号線にLEDがつながっているので何か影響があるのかもしれない。

PSoC 4 Prototyping Kitはまたまた認識されにくくて困った。

Windowsのデバイスマネージャーの「ポート(COMとLPT)」に現れず、「ユニバーサル シリアル バス コントローラー」にあやしいデバイスが表示される場合(プロパティを見ると、製造元がCypressになっている)、Windowsを再起動すると認識されるようだ。←今日の経験則

<追記:2016.09.25>

画像のように、ポートの項にCOMポートが追加されず、ユニバーサル シリアル バス コントローラーの項の囲みのような項目が表示される。

</追記>

Bootloader Hostで書き込む場合Baudが115200になっていないと書き込みに失敗する。

メモ:


PSoC 4ではPort[P1]を避ければCharLCDを使えそうだ。

PSoC 5LPでCharLCDがポートによってちゃんと使えなったのは実験ミスかもしれないしPSoCのバグかもしれない。PSoC 5LPをまた使う機会があれば調べてみたい。

2016年9月21日水曜日

LME49600ヘッドホンアンプ 音出しチェック

iPad3で音出しチェックをしてみた。


ポリウレタン線を使ったジャンパの再考


音出しチェックをする前にもう一度入出力チェックをしてみたが、片チャンネルが出力されなかったりして不安定。絶縁されているべきところがテスタで測定すると数100kΩになったりする。

ICを挿さなくても回路にコンデンサが入っているので特定がなかなか難しい(@@;

ポリウレタン線を使って2層目を配線しているが、これが原因だと思う。

熱を加えたり、ひっかけたりするとポリウレタンの被覆が簡単に破損するので、下に配線しているすずメッキ線と導通したりしなかったりな状態になるのかもしれない。

一旦ジャンパ線をはずしてポリイミドテープで絶縁して配線しなおした。

ポリイミドテープで絶縁しても、真面目に考えるなら導線と導線の間がポリウレタンとポリイミドで絶縁されているので容量成分(キャパシタ)として働いていそうだ。オーディオ回路だとpFレベルは無視しても良さそうだがよくわからない。

はんだ面でのジャンパー配線は、はんだ付けのテクニックが必要なのでユニバーサル基板でも配線しやすくするためにジャンパーの距離をできるだけ短くするように工夫して、部品面側でジャンパー配線した方がいいかもしれない。eagleでそういう配線を作図する方法がわからないので今までしていなかったが、次回は考えてみる。


まあ、ともあれヘッドホンで聴くと今まで作ったヘッドホンアンプの中では一番いい感じだと思います。気分の問題かもしれないですが(^q^;

特性の測定はまたいずれ。

LME49600のデカップリングコンデンサ


LME49600のデカップリングコンデンサを基板に付けた。できるだけICに近いところがいいので変換基板に付けるべきだと思うが、LME49600はGND線がないのでピッチ変換基板にはGND線は引き出せなくて基板設計の時はあきらめていた。

が、変換基板の使っていない側の6~10PinにGND線を引き出せば変換基板上でデカップリングコンデンサをつけられるかもしれない。


メモ:


KESTERのはんだはコネクタのはんだ付けに向いていると思う。ユニバーサル基板で使うとヤニでベタベタになって嫌な感じだが、コネクタに使う場合はスルッとはんだが流れてくれるので楽だし気持ちいい(^q^/

2016年9月19日月曜日

LME49600のヘッドホンアンプ はんだ付け完了


回路図

基板図

DCサーボでDC成分はキャンセルされるので、入力のACカップリングは外した。PCM2704の出力を直結するとちょっと怪しいこともあったが(参考「LME49600とPCM2704基板をつないでみる実験」)これはPCM2704の出力でACカップリングしてなんとか対策する。

PCM2704の直出し以外のDCバイアスのかかっていない音源だとACカップリングするのはもったいない。

また、電源ケーブルのコネクタをターミナル・ブロックをやめて方向が固定されるコネクタにした(共立で売っているAMP製EI)。電源の逆刺しは回避できるのでポリスイッチも除去。

オペアンプとLME49600を外した状態

導通テストした後、入出力の状態をかんたんに見てみたが正常動作しているようだ。導通テストは手持ちのテスタだと0.1Ωまでしか計れないので0.0Ω以上になっていないかチェックした。

ハンダ面

0.6mmφのスズメッキ線と0.6mmφのポリウレタン線で配線。はんだは正月に共立で買った福袋に入っていたKESTER44を使ってみた。いつも使っているGOOTのハンダと比べると濡れがすごい。フラックス除去剤で掃除しておいた方がいいかも?

接続ケーブルを作って音出し&測定する予定。

Github:

2016年9月16日金曜日

ベースマシン パターン切替スイッチをつける構想。

SDカードにパラメータを保存しようと思ってArduinoでSDカードの実験をしてみたが、そもそもシーケンスのパターンが切り替えられない。

いくつかスイッチを並べてパターンの保存、呼び出しをできればいいのだが、4x4のキーパッドを使ったことがあるのでこれを使ってみることを考えた。


32bit/384kHzのDACのPCM5102を使ったファンクションジェネレータを作った時にこのキーパッドは使ったことがあるので(「参考:オーディオ用DACを使ったファンクションジェネレータ」)とりあえずこの方向で考えてみる。

メンブレンで押し心地はあまりよくないが、タクトスイッチをマトリクスで配線すれば同等の機能は実装できる。

メモ:


Nucleoのピンが足りないので、UI制御系と音源のシーケンサーでMPUを分けることを考える。

SPI信号の補強に3-State Bufferの74HC125を使ってみる&ダンピング抵抗

基板どうしの接続に長々と線材を引き回すのでSPI信号を3-State Bufferで強化できるかどうか実験してみた。

回路図

ほんとはSPIのSCK、MOSIの2本、DCO、DCF、DCAそれぞれのCSの3本、DCAのLDAC(MCP4922用のラッチ)で計6本欲しいが、手持ちにある3-State Bufferの74HC125は4回路なので4本だけでテスト。

特に導通を制御する必要はないので、OEは全部直接GNDに落として常時バッファが動作するようにした。

3-Stateバッファでも74HC541という品種が8回路入っているようなので、実際使うときはこちらを使うつもり。

配線図

信号波形


ブレッドボード上で測定した。

バッファなし

ch1: MOSI ch2:SCK

バッファあり

74HC125を入れると波形のリンギングは整形される。が、立ち上がり、立下りはまあまあゆるい感じだ。使っているSPIのモード(MODE0)はクロック(ch2:SCK)の立ち上がりで評価するのでリンギングを低減させられれば精度を上げる効果はあると思う。

ダンピング抵抗


波形のリンギングを低減するのにダンピング抵抗を入れてみた。ちゃんと読んでないが、ダンピング抵抗は出力側近くに入れた方がいいらしいので74HC125から出力する直後に入れてみた。(参考:http://www.elsena.co.jp/elspear/specialist_column/technology_column7.html


信号波形


ダンピング抵抗の値を10Ω、47Ω、100Ω、470Ωに差し替えてSPI信号の波形を測定してみた。DCOにSPI信号を入力する付近で測定。

ダンピング抵抗なし

ダンピング抵抗:10Ω

ダンピング抵抗:47Ω

ダンピング抵抗:100Ω

ダンピング抵抗:470Ω

470Ωでは正常に読み取れないようで音が出なかった。