AD9834DDSをPICで制御する実験は、一昨年、PIC16F883のMSSPモジュールを使って行いました。
しかし、上手くいかずに中断して、Arduinoでの制御に切り替えて動作させました。
Arduino(あちゃんでいいの)で制御したAD9834DDSを使ったVFOは、7MHz用のアカギスタンダードに搭載して実際の交信に使っています。
今回は、PIC16F628AでAD9834DDSを制御する実験を行い、うまくいきましたので、記事を掲載したいと思います。
今更とも思うのですが、PICを使ったAD0934DDS制御の例はWeb上には少なく、アセンブラで記述された例はほとんど見ません。
参考になったのは、henteko.orgというサイトの「AD9834を使った実験用DDS-VFOの製作」という記事です。
この記事とArduinoでの制御スケッチを見て気づいたのですが、AD9834を制御するSPI信号のシリアルタイミングに問題があって、動かなかったようです。
そこで、再度AD9834DDSの説明書(日本語版)を見ると、シリアルタイミングは次のようになっています。
まず、FSYNCをLOWにしてから、SDATAを有効にして、クロックSCLKの立下りで、DDSにデータが読み込まれます。
次のようなアセンブラプログラム(サブルーチン)を作って試してみました。
D1,D0にDDSに送るデータ(8+8=16ビット)を入れておきます。
SPI_SEND
MOVLW d'16' ;送信ビット数
MOVWF DCNT ;カウンタにセット
BCF SPI_FS ;FSYNC=LOW SPI start
SPI_LOOP
BCF STATUS,C ;Cクリア
RLF D0,F ;左に1ビットシフト
RLF D1,F
BTFSC STATUS,C ;C=0ならスキップSDATA=0
GOTO DATA1 ;C=1ならSDATA=1
BCF SPI_DA
GOTO NEXT
DATA1
BSF SPI_DA
NEXT
BCF SPI_CK ;SCLK=LOW
BSF SPI_CK ;SCLK=HIGH
DECFSZ DCNT ;DCNT=0ならスキップ
GOTO SPI_LOOP
BSF SPI_FS ;FSYNC=HIGH SPI end
RETURN
MOVLW d'16' ;送信ビット数
MOVWF DCNT ;カウンタにセット
BCF SPI_FS ;FSYNC=LOW SPI start
SPI_LOOP
BCF STATUS,C ;Cクリア
RLF D0,F ;左に1ビットシフト
RLF D1,F
BTFSC STATUS,C ;C=0ならスキップSDATA=0
GOTO DATA1 ;C=1ならSDATA=1
BCF SPI_DA
GOTO NEXT
DATA1
BSF SPI_DA
NEXT
BCF SPI_CK ;SCLK=LOW
BSF SPI_CK ;SCLK=HIGH
DECFSZ DCNT ;DCNT=0ならスキップ
GOTO SPI_LOOP
BSF SPI_FS ;FSYNC=HIGH SPI end
RETURN
MPLAB IDEのロジックアナライザでシミュレーションしてみると次のようになります。
一見、説明書の図とは違って見えますが、タイミングは指定どおりです。
PIC16F628Aは、内部クロック4MHzで動作させますので、1サイクルは1usです。従ってSCLKのパルス幅は、1usです。
実験回路の回路図です。
今回は、1MHzを発生させるプログラムを作りました。
ブレッドボードと周波数カウンタの様子です。
これにディスプレイとロータリーエンコーダを加えて、VFOに仕上げてみたいと思っています。