miniDDSと疑似正弦波発生器               TOPページへもどる

 miniDDS(Direct Digital Synthsis)・・・正弦波、鋸波、三角波、矩形波  2007.03.21
 疑似正弦波発生器 2007.02.04  


 miniDDS(Direct Digital Synthsis)
 これはオリジナルでなくjesperhさんがWebに発表されたものを、さらにすんさんに教えていただいて完成したというものです。Tiny2313と抵抗だけで作ることができ、 10kHzまでの正弦波、のこぎり波、三角波、矩形波を作り出せるという立派なものです。低周波回路(オーディオ回路)の実験をするときに便利な信号発生器です。 トラ技2007.4のオペアンプの実験では2台のPCを用いて1台で信号を発生していますが、このminiDDSを使うと1台のPCで実験が可能になります。
 掲示板で正弦波発生器の話をしているとChuckさんからJesper's AVR pages - MiniDDSがあることを 教えていただきました。これをすんさんが解析・研究されて、私の正弦波発生器に移植できるものを試作されました。 改良されたコントローラを含めて、余りにも素晴らしいので、多くの方に体験していただこうとすんさんに提案しましたところ、R2Rラダーのハードに付いてはこちらで UPしてはどうかといわれここに登場した次第です。tinyへのアセンブルプログラムの変更やコンパイルの方法まですべてすんさんに教えてもらっています(多謝)。


ハードウエアは原作とほとんど変わりません。

デバイスは新しいTinyとしました(秋月で安く買えます)。水晶は入手性のよい12MHzです。ラダー抵抗は手持ちに沢山の10kがありましたので 使いましたが原作と同じ値になりました。抵抗値のばらつきには無頓着で使っています。
コントローラ(波の形、周波数を変更する)からの信号はCOMポート経由で受けますので、COMポートの接続を考えねばなりません。私はCP2102を使ったUSB-シリアル変換 回路で正論理のTTLレベルにしたものを使っていますのでTXDとRXDにそのままつないでいます。COMポートから直接取るなら、原作のようにシリアル-TTLの変換ICを使うか、 または ChaNさんの簡易回路を用意する必要があります。(私がUSBを使うのは、COMポートはプログラマに使用しているからです。)

ファームウエアはすんさんに教えていただいて変更したところがあります。  オリジナルからの変更を整理しますと、
まず、Jesper's pageからDownload ASM-codeでアセンブリコードをエディタに読み込みます。
インクルードファイル を #include <avr/io.h> に変更します。
レジスタ名を次のように変更します。
  USR→UCSRA
  UCR→UCSRB
  UBRR→UBRRL
次は命令の変更で、in を lds に変更します。
また、out を sts にします。
ただし、LOOP中の out だけは out _SFR_IO_ADDR(PORTB),r0 ; 1 とします。(stsは2cycle、outだと1cycle)
ボーレートを9600bpsの指定値にします。12MHzでは0x4D(10進77)をUBRRLにセットします。

アセンブルは、AVR Studio4の新規を作って(Initial file不要)、Custom OptionsのLinker Optionsの設定で、
-nostdlib
を追加します。
これでアセンブルは完成です。buidするとhexファイルができるでしょう。

GNUライセンスのもとで、変更・再配布が可能なようですので、変更したソースファイルおよび関係ファイルを おきますが、オリジナルからご自分で変更されるのがよりおもしろいと思います。

制御ソフト Windows側の波形・周波数などを変更するコントロールソフトウエアは すんさんのAVR用コントロールソフトが 素晴らしいできばえです。了解を得てここに実行ファイルを置きますが、使用法などを含めて是非、 すんさんのページを訪ねてください。

これを起動して、水晶周波数を12000000Hzに設定して「セットボタン」を押します。また、LOOPサイクル数は"9"を指定します。COMポートの番号を自分のPCにあわせて、 PCのボーレートを9600bpsにするとともに、ポーレート窓の値を9600にします。
これで自在に波形と周波数を設定できます。10kHzまでは極めてきれいな波形だと思います。多少の変形を許せば50kHzも実用になるでしょう。


後記: 冒頭にも書きましたが、私のように低周波発振器を持たないアマチュアには素晴らしいものだと思います。オリジナルのアセンブルリストだけでは 作成が困難だったので教えていただきながら「誰もが作成できる形」を求めて書いてみました。PCとの通信がありますので、超初心者の方には難しい点があるかもしれ ませんが作る価値はあると思います。ここまでのところはブレッドボードで実験しています。基板に完成したら写真を載せましょう。
私のお師匠さんのページもご覧になってください。DAC ICを使ったものを研究しておられます。

(2007.03.24) 90S2313の手持ちがほとんどなくなって、また秋月でTiny2313が安く手に入る用になりましたから、tinyで進めましたが、90S2313 のリクエストがありましたので実験しました。結果的には上記変更点の通信に関する設定をオリジナルのままにすれば良いことになります。
  USR、UCR、UBRR 
をそのまま残します。(他の部分はすべて変更します)
ここに関係のファイルを置きます。なお、またまた「すん」さんのお世話になりました。そのうえ、実験上のケアレスミスでご迷惑をかけました。


 疑似正弦波発生器
 上記のminiDDSが完成すると陰の薄い作品ですが、上記を知る前のオリジナルな作品ですから、消さないでここに置きます。
 TI MSP430のDA変換でディジタルサイン値から正弦波を生成することを体験しました。ところが、メモリの制限とDA変換の速度から、1周期を50分割した程度の 間隔の荒いサインウエーブを作るにとどまりました。DA変換を調べてみるとはしご型抵抗による変換=R-2Rラダー回路=が簡単にできることがわかりましたので スピードの速いAVRで試作することにしました。

はじめは、TINY2313を使って、10ビットで試作しましたが、8ビットでもそれなりの波形に見えるので処理の簡単な8ビットに変更し、SRAMに余裕がある mega48に変更しました。 なお、抵抗は以前デジットで購入した1.5kのチップ抵抗(500個ほど入って\100)を使いました。

周波数の変更は、割り込みタイマーで出力の遅延を調整して行おうと考えましたが、タイマー割り込みのオーバーヘッドがかなり大きいようで高い周波数が得られな かった(1.2kHz位)ので、単に遅延ループを回して時間軸の引き延ばしをしています。ループの中でsin()の計算を一つさせると、たまたま適当な時間になりましたから 使っています。
サイン値はプログラム内で計算をさせてみました。math.hをインクルードしてもコンパイルができません。MSP430の時も同じことが起こりコンパイル時にlibm.cもリンク されるように-lmオプションが必要だと教えられました。今回、akibowさんのlibc和訳 を見ますとFAQのNo.2にその旨が明記されていました。
これにしたがって、makefileを眺めますと、
「# Floating point printf version (requires MATH_LIB = -lm below)」
とありましたから、次の行の最後に -lm を追加しましたところ無事コンパイルできました。

最終的には、サイン値はすんさんのまねをして数値で書き込んであります。分割数は正弦波の周波数がある程度伸びるところを考えて192分割としていますが、  sin(2*3.1415*n/192)*100+150
をexcelで計算し列行変換で横並びのデータをテキストエディタさくらにコピーして、タブをカンマに置き換えてプログラムに定数として書き込みました。
この計算では、maxが250、minが50になりますが、後段のオペアンプが入力0近くでクリップするようなので下駄を履かせています。

周波数の変更(delay時間)をPCから通信で行うことを考えましたので回路図は次のようになりました。


工作結果です。集合抵抗は、3個または2個半田付けしたものをエポキシ接着剤ではがきに貼り付けて一体としたものを配線しています。

LM358は後で取り外しやすい用に、2本脚しか基板に半田付けしていません。また、コネクタのピンは真鍮の針金を両面基板に半田付けしてあるだけです。1本ずつ バラバラですから簡単に取り外せます。専門の方には叱られそうなことですが、遊びでは結構動いてくれます。コネクタの接続は自分が忘れますのでここに書いておくこと にしました。

プログラムはとりあえず、こんなものです。

最高の周波数はおよそ5kHzで、低い方はいくらでも、ですが変更領域の入力も関係して15Hzにしました。tera termを起動して、cp2102のusb-シリアルの自作変換 ケーブルで mcuのRXDに割り込みで3桁の数値を送ります。0〜9以外の文字を送っても受け取って迷走しますから、注意のいるプログラムです。3桁の区切りがわからなくなると困ります ので、3桁の入力中はLEDが消え、入力が終わると点くようにしてあります。間違えたら、数値キーを1つずつ押しながらLEDが点いたら、改めて正しい数値を送ればよいこと になります。(自分の考えたことを忘れるのでメモしています)

3桁の周波数決定数(ディレイ時間)の関係は実測の結果次のようになりました。
             ディレイカウントと周波数
    delay  f           delay  f           delay  f
   --------------------------------------------------
    001  5470          013  1010          110   133
    002  4003          014   946          147   100
    003  3154          017   794          160    92
    004  2602          020   685          220    67
    005  2215          028   501          320    46
    006  1927          035   405          440    34
    007  1706          040   357          640    23
    008  1531          056   258          999    15
    009  1388          073   199
    010  1269          080   182
この関係をグラフにしたものがこれです。


最高の周波数を(古典的オシロで)みたものです。

実画面では点線に見えるのですが、写真に撮ると(スローシャッター)繋がって見えます。また、よく見ると1周期に6回の規則的な乱れがありますが、オペアンプ を通る前は規則的なひげになっています。いろいろ考えましたが原因は不明です。最初、プログラムで計算した数値が乱れているのかと思い、エクセルで定数を計算 したのもこれを確認するのが目的でした。

ラダーとオペアンプの間に1500pFのコンデンサをGND間に入れてローパスフィルターとするとなめらかなきれいな映像になります。


あとがき:正弦波の発振器が必要なわけではないのですが、30数年昔に、真空管アンプを作っていた頃に発振器がほしくてトランジスタを使ったものを作ろうと しましたが、特定の周波数を除いて安定に発振するものを作ることができませんでした。そんなこともあって、サインウエーブにはずっと妙な関係があったのかもしれ ません。オシロスコープにその波形を見たときは懐かしい感じがしました。

今回も、書いてしまうと簡単なことですが、はじめて勉強すること、勉強し直すことが沢山あって思いのほか時間がかかりました。寝床に入っても、風呂に浸かっていても 何度もあれこれ考えたものです。




TOPページへもどる


inserted by FC2 system