写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる

 

それはさておき、

 

このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。

 

変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。

 

まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。

 

フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。

 

半田吸い取り線で、余分な半田を吸い取って、出来上がり。

 

慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。

 

このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。

 

今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。

mbed AD9834 DDS FSKの実験

投稿日 2011/07/17

アナログデバイセズ(AD)のDDS AD9834でFSK(Frequency Shift Keying)の実験をしてみました。

 

(単一周波数の発生は、mbed AD9834 DDSで投稿しました。)

 

FSKは二つの周波数で論理1と0を表現して通信を行う、デジタル変調方式の一種です。

 

アマチュア無線のFSKは170Hz離れた周波数を用います。たとえば7MHzの場合、7.030000MHzと7.030170Mhzといった具合です。

 

AD9834は周波数レジスタ(位相アキュムレータ)を2つ持っており、異なる周波数を設定して、瞬時に切り替えて発生させることが可能ですから、FSKのような用途にはうってつけです。しかも使用周波数を直接発振させることができます。

 

実験はAD9834の出力に適当な長さのワイヤをつなぎ、無線機に近づけておいて適度な強さで受信させます。

 

FSKを復調できるソフトをパソコンで実行し、無線機のAF出力につないでおきます。今回は復調ソフトとしてJE3HHT氏のMMVariを使用させていただきました。

 

mbed側のプログラムは簡単で、AD9834の2つの周波数レジスタに7.030000MHzと7.030170MHzをセットしておき、FSELECTをボーレートに準じた速さで文字コードに応じて切り替えます。

 

文字列はテレタイプのテスト用で有名な、

 

"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890"

 

を、繰り返し送信します。

mbed_AD9834_dds_FSK画面.jpg

MMvariの画面


 

文字コードは5単位のBAUDOTを使いますが、各文字コードの先頭がスペースの0、最後がストップビットの1が付加されるため7ビット/文字となります。

 

たとえば文字AのBAUDOTコードは11000ですが、先頭のスタートビット0と最後のストップビット1がついて
0110001となり、16進で表記すると0x31となります。

 

速度は45.45ボーとしました。1ビット当たり22mSで送りますが、ストップビットのみ1.5倍の33mSとします。

 

BAUDOTは5ビットなのでシフトコード(Figure/Letter)を用いてアルファベットと記号数字を切り替えて使います。RTTYのソフトはUOS(アンシフトオンスペース)が働き、文字のスペースのあとLetterモードに戻るので、スペースの後、記号数字する場合はFigureを出す必要があります。

 

MMVariの設定はRTTY-L 45.45ボーに設定し、周波数を合わせます。

 

受信画面に上記文字列が表示されれば成功です。

 

受信音は、アマチュア無線ではおなじみのピロピロピロとなります。

 

AD9834は位相制御もできるので位相変調のBPSKも試してみたいと思います。

mbed_AD9834_dds_FSK_kairozu.jpg

回路図

 

以下はプログラムのソースコードです。

 

/*FSK with A9834 by MLabo 2011/07/17*/
#include "mbed.h"
#include "TextLCD.h"

 

TextLCD lcd(p24, p26, p27, p28, p29, p30); //StarBoard Orenge
DigitalOut FSELECT(p17);
DigitalOut FSYNC(p18);
DigitalOut SCLK(p19);
DigitalOut SDATA(p20);

 

void serial_out(uint16_t data) {
 mbed AD9834 DDS参照
}

 

int main() {
float SetFreq;
uint32_t temp, freqdata;
uint16_t Uptemp, Lowtemp;
char l[63];

 

SCLK = 1;
SDATA = 0;
FSYNC = 1;
FSELECT = 0;

lcd.cls();
lcd.locate(0,0);
lcd.printf("FSK With AD9834" );

l[0] = 0x01; //BLNK
l[1] = 0x01; //BLNK
l[2] = 0x01; //BLNK
l[3] = 0x03; //T
l[4] = 0x0B; //H
l[5] = 0x21; //E
l[6] = 0x09; //SP
l[7] = 0x3B; //Q
l[8] = 0x39; //U
l[9] = 0x19; //I
l[10] = 0x1D; //C
l[11] = 0x3D; //K
l[12] = 0x09; //SP
l[13] = 0x27; //B
l[14] = 0x15; //R
l[15] = 0x07; //O
l[16] = 0x33; //W
l[17] = 0x0D; //N
l[18] = 0x09; //SP
l[19] = 0x2D; //F
l[20] = 0x07; //O
l[21] = 0x2F; //X
l[22] = 0x09; //SP
l[23] = 0x35; //J
l[24] = 0x39; //U
l[25] = 0x0F; //M
l[26] = 0x1B; //P
l[27] = 0x29; //S
l[28] = 0x09; //SP
l[29] = 0x07; //O
l[30] = 0x1F; //V
l[31] = 0x21; //E
l[32] = 0x15; //R
l[33] = 0x09; //SP
l[34] = 0x03; //T
l[35] = 0x0B; //H
l[36] = 0x21; //E
l[37] = 0x09; //SP
l[38] = 0x13; //L
l[39] = 0x31; //A
l[40] = 0x23; //Z
l[41] = 0x2B; //Y
l[42] = 0x09; //SP
l[43] = 0x25; //D
l[44] = 0x07; //O
l[45] = 0x17; //G
l[46] = 0x37; //Figures
l[47] = 0x0F; //.
l[48] = 0x09; //SP
l[49] = 0x37; //Figures
l[50] = 0x3B; //1
l[51] = 0x33; //2
l[52] = 0x21; //3
l[53] = 0x15; //4
l[54] = 0x03; //5
l[55] = 0x2B; //6
l[56] = 0x39; //7
l[57] = 0x19; //8
l[58] = 0x07; //9
l[59] = 0x1B; //0
l[60] = 0x05; //CR
l[61] = 0x11; //LF
l[62] = 0x3F; //Letter

freqdata = 7030000; //Space
SetFreq = 5.592405 * (uint32_t)freqdata;
temp = (uint32_t)SetFreq;
Lowtemp = (uint16_t)(temp & 0x3FFF);
Uptemp = (uint16_t)((temp/16384) & 0x3FFF); 
serial_out(0x2228);
serial_out(Lowtemp + 0x4000);
serial_out(Uptemp + 0x4000);

freqdata = 7030170; //Mark
SetFreq = 5.592405 * (uint32_t)freqdata;
temp = (uint32_t)SetFreq;
Lowtemp = (uint16_t)(temp & 0x3FFF);
Uptemp = (uint16_t)((temp/16384) & 0x3FFF); 
serial_out(0x2A28);
serial_out(Lowtemp + 0x8000);
serial_out(Uptemp + 0x8000);

while(1){
for(int i = 0; i < 64; i++){
for(int j = 0; j < 7; j++){

if((l[i] << j + 1) & 0x80) FSELECT = 1; else FSELECT = 0;
if(j != 6) wait_ms(22); else wait_ms(33);

}

wait_ms(1000); 

}

 

参考:JH1BIH 相原 實著 PSK31・RTTY入門 CQ出版社



 

(JF1VRR)

コメント(5)

  • 144mhz帯でのメッセージ送受信【FSK信号】はどうしたらよい物でしょうか、おわかりでしたらヒントくださlql*8*2 ] 2012/10/16(火) 午後 0:43

  • lql*8*2さん、周波数が高くなっても原理は同じです。ただ144MHzともなれば上で使用したAD9834は使えず、AD9953あたりが候補と思います。AD9834は周波数レジスタを2つ持っていましたが、AD9953には無く、代わりに波形発生用のRAMを持っており、このRAMに170Hz差のデータをセットしておき、ダイレクトスイッチモードで切り替えてFSKを発生させることになると思います。つまりプログラミングがちょっと違います。受信は、144MHzの受信機のオーディオ出力をPCに入力し、MMVari等の復調ソフトで復調するのは同じです。AD9853が入手できたら試してみたいと思います。(JF1VRR) 2012/10/16(火) 午後 3:50

  • はじめまして。RTTYの送信プログラムを作ろうと思って調べておりましたところ、ここへたどり着きました。上記プログラムについてですが、下から7行目のif((l[i] << j + 1) & 0x80) FSELECT = 1; else FSELECT = 0; のところのif文がどういう動作をするのかいまひとつイメージがわかず理解できていません・・。*周波数レジスタ0/1の切り替えということは分かりますが、どういう条件分岐なのでしょうか?大変恐れ入りますが、ご説明をお願いします。jn4jgk/3 ] 2013/2/14(木) 午前 0:02

  • in4igk/3さん、ご訪問有難うございます。ご質問の件ですが、l[i]の配列には文字コードのビットパターンが格納されています。それをj+1回左にシフトし、左端に持ってきて、0x80でマスクをとり、そのビットが1か0かで、予めDDSにセットしてあるFREQ0の周波数か、FREQ1の周波数を出力するため、それをFSELECTで選択しています。たとえば文字Aの場合、文字コードは0x31なので、ビットパターンは00110001です。jは0から6まで変化するので、まずJ=0 +1で1ビット左にシフト(<<)され、01100010となり、それと0x1000000とアンドをとり左端のビットのみが残ります。それが0ならIF文はFALSEでFSELECT=0が、1ならTRUEとなってFSELECT=1を実行します。
    FSELECTで選択されるFREQ0と1には170Hz離れた周波数がセットされており、文字コードのビットが0なら下、1なら上の周波数を出力している訳です。これを無線機で聴くと、おなじみのピロピロという音に聞こえるわけです。(JF1VRR) 
    2013/2/14(木) 午前 2:30

  • 早々のお返事ありがとうございます。理解できました!if文が省略形だったのと0x80が何を意味しているのかが分からなかったため理解できていませんでした。シフト演算と0x80によるマスク操作、非常にうまくできた仕組みだと、目からウロコです。詳しいご説明ありがとうございます、参考にさせていただきます!jn4jgk/3 ] 2013/2/14(木) 午後 10:09