DDS信號發生器采用直接數字頻率合成(Direct Digital Synthesis,簡稱DDS)技術,把信號發生器的頻率穩定度、準確度提高到與基準頻率相同的水平,并且可以在很寬的頻率范圍內進行精細的頻率調節。采用這種方法設計的信號源可工作于調制狀態,可對輸出電平進行調節,也可輸出各種波形。
DDS原理
在介紹DDS信號發生器原理之前我們先了解一下DDS原理。
若對一正弦波形進行采樣,每周期為 m 個采樣點,分別記為 1~m。 對應每次參考時鐘 f c , 輸出一個采樣點,輸出圖中所示的一個周期的正弦,需要 m 個時鐘周期,則輸出的波形頻率為 f a =f c/m。對于這種情況, 每次時鐘到來時,相位累加器加 1 ,則就會在第 i 個時鐘周期輸出 第 i 個采樣點( i = 1~m) ,第 m + 1 個時鐘輸出第 1 個采樣點,以此循壞,這時的相位累加器實 際上是步進為 1 的模 m 計數器。 如果每次時鐘到來時, 總是間隔一個采樣點輸出,即相位累 加器的步進為 2 ,這時在第 i 個周期輸出第 2i 個采樣點,輸出波形如圖 1. 2 的波形 b,顯然波 形 b 的頻率是 a 的 2 倍,即 f b = 2 f a 。
綜上所述,如果相位累加器的步進為 B, 則輸出波形的頻率為 B×f a , f a 是最小的輸 出頻率稱為頻率分辨率或步進間隔, B 為頻率控制字。給定不同的頻率控制字即可輸出不同 的頻率。頻率輸出公式為: f 0 = fc/m* B
在實際設計中,如果累加器長度為N ,則可以有2N 個存儲單元存儲采樣數據,如果我們 對一個周期的波形進行2N 個點的采樣,即m = 2N , 此時輸出頻率f o 和系統時鐘頻率f c ,相 fc f0 = N B 2 位累加器長度N 以及頻率控制字B的關系為: 為了使波形輸出不失真,根據奈奎 斯特定理, B最高為2 N - 1 。另外要提高DDS 的精度,就需要分母越大越好,即采樣點的個數 越多,越接近實際波形。但實際上不可能提供如此之多的存儲空間,這就需要對采樣點進行量 化。如圖1 (c) 所示,如果量化單位為K,則前K 個點的值總是相同的,為采樣值1 ,第二組K 個 采樣點的值為采樣值2 ,以此類推,第i 組K 個采樣點的值為采樣值i , 共需要m/K個存儲單元 來存儲m/K個采樣點。
DDS 的雜散來源之一就是相位累加器相位舍位造成的雜散。現有的頻率控制主要采用 二進制頻率控制原理。這是因為 FPGA 采用二進制的數據處理機制以及波形存儲器的二進 制尋址方式,所以通常情況下 mK、m、K 都是二進制整數,如 m = 2^N ,這就要求對計算結果 進行十進制近似取舍,造成了波形發生器的輸出頻率以及頻率分辨率存在無法消除的誤差。
DDS 以數控振蕩器的方式,產生頻率、相位可控制的正弦,電路包括了基準時鐘源、相位累加器、相位調制器、正弦ROM 查找表、D/A 轉換 器和低通濾波器等。 頻率控制字N 和相位控制字M 分別控制DDS 所輸出的正弦波的頻率和相 位。DDS 系統的核心是相位累加器,它由一個N 位累加器與N 位相位寄存器構成。時鐘脈沖每觸發一次, 累加器便將頻率控制數據與相位寄存器輸出的累加相位數據相加, 然后把相加后的結果送至相位寄存器的數據輸入端。 相位寄存器將累加器在上一個時鐘作用后所產生的新相位數據反饋到累加器的輸入端, 以使加法器在下一個時鐘的作用下繼續與頻率控制數據相加。 這樣, 相位累加器在參考時鐘的作用下將進行線性相位累加, 當相位累加器累加滿時, 就會產生一次溢出, 以完成一個周期性的動作, 這個周期就是DDS 合成信號的一個頻率周期, 相位累加器的溢出頻率就是DDS 輸出的信號頻率。 相位寄存器的輸出與相位控制字相加, 結果作為正弦查找表的地址。 查找表由ROM 構成, 其內部存有一個完整周期正弦波的數字幅度信息, 每個查找表的地址對應正弦波中的一個相位點。 查找表把輸入地址信息映射成正弦波幅度信號, 同時輸出到D/A 轉換器的輸入端, 通過D/A 可將數字量形式的波形幅值轉換成所要求的合成頻率模擬量形式信號。 低通濾波器用于衰減和濾除不需要的取樣分量, 以便輸出頻譜純凈的正弦波信號。
DDS信號發生器原理
DDS信號發生器原理是建立在采樣定理基礎上,首先對需要產生的波形進行采樣,將采樣值數字化后存入存儲器作為查找表,然后通過查表讀取數據,再經D/A轉換器轉換為模擬量,將保存的波形重新合成出來。DDS基本原理框圖如圖所示。
除了濾波器之外,DDS系統都是通過數字集成電路實現的,易于集成和小型化。系統的參考時鐘源通常是一個具有高穩定性的晶體振蕩器,為各組成 部分提供同步時鐘。頻率控制字(FSW)實際上是相位增量值(二進制編碼)作為相位累加器的累加值。相位累加器在每一個參考時鐘脈沖輸入時,累加一次頻率,其輸出相應增加一個步長的相位增量。由于相位累加器的輸出連接在波形存儲器(ROM)的地址線上,因此其輸出的改變就相當于查表。這樣就可以通過查表 把存儲在波形存儲器內的波形抽樣值(二進制編碼)查找出來。ROM的輸出送到D/A轉換器,經D/A轉換器轉換成模擬量輸出。
DDS信號發生器設計
1、方案設計與論證
設計的DDS信號發生器系統以STC89C52芯片為核心控制,通過可編程放大電路實現了正弦波、方波的輸出功能,其頻率步進值和幅度步進值達到了設計要求。
本設計采用直接數字頻率合成。單片機從鍵盤獲得控制信息,控制兩路DDS芯片AD9850產生的兩路設定頻率的正弦波和方波。輸出信號經過調整后輸入AD7524可以在單片機的控制下完成對信號的程控誤差。從DDS模塊輸出的兩路信號經過低通濾波和直流偏置將兩路信號輸入模擬乘法器AD835,一路作為載波,一路作為調制波,從AD835產生調制波。同時可以將DDS信號輸入到CD4046B芯片進行振蕩輸出調頻信號。
整體設計方案:以單片機STC89C52為核心,完成四方面的功能:采用DDS專用芯片AD9850產生正弦波和方波,高帶DA轉換器AD7524控制AM調制度,接收紅外遙控的控制碼,同進LCD液晶顯示所有數據。其系統如圖所示。
2、理論分析、計算與各模塊設計
(1)DDS波形產生電路設計
DDS基本原理:正弦波形一個周期離散樣點的幅值數字量存于ROM(或RAM)中,按一定的地址間隔(相位增量)讀出,由D/A轉換成模擬正弦信號,經過低通濾波,濾除D/A帶來的小臺階和數字電路產生的毛刺,即可獲得所需要的正弦信號。AD9850可以產生正弦波、方波。AD9834內部的相位累加器的字寬為32位,SIN函數表有4096樣點值,因此32位的相位累加器輸出僅截取12位用于查表。其內部原理框圖如下:
AD9850參數:
最高參考時鐘為125MHz,輸出頻率分辨率可達0.0291Hz,允許產生最高輸出頻率62.5MHz。芯片內部提供5bits數字控制相位調制,
AD9850有32位相位累加器,而ROM為14位,將32位累加器的輸出截高位的14位輸入正弦(ROM)查詢表,從查詢表輸出給D/A。D/A的輸出是兩個互補的模擬電流,在12腳處接一個電阻Rset,使滿量程輸出為10~20mA電流,經過濾波器輸出正弦波。
AD9850主要引腳說明:
1、(D0~D7):8bit數據輸入端。用于下載32bit頻率調節字和8bit相位控制字。
2、(W-CLK):字裝載時鐘,用于裝載并行或串行的頻率/相位/控制字
3、(RSET):DAC外接電阻,該電阻決定DAC輸出電流的最大值。對于典型應用(IOUTmax=10mA)時,RSET的值為3.9kΩ,另一端連接到地線。外接電阻RSET與DAC輸出電流 IOUT的關系為
電路原理圖如圖2-2所示:
圖2-2 DDS波形產生電路
(2)程控衰減電路設計
程控衰減電路由D/A轉換芯片AD7524構成,主要利用此D/A芯片的可程控電阻網絡構成基于AD7524構成的程控衰減器,而在其輸出端得到幅度可控的正弦波。由AD7524的8位數據輸入端進行控制,可實現1~1/56級衰減。其相關電路如圖2-3所示:
圖2-3 程控衰減電路
(3)模擬AM電路設計
該電路選用AD835作為乘法器,將載波和調制信號相乘得AM信號,其兩路輸入信號幅值可達到-1V—+1V,對噪聲可形成較強的抑制能力。另外,普通雙邊帶調制需要調制信號疊加直流成分,因此調制信號在輸入到乘法器前需經過電平轉換電路為調制信號疊加適當的直流。由于前級的調制信號是由程控衰減器輸出,所以在程控衰減器初始輸出的情況下,可以通過調節電平轉換電路的直流偏置,使模擬AM電路的初始輸出的調幅波形的調制度調整至1。這樣設置可以為之后的程控調制帶來方便。通過P8的跳線可以選擇調制波為方波,從面實現ASK調制。其電路如圖所示。
圖2-4 AM信號產生電路
(4)模擬FM電路的設計
頻率調頻信號的基本特點是它的瞬時頻率按調制信號規律變化,因而,一種最容易想到的方法是用調制信號直接控制振蕩器的振蕩頻率,使其不失真地反映調制信號的變化。通常將這種直接調變振蕩器頻率的方法稱為直接調頻法。本設計中,使用鎖相環集成電路CD4046內部自帶的VCO產生FM波。通過P10 的跳線可以選擇方波為調制波,從而實現FSK。其電路如5所示。
圖2-5 FM、FSK信號產生電路
(5)控制與顯示電路
輸入控制采用紅外遙控器控制,通過HS0038紅外一體化接收頭解碼、放大,將控制碼發送給單片機,再由單片機控制DDS模塊、程控衰減模塊產生不同的波形。
顯示部分使用128*64點陣寬屏液晶,可以顯示不同模式下的頻率及波形,達到直觀、形象的效果。
此模塊如圖所示:
3、程序設計
主程序流程圖如圖所示
4、代碼
AD9850的驅動程序C文件
#include《intrins.h》
#include “AD9850I.h”
#include “lcd12864.h”
//unsigned char freq[8]; //液晶顯示8種步進頻率值
unsigned char freq[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/********************
函數:AD9850Reset
功能:AD9850的復位函數
********************/
void AD9850Reset(void)
{
AD9850WCLK = 1;
AD9850FQUD = 1;
// AD9850ReSet = 0;
// AD9850ReSet = 1;//復位腳置高電平(10個AD9850的時鐘周期)
// _nop_();_nop_();_nop_();_nop_();_nop_();
// _nop_();_nop_();_nop_();_nop_();_nop_();//延時,其實不用這么長
// AD9850ReSet = 0;//復位完成,再拉低
}
/*步進按鍵函數*/
void f10Mhz(void) //10Mhz步進
{
freq[0]=freq[0]+1;
if(freq[0]》=10)
{
freq[0]=0;
}
display_led();
}
void f1Mhz(void) //1Mhz步進
{
freq[1]=freq[1]+1;
if(freq[1]》=10)
{
freq[1]=0;
}
display_led();
}
void f100Khz(void) //100Khz步進
{
freq[2]=freq[2]+1;
if(freq[2]》=10)
{
freq[2]=0;
}
display_led();
}
void f10Khz(void) //10Khz步進
{
freq[3]=freq[3]+1;
if(freq[3]》=10)
{
freq[3]=0;
}
display_led();
}
void f1Khz(void) //1Khz步進
{
freq[4]=freq[4]+1;
if(freq[4]》=10)
{
freq[4]=0;
}
display_led();
}
void f100Hz(void) //100hz步進
{
freq[5]=freq[5]+1;
if(freq[5]》=10)
{
freq[5]=0;
}
display_led();
}
void f10Hz(void) //10hz步進
{
freq[6]=freq[6]+1;
if(freq[6]》=10)
{
freq[6]=0;
}
display_led();
}
void f1Hz(void) //1hz步進
{
freq[7]=freq[7]+1;
if(freq[7]》=10)
{
freq[7]=0;
}
display_led();
}
/***計算控制字************/
/***入口:頻率數組指針***出口,控制字值*****/
unsigned long jisuan(unsigned char data *fno)//*fno-0》freq[0.。.7]
{
unsigned long dds_no ;
dds_no=
(*(fno+7))*FF0+
(*(fno+6))*FF1+
(*(fno+5))*FF2+
(*(fno+4))*FF3+
(*(fno+3))*FF4+
(*(fno+2))*FF5+
(*(fno+1))*FF6+
(*fno)*FF7 ;
return(dds_no);
}
/********************
**函數:AD9850SetFre
**功能:AD9850設定頻率控制字函數
**參數:Fre,float型,要設定的頻率,單位Hz
********************/
void AD9850ISetFre()
{
unsigned long FTW = 0;//要寫入的32位頻率控制字(AD9850一次需要寫入40位控制字)
unsigned char part1,part2,part3,part4;
FTW=jisuan(freq);
// if(FTW 》 30000000)
// FTW = 30000000;
// FTW = (unsigned long) (Fre * AD9850_125M);//計算頻率控制字(公式:FTW=(2^32/fosc)*Fre)
/*以下將32位頻率控制字分解*/
part1 = (unsigned char) (FTW》》24);//取32~25位
part2 = (unsigned char) (FTW》》16);//取24~17位
part3 = (unsigned char) (FTW》》8); //取16~9位
part4 = (unsigned char) (FTW); //取8~1位
/*以上將32位頻率控制字分解*/
AD9850FQUD = 1;
AD9850WCLK = 1;
AD9850DATAPORT = 0x00;//寄存器最高的八位只送0x00
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part1;
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part2;
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part3;
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part4;
AD9850WCLK = 0;//AD9850WCLK上升沿送數據
_nop_();
AD9850FQUD = 0;//AD9850FQUD上升沿將AD9850緩沖區的40位數據送入DDS Core
}
/********************
**函數:AD9850SetFre
**功能:AD9850設定頻率控制字函數
**參數:Fre,float型,要設定的頻率,單位Hz
********************/
void AD9850IISetFre(float Fre)
{
unsigned long FTW = 0;//要寫入的32位頻率控制字(AD9850一次需要寫入40位控制字)
unsigned char part1,part2,part3,part4;
if(Fre 》 30000000)
Fre = 30000000;
FTW = (unsigned long) (Fre * 34.3597384);//計算頻率控制字(公式:FTW=(2^32/fosc)*Fre)
/*以下將32位頻率控制字分解*/
part1 = (unsigned char) (FTW》》24);//取32~25位
part2 = (unsigned char) (FTW》》16);//取24~17位
part3 = (unsigned char) (FTW》》8); //取16~9位
part4 = (unsigned char) (FTW); //取8~1位
/*以上將32位頻率控制字分解*/
AD9850FQUD = 1;
AD9850WCLK = 1;
AD9850DATAPORT = 0x00;//寄存器最高的八位只送0x00
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part1;
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part2;
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part3;
AD9850WCLK = 0;//WCLK上升沿送數據
_nop_();
AD9850WCLK = 1;
AD9850DATAPORT = part4;
AD9850WCLK = 0;//AD9850WCLK上升沿送數據
_nop_();
AD9850FQUD = 0;//AD9850FQUD上升沿將AD9850緩沖區的40位數據送入DDS Core
}
主程序
#include 《reg52.h》
#include “AD9850I.h”
#include “hs0038.h”
#include “lcd12864.h”
void main()
{
hs0038_init(); //HS0038初始化,使用了外部中斷0///定時器1
lcd12864_init();
AD9850Reset();
while(1)
{
Get_Ircode_And_Dis();
switch (ircode[2])
{ /**************模式選擇****************/
case 0x07:xuanzekey();break;
case 0x15:quedingkey();break;
case 0x09:fanhuikey();break;
/*************頻率調整區***************/
case 0x0c:if(flag1==1) {f10Mhz();}; break;
case 0x18:if(flag1==1) {f1Mhz(); };break;
case 0x5e:if(flag1==1) {f100Khz();};break;
case 0x08:if(flag1==1) {f10Khz(); };break;
case 0x1c:if(flag1==1) {f1Khz(); } ;break;
case 0x5a:if(flag1==1) {f100Hz();} ;break;
case 0x42:if(flag1==1) {f10Hz(); } ;break;
case 0x52:if(flag1==1) {f1Hz(); } ;break;
/***************頻率確認***************/
case 0x4a: if(flag1==1)
{
pce1=0;
pce2=1;
pce3=1;
AD9850ISetFre();
};
break;
/***************AM調制*********************/
case 0x16: pce1=1; //片選AD9850 I 實驗板U1
pce2=0; //片選AD9850 I 實驗板U2
pce3=1;
AD9850IISetFre(1000.0);break;
case 0x44:if(flag2==1)
{
pce1=1;
pce2=1;
pce3=0;
pwr=0;
AM_mastepdown();
};
break;
case 0x40: if(flag2==1)
{
pce1=1;
pce2=1;
pce3=0;
pwr=0;
AM_mastepup();
};
break;
/***************FM調制*********************/
case 0x19:AD9850IISetFre(5000.0);break;
default:break;
}
ircode[2]=0; //注意一定要把ircode[2]清零。。。。。
// AD9850SetFre();
}
}
?
由表可以看出,此DDS信號發生器設計方案在頻率穩定度方面,正弦波、三角波、方波在帶負載的情況下均十分穩定,這正是DDS專用芯片AD9834的特點。
評論
查看更多