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的特点。
评论
查看更多