一天一个设计实例-基于FPGA的模数转换器应用设计

基于FPGA的模数转换器应用设计

1.1.1八通道AD7606应用设计

7.3.1.1 AD7606简介

AD7606 是一款集成式 8 通道数据采集系统,片内集成输入放大器、过压保护电路、二阶模拟抗混叠滤波器、模拟多路复用器、 16 位 200 kSPS SAR ADC和一个数字滤波器。

图7‑10所示电路包括两个AD7606 器件,可以配置为使用 2.5 V内部基准电压源或 2.5 V外部基准电压源ADR421。如果REF SELECT引脚接逻辑高电平,则选择内部基准电压源。如果REF SELECT引脚接逻辑低电平,则选择外部基准电压源。

在电力线路测量和保护系统中,需要对多相输配电网络的大量电流和电压通道进行同步采样。这些应用中,通道数量从6 个到 64 个以上不等。AD7606 8 通道数据采集系统(DAS)集成 16 位双极性同步采样SAR ADC和片内过压保护功能,可大大简化信号调理电路,并减少器件数量、电路板面积和测量保护板的成本。高集成度使得每个AD7606 只需 9 个低值陶瓷去耦电容就能工作。

在测量和保护系统中,为了保持多相电力线网络的电流和电压通道之间的相位信息,必须具备同步采样能力。AD7606具有宽动态范围, 是捕获欠压/欠流和过压/过流状况的理想器件。输入电压范围可以通过引脚编程设置为±5 V 或±10 V。此电路笔记详细介绍针对采用多个AD7606 器件应用而推荐的印刷电路板(PCB)布局。该布局在通道间匹配和器件间匹配方面进行了优化,有助于简化高通道数系统的校准程序。当通道间匹配非常重要时,此电路可以使用 2.5 V内部基准电压源AD7606;而对于要求出色绝对精度的高通道数应用,此电路可以使用外部精密基准电压源ADR421,它具有高精度(B级:最大值±1 mV)、低漂移(B级:最大值 3 ppm/°C)、低噪声(典型值 1.75 μV p-p, 0.1 Hz至 10 Hz)等特性。低噪声及出色的稳定性和精度特性使得ADR421非常适合高精度转换应用。这两个器件相结合,能够实现业界前所未有的集成度、通道密度和精度。

图7‑10采用两个AD7606 8 通道DAS的 16 通道、 16 位数据采集系统

图7‑11 AD7606功能框图

图7‑12 引脚配置图

图7‑13 AD7606时序图

况的理想器件。输入电压范围可以通过引脚编程设置为±5 V 或±10 V。此电路笔记详细介绍针对采用多个AD7606 器件应用而推荐的印刷电路板(PCB)布局。该布局在通道间匹配和器件间匹配方面进行了优化,有助于简化高通道数系统的校准程序。当通道间匹配非常重要时,此电路可以使用 2.5 V内部基准电压源AD7606;而对于要求出色绝对精度的高通道数应用,此电路可以使用外部精密基准电压源ADR421,它具有高精度(B级:最大值±1 mV)、低漂移(B级:最大值 3 ppm/°C)、低噪声(典型值 1.75 μV p-p, 0.1 Hz至 10 Hz)等特性。低噪声及出色的稳定性和精度特性使得ADR421非常适合高精度转换应用。这两个器件相结合,能够实现业界前所未有的集成度、通道密度和精度。

AD7606 可以对所有 8 路的模拟输入通道进行同步采样。当两个 CONVST引脚(CONVSTA 和 CONVSTB)连在一起时, 所有通道同步采样。此共用CONVST 信号的上升沿启动对所有模拟输入通道的同步采样(V1 至 V8)。

AD7606 内置一个片内振荡器用于转换。所有 ADC 通道的转换时间为tCONV。BUSY 信号告知用户正在进行转换, 因此当施加 CONVST 上升沿时,BUSY 变为逻辑高电平, 在整个转换过程结束时变成低电平。BUSY 信号下降沿用来使所有八个采样保持放大器返回跟踪模式。BUSY 下降沿还表示,现在可以从并行总线 DB[15:0]读取 8 个通道的数据。

7.3.1.2 AD7606配置

在 AN706 8 通道的 AD 模块硬件电路设计中,我们对 AD7606 的 3 个配置Pin 脚通过加上拉或下拉电阻来设置 AD7606 的工作模式。

1. AD7606 这款芯片支持外部基准电压输入或内部基准电压。如果使用外部基准电压,芯片的 REFIN/REFOUT 需要外接一个 2.5V 的基准源。如果使用内部的基准电压。REFIN/REFOUT 引脚为 2.5V 的内部基准电压输出。REFSELECT 引脚用于选择内部基准电压或外部基准电压。在本模块中, 因为考虑到 AD7606 的内部基准电压的精度也非常高( 2.49V~2.505V),所以电路设计选择使用了内部的基准电压。

表7‑1 REF SELECT 引脚设置

Pin 脚名

设置电平

说明

REF SELECT

高电平

使用内部的基准电压 2.5V

2. AD7606 的 AD 转换数据采集可以采用并行模式或者串行模式,用户可以通过设置 PAR/SER/BYTE SEL 引脚电平来设置通信的模式。我们在设计的时候,选择并行模式读取 AD7606 的 AD 数据。

表7‑2 PAR/SER/BYTE SEL 引脚设置

Pin 脚名

设置电平

说明

PAR/SER/BYTE SEL

低电平

选择并行接口

3. AD7606 的 AD 模拟信号的输入范围可以设置为±5V 或者是±10V,当设置± 5V 输入范围时,1LSB=152.58uV;当设置 ±10V 输入范围时,1LSB=305.175uV。用户可以通过设置 RANGE 引脚电平来设置模拟输入电压的范围。我们在设计的时候,选择±5V 的模拟电压输入范围。

表7‑3 模拟信号输入范围选择设置

Pin 脚名

设置电平

说明

RANGE

低电平

模拟信号输入范围选择:±5V

4. AD7606 内置一个可选的数字一阶 sinc 滤波器,在使用较低吞吐率或需要更高信噪比的应用中,应使用滤波器。数字滤波器的过采样倍率由过采样引脚 OS[2:0]控制。下表提供了用来选择不同过采样倍率的过采样位解码。

表7‑4 过采样位解码设置

在 AN706 模块的硬件设计中, OS[2:0] 已经引到外部的接口中,FPGA 或CPU 可以通过控制 OS[2:0]的管脚电平来选择是否使用滤波器,以达到更高的测量精度。

7.3.1.3 AD7606 AD转换

AD7606 的输出编码方式为二进制补码。所设计的码转换在连续 LSB 整数的中间(既 1/2LSB 和 3/2LSB)进行。AD7606 的 LSB 大小为 FSR/65536。

AD7606 的理想传递特性如下图所示:

图7‑14 理想传递特性

7.3.1.4 基于FPGA的AD7606应用设计

图7‑15 基于FPGA的AD7606应用设计建模图

上图中:

1. AD 数据采集程序:AD7606采集模块

根据 AD7606 的时序, 采样 8 路模拟信号 AD 转换后的 16bit 的数据。程序先发送 CONVSTAB 信号给 AD7606 启动 AD 数据转换,等待 Busy 信号为低后依次读取 AD 通道 1 到通道 8 的数据。

2. AD 数据的电压转换程序:电压转换模块

程序把从 ad7606.v 采集来的 16bit 的数据, Bit[15]转换为正负符号,Bit[14:0]先通过以下的公式转换成电压值,再把十六进制的电压值转换成 20 位BCD 码。

AD 电压换算(1 LSB) = 5V / 32758 = 0.15mV

3. 串口发送程序:串口发送模块

定时通过 uart 发送 8 路的电压数据到 PC, 串口的发送时钟通过 50Mhz 的分频得到,发送的波特率为 9600bps。

代码7‑1 AD 数据采集程序

1.`timescale 1ns / 1ps

2.//////////////////////////////////////////////////////////////////////////////////

3.// Module Name:    ad7606

4.//////////////////////////////////////////////////////////////////////////////////

5.module ad7606(

6.   input                clk,                  //50mhz

7.    input               rst_n,

8.

9.    input [15:0]        ad_data,            //ad7606 采样数据

10.    input               ad_busy,            //ad7606 忙标志位

11.   input                first_data,         //ad7606 第一个数据标志位

12.    output [2:0]        ad_os,              //ad7606 过采样倍率选择

13.    output reg          ad_cs,              //ad7606 AD cs

14.    output reg          ad_rd,              //ad7606 AD data read

15.    output reg          ad_reset,           //ad7606 AD reset

16.    output reg          ad_convstab,         //ad7606 AD convert start

17.

18.    output reg [15:0] ad_ch1,              //AD第1通道的数据

19.    output reg [15:0] ad_ch2,              //AD第2通道的数据

20.    output reg [15:0] ad_ch3,              //AD第3通道的数据

21.    output reg [15:0] ad_ch4,              //AD第4通道的数据

22.    output reg [15:0] ad_ch5,              //AD第5通道的数据

23.    output reg [15:0] ad_ch6,              //AD第6通道的数据

24.    output reg [15:0] ad_ch7,              //AD第7通道的数据

25.    output reg [15:0] ad_ch8               //AD第8通道的数据

26.

27.

28.

29.    );

30.

31.

32.

33.reg [15:0]  cnt;

34.reg [5:0] i;

35.reg [3:0] state;

36.

37.parameter IDLE=4'd0;

38.parameter AD_CONV=4'd1;

39.parameter Wait_1=4'd2;

40.parameter Wait_busy=4'd3;

41.parameter READ_CH1=4'd4;

42.parameter READ_CH2=4'd5;

43.parameter READ_CH3=4'd6;

44.parameter READ_CH4=4'd7;

45.parameter READ_CH5=4'd8;

46.parameter READ_CH6=4'd9;

47.parameter READ_CH7=4'd10;

48.parameter READ_CH8=4'd11;

49.parameter READ_DONE=4'd12;

50.

51.assign ad_os=3'b000;

52.

53.//AD 复位电路

54.always@(posedge clk)

55. begin

56.    if(cnt<16'hffff) begin

57.        cnt<=cnt+1;

58.        ad_reset<=1'b1;

59.      end

60.      else

61.        ad_reset<=1'b0;

62.   end

63.

64.always @(posedge clk)

65. begin

66.     if (ad_reset==1'b1) begin

67.             state<=IDLE;

68.             ad_ch1<=0;

69.             ad_ch2<=0;

70.             ad_ch3<=0;

71.             ad_ch4<=0;

72.             ad_ch5<=0;

73.             ad_ch6<=0;

74.             ad_ch7<=0;

75.             ad_ch8<=0;

76.             ad_cs<=1'b1;

77.             ad_rd<=1'b1;

78.             ad_convstab<=1'b1;

79.             i<=0;

80.     end

81.     else begin

82.          case(state)

83.          IDLE: begin

84.                 ad_cs<=1'b1;

85.                 ad_rd<=1'b1;

86.                 ad_convstab<=1'b1;

87.                 if(i==20) begin

88.                     i<=0;

89.                     state<=AD_CONV;

90.                 end

91.                 else

92.                     i<=i+1'b1;

93.          end

94.          AD_CONV: begin

95.                 if(i==2) begin                        //等待2个clock

96.                     i<=0;

97.                     state<=Wait_1;

98.                     ad_convstab<=1'b1;

99.                 end

100.                 else begin

101.                     i<=i+1'b1;

102.                     ad_convstab<=1'b0;                     //启动AD转换

103.                 end

104.          end

105.          Wait_1: begin

106.                 if(i==5) begin                  //等待5个clock, 等待busy信号为高

107.                     i<=0;

108.                     state<=Wait_busy;

109.                 end

110.                 else

111.                     i<=i+1'b1;

112.          end

113.          Wait_busy: begin

114.                 if(ad_busy==1'b0) begin                    //等待busy信号为低

115.                     i<=0;

116.                     state<=READ_CH1;

117.                 end

118.          end

119.          READ_CH1: begin

120.                 ad_cs<=1'b0;                              //cs信号有效

121.                 if(i==3) begin

122.                     ad_rd<=1'b1;

123.                     i<=0;

124.                     ad_ch1<=ad_data;                        //读CH1

125.                     state<=READ_CH2;

126.                 end

127.                 else begin

128.                     ad_rd<=1'b0;

129.                     i<=i+1'b1;

130.                 end

131.          end

132.          READ_CH2: begin

133.                 if(i==3) begin

134.                     ad_rd<=1'b1;

135.                     i<=0;

136.                     ad_ch2<=ad_data;                        //读CH2

137.                     state<=READ_CH3;

138.                 end

139.                 else begin

140.                     ad_rd<=1'b0;

141.                     i<=i+1'b1;

142.                 end

143.          end

144.          READ_CH3: begin

145.                 if(i==3) begin

146.                     ad_rd<=1'b1;

147.                     i<=0;

148.                     ad_ch3<=ad_data;                        //读CH3

149.                     state<=READ_CH4;

150.                 end

151.                 else begin

152.                     ad_rd<=1'b0;

153.                     i<=i+1'b1;

154.                 end

155.          end

156.          READ_CH4: begin

157.                 if(i==3) begin

158.                     ad_rd<=1'b1;

159.                     i<=0;

160.                     ad_ch4<=ad_data;                        //读CH4

161.                     state<=READ_CH5;

162.                 end

163.                 else begin

164.                     ad_rd<=1'b0;

165.                     i<=i+1'b1;

166.                 end

167.          end

168.          READ_CH5: begin

169.                 if(i==3) begin

170.                     ad_rd<=1'b1;

171.                     i<=0;

172.                     ad_ch5<=ad_data;                        //读CH5

173.                     state<=READ_CH6;

174.                 end

175.                 else begin

176.                     ad_rd<=1'b0;

177.                     i<=i+1'b1;

178.                 end

179.          end

180.          READ_CH6: begin

181.                 if(i==3) begin

182.                     ad_rd<=1'b1;

183.                     i<=0;

184.                     ad_ch6<=ad_data;                        //读CH6

185.                     state<=READ_CH7;

186.                 end

187.                 else begin

188.                     ad_rd<=1'b0;

189.                     i<=i+1'b1;

190.                 end

191.          end

192.          READ_CH7: begin

193.                 if(i==3) begin

194.                     ad_rd<=1'b1;

195.                     i<=0;

196.                     ad_ch7<=ad_data;                        //读CH7

197.                     state<=READ_CH8;

198.                 end

199.                 else begin

200.                     ad_rd<=1'b0;

201.                     i<=i+1'b1;

202.                 end

203.          end

204.          READ_CH8: begin

205.                 if(i==3) begin

206.                     ad_rd<=1'b1;

207.                     i<=0;

208.                     ad_ch8<=ad_data;                        //读CH8

209.                     state<=READ_DONE;

210.                 end

211.                 else begin

212.                     ad_rd<=1'b0;

213.                     i<=i+1'b1;

214.                 end

215.          end

216.          READ_DONE:begin

217.                     ad_rd<=1'b1;

218.                     ad_cs<=1'b1;

219.                     state<=IDLE;

220.          end

221.          default:  state<=IDLE;

222.          endcase

223.    end

224.

225. end

226.

227.endmodule

代码7‑2 AD 数据的电压转换程序代码

1.`timescale 1ns / 1ps

2.//////////////////////////////////////////////////////////////////////////////////

3.// Module Name:    volt_cal

4.//////////////////////////////////////////////////////////////////////////////////

5.module volt_cal(

6.   input                clk,                  //50mhz

7.    input               ad_reset,

8.

9.    input [15:0] ad_ch1,              //AD第1通道的数据

10.    input [15:0] ad_ch2,              //AD第2通道的数据

11.    input [15:0] ad_ch3,              //AD第3通道的数据

12.    input [15:0] ad_ch4,              //AD第4通道的数据

13.    input [15:0] ad_ch5,              //AD第5通道的数据

14.    input [15:0] ad_ch6,              //AD第6通道的数据

15.    input [15:0] ad_ch7,              //AD第7通道的数据

16.    input [15:0] ad_ch8,              //AD第8通道的数据

17.

18.

19.    output [19:0] ch1_dec,             //AD第1通道的十进制电压数据

20.    output [19:0] ch2_dec,             //AD第1通道的十进制电压数据

21.    output [19:0] ch3_dec,             //AD第1通道的十进制电压数据

22.    output [19:0] ch4_dec,             //AD第1通道的十进制电压数据

23.    output [19:0] ch5_dec,             //AD第1通道的十进制电压数据

24.    output [19:0] ch6_dec,             //AD第1通道的十进制电压数据

25.    output [19:0] ch7_dec,             //AD第1通道的十进制电压数据

26.    output [19:0] ch8_dec,             //AD第1通道的十进制电压数据

27.

28.    output reg [7:0] ch1_sig,          //AD第1通道的数据正负字符

29.    output reg [7:0] ch2_sig,          //AD第2通道的数据正负字符

30.    output reg [7:0] ch3_sig,          //AD第1通道的数据正负字符

31.    output reg [7:0] ch4_sig,          //AD第2通道的数据正负字符

32.    output reg [7:0] ch5_sig,          //AD第1通道的数据正负字符

33.    output reg [7:0] ch6_sig,          //AD第2通道的数据正负字符

34.    output reg [7:0] ch7_sig,          //AD第1通道的数据正负字符

35.    output reg [7:0] ch8_sig           //AD第2通道的数据正负字符

36.

37.

38.    );

39.

40.

41.reg [15:0] ch1_reg;

42.reg [15:0] ch2_reg;

43.reg [15:0] ch3_reg;

44.reg [15:0] ch4_reg;

45.reg [15:0] ch5_reg;

46.reg [15:0] ch6_reg;

47.reg [15:0] ch7_reg;

48.reg [15:0] ch8_reg;

49.

50.reg [31:0] ch1_data_reg;

51.reg [31:0] ch2_data_reg;

52.reg [31:0] ch3_data_reg;

53.reg [31:0] ch4_data_reg;

54.reg [31:0] ch5_data_reg;

55.reg [31:0] ch6_data_reg;

56.reg [31:0] ch7_data_reg;

57.reg [31:0] ch8_data_reg;

58.

59.reg [31:0] ch1_vol;

60.reg [31:0] ch2_vol;

61.reg [31:0] ch3_vol;

62.reg [31:0] ch4_vol;

63.reg [31:0] ch5_vol;

64.reg [31:0] ch6_vol;

65.reg [31:0] ch7_vol;

66.reg [31:0] ch8_vol;

67.

68.

69.//AD 电压换算

70.always @(posedge clk)

71.begin

72.  if(ad_reset == 1'b1) begin

73.     ch1_reg<=0;

74.      ch2_reg<=0;

75.     ch3_reg<=0;

76.      ch4_reg<=0;

77.     ch5_reg<=0;

78.      ch6_reg<=0;

79.     ch7_reg<=0;

80.      ch8_reg<=0;

81.  end

82.  else begin

83.    //////////CH1数据/////////////

84.    if(ad_ch1[15]==1'b1) begin                      //如果是负电压

85.        ch1_reg<=16< span="">'hffff-ad_ch1+1'b1;

86.         ch1_sig <= 45;                                //'-' asic码

87.     end

88.     else begin

89.       ch1_reg<=ad_ch1;

90.         ch1_sig<=43;                                  //'+' asic码

91.     end

92.

93.    //////////CH2数据/////////////

94.    if(ad_ch2[15]==1'b1) begin                      //如果是负电压

95.        ch2_reg<=16< span="">'hffff-ad_ch2+1'b1;

96.         ch2_sig <= 45;                                //'-' asic码

97.     end

98.     else begin

99.       ch2_reg<=ad_ch2;

100.         ch2_sig<=43;                                  //'+' asic码

101.     end

102.

103.    //////////CH3数据/////////////

104.    if(ad_ch3[15]==1'b1) begin                      //如果是负电压

105.        ch3_reg<=16< span="">'hffff-ad_ch3+1'b1;

106.         ch3_sig <= 45;                                //'-' asic码

107.     end

108.     else begin

109.       ch3_reg<=ad_ch3;

110.         ch3_sig<=43;                                  //'+' asic码

111.     end

112.

113.    //////////CH4数据/////////////

114.    if(ad_ch4[15]==1'b1) begin                      //如果是负电压

115.        ch4_reg<=16< span="">'hffff-ad_ch4+1'b1;

116.         ch4_sig <= 45;                                //'-' asic码

117.     end

118.     else begin

119.       ch4_reg<=ad_ch4;

120.         ch4_sig<=43;                                  //'+' asic码

121.     end

122.

123.    //////////CH5数据/////////////

124.    if(ad_ch5[15]==1'b1) begin                      //如果是负电压

125.        ch5_reg<=16< span="">'hffff-ad_ch5+1'b1;

126.         ch5_sig <= 45;                                //'-' asic码

127.     end

128.     else begin

129.       ch5_reg<=ad_ch5;

130.         ch5_sig<=43;                                  //'+' asic码

131.     end

132.

133.    //////////CH6数据/////////////

134.    if(ad_ch6[15]==1'b1) begin                      //如果是负电压

135.        ch6_reg<=16< span="">'hffff-ad_ch6+1'b1;

136.         ch6_sig <= 45;                                //'-' asic码

137.     end

138.     else begin

139.       ch6_reg<=ad_ch6;

140.         ch6_sig<=43;                                  //'+' asic码

141.     end

142.

143.    //////////CH7数据/////////////

144.    if(ad_ch7[15]==1'b1) begin                      //如果是负电压

145.        ch7_reg<=16< span="">'hffff-ad_ch7+1'b1;

146.         ch7_sig <= 45;                                //'-' asic码

147.     end

148.     else begin

149.       ch7_reg<=ad_ch7;

150.         ch7_sig<=43;                                  //'+' asic码

151.     end

152.

153.    //////////CH8数据/////////////

154.    if(ad_ch8[15]==1'b1) begin                      //如果是负电压

155.        ch8_reg<=16< span="">'hffff-ad_ch8+1'b1;

156.         ch8_sig <= 45;                                //'-' asic码

157.     end

158.     else begin

159.       ch8_reg<=ad_ch8;

160.         ch8_sig<=43;                                  //'+' asic码

161.     end

162.

163.    end

164.end

165.

166.

167.//AD 电压换算(1 LSB = 5V / 32758 = 0.15mV

168.always @(posedge clk)

169.begin

170.  if(ad_reset == 1'b1) begin

171.     ch1_data_reg<=0;

172.      ch2_data_reg<=0;

173.     ch3_data_reg<=0;

174.      ch4_data_reg<=0;

175.     ch5_data_reg<=0;

176.      ch6_data_reg<=0;

177.     ch7_data_reg<=0;

178.      ch8_data_reg<=0;

179.     ch1_vol<=0;

180.     ch2_vol<=0;

181.     ch3_vol<=0;

182.     ch4_vol<=0;

183.     ch5_vol<=0;

184.     ch6_vol<=0;

185.     ch7_vol<=0;

186.     ch8_vol<=0;

187.  end

188.  else begin

189.           ch1_data_reg<=ch1_reg * 50000;

190.           ch2_data_reg<=ch2_reg * 50000;

191.           ch3_data_reg<=ch3_reg * 50000;

192.           ch4_data_reg<=ch4_reg * 50000;

193.           ch5_data_reg<=ch5_reg * 50000;

194.           ch6_data_reg<=ch6_reg * 50000;

195.           ch7_data_reg<=ch7_reg * 50000;

196.           ch8_data_reg<=ch8_reg * 50000;

197.

198.         ch1_vol<=ch1_data_reg>>15;

199.         ch2_vol<=ch2_data_reg>>15;

200.         ch3_vol<=ch3_data_reg>>15;

201.         ch4_vol<=ch4_data_reg>>15;

202.         ch5_vol<=ch5_data_reg>>15;

203.         ch6_vol<=ch6_data_reg>>15;

204.         ch7_vol<=ch7_data_reg>>15;

205.         ch8_vol<=ch8_data_reg>>15;

206.     end

207.  end

208.

209.//16进制转化为十进制的

210.bcd bcd1_ist(

211.               .hex           (ch1_vol[15:0]),

212.                    .dec           (ch1_dec),

213.                    .clk           (clk)

214.                    );

215.

216.//16进制转化为十进制的

217.bcd bcd2_ist(

218.               .hex           (ch2_vol[15:0]),

219.                    .dec           (ch2_dec),

220.                    .clk           (clk)

221.                    );

222.

223.//16进制转化为十进制的

224.bcd bcd3_ist(

225.               .hex           (ch3_vol[15:0]),

226.                    .dec           (ch3_dec),

227.                    .clk           (clk)

228.                    );

229.

230.//16进制转化为十进制的

231.bcd bcd4_ist(

232.               .hex           (ch4_vol[15:0]),

233.                    .dec           (ch4_dec),

234.                    .clk           (clk)

235.                    );

236.

237.//16进制转化为十进制的

238.bcd bcd5_ist(

239.               .hex           (ch5_vol[15:0]),

240.                    .dec           (ch5_dec),

241.                    .clk           (clk)

242.                    );

243.

244.//16进制转化为十进制的

245.bcd bcd6_ist(

246.               .hex           (ch6_vol[15:0]),

247.                    .dec           (ch6_dec),

248.                    .clk           (clk)

249.                    );

250.

251.//16进制转化为十进制的

252.bcd bcd7_ist(

253.               .hex           (ch7_vol[15:0]),

254.                    .dec           (ch7_dec),

255.                    .clk           (clk)

256.                    );

257.

258.//16进制转化为十进制的

259.bcd bcd8_ist(

260.               .hex           (ch8_vol[15:0]),

261.                    .dec           (ch8_dec),

262.                    .clk           (clk)

263.                    );

264.

265.

266.endmodule

在这段代码中还调用了十六进制的电压值转换成 20 位BCD 码的《函数》。如下:

代码7‑3 十六进制的电压值转换成 20 位BCD 码代码

1.module bcd(clk,

2.          hex,

3.          dec);

4.

5.input  clk;

6.input  [16:0] hex;

7.output [19:0] dec;

8.

9.wire [15:0] rrhex;

10.reg [3:0] rhex[3:0];

11.

12.reg [18:0] rhexd;

13.reg [13:0] rhexc;

14.reg [9:0] rhexb;

15.reg [3:0] rhexa;

16.

17.reg [5:0] resa,resb,resc,resd;

18.reg [3:0] rese;

19.

20.assign rrhex = hex[16] ? ~hex[15:0]+1'b1 : hex[15:0];         //去符号

21.assign dec = {rese,resd[3:0],resc[3:0],resb[3:0],resa[3:0]};

22.

23.always@(posedge clk)                 //第一级寄存器

24.begin

25.    rhex[3] <= rrhex[15:12];

26.    rhex[2] <= rrhex[11:8];

27.    rhex[1] <= rrhex[7:4];

28.    rhex[0] <= rrhex[3:0];

29.end

30.

31.always@(posedge clk)                  //高4bit译码

32.begin

33.    case(rhex[3])

34.        4'h0: rhexd <= 19'h00000;

35.        4'h1: rhexd <= 19'h04096;            //0x1000 -> 4096 (十进制)

36.        4'h2: rhexd <= 19'h08192;            //0x2000 -> 8192 (十进制)

37.        4'h3: rhexd <= 19'h12288;            //0x3000 -> 12288 (十进制)

38.        4'h4: rhexd <= 19'h16384;            //0x4000 -> 16384 (十进制)

39.        4'h5: rhexd <= 19'h20480;            //0x5000 -> 20480 (十进制)

40.        4'h6: rhexd <= 19'h24576;            //0x6000 -> 24576 (十进制)

41.        4'h7: rhexd <= 19'h28672;            //0x7000 -> 28672 (十进制)

42.          4'h8: rhexd <= 19'h32768;            //0x8000 -> 32768 (十进制)

43.          4'h9: rhexd <= 19'h36864;            //0x9000 -> 36864 (十进制)

44.          4'ha: rhexd <= 19'h40960;            //0xa000 -> 40960 (十进制)

45.          4'hb: rhexd <= 19'h45056;            //0xb000 -> 45056 (十进制)

46.          4'hc: rhexd <= 19'h49152;            //0xc000 -> 49152 (十进制)

47.          4'hd: rhexd <= 19'h53248;            //0xd000 -> 53248 (十进制)

48.          4'he: rhexd <= 19'h57344;            //0xe000 -> 57344 (十进制)

49.          4'hf: rhexd <= 19'h61440;            //0xf000 -> 61440 (十进制)

50.        default: rhexd <= 19'h00000;

51.    endcase

52.end

53.

54.always@(posedge clk)                //次高4bit译码

55.begin

56.    case(rhex[2])

57.        4'h0: rhexc <= 14'h0000;

58.        4'h1: rhexc <= 14'h0256;           //0x100 -> 256 (十进制)

59.        4'h2: rhexc <= 14'h0512;           //0x200 -> 512 (十进制)

60.        4'h3: rhexc <= 14'h0768;           //0x300 -> 768 (十进制)

61.        4'h4: rhexc <= 14'h1024;           //0x400 -> 1024 (十进制)

62.        4'h5: rhexc <= 14'h1280;           //0x500 -> 1280 (十进制)

63.        4'h6: rhexc <= 14'h1536;           //0x600 -> 1536 (十进制)

64.        4'h7: rhexc <= 14'h1792;           //0x700 -> 1792 (十进制)

65.        4'h8: rhexc <= 14'h2048;           //0x800 -> 2048 (十进制)

66.        4'h9: rhexc <= 14'h2304;           //0x900 -> 2304 (十进制)

67.        4'ha: rhexc <= 14'h2560;           //0xA00 -> 2560 (十进制)

68.        4'hb: rhexc <= 14'h2816;           //0xB00 -> 2816 (十进制)

69.        4'hc: rhexc <= 14'h3072;           //0xC00 -> 3072 (十进制)

70.        4'hd: rhexc <= 14'h3328;           //0xD00 -> 3328 (十进制)

71.        4'he: rhexc <= 14'h3584;           //0xE00 -> 3584 (十进制)

72.        4'hf: rhexc <= 14'h3840;           //0xF00 -> 3840 (十进制)

73.        default: rhexc <= 14'h0000;

74.    endcase

75.end

76.

77.always@(posedge clk)

78.begin

79.    case(rhex[1])

80.        4'h0: rhexb <= 10'h000;

81.        4'h1: rhexb <= 10'h016;

82.        4'h2: rhexb <= 10'h032;

83.        4'h3: rhexb <= 10'h048;

84.        4'h4: rhexb <= 10'h064;

85.        4'h5: rhexb <= 10'h080;

86.        4'h6: rhexb <= 10'h096;

87.        4'h7: rhexb <= 10'h112;

88.        4'h8: rhexb <= 10'h128;

89.        4'h9: rhexb <= 10'h144;

90.        4'ha: rhexb <= 10'h160;

91.        4'hb: rhexb <= 10'h176;

92.        4'hc: rhexb <= 10'h192;

93.        4'hd: rhexb <= 10'h208;

94.        4'he: rhexb <= 10'h224;

95.        4'hf: rhexb <= 10'h240;

96.        default: rhexb <= 10'h000;

97.    endcase

98.end

99.

100.always@(posedge clk)

101.begin

102.    rhexa <= rhex[0];

103.end

104.

105.always@(posedge clk) //每个结果按同级单个bcd码相加,高一级的bcd码要加上低一级的进位,也就是高出4位的部分

106.begin

107.    resa = addbcd4(rhexa[3:0],rhexb[3:0],rhexc[3:0],  rhexd[3:0]);

108.    resb = addbcd4(resa[5:4], rhexb[7:4],rhexc[7:4],  rhexd[7:4]);

109.    resc = addbcd4(resb[5:4], rhexb[9:8],rhexc[11:8], rhexd[11:8]);

110.    resd = addbcd4(resc[5:4], 4'h0,      rhexc[13:12],rhexd[15:12]);

111.    rese = resd[5:4] + rhexd[18:16];

112.end

113.

114.function [5:0] addbcd4;

115.input [3:0] add1,add2,add3,add4;

116.begin

117.    addbcd4 = add1 + add2 + add3 + add4;

118.    if(addbcd4 > 6'h1d)               //>29 最低有一个可能出现0xf,但由二进制转换而来的数在这里不会出现大于40的情况

119.        addbcd4 = addbcd4 + 5'h12;

120.    else if(addbcd4 > 5'h13)          //>19对结果加12

121.        addbcd4 = addbcd4 + 4'hc;

122.    else if(addbcd4 > 4'h9)           //>9对结果加6

123.        addbcd4 = addbcd4 + 4'h6;

124.end

125.endfunction

126.

127.

128.

129.

130.endmodule

代码7‑4 串口发送程序(一)

1.`timescale 1ns / 1ps

2.//////////////////////////////////////////////////////////////////////////////////

3.//////////////////////////////////////////////////////////////////////////////////

4.module uart(

5.           input clk50,                     //50Mhz clock

6.              input reset_n,

7.

8.              input [19:0] ch1_dec,

9.              input [19:0] ch2_dec,

10.              input [19:0] ch3_dec,

11.              input [19:0] ch4_dec,

12.              input [19:0] ch5_dec,

13.              input [19:0] ch6_dec,

14.              input [19:0] ch7_dec,

15.              input [19:0] ch8_dec,

16.

17.           input [7:0] ch1_sig,

18.           input [7:0] ch2_sig,

19.           input [7:0] ch3_sig,

20.           input [7:0] ch4_sig,

21.           input [7:0] ch5_sig,

22.           input [7:0] ch6_sig,

23.           input [7:0] ch7_sig,

24.           input [7:0] ch8_sig,

25.

26.

27.           output tx

28.    );

29.

30.

31./********************************************/

32.//存储待发送的串口信息

33./********************************************/

34.reg [7:0] uart_ad [113:0];                        //存储发送的ASIC字符

35.

36.always @(clk)

37.begin     //定义发送的字符

38.   if(uart_stat==3'b000) begin

39.         uart_ad[0]<=65;                           //存储字符 A

40.         uart_ad[1]<=68;                           //存储字符 D

41.         uart_ad[2]<=49;                           //存储字符 1

42.         uart_ad[3]<=58;                           //存储字符 :

43.         uart_ad[4]<=ch1_sig;                      //存储字符 正负

44.         uart_ad[5]<=ch1_dec[19:16] + 48;          //存储字符 个位

45.         uart_ad[6]<=46;                           //存储字符 .

46.         uart_ad[7]<=ch1_dec[15:12] + 48;          //存储字符 小数点后一位

47.         uart_ad[8]<=ch1_dec[11:8] + 48;           //存储字符 小数点后二位

48.         uart_ad[9]<=ch1_dec[7:4] + 48;            //存储字符 小数点后三位

49.         uart_ad[10]<=ch1_dec[3:0] + 48;            //存储字符 小数点后四位

50.         uart_ad[11]<=86;                          //存储字符 V

51.         uart_ad[12]<=32;                          //存储字符 空格

52.         uart_ad[13]<=32;                          //存储字符 空格

53.

54.         uart_ad[14]<=65;                           //存储字符 A

55.         uart_ad[15]<=68;                           //存储字符 D

56.         uart_ad[16]<=50;                           //存储字符 2

57.         uart_ad[17]<=58;                           //存储字符 :

58.         uart_ad[18]<=ch2_sig;                      //存储字符 正负

59.         uart_ad[19]<=ch2_dec[19:16] + 48;          //存储字符 个位

60.         uart_ad[20]<=46;                           //存储字符 .

61.         uart_ad[21]<=ch2_dec[15:12] + 48;          //存储字符 小数点后一位

62.         uart_ad[22]<=ch2_dec[11:8] + 48;           //存储字符 小数点后二位

63.         uart_ad[23]<=ch2_dec[7:4] + 48;            //存储字符 小数点后三位

64.         uart_ad[24]<=ch2_dec[3:0] + 48;            //存储字符 小数点后四位

65.         uart_ad[25]<=86;                           //存储字符 V

66.         uart_ad[26]<=32;                           //存储字符 空格

67.         uart_ad[27]<=32;                           //存储字符 空格

68.

69.         uart_ad[28]<=65;                           //存储字符 A

70.         uart_ad[29]<=68;                           //存储字符 D

71.         uart_ad[30]<=51;                           //存储字符 3

72.         uart_ad[31]<=58;                           //存储字符 :

73.         uart_ad[32]<=ch3_sig;                      //存储字符 正负

74.         uart_ad[33]<=ch3_dec[19:16] + 48;          //存储字符 个位

75.         uart_ad[34]<=46;                           //存储字符 .

76.         uart_ad[35]<=ch3_dec[15:12] + 48;          //存储字符 小数点后一位

77.         uart_ad[36]<=ch3_dec[11:8] + 48;           //存储字符 小数点后二位

78.         uart_ad[37]<=ch3_dec[7:4] + 48;            //存储字符 小数点后三位

79.         uart_ad[38]<=ch3_dec[3:0] + 48;            //存储字符 小数点后四位

80.         uart_ad[39]<=86;                           //存储字符 V

81.         uart_ad[40]<=32;                           //存储字符 空格

82.         uart_ad[41]<=32;                           //存储字符 空格

83.

84.         uart_ad[42]<=65;                           //存储字符 A

85.         uart_ad[43]<=68;                           //存储字符 D

86.         uart_ad[44]<=52;                           //存储字符 4

87.         uart_ad[45]<=58;                           //存储字符 :

88.         uart_ad[46]<=ch4_sig;                      //存储字符 正负

89.         uart_ad[47]<=ch4_dec[19:16] + 48;          //存储字符 个位

90.         uart_ad[48]<=46;                           //存储字符 .

91.         uart_ad[49]<=ch4_dec[15:12] + 48;          //存储字符 小数点后一位

92.         uart_ad[50]<=ch4_dec[11:8] + 48;           //存储字符 小数点后二位

93.         uart_ad[51]<=ch4_dec[7:4] + 48;            //存储字符 小数点后三位

94.         uart_ad[52]<=ch4_dec[3:0] + 48;            //存储字符 小数点后四位

95.         uart_ad[53]<=86;                           //存储字符 V

96.         uart_ad[54]<=32;                           //存储字符 空格

97.         uart_ad[55]<=32;                           //存储字符 空格

98.

99.         uart_ad[56]<=65;                           //存储字符 A

100.         uart_ad[57]<=68;                           //存储字符 D

101.         uart_ad[58]<=53;                           //存储字符 5

102.         uart_ad[59]<=58;                           //存储字符 :

103.         uart_ad[60]<=ch5_sig;                      //存储字符 正负

104.         uart_ad[61]<=ch5_dec[19:16] + 48;          //存储字符 个位

105.         uart_ad[62]<=46;                           //存储字符 .

106.         uart_ad[63]<=ch5_dec[15:12] + 48;          //存储字符 小数点后一位

107.         uart_ad[64]<=ch5_dec[11:8] + 48;           //存储字符 小数点后二位

108.         uart_ad[65]<=ch5_dec[7:4] + 48;            //存储字符 小数点后三位

109.         uart_ad[66]<=ch5_dec[3:0] + 48;            //存储字符 小数点后四位

110.         uart_ad[67]<=86;                           //存储字符 V

111.         uart_ad[68]<=32;                           //存储字符 空格

112.         uart_ad[69]<=32;                           //存储字符 空格

113.

114.         uart_ad[70]<=65;                           //存储字符 A

115.         uart_ad[71]<=68;                           //存储字符 D

116.         uart_ad[72]<=54;                           //存储字符 6

117.         uart_ad[73]<=58;                           //存储字符 :

118.         uart_ad[74]<=ch6_sig;                      //存储字符 正负

119.         uart_ad[75]<=ch6_dec[19:16] + 48;          //存储字符 个位

120.         uart_ad[76]<=46;                           //存储字符 .

121.         uart_ad[77]<=ch6_dec[15:12] + 48;          //存储字符 小数点后一位

122.         uart_ad[78]<=ch6_dec[11:8] + 48;           //存储字符 小数点后二位

123.         uart_ad[79]<=ch6_dec[7:4] + 48;            //存储字符 小数点后三位

124.         uart_ad[80]<=ch6_dec[3:0] + 48;            //存储字符 小数点后四位

125.         uart_ad[81]<=86;                           //存储字符 V

126.         uart_ad[82]<=32;                           //存储字符 空格

127.         uart_ad[83]<=32;                           //存储字符 空格

128.

129.         uart_ad[84]<=65;                           //存储字符 A

130.         uart_ad[85]<=68;                           //存储字符 D

131.         uart_ad[86]<=55;                           //存储字符 7

132.         uart_ad[87]<=58;                           //存储字符 :

133.         uart_ad[88]<=ch7_sig;                      //存储字符 正负

134.         uart_ad[89]<=ch7_dec[19:16] + 48;          //存储字符 个位

135.         uart_ad[90]<=46;                           //存储字符 .

136.         uart_ad[91]<=ch7_dec[15:12] + 48;          //存储字符 小数点后一位

137.         uart_ad[92]<=ch7_dec[11:8] + 48;           //存储字符 小数点后二位

138.         uart_ad[93]<=ch7_dec[7:4] + 48;            //存储字符 小数点后三位

139.         uart_ad[94]<=ch7_dec[3:0] + 48;            //存储字符 小数点后四位

140.         uart_ad[95]<=86;                           //存储字符 V

141.         uart_ad[96]<=32;                           //存储字符 空格

142.         uart_ad[97]<=32;                           //存储字符 空格

143.

144.         uart_ad[98]<=65;                           //存储字符 A

145.         uart_ad[99]<=68;                           //存储字符 D

146.         uart_ad[100]<=56;                          //存储字符 8

147.         uart_ad[101]<=58;                          //存储字符 :

148.         uart_ad[102]<=ch8_sig;                     //存储字符 正负

149.         uart_ad[103]<=ch8_dec[19:16] + 48;         //存储字符 个位

150.         uart_ad[104]<=46;                          //存储字符 .

151.         uart_ad[105]<=ch8_dec[15:12] + 48;         //存储字符 小数点后一位

152.         uart_ad[106]<=ch8_dec[11:8] + 48;          //存储字符 小数点后二位

153.         uart_ad[107]<=ch8_dec[7:4] + 48;           //存储字符 小数点后三位

154.         uart_ad[108]<=ch8_dec[3:0] + 48;           //存储字符 小数点后四位

155.         uart_ad[109]<=86;                          //存储字符 V

156.         uart_ad[110]<=32;                          //存储字符 空格

157.         uart_ad[111]<=32;                          //存储字符 空格

158.

159.         uart_ad[112]<=10;                          //换行符

160.         uart_ad[113]<=13;                          //回车符

161.    end

162.end

163.

164./********************************************/

165.//串口发送时间字符串

166./********************************************/

167.reg [15:0] uart_cnt;

168.reg [2:0] uart_stat;

169.

170.reg  [7:0]  txdata;             //串口发送字符

171.reg         wrsig;               //串口发送有效信号

172.

173.reg [8:0] k;

174.

175.reg [15:0] Time_wait;

176.

177.always @(posedge clk )

178.begin

179.  if(!reset_n) begin

180.        uart_cnt<=0;

181.        uart_stat<=3'b000;

182.        k<=0;

183.  end

184.  else begin

185.     case(uart_stat)

186.     3'b000: begin

187.       if (Time_wait == 16'hffff) begin          //如果秒数据有变化

188.            uart_stat<=3'b001;

189.             Time_wait<=0;

190.         end

191.         else begin

192.             uart_stat<=3'b000;

193.             Time_wait<=Time_wait + 1'b1;

194.         end

195.     end

196.     3'b001: begin

197.         if (k == 113 ) begin           //发送第112个字符

198.                 if(uart_cnt ==0) begin

199.                    txdata <= uart_ad[113];

200.                    uart_cnt <= uart_cnt + 1'b1;

201.                    wrsig <= 1'b1;

202.                 end

203.                 else if(uart_cnt ==254) begin

204.                    uart_cnt <= 0;

205.                    wrsig <= 1'b0;

206.                    uart_stat <= 3'b010;

207.                    k <= 0;

208.                 end

209.                 else   begin

210.                     uart_cnt <= uart_cnt + 1'b1;

211.                     wrsig <= 1'b0;

212.                 end

213.         end

214.        else begin                      //发送前111个字符

215.                 if(uart_cnt ==0) begin

216.                    txdata <= uart_ad[k];

217.                    uart_cnt <= uart_cnt + 1'b1;

218.                    wrsig <= 1'b1;

219.                 end

220.                 else if(uart_cnt ==254) begin

221.                    uart_cnt <= 0;

222.                    wrsig <= 1'b0;

223.                    k <= k + 1'b1;

224.                 end

225.                 else   begin

226.                     uart_cnt <= uart_cnt + 1'b1;

227.                     wrsig <= 1'b0;

228.                 end

229.         end

230.     end

231.     3'b010: begin       //发送finish

232.            uart_stat <= 3'b000;

233.     end

234.     default:uart_stat <= 3'b000;

235.    endcase

236.  end

237.end

238.

239./**********产生串口时钟***********/

240.clkdiv u0 (

241.        .clk50                   (clk50),

242.        .clkout                  (clk)             //串口发送时钟

243. );

244.

245./*************串口发送程序************/

246.uarttx u1 (

247.        .clk                     (clk),

248.        .datain                  (txdata),

249.      .wrsig                   (wrsig),

250.      .idle                    (idle),

251.       .tx                      (tx)

252. );

253.

254.

255.

256.endmodule

代码7‑5 串口发送程序(二)

1.`timescale 1ns / 1ps

2.//////////////////////////////////////////////////////////////////////////////////

3.// Module Name:    uarttx //

4.//////////////////////////////////////////////////////////////////////////////////

5.module uarttx(clk, datain, wrsig, idle, tx);

6.input clk;                //UART时钟

7.input [7:0] datain;       //需要发送的数据

8.input wrsig;              //发送命令,上升沿有效

9.output idle;              //线路状态指示,高为线路忙,低为线路空闲

10.output tx;                //发送数据信号

11.reg idle, tx;

12.reg send;

13.reg wrsigbuf, wrsigrise;

14.reg presult;

15.reg[7:0] cnt;             //计数器

16.parameter paritymode = 1'b0;

17.

18.//检测发送命令是否有效

19.always @(posedge clk)

20.begin

21.   wrsigbuf <= wrsig;

22.   wrsigrise <= (~wrsigbuf) & wrsig;

23.end

24.

25.always @(posedge clk)

26.begin

27.  if (wrsigrise &&  (~idle))  //当发送命令有效且线路为空闲时,启动新的数据发送进程

28.  begin

29.     send <= 1'b1;

30.  end

31.  else if(cnt == 8'd168)      //一帧资料发送结束

32.  begin

33.     send <= 1'b0;

34.  end

35.end

36.

37.always @(posedge clk)

38.begin

39.  if(send == 1'b1)  begin

40.    case(cnt)                 //产生起始位

41.    8'd0: begin

42.         tx <= 1'b0;

43.         idle <= 1'b1;

44.         cnt <= cnt + 8'd1;

45.    end

46.    8'd16: begin

47.         tx <= datain[0];    //发送数据0位

48.         presult <= datain[0]^paritymode;

49.         idle <= 1'b1;

50.         cnt <= cnt + 8'd1;

51.    end

52.    8'd32: begin

53.         tx <= datain[1];    //发送数据1位

54.         presult <= datain[1]^presult;

55.         idle <= 1'b1;

56.         cnt <= cnt + 8'd1;

57.    end

58.    8'd48: begin

59.         tx <= datain[2];    //发送数据2位

60.         presult <= datain[2]^presult;

61.         idle <= 1'b1;

62.         cnt <= cnt + 8'd1;

63.    end

64.    8'd64: begin

65.         tx <= datain[3];    //发送数据3位

66.         presult <= datain[3]^presult;

67.         idle <= 1'b1;

68.         cnt <= cnt + 8'd1;

69.    end

70.    8'd80: begin

71.         tx <= datain[4];    //发送数据4位

72.         presult <= datain[4]^presult;

73.         idle <= 1'b1;

74.         cnt <= cnt + 8'd1;

75.    end

76.    8'd96: begin

77.         tx <= datain[5];    //发送数据5位

78.         presult <= datain[5]^presult;

79.         idle <= 1'b1;

80.         cnt <= cnt + 8'd1;

81.    end

82.    8'd112: begin

83.         tx <= datain[6];    //发送数据6位

84.         presult <= datain[6]^presult;

85.         idle <= 1'b1;

86.         cnt <= cnt + 8'd1;

87.    end

88.    8'd128: begin

89.         tx <= datain[7];    //发送数据7位

90.         presult <= datain[7]^presult;

91.         idle <= 1'b1;

92.         cnt <= cnt + 8'd1;

93.    end

94.    8'd144: begin

95.         tx <= presult;      //发送奇偶校验位

96.         presult <= datain[0]^paritymode;

97.         idle <= 1'b1;

98.         cnt <= cnt + 8'd1;

99.    end

100.    8'd160: begin

101.         tx <= 1'b1;         //发送停止位

102.         idle <= 1'b1;

103.         cnt <= cnt + 8'd1;

104.    end

105.    8'd168: begin

106.         tx <= 1'b1;

107.         idle <= 1'b0;       //一帧资料发送结束

108.         cnt <= cnt + 8'd1;

109.    end

110.    default: begin

111.          cnt <= cnt + 8'd1;

112.    end

113.   endcase

114.  end

115.  else  begin

116.    tx <= 1'b1;

117.    cnt <= 8'd0;

118.    idle <= 1'b0;

119.  end

120.end

121.endmodule

最后就是将上诉代码进行封装,封装后的程序如下:

代码7‑6 封装后的代码

1.`timescale 1ns / 1ps

2.//////////////////////////////////////////////////////////////////////////////////

3.// Module Name:    ad706_test

4.//////////////////////////////////////////////////////////////////////////////////

5.module ad706_test(

6.   input        clk,                  //50mhz

7.    //input        rst_n,

8.

9.    input [15:0] ad_data,            //ad7606 采样数据

10.    input        ad_busy,            //ad7606 忙标志位

11.   input        first_data,         //ad7606 第一个数据标志位

12.    output [2:0] ad_os,              //ad7606 过采样倍率选择

13.    output       ad_cs,              //ad7606 AD cs

14.    output       ad_rd,              //ad7606 AD data read

15.    output       ad_reset,           //ad7606 AD reset

16.    output       ad_convstab,         //ad7606 AD convert start

17.

18.    input        rx,

19.    output       tx

20.

21.

22.    );

23.

24.

25.wire [15:0] ad_ch1;

26.wire [15:0] ad_ch2;

27.wire [15:0] ad_ch3;

28.wire [15:0] ad_ch4;

29.wire [15:0] ad_ch5;

30.wire [15:0] ad_ch6;

31.wire [15:0] ad_ch7;

32.wire [15:0] ad_ch8;

33.

34.wire [19:0] ch1_dec;

35.wire [19:0] ch2_dec;

36.wire [19:0] ch3_dec;

37.wire [19:0] ch4_dec;

38.wire [19:0] ch5_dec;

39.wire [19:0] ch6_dec;

40.wire [19:0] ch7_dec;

41.wire [19:0] ch8_dec;

42.

43.wire [7:0] ch1_sig;

44.wire [7:0] ch2_sig;

45.wire [7:0] ch3_sig;

46.wire [7:0] ch4_sig;

47.wire [7:0] ch5_sig;

48.wire [7:0] ch6_sig;

49.wire [7:0] ch7_sig;

50.wire [7:0] ch8_sig;

51.

52.wire rst_n=1'b1;

53.

54.ad7606 u1(

55.    .clk              (clk),

56.    .rst_n            (rst_n),

57.    .ad_data          (ad_data),

58.    .ad_busy          (ad_busy),

59.    .first_data       (first_data),

60.    .ad_os            (ad_os),

61.    .ad_cs            (ad_cs),

62.    .ad_rd            (ad_rd),

63.    .ad_reset         (ad_reset),

64.    .ad_convstab      (ad_convstab),

65.    .ad_ch1           (ad_ch1),           //ch1 ad data 16bit

66.    .ad_ch2           (ad_ch2),           //ch2 ad data 16bit

67.    .ad_ch3           (ad_ch3),           //ch3 ad data 16bit

68.    .ad_ch4           (ad_ch4),           //ch4 ad data 16bit

69.    .ad_ch5           (ad_ch5),           //ch5 ad data 16bit

70.    .ad_ch6           (ad_ch6),           //ch6 ad data 16bit

71.    .ad_ch7           (ad_ch7),           //ch7 ad data 16bit

72.    .ad_ch8           (ad_ch8)            //ch8 ad data 16bit

73.

74.

75.    );

76.

77./**********电压转换程序***********/

78.volt_cal u2(

79.    .clk              (clk),

80.    .ad_reset         (ad_reset),

81.    .ad_ch1           (ad_ch1),           //ch1 ad data 16bit (input)

82.    .ad_ch2           (ad_ch2),           //ch2 ad data 16bit (input)

83.    .ad_ch3           (ad_ch3),           //ch3 ad data 16bit (input)

84.    .ad_ch4           (ad_ch4),           //ch4 ad data 16bit (input)

85.    .ad_ch5           (ad_ch5),           //ch5 ad data 16bit (input)

86.    .ad_ch6           (ad_ch6),           //ch6 ad data 16bit (input)

87.    .ad_ch7           (ad_ch7),           //ch7 ad data 16bit (input)

88.    .ad_ch8           (ad_ch8),           //ch8 ad data 16bit (input)

89.

90.    .ch1_dec           (ch1_dec),         //ch1 ad voltage (output)

91.    .ch2_dec           (ch2_dec),         //ch2 ad voltage (output)

92.    .ch3_dec           (ch3_dec),         //ch3 ad voltage (output)

93.    .ch4_dec           (ch4_dec),         //ch4 ad voltage (output)

94.    .ch5_dec           (ch5_dec),         //ch5 ad voltage (output)

95.    .ch6_dec           (ch6_dec),         //ch6 ad voltage (output)

96.    .ch7_dec           (ch7_dec),         //ch7 ad voltage (output)

97.    .ch8_dec           (ch8_dec),         //ch8 ad voltage (output)

98.

99.   .ch1_sig           (ch1_sig),         //ch1 ad 正负 (output)

100.    .ch2_sig           (ch2_sig),         //ch2 ad 正负 (output)

101.    .ch3_sig           (ch3_sig),         //ch3 ad 正负 (output)

102.    .ch4_sig           (ch4_sig),         //ch4 ad 正负 (output)

103.    .ch5_sig           (ch5_sig),         //ch5 ad 正负 (output)

104.    .ch6_sig           (ch6_sig),         //ch6 ad 正负 (output)

105.    .ch7_sig           (ch7_sig),         //ch7 ad 正负 (output)

106.    .ch8_sig           (ch8_sig)          //ch8 ad 正负 (output)

107.

108.    );

109.

110./**********AD数据Uart串口发送程序***********/

111.uart u3(

112.        .clk50                      (clk),

113.        .reset_n                 (rst_n),

114.

115.        .ch1_dec                 (ch1_dec),         //ad1 BCD voltage

116.        .ch2_dec                 (ch2_dec),         //ad2 BCD voltage

117.        .ch3_dec                 (ch3_dec),         //ad3 BCD voltage

118.        .ch4_dec                 (ch4_dec),         //ad4 BCD voltage

119.        .ch5_dec                 (ch5_dec),         //ad5 BCD voltage

120.        .ch6_dec                 (ch6_dec),         //ad6 BCD voltage

121.        .ch7_dec                 (ch7_dec),         //ad7 BCD voltage

122.        .ch8_dec                 (ch8_dec),         //ad8 BCD voltage

123.

124.        .ch1_sig                 (ch1_sig),          //ch1 ad 正负

125.        .ch2_sig                 (ch2_sig),          //ch2 ad 正负

126.        .ch3_sig                 (ch3_sig),          //ch3 ad 正负

127.        .ch4_sig                 (ch4_sig),          //ch4 ad 正负

128.        .ch5_sig                 (ch5_sig),          //ch5 ad 正负

129.        .ch6_sig                 (ch6_sig),          //ch6 ad 正负

130.        .ch7_sig                 (ch7_sig),          //ch7 ad 正负

131.        .ch8_sig                 (ch8_sig),          //ch8 ad 正负

132.

133.        .tx                      (tx)

134.

135.

136.    );

137.

138.

139.

140.endmodule

上诉代码在进行封装时,参考图7‑15,将上诉代码进行综合,综合后的电路如下:

图7‑16 综合后的RTL电路

将程序下载到 FPGA 中。打开串口调试助手工具,设置串口的通信波特率如下。

图7‑17 串口上位机设置

串口通信里会出现 AN706 AD 模块的8路信号输入的电压值。

图7‑18 串口助手接收的8通道数据

以上的数据为8路没有信号输入的数据,因为 AD 信号输入处于悬空的状态,AD 转换输出的数据为 1.75V 左右。

通过外加电压和高精度的电压表的测量比较, AD706 的实际测量精度在-5V~+5V电压输入范围之内高达 0.5mV 以内。

下表为我们8个通道对四个模拟电压的测试结果,第一列基准电压为高精度数字万用表测量的数据,后面8列为 AN706 的 AD 模块测量的结果。

表7‑5 测量精度对比

在本测试例程,尚未使用过采样倍率使能过滤器来提高 AD 的精度,对于想进一步提高采样的精度的用户而对采样的速度要求不高的情况下,可以在程序里采用设置过采样倍率的方法。

(0)

相关推荐

  • 【精品博文】串口接收模块电路设计

    概述 串口通信指串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据.这里主要讲解串口接收模块的电路设计. 图1 串口传输时 ...

  • 二进制转BCD码

    应用: 用fpga实现对数码管显示,以前通常的方法是进行整除和取余进行运算,但是fpga并不擅长乘法除法运算,所以可以用BCD码来转换. BCD码:通俗的可以理解为用四位二进制数表示一位十进制数字.例 ...

  • 凔海笔记之FPGA(八):Verilog描述RS232 UART

    在我看来,有些代码会用,但未必理解,有些代码理解,但未必会写,有些代码会写,但未必能用自己的话说出来.当能够以自己的想法深入浅出的讲解所学知识,那也就可以说自己掌握了,所以,我还是来发帖吧. 记得刚用 ...

  • 一天一个设计实例-基于FPGA的数模转换器应用设计

    基于FPGA的数模转换器应用设计 1.1.1带 EEPROM 存储器的 12 位MCP4725应用设计 7.4.1.1 MCP4725简介 MCP4725 是低功耗.高精度.单通道的 12 位缓冲电压 ...

  • 一天一个设计实例-基于FPGA的模数、数模转换器应用设计

    基于FPGA的模数.数模转换器应用设计 本节设计采用黑金ADDA模块,模块硬件结构如下: 图7‑32 硬件结构 数模转换( DA) 电路 如硬件结构图所示, DA 电路由高速 DA 芯片. 7 阶巴特 ...

  • 一天一个设计实例-Xilinx FPGA命名规则

    Xilinx的ug112第一章中介绍了Xilinx公司的FPGA命名规则.一般而言,大的FPGA的上表面是这个样子的: 图1‑29 Xilinx FPGA器件表面 譬如,对于编号为XC4VLX60-1 ...

  • 基于FPGA的网口通信设计(完结)

    目前,所有相关的<基于FPGA的网口通信设计>都更新完毕,之前答应大家5月底完成更新,正好趁着这个周末完成了更新.      详细目录如下: 基于FPGA的网口通信设计 例说七层OSI参考 ...

  • 干货!基于FPGA之低速协议设计实验手稿及源码

    来源:EETOP BBS    作者:qinzhanao 该资料为网友:qinzhanao 原创,已分享在EETOP论坛,非常适合FPGA入门学习与提高. 内容包括: FPGA学习方法 SPI接口实现 ...

  • 基于FPGA之低速协议设计实验手稿及源码

    这是一个非常好的FPGA入门学习资料,作者:qinzhanao(EETOP). 内容包括: FPGA学习方法 SPI接口实现 UART接口实现 PS2接口实现 IIC接口实现 VGA几口实现

  • 【学术论文】基于FPGA的3D图像传感器设计与实现

    摘要: 针对现有3D拍摄设备体积庞大.价格昂贵等问题,利用FPGA高速并行处理能力与图像传感器,设计了微型嵌入式3D图像传感器.通过FPGA同步设置,采集双CMOS图像传感器图像数据,传输至SDRAM ...

  • 【原创博文】基于FPGA的异步FIFO设计

    今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...

  • 【精品博文】基于FPGA的原理图PCB设计 | 电源供电方案选择

    由于FPGA的可编程性,同一芯片在不同应用需求下,使用的逻辑资源不一样时,功率可能会有很大差别,因此在不同应用下可根据功率等来选择不同电源方案. 之前看到看过大牛crazybingo写的一篇关于电源方 ...