- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
PAGE
PAGE 7
单片机模拟dds信号发生器
信号发生器原理
信号发生器就是能够产生如正弦信号,三角波信号及锯齿波信号的装置。在模拟电路中可以用运放、电阻和电容来搭建。数字电路中需要DA转换。这里主要讨论数字方式产生信号,并且以正弦信号为列来讲解。
首先,需要一个均匀采样一个正弦周期的数据,通常将这个数据表固化在ROM中,网上有这种软件,可以直接生成数据表。然后,在程序中不断的将这个数据表中的数据顺序送出,就可以产生正弦信号。如图1所示。实际单片机送出的数据为红色的圆点,圆点的包络就是一个正弦信号,当然DAC输出后用低通滤波器滤波后效果会更好。
图1 信号发生器原理示意图
简易信号发生器
根据上面叙述的原理,在设计的时候用定时器给DAC送数据,那么DAC输出的数据就是一个正弦信号。采用定时器2启动DAC0来产生信号。定时器2初始化产生溢出时间为50us(频率为20kHz),也就是说每隔50us会向DAC写入一个数据。由此可以计算出频率最小(当256个点都写入到DAC时,程序中变量step为1)为1/(50us*256)=78.125Hz;最大频率(只有两个点输入DAC中,程序中变量step为127)为10Khz,但是此时输出就是一个方波信号了。而且频率调整的时候只能是78.125Hz的倍数。
简易信号发生器的问题及缺陷
上面简易信号发生器有很多不完善的地方:
= 1 \* GB3 ①、频率范围比较小(78.125Hz~10kHz);
= 2 \* GB3 ②、频率调整只能是78.125Hz的倍数,不能实现连续调整;
= 3 \* GB3 ③、对于有按键输入的系统,不能实现任意频率信号的输出。
为了能增加频率,只能缩短定时器溢出时间,但是不能太小,要保证能大于中断函数中代码执行的时间。为了能进一步减小频率,可以有两种方法:一是延长定时器中断溢出时间;二是在向DAC输出数据的时候,将一个数据重复写入DAC中(可以理解为步进值step为负数)。如果采用第一种方法,那么在频率调整的时候需要调整两个参数,即步进值step和中断初值,这种方法对于精确调整频率是很难实现的,因此,我们需要调整一个参数就能实现频率的精确调整。通常为了计算方便,中断溢出的时间是一定的,调整的参数是步进值step。前面说到,要进一步减小频率,需要进一步减小步进值,但是最小也只能为1,那么如何做到进一步减小步进值呢?这就需要DDS的原理。
DDS原理简单介绍
DDS原理如图2所示。在上面讨论中,希望步进值可以更小,实际上DDS原理就是一种能够使得步进值可以更小的算法。
图2 DDS原理框图
假设时钟为2MHz,数据保持寄存器选择N Bit,在时钟驱动下,累加器输出结果S被反馈到累加器输入端B,B和A的数据被累加到S,下一个时钟脉冲又将S反馈到B,再次与A累加到S,下一个时钟脉冲又将S反馈到B,如此循环累加,实现按步进值,按时钟节拍循环累加,使得N Bit数据被徐循环累加。完成一次地址循环需要的时间由时钟和步进值决定,可以由公式计算:
当晶振(2M)和计数器Bit数N确定之后,fout即与K成正比,对K的调整可以完成对fout的设定,当N足够大时,比例常数可以很小,例如0.01,即fout等于K的0.01倍,这样就可以实现对fout的精细调整,譬如0.01Hz。
单片机编程实现DDS
用单片机模拟DDS的程序其实很简单,主要就是在中断函数中对DAC写数据就可以了,具体程序如下:
void timer2_isr(void) interrupt 5
{
TF2 = 0; //清除中断标志位,定时器2的中断标志位必须用软件清零
counter = counter + step; //累加器累累加
DAC0L=sin_data[(unsigned char)(counter8)];//取出累加器的高8位作为偏移量
DAC0H = sin_data[(unsigned char)(counter8)]8;
}
定时器2配置为16位自动重载方式,初值设定函数如下:
CKCON = 0x78; //将定时器0、1、2、4的时钟选择为系统时钟24M 不分频
T2CON = 0x00; //将定时器2配置为16位自动装载定时模式
TH2 = 0xfe; //装初始值,在24M时钟下,中断时间为15.25uS
TL2 = 0x92; //装初始值
RCAP2H = 0xfe; //重载寄存器高位初始值
RCAP2L = 0x92; //重载寄存器地位初始值
ET2 = 1; //允许定时器2中断
EA = 1; //中断总允许
TR2 = 1; //启动定时器2
下面主要讨论下计算问题:
为了设计简单,在调
原创力文档


文档评论(0)