SyntaxHigh

Thursday, May 15, 2014

ローパスフィルタとSPI

TLC5940 の SOUT のタイミングが早過ぎるので、ローパスフィルタを入れたのだけど、ローパスフィルタを強くしすぎた。1kΩから 330Ωに変更。 rise time が 668nsec ->375 nsec になった。

1kΩ+22pF

330Ω+22pF

SPI の設定は 1/16 で動かしている。これ以上速くする必要はない(そこまで長い伝送線に対応できない)ので、この設定になる。

SOUTのタイミングについては仕様上こうなっているのか、未だによくわからないが、SPIのクロックタイミングを見る限りこうしないと動かない。

void setSPI(void)
{
  // naosu
  //SPSR = _BV(SPI2X); // double speed (f_osc / 2)
  SPCR = _BV(SPE)    // enable SPI
    | _BV(SPR0) // 1/4
    //| _BV(SPR1) // 1/4
    | _BV(MSTR);  // master mode
}

次の図で、上が一つ目のTLC5940 のSOUT,下がSCLK。TLC5940 の二段目は、SOUTの"0"のデータを、真ん中のy軸のタイミングで読むことになっているのだけど、ローパスフィルタ無しではほぼ同じタイミングで立ち上がってしまい、"1"なのか"0"なのかタイミングが怪しくなってしまう。48MHzのオシロでは違いがわからないくらいのdelayしかない。

ローパスフィルタで遅らせるのだけど, rise time を遅くし過ぎるとデータが正しく送れない。


SIN に 1010101010 を送ってみた場合

赤の縦線が、データが送られるタイミング。このタイミングだと、SOUT が次の値になる前に SCLK がはいっていることがわかる。ただ、本来ならきっちり半クロック遅らせるのが理想的だと思われる。ローパスフィルタによって信号が鈍るので、ノイズに弱くなってしまうかもしれない。

SPI を二倍にして 1/8 の分周比でうごかすと

やはり少し信号が遅くなる.  一回のアップデートで送るデータは TLC5940 の個数 *24 byte、10個の場合はたったの 240byte になる。一秒に30回更新するとしても 7.2kbyte なので、分周比 1/16 ならば十分だ。


シリアルの速度は 256k (BAUD) で、分周比 1/16 の時 1MHz なので、SPI がかなり速い。シリアルを早くしても結局データの量が多すぎれば損失が起こる。

速度を測ったところ、シリアルでかかる時間のほうが大きいので、SPIは遅くても構わない。分周比はシリアルとほぼ同じ 1/64 (250kHz) に設定した。これでシリアルで 240byte 送って SPI 送出して PC に帰ってくるまでに 20msec ほど。SPIを早くしても 数ミリ秒早くなるだけなので、この設定でいこう。

1/64 分周比の波形。上が二段目のSINで、下がSCLK
これならばなんとか。
しかし、TLC5940のSOUTのタイミングはバグとしか思えない。。。何か僕が勘違いしているのだろうか。