AVRでR-2RDACを使いサイン波を作るのは随分前に実験だけはしていました。今回、SPテスト用に10Hz~20000Hzまで周波数スイープが出来ないか?ちょっと検討?実験をして見ることにしました。
プログラムはテーブルにサイン波用のデータを用意しそれを読み込み、オーソドックスなものです。CPU clock = 20MHzです。
10Hzは _deleay_us(400)で得ることができましたが、_delay_us(0)にしても、5.5KHzにしかなりません。
サイン波発生はアッセンブラで作らないと駄目なのかも、、、、。周波数可変も_delay_us(xx)を使うのが適切なのか?
また、スイープをどうするべきなのか?、、、どうも沈没しそうですね。
http://akizukidenshi.com/catalog/g/gK-06298/ <---これを使ったほうが良さそうです。
スイープ時の周波数の切り替えポイントはゼクロスで行うと綺麗に切り替わります。
1周期分のデータの総数が10Hzから20KHzまでで何バイトになるか計算して、AVRのフラッシュメモリに収まるならSDカードなどの外部メモリは不要でしょう。
どうも、ヒントを有難うございます。
何れにしろ、私にとっては敷居が高くて乗り越えられそうもありません。
この件ですが、
「PIC AVR 工作室」の「DDSファンクションジェネレータ」が
参考になる気がします。
http://picavr.uunyan.com/avr_m2_dds_fg.html
詳しい解説もありますので、有益です。
時間軸のサンプリング数がどれくらいかわかりませんが、
データから、R2RのI/Oピンをドライブするプログラムステップ数が
多すぎるわけですね。ちょっと計算してみました。
時間軸のサンプル数を1周期、32区間として、1区間あたりの時間は、33μs、
クロックが20Mhzなので、1命令あたり、0.05μs、1デコードに
660ステップも要していることになります。
8ビットのR2Rだとすると、1ビットのデコードに80ステップもかかるのは、ちょっとおかしい。
C言語でも、1ビットあたり、20ステップ(ASMで)くらいで処理が出来そうな気がします。、
ここまで減らせば、20Khzくらいまでの音声周波数になります。
例えば、 テーブルからのデータを、128,64,32と次々に引いて行き、
そのときの正負でI/Oポートを叩いて、これを8回くりかえすとR2Rに値が出る。
このやりかたなら、1ビットあたり20ステップ以下に納まりそうな期待が持てますが。
これだと周波数は飛び飛びになってしまいます。
DDSは、位相アキュムレータの出力でサイン波データを参照する形になります。
このサイトが分かり易いでしょう。http://www.ni.com/white-paper/5516/ja/
To senshuさん
どうもURLのご紹介有難うございます。じっくり読んで見ます。
To がた老AVR研究所さん
どうも計算までしていただき恐縮しております。256個のサイン波のテーブルから+1しています。
この辺のことは、今ひとつ理解が足りませんので、がた老AVR研究所さんの計算を元に検討して見ます。
To ikkeiさん
AVRによるDDSもどきと言うほうがいいのかも知れません。DDSについては浅はかな知識がしかありません。ご紹介のURLで理解を深めたいと思います。どうも有難うございました。
1周期が256もあったら、20Mhzのクロックでは、この程度で精一杯でしょう。
デコードは、ラジオ少年さんの
PORTx = wavetable[k]; が、一発でスマートですね。もちろん、
PORTxのピンが8本連続してとれることが条件ですが。
ikkeiさんの言われるような厳密なことが求められていないら、サンプル点を減らして、
LPFをかけるとかすれば、音声周波数程度なら、AVRでも実用になるような。
因みにサンプル数を+4ずつにすれば22KHzくらいに周波数が伸びます。
しかし、波形の品質は悪くなりますね。何れにしろ、LPFは必要です。
任意の周波数を得るには_delay_us(xx)でxxを変えればいいと思うのですが、スイープさせるとなると(スイープ時間も可変)、、、、このxxを連続可変すれば良さそうに思えますが、果たしてどうなのか?です。
連続可変のスピードを変えれば、スイープ時間の可変もできるのではと。
浅はかな愚考をしております。