当前位置:   article > 正文

CASE_05 基于FPGA的DDS信号发生器_dds信号发生器 fpga

dds信号发生器 fpga

         该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源。

目录

1 简介

2 DDS原理与方案

2.1 方案一:基于CORDIC算法实现

2.2 方案二:基于ROM查找表的实现方式

3 DDS信号发生器的模块设计

 3.1 按键消抖模块

3.2 波形选择模块

3.2.1 波形选择模块代码

3.3 频率调整模块

3.3.1 频率调整模块代码

3.4  显示数值分解模块

数码管译码与动态扫描模块

 3.6 DDS波形合成模块

 4 DDS信号发生器的系统设计

4.1 DDS信号发生器顶层设计代码

 4.2 DDS信号发生器系统模块框图

5 硬件设计

 5.1 电源接口电路设计

5.2 电源系统设计

5.3 时钟设计

5.4 JTAG端口和FPGA配置电路设计

5.5  FPGA芯片的电源引脚

5.6 数码管电流扩展电路

5.7 数码管电路

5.8 复位电路

 5.9 指示灯显示电路

5.10 蜂鸣器电路

5.11 按键控制电路

6 实物验证

 6.1 管脚分配

6.2  实物验证

资料合集包传送门:


1 简介

        DDS信号发生器采用直接数字频率合成(Direct Digital Synthesis,简称DDS)技术,把信号发生器的频率稳定度、准确度提高到与基准频率相同的水平,并且可以在很宽的频率范围内进行精细的频率调节。采用这种方法设计的信号源可工作于调制状态,可对输出电平进行调节,也可输出各种波形。

2 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

                        

2.1 方案一:基于CORDIC算法实现

        J. Volder于1959年提出了一种快速算法,称之为CORDIC(COordinate Rotation DIgital Computer) 算法,这个算法只利用移位和加减运算,就能计算常用三角函数值,如Sin,Cos,Sinh,Cosh等函数。 J. Walther在1974年在这种算法的基础上进一步改进,使其可以计算出多种超越函数,更大的扩展了Cordic 算法的应用。因为Cordic 算法只用了移位和加法,很容易用纯硬件来实现,因此常能在FPGA运算平台上见到它的身影。

        可以通过该算法来产生波形所需要的采样点值,例如产生正弦波,可以使用CORDIC算法去计算sin函数,以此来达到合成波形的目的,不过这种方式所能产生的波形种类有限。(更多关于CORDIC的算法,大家可以关注工作室后续的课程)

2.2 方案二:基于ROM查找表的实现方式

        使用工具将预定好的波形的一个周期采样量化的数值存储到一个ROM里边,然后根据相位计数器产生的ROM地址(即相位)去读出存储在ROM的波形的数值,送往DAC即可完成波形的合成,通过改变相位计数器的大小即可控制输出波形的频率。此种方式较为常用,本文将按照此种方式进行DDS信号发生器的设计,设计参数如下:

       DAC型号:8-Bit, 100 MSPS+ TxDAC® D/A Converter  AD9708 ,最高转换速率125MSPS,该ADC在单端信号输入的DAC中转换速率已经很高,当然考虑到成本问题,没有使用速度更高的DAC,设计时将转换频率设置在100MSPS的转换速率上。

       数据波形统一采用:8-Bit, 每个周期64点的数据进行存储。(为了兼顾高频率的波形合成,受DAC转换速率的限制,采样点数不易过多,但是在低频段1hz时,波形效果在数字示波器上可以看出一个个采样点属于正常现象)

       波形合成频率:1hz – 1Mhz  精度1hz 波形频率越高时,合成频率变化不明显,受参考频率影响。

       合成波形种类:正弦波、方波、三角波、锯齿波,也可通过修改ROM数据进行合成。

3 DDS信号发生器的模块设计

         DDS信号发生波形设计框图如图所示,设计总共包含了6个模块,分别为按键消抖模块、频率调整模块、波形选择模块、数值分解模块、DDS波形合成模块、数码管译码模块。

 3.1 按键消抖模块

        按键消抖:通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。(摘自:百度百科)

        为什么要进行消抖呢?

        在不同的使用场景下,原因不同,总结一句解释消除抖动带来的不利影响;例如:弱电按钮控制强电开关,若不进行消抖,强电开关在闭合时反复抖动,引起高压电拉电弧,容易引发危险。

        按键抖动通常存在两种形式,第一种为高电平有效的,如图所示:

              

        按键在没有按下时,处于常低状态;

        第二种为低电平有效的,如图所示:

                

         按键在没有按下时,处于常高状态;

        如何设计一个模块同时对两种状态都可以进行消抖呢?设置一个计数器数一定长度,当发现按键状态有变化时就开始清零计数,只有当计数器的值大于设定的长度时(这时证明按键状态稳定了),才输出按键的状态,这样就可以达到消抖的目的。

        受篇幅限制, 所有仿真工程和源码和指导视频在下方链接的资料包中统一提供。

仿真文件中模拟输入了一个常高和常低按键按下过程各一个。(注:仿真过程参见视频

)仿真结果如下图:

        

         上面的内容进行单个按键的消抖,在DDS信号发生器的设计中,一共需要使用7个按键,为了集中对按键进行消抖处理,单独设置一个模块,调用7个按键消抖模块,在这个模块中统一对按键进行消抖处理输出,这样可使系统设计的结构更加简明。

        仿真文件中模拟输入了7个抖动的按键输入。(注:仿真过程参见视频)

        仿真结果如下图:

          

3.2 波形选择模块

        在DDS中需要一个模块来控制合成波形的选择,该模块生成一个波形选择值给DDS波形合成器,用于控制合成波形的种类,同时驱动LED灯显示当前合成波形的种类:

       波形合成数值含义:

              0:正弦波 1:方波 2:三角波 3:锯齿波

3.2.1 波形选择模块代码

        仿真文件中模拟了一个波形选择的过程。(注:仿真过程参见视频)

        仿真结果如下图:

3.3 频率调整模块

DDS中需要一个使用按键来调整输出波形频率的模块,设计思路如下:

模块一共接入了6个按键用于调整频率:

add_key_1hz       :1hz步进按键

add_key_10hz      :10hz步进按键

add_key_100hz     :100hz步进按键

add_key_1khz      :1khz步进按键

add_key_10khz     :10khz步进按键

add_key_100khz    :100khz步进按键

       同时对输出波形的频率最大限制在了1Mhz,设置大于1Mhz时会主动回到1hz的频率,按下复位键也同样可以回到1hz的频率。

3.3.1 频率调整模块代码

 

 仿真文件中模拟了一个每档步进按键被顺序被按下的过程的过程。(注:仿真过程参见视频)

仿真结果如下图:

3.4  显示数值分解模块

      频率调整模块功能完成了以后,设置了频率值,但是这个值是无法直接在数码管上显示的。所以必须使用一个模块将数值按个位、十位、百位、千位等分开,这样才能用于数码管的显示。

       

实现方案:设计中最高可现实7位频率值,采用以下步骤可将数值分离:

第1步:输入的频率值除以1_000_000求商可得出第7位的数值;

第2步:将上一步的余数除以100_000求商可得出第6位的数值;

第3步:将上一步的余数除以10_000求商可得出第5位的数值;

第4步:将上一步的余数除以1_000求商可得出第4位的数值;

第5步:将上一步的余数除以100求商可得出第3位的数值;

第6步:将上一步的余数除以10求商可得出第2位的数值,剩下的余数是即是第1位;

以上步骤中一共要使用6次除法,在FPGA中使用6个除法去完成是不合理的(占用大量的逻辑资源,资源少的FPGA可能时序难以收敛),所以设计采用分时复用的方法,使用一个除法器去完成所有的除法运算。

        仿真文件中分别输入了两个数0_123_456和0_654_321两个数,测试数值分解模块的功能。(注:仿真过程参见视频)

仿真结果如下图:

          

       结论:可以看出,当输入数为0_123_456时,num7~num1按顺序分解了;当输入数为0_654_321时,num7~num1则按顺序分解了,证明拆分结果正确。

        受篇幅限制, 所有仿真工程和源码和指导视频在下方链接的资料包中统一提供。

数码管译码与动态扫描模块

这里指的数码管就是最常见的七段显示数码管,如图:

        可以看出它是由7段小灯组成的,通过点亮小灯的组合不同可以组成不同的字符。管脚图如下:

       每个管脚控制着一段灯管,数码管还分为共阴和共阳两种,共阴是说每段小灯的负极是连接在一起的(一个共地管脚),每段小灯的正级是分开的(对应着每个管脚),共阳数码管的则刚好相反,本文就以共阴的数码管为例来讲解。

       数码管显示0~9这10个数字,按照管脚状态的组合,可以得到如下的数字管脚组合表,称它为译码表(小数点忽略,该设计不涉及小数点的使用):

       图中用‘1’表示该管脚状态为高,点亮该管脚对应的段码;‘0’则相反;

数字   管脚

a

b

c

d

e

f

g

0

1

1

1

1

1

1

0

1

0

1

1

0

0

0

0

2

1

1

0

1

1

0

1

3

1

1

1

1

0

0

1

4

0

1

1

0

0

1

1

5

1

0

1

1

0

1

1

6

1

0

1

1

1

1

1

7

1

1

1

0

0

0

0

8

1

1

1

1

1

1

1

9

1

1

1

1

0

1

1

       了解数码管的基本原理以后,还需要解决一个问题,频率计中一共使用了8个数码管,如果每个数码管都需要单独驱动的话,那么就需要56个管脚,管脚使用太多的话不论是对FPGA IO资源占用还是PCB布线都是不合理的,所以需要使用数码管的动态扫描来解决这个问题。

       动态扫描的原理(百度百科):数码管动态显示接口是嵌入式系统中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是哪个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。

        仿真文件中在数码管译码与动态扫描的数字输入端口num7~num1上分别输入了数字1、2、3、4、5、6、7,查看功能是否正确。(注:仿真过程参见视频)

仿真结果如下图:

        

        结论:一共出现7段波形,从左至右分别是:第7位数码管显示1、第6位数码管显示2、第5位数码管显示3、第4位数码管显示4、第3位数码管显示5、第2位数码管显示6、第1位数码管显示7,证明显示结果正确。

         受篇幅限制, 所有仿真工程和源码和指导视频在下方链接的资料包中统一提供。

 3.6 DDS波形合成模块

        DDS波形合成模块是该设计的核心,其余模块则作为该模块的辅助作用,波形的合成最终还是靠这个模块的来完成,以此称该模块的DDS核(DDS_DORE),框图如下:

最核心的内容即为相位计数器的计算,下面给出了相位计数器的推导过程:

PHASE_CNT     :相位计数器    

 CLK_FRE        :采样时钟频率  (DAC输出的频率  =  100Mhz)

WAVE_FRE      :波形频率      (合成波形的频率 =  人为设定)

SAMPLING_NUM :采样点个数    (一个周期的采样点个数 = 64个)

              PHASE_CNT = CLK_FRE/WAVE_FRE/SAMPLING_NUM; (1)

       由于CLK_FRE和SAMPLING_NUM已知,再定义一个参数:

              CLK_SAMPLING = CLK_FRE/SAMPLING_NUM; (2)

       最后推出:

              PHASE_CNT = CLK_SAMPLING /WAVE_FRE;(3)

只需要计算这个式子即可。

        这里顺带提一下DAC的驱动,设计采用的AD9708属于高速DAC,驱动时序很简单,在给出DAC时钟的同时,给你DAC的数值即可,只要保证时序条件不违规即可(关于时序约束请持续关注时序约束与时序分析系列博客)。

        仿真文件中模拟了一个1MHZ 正弦波、方波、三角波、锯齿波 到500Khz正弦波、方波、三角波、锯齿波一一切换输出的过程。(注:仿真过程参见视频)

仿真结果如下图:

 4 DDS信号发生器的系统设计

        上一章已经完成了DDS信号发生器的各个模块的仿真验证工作,这一章将上一章节的模块有机的结合起来就构成了一个完整的DDS信号发生器,这里要完成的工作即是编写DDS信号发生器顶层设计代码,将各个模块连接起来。

4.1 DDS信号发生器顶层设计代码

 

 

 

 

 4.2 DDS信号发生器系统模块框图

        用quartuse ii对系统工程进行综合以后,点击RTL_VIWER系统可以自动生成设计的系统框图(RTL视图),也就是大家误以为的连线图和原理图,如图:

  

        仿真文件中模拟了一个使用按键调整输出一个1MHZ正弦波输出的过程。(注:仿真过程参见视频)

仿真结果如下图:

5 硬件设计

        前面的硬件描述语言已经把整个设计的做完,功能仿真也进行完毕了。但是的硬件设计的核心器件还没有定下来。采用器件(EP4CE6E22C8)对工程进行综合编译,可以看到资源占用报告,如图:

        可以看出设计占用了该器件36%的资源,这样还有64%的资源余量,那这样看来该器件是可以完成该设计的。

       下面以FPGA为例选用EP4CE6E22C8来完成该设计,下面分模块对硬件原理图进行讲解。

         

 5.1 电源接口电路设计

         电源接口电路采用了两种供电的方式,满足不同的情况下使用。

        (1)Micro Usb供电,取电方便,用智能手机的充电线或者充电宝均可取电;(2)排针供电,但是必须要实验室直流电源通过排线接入5V电源。

        电路中使用D1用来防反接,防止电源接反;R1使用的是自恢复保险丝,当后面电路意外短路的时,电阻急剧增大,形成高阻状态,防止烧坏后面电路的器件,当短路情况消失后,电阻减少,形成低阻状态,从而不需要人工干预,有效地保护电路。LED作为一个电源指示灯,当电源接好并且K1开关打开时,电源指示灯常亮。

5.2 电源系统设计

        FPGA芯片需要用到3种电源供电,所以电路中设计3种电源转换电路。

(1)5V电源转3.3V,E5、E6用来滤波储能,C3、C6用来滤出高频电源噪声。

(2)5V电源转2.5V,外部加的滤波电容功能同上。

(3)3V电源转1.2V,外部的电容功能同上。

5.3 时钟设计

        全局主时钟采用50M有源晶振设计,频率精度高、稳定性好,C7、C8用来滤除有源晶振的电源噪声。

5.4 JTAG端口和FPGA配置电路设计

         程序的下载,采用通用的JTAG方式下载程序,由于FPGA掉电易失,所以需要挂一个存储器,电路中选用的是EPCS16S18N,设计PCB板的时候需要注意的地方,就是有些脚需要上拉电阻。

5.5  FPGA芯片的电源引脚

                                  

        FPGA的电源引脚分布情况,VCC3_3,VCC1_2,以及VCC2_5。

5.6 数码管电流扩展电路

        此次设计的数码管电路采用动态扫描的方式来显示。由于电路中有8个数码管,如果不采用动态扫描电路,那么将会用到60多个IO口,不利用PCB布线且也浪费了FPGA芯片的IO口。由于闪烁的频率在大于40HZ后,人眼就无法识别闪烁了,这样,在程序中设置每个数码管的点亮时间大于40HZ,就会实现眼睛被欺骗的结果,数码管常亮。在使用数码管动态扫描电路的时候,一定要注意驱动电流的选择,如果不增加电流扩展电路,那么最终的结果就是数码管的显示很暗又或者显示不稳定,电路中每个公共信号都采用一个NPN三极管来扩展电流,增加驱动能力。

5.7 数码管电路

        电路里面的使用了8个上图所示的数码管,采用共阴极的接法,程序中按照8个数码管从高到地位分时选择seg_en_x的管脚,点亮选择的数码管,由于分时选择的速度很快,远远大于人眼能够识别的频率,从而看上去数码管都是亮的。

5.8 复位电路

       复位电路,用于程序的复位,本电路中使用的是低电平复位。

 5.9 指示灯显示电路

        电路设计上留了4个不同颜色的灯,均通过FPGA芯片的IO口直接供电,高电平,点亮对应的灯,这4种灯具有以下的功能:LED3(闹钟设置模式指示灯)、LED4(日期设置模式指示灯)、LED5(时间调整模式指示灯)、LED6(正常显示模式下指示灯)。

5.10 蜂鸣器电路

         蜂鸣器用来配合着闹钟使用,当定时的时间到了设定的值后,蜂鸣器会鸣叫,提示闹钟设置时间到。电路中用的蜂鸣器是有源蜂鸣器,只需通电,便会鸣叫,方便易于控制,高电平导通,蜂鸣器鸣叫。

5.11 按键控制电路

         根据程序的功能,设计了4个按键,分别是数码管显示切换按键,调整增加按键,移位按键以及模式调整按键;高电平有效。

6 实物验证

        在这里就已经到达设计的最后一个阶段了,需要把整个设计在的实物上进行验证。

 6.1 管脚分配

Step1:打开DDS\formal_code\DDS中的工程

        (注:formal_code正式程序中的在系统仿真的工程中加入了锁相环,以后可以方便的通过锁相环将设计应用于任何开发板)。

Step2:选择Pin Planner

 Step3:根据《管脚分配手册》,对管脚进行分配

       分配完成以后保存并从新编译工程。(注:在正式程序的工程中,管脚已经分配好,所以使用时无需再进行分配,这里只是带大家学习这一过程。

6.2  实物验证

        最后一步任务就是把程序下载进入设计的开发板中,然后就可以验证功能是否正确了。

Step1:将实物行如下连接:

Step2: 打开DDS\formal_code\DDS中的工程

  Step3:打开programmer

  Step4:设置硬件链接

Step4:点击start等待下载完成,下载完成后重新上电

运行结果:(工程中的下载配置文件已固化好,下载即可,若想学习如何进行下载文件的生成,请自行搜索相关方法

设定好想要的波形和频率,然后使用示波器测量波形。

资料合集包传送门:

          至此,基于FPGA的等精度数字频率流程已经讲解完毕,博客中讲解了所有的设计原理和设计重点,同时介于篇幅的限制,部分源码没办法全部给出,需要进一步学习的可下载全套资料合集包:

        传送门: DDS_Verilog.rar​​​​​​​

资料包含内容如下:

文件夹名

功能描述

备注

bom

元器件清单

module_test

模块级的仿真工程(可能采用不同的仿真形式和仿真工具,具体以对应的博客为准)

需要安装Quartuse II 13.1

system_test

系统级的仿真工程(可能采用不同的仿真形式和仿真工具,具体以对应的文档为准)

需要安装Quartuse II 13.1

formal_code

程序工程的实物运行版本版本,用于下载到板卡上运行的(与仿真版本只有参数上的差异,并且生成了配置文件)

需要安装Quartuse II 13.1

sch&pcb

原理图和PCB设计图

打开文档需要安装Adobe Acrobat

video

产品设计讲解课程,与document的文件使用方法相同,也需要用你的机器码来获取播放密码。并且需要“比特电子视频专用播放器”打开,否则会报文件损坏错误。

使用“比特电子视频专用播放器” 去打开视频

软件提取网址

工作室提供了文件使用所需要的软件下载地址和对应的软件安装使用教程提取网址

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/666900
推荐阅读
相关标签
  

闽ICP备14008679号