昨日の投稿で、DAC搭載STM32が少ないので自分でつけるべくアキバへ行った件の続報.
秋月でPT8211を買いました.
↓weactのSTM32F401基板に取り付けました.動きました.
少してこづったので要点を書いときます.
まずclk構成です.
STM32F401のclkは84MHz
I2Sの内部で分周してサンプリングclk 8kHzをつくります(Master Mode)
I2SはLRCK=8kHzを出力します
DATAは16bitです(LRだから32bit)
BCKは8x32=256kHz
気分が悪いことの1つを先に書いときますと、I2Sが生成するFsの選択肢はこれだけです.中間値は選択できません.
ならばSlave Modeを使えばいいと思うでしょうけど、SlaveだとBCKとLRCK=BCK/32を与えなくてはいけないので、外部clkでI2Sを動かしたければ外部にFPGAでも搭載して÷32までせにゃいけません.楽したいからSTM32を使うのにわざわざFPGAを載せたりするかフツー?
こうゆうclk系の不都合って出鼻を挫かれるのですごく嫌いなんです、わたしは.
一番遅い8kHzで動かすことにします.
ーーーー
それではSTM32CubeMXの設定をば.
↓キモの部分は赤線のところでしょう.
clock pol.は効いてるのか効いてないのかよくわかりません.というか何が変わったのか分かりません.
ーーーー
↓8kHzに間に合わせてI2Sを動かすにはDMAが必須です.I2SにDMAを紐づけときます.
bufferはCircularです.16bitなのでHalf Wordです.
codeへ.
まずデータ準備.
PT8211は2の補数の16bitです.実験ですので何も考えずにベタ並べしときます.
偶数番目がLch、奇数番目がRchということ.(逆かもw)
int16_t DACbuf[26];
DACbuf[0] = -30000; DACbuf[1] = 30000;
DACbuf[2] = -25000; DACbuf[3] = 25000;
DACbuf[4] = -20000; DACbuf[5] = 20000;
DACbuf[6] = -15000; DACbuf[7] = 15000;
DACbuf[8] = -10000; DACbuf[9] = 10000;
DACbuf[10] = -5000; DACbuf[11] = 5000;
DACbuf[12] = 0; DACbuf[13] = 0;
DACbuf[14] = 5000; DACbuf[15] = -5000;
DACbuf[16] = 10000; DACbuf[17] = -10000;
DACbuf[18] = 15000; DACbuf[19] = -15000;
DACbuf[20] = 20000; DACbuf[21] = -20000;
DACbuf[22] = 25000; DACbuf[23] = -25000;
DACbuf[24] = 30000; DACbuf[25] = -30000;
DMA関連
main()の始まりの方でDMAを起動.26wordを送信させるおまじない.
HAL_I2S_Transmit_DMA( &hi2s3, DACbuf, 26);
DMAのcallback関数、何処かで_weak宣言されているので自作関数で上書きする.DMA送信完了したらすぐさま次のDMAを起動している.
void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s){
HAL_I2S_Transmit_DMA( &hi2s3, DACbuf, 26);
追記:bufferがcircularなので↑このDMA都度起動はしなくても良いかもしれない.
以上で、こんな波形がでるというわけ.
続きます.
続きはADCとの連携動作.
ーーーーーーーー
DACはI2Sが生成するFsで動きました.
でも、これでおしまいじゃないです.
最終的には、ADC→信号処理→DAC のように信号を流したいわけです.つまり、ADCとDACが同じclkで動かなくちゃいけません.
でも、I2Sは勝手に動きます.
ADCはI2Sとは別の動きをします. ←こいつら同期しないじゃん! fuckでしょこんなの
ADCとI2Sをどうやって同期させるか?
↓無理やりですがこうすれば同期できると思います.
I2Sの分周器の分周比と、TIM1の分周比を同じにすればADC系列とI2S系列を同期できるという理屈です.
84MHz→8kHzを作るのですから分周比=10500だと予想できます.
しかし、この分周比が10500じゃないんですよ.
精密に実測したところ、分周比は10495でした.厳密に8kHzじゃないんです.8003Hzとかそんななの.I2Sの内部回路なにやってんの? イミフすぎて腰が抜けるんだが....
ともあれ10495というmagic numberが判明したのですから、TIM1の分周比も同じくします.この操作によって、全処理系のclkが同期しました.
続きます.
あでゅ~
0 件のコメント:
コメントを投稿