一天一个设计实例-基于FPGA的模数、数模转换器应用设计
基于FPGA的模数、数模转换器应用设计
本节设计采用黑金ADDA模块,模块硬件结构如下:

图7‑32 硬件结构
数模转换( DA) 电路
如硬件结构图所示, DA 电路由高速 DA 芯片、 7 阶巴特沃斯低通滤波器、幅度调节电路和信号输出接口组成。
使用的高速 DA芯片是 AD公司推出的 AD9708。AD9708 是 8位,125MSPS的 DA 转换芯片,内置 1.2V 参考电压,差分电流输出。芯片内部结构图如下图所示

图7‑33 芯片内部结构图
AD9708 芯片差分输出以后, 为了防止噪声干扰,电路中接入了 7 阶巴特沃斯低通滤波器, 带宽为 40MHz, 频率响应如下图所示

图7‑34 频率响应
滤波器参数如下图所示

图7‑35 滤波器参数
滤波器之后,我们使用了 2 片高性能 145MHz 带宽的运放 AD8056,实现差分变单端,以及幅度调节等功能,使整个电路性能得到了最大限度的提升。幅度调节,使用的是 5K 的电位器,最终的输出范围是-5V~5V( 10Vpp)。
注:由于电路器的精度不是很精确,最终的输出有一定误差, 有可能波形幅度不能达到 10Vpp,也有可能出现波形削顶等问题,这些都属正常情况。
波形展示:
![]() |
![]() |
![]() |
![]() |
注:由于幅频特性的影响,随着频率的增加, 波形的幅度会不断减小。 |
图7‑36 波形展示
模数转换( AD)电路
如硬件结构图中所示, AD 电路由高速 AD 芯片、衰减电路和信号输入接口组成。
AD9280是一款单芯片、8位、32 MSPS模数转换器(ADC),采用单电源供电,内置一个片内采样保持放大器和基准电压源。它采用多级差分流水线架构,数据速率达32 MSPS,在整个工作温度范围内保证无失码。
AD9280的输入经过设计,使成像和通信系统的开发更加轻松。用户可以选择各种输入范围和偏移,并可通过单端或差分方式驱动输入。
AD9280具有一个片上可编程基准电压源。也可以选用外部基准电压,以满足应用的直流精度与温度漂移要求。AD9280采用+2.7 V至+5.5 V电源供电,非常适合高速应用中的低功耗操作。AD9280的额定温度范围为-40°C至+85°C工业温度范围。
AD9280 特性
与AD876-8引脚兼容;
功耗:95 mW(3 V电源);
工作电压范围:+2.7V至+5.5V;
微分非线性(DNL)误差:0.2 LSB;
省电(休眠)模式;
三态输出;
超量程指示;;
内置钳位功能(直流复位);
可调片内基准电压;
IF欠采样至135 MHz;
内部结构图如下图所示:

图7‑37 AD9280内部结构图
根据下图的配置,我们将 AD 电压输入范围设置为:0V~2V

图7‑38 AD 电压输入范围设置为:0V~2V
在信号进入 AD 芯片之前,我们用一片 AD8056 芯片构建了衰减电路, 接口的输入范围是-5V~+5V(10Vpp)。衰减以后,输入范围满足 AD 芯片的输入范围( 0~2V)。转换公式如下:

65(.)
当输入信号 Vin=5(V)的时候,输入到 AD 的信号 Vad=2(V);
当输入信号 Vin=-5(V)的时候,输入到 AD 的信号 Vad=0(V);
DA 实验操作步骤
因为代码比较简单,所以就不贴代码了,实验步骤如下:
1. 利用 Quartus II 软件,将程序下载到 FPGA 中。
2. 调整示波器,使其正确显示完整波形。
3. 您可以通过电位器( U6)来手动调节波形的幅值。
AD 实验操作步骤
1.利用 Quartus II 软件,将程序下载到 FPGA 中。
2.利用 SignalTap II 对数据进行实时采集。
AGC的FPGA实现
基于前面介绍的硬件实现AGC,硬件结构及框图非常简单,这里就不再赘述,代码如下:
代码7‑9 7.5.5 AGC的FPGA实现代码
1.module Autogreat(clkin_50MHz,ADCclk_25MHz,DACclk_25MHz,ADCin,DACout); 2.//50MHz 分频 25MHz, ADCin 读入 8 位 ADC 数据, DACout 发送 8 位转换数据,进行 DAC 转换 3.input clkin_50MHz; 4.input [7:0]ADCin; 5.output reg ADCclk_25MHz; 6.output reg DACclk_25MHz; 7.output reg[7:0]DACout; 8.reg[3:0]counter; 9.reg[8:0]cnt500;//2^9=512,采集 500 次,进行冒泡 10.//reg [7:0]max,tmp;//冒泡使用 11.reg [7:0]tmp; 12.reg [7:0]great;//定义增益使用 13.reg [7:0]great1;//接受 great 的高八位 14.reg [15:0]tmp16; 15.reg [7:0]realgreat;//真正增益,相当于 great 右移 8 位 16.//---@分频开始@---// 17.always@(posedge clkin_50MHz) 18. begin 19. if(counter==1) 20. begin 21. ADCclk_25MHz<=~ADCclk_25MHz; 22. DACclk_25MHz<=~DACclk_25MHz; 23. counter<=0; 24. end 25. else if(counter==0) 26. begin 27. counter<=counter+1; 28. end 29. end 30.//---@分频结束@---// 31.//---@获取自动增益,并调整输出电压开始@---// 32.always@(posedge DACclk_25MHz) 33. begin 34. tmp16<=(adcin-128)*great1;< span="">//ADCin-128,取中线上面部分, 35.//128 即 1000_0000 为正电压中心线,乘以增益,单边放大 36. realgreat<=tmp16[15:8];< span="">//取得 tmp 高 8 位,即浮点数整数部分 37. DACout<=128+realgreat;< span="">//真正 DAC 输出部分 38.//---@实验成功语句@---// 39.//---@DACout<=(ADCin-128)*1+128;@---// 40.//---@实验成功语句@---// 41. end 42.//---@对 ADCin 进行处理@---// 43.always@(posedge ADCclk_25MHz) 44. begin 45.//---@冒泡取大开始@---// 46. if(cnt500>=500) 47. begin 48. cnt500<=0; 49.//max<=tmp;//取得 500 次采样最大值 50.//great<=(64*256)/(max-128);//64 为设定电压值,相当于放大倍数, 51.//64 乘以 256 相当于左移 8 位,需要 16 位储存, max-8'b10000000 52. great<=(36*256)/(tmp-128);//此时 great 为 16 位,需要其高八位, 53.//64 为 0100_0000,当设置输出为正负 2.5V 时用 64,比较时运用差值 54. great1<=great[7:0]; 55. end 56. else if(cnt500<500)< span="">//在两个信号周期内采样 57. begin 58. if(tmp<=adcin)< span="">//当前 tmp 小于等于 ADCin 59. begin 60. tmp<=adcin;< span="">//冒泡取得比当前大的值 61. end 62. else 63. begin 64. tmp<=tmp;< span="">//保持当前值 65. end 66. cnt500<=cnt500+1;< span="">//cnt500 自增 67. end 68.//---@冒泡取大结束@---// 69. end 70.//---@获取自动增益,并调整输出电压结束@---// 71.endmodule |
FPGA 与外部端口在上一节已经说明。整个 HDL 分为分频部分、读取 ADC转换值部分、增益处理和 DAC 输出波形部分。
1.分频部分
第一个部分请见
1.always@(posedge clkin_50MHz) 2.begin 3.….. 4.end |
部分,为二分频,分别产生 20MHz 和 AD 和 DA 时钟。
1.读取 ADC 转换值部分
第二个部分请见
1.always@(posedge clkin_50MHz) 2.begin 3.….. 4.end |
部分。其中输入信号为 100KHz, ADC 采样时钟为 25MHZ,所以一个信号周期可以采样 250 次,设置采集 500 次,利用冒泡法取得最大值,信号最大值的 AD 转换值储存在 tmp 当中;记录 500 次后,利用 tmp 取得正半周期的幅度,即“tmp-128”,因为根据上一节介绍,其 AD 电路将正弦信号负半周衰减后抬升到正电压, “tmp-128”即为 tmp-8’b100_0000,即得到正半周期的幅度。
此时,再利用“great<=(36*256)/(tmp-128);”,得到与预设电压的增益或者衰减系数,注意 great 为 8 位, 而(36*256)是将 36 左移 8 位, 这里运用了 8 位拓展为 16 位,来就利用 FPGA 完成浮点数运算。
紧接着这句话,是“great1<=great[7:0];”,这句话其实并没有什么现实意义,但是最初写的时候, great 是 16 位的,后来写我就没有改。注意 great1 也是 8 位的。
2.增益处理和 DAC 输出波形部分
第二个部分请见
1.always@(posedge DACclk_25MHz) 2.begin 3.….. 4.end |
部分。首先是“tmp16<=(ADCin-128)*great1;”, 这句话中 tmp16 是 16位数据, “ADCin-128” 为 ADCin 的值减去轴的值(见 2.2.2) , 然后乘以增益(great1 大于等于 1 为增益,小于 1 则为衰减,这里都叫为增益) , 8 位乘以 8位得到 16 位,恰巧这里又用了拓展位数进行浮点数运算。
最后“realgreat<=tmp16[15:8];”和“DACout<=128+realgreat;”则为将 tmp1的高八位给 realgreat,即将整数部分给 realgreat,而后一句则为 DACout 是当前计算得到的值再加上轴的值(128,即 8’b1000000)。最后 DAC 输出,得到波形。
实验结果如下:
最后的实验效果可以见下图中。可以看到,随着输入信号幅值变化,输出信号可以稳定在一个设定值(设定为 36,即输出用十进制表示为:92~154) 附近,但是波形稳定不是很好,另外当输入信号电压峰峰值超过AD 模块限定的 10V 时,出现削顶。




图7‑39 实验结果图
