FPGA实现的数模转换技术探索

FPGA实现的数模转换

D/A 转换器在电子系统中应用极为广泛,除了在微机系统中将数字量转化为模拟量典型应用之外,还常用于波形生成、各种数字式的可编程应用

数字信号通常要用二进制的数来表示数的大小,按照“位权”的定义原则,每一位二进制代码根据其在数据中的位置不同,分别表示不同的值,为了将数字量转换成模拟量,必须将每一位的代码按其权的大小转换成相应的模拟量,然后将这些模拟量相加,得到与数字量成正比的总模拟量,这就是D/A转换的基本思路。

在D/A转换过程中,输入的数字信号是二进制编码。通过转换,将该编码按每位权的大小换算成相应的模拟量,然后将代表各位数字的模拟量相加,得到的和就是与输入的数字信号成正比的模拟量。

以下是通过调用两个模块实现数模转换:

顶层模块:

module DA(clk, rst_n, load, ldac, da_clk, da_data, sel, seg);

 input           clk;

 input           rst_n;

 

 output          load;

 output          ldac;

 output          da_clk;     //最大1MHz

 output          da_data;

 output    [2:0] sel;

 output    [7:0] seg;

 

 wire [12:0] data;

 DA_driver DA_driver_inst(

   .clk        (clk),

   .rst_n      (rst_n),

   .load       (load),

   .ldac       (ldac),

   .da_clk     (da_clk),

   .da_data    (da_data),

   .data       (data)

 );

 seven_tube_driver seven_tube_driver_inst(

   .clk        (clk),

   .rst_n      (rst_n),

   .data       (data),

   .sel        (sel),    

   .seg        (seg)

 );

endmodule

DA_drive模块:data的每一位显示在相应的数码管上,在da-clk的上升沿给da_data赋值,赋值显示在程序中,data赋值之后给数码管现实

module DA_driver(clk, rst_n, load, ldac, da_clk, da_data, data);

 input       clk;

 input       rst_n;

 

 

 output   reg   load;

 output         ldac;

 output   reg   da_clk;

 output   reg   da_data;

 

 output  [12:0] data;

 

 parameter code = 8'd150;

 parameter RNG = 1;

 parameter selet = 2'b00;

 parameter t = 550;

 

 reg [9:0] cnt;

 

 assign ldac = 1'b0;

 always @ (posedge clk, negedge rst_n)

 begin

   if(rst_n == 1'b0)

     cnt <= 10'd0;

   else if(cnt == t - 1)

     cnt <= 10'd0;

   else

     cnt <= cnt + 1'b1;

 end

 always @ (posedge clk, negedge rst_n)

 begin

   if(rst_n == 1'b0)

     begin

       load <= 1'b1;

       da_clk <= 1'b0;

       da_data <= 1'b0;

     end

   else

     case(cnt)

       0 : begin

             da_clk <= 1'b1;

             da_data <= selet[1];

           end

       24  : da_clk <= 1'b0;

       49  : begin

               da_clk <= 1'b1;

               da_data <= selet[0];

             end

       74  : da_clk <= 1'b0;

       99  : begin

               da_clk <= 1'b1;

               da_data <= RNG;

             end

       124 : da_clk <= 1'b0;

       149 : begin

               da_clk <= 1'b1;

               da_data <= code[7];

             end

       174 : da_clk <= 1'b0;

       199 : begin

               da_clk <= 1'b1;

               da_data <= code[6];

             end

       224 : da_clk <= 1'b0;

       249 : begin

               da_clk <= 1'b1;

               da_data <= code[5];

             end

       274 : da_clk <= 1'b0;

       299 : begin

               da_clk <= 1'b1;

               da_data <= code[4];

             end

       324 : da_clk <= 1'b0;

       349 : begin

               da_clk <= 1'b1;

               da_data <= code[3];

             end

       374 : da_clk <= 1'b0;

       399 : begin

               da_clk <= 1'b1;

               da_data <= code[2];

             end

       424 : da_clk <= 1'b0;

       449 : begin

               da_clk <= 1'b1;

               da_data <= code[1];

             end

       474 : da_clk <= 1'b0;

       499 : begin

               da_clk <= 1'b1;

               da_data <= code[0];

             end

       524 : da_clk <= 1'b0;

       529 : load <= 1'b0;

       544 : load <= 1'b1;

       549 : ;      550做一个循环

       default:  ;

     endcase

 end

 assign data = 2500 * code / 256 * (1 + RNG);

endmodule

module seven_tube_driver模块:数码管控制模块

module seven_tube_driver(clk, rst_n, data, sel, seg);

 input         clk;

 input         rst_n;

 

 input   [12:0]    data;

 

 output  reg [2:0] sel;

 output      [7:0] seg;

 

 parameter t = 50_000;  五十分频的时钟

 reg [15:0] cnt;

 reg flag;

 

 always @ (posedge clk, negedge rst_n)

 begin

   if(rst_n == 1'b0)

     begin

       cnt <= 16'd0;

       flag <= 1'b0;

     end

   else if(cnt == t - 1)

     begin

       cnt <= 16'd0;

       flag <= 1'b1;

     end

   else

     begin

       cnt <= cnt + 1'b1;

       flag <= 1'b0;

     end

 end

 

 always @ (posedge clk, negedge rst_n)

 begin

   if(rst_n == 1'b0)

     sel <= 3'b010;

   else if(flag)

     begin

       if(sel == 3'b101)

         sel <= 3'b010;

       else

         sel <= sel + 1'b1;

     end

   else

     sel <= sel;

 end

 

 reg [3:0] show_data;

 

 always @ (*)

 begin

   case(sel)

//      3'b000  : show_data = data/100000;

//      3'b001  : show_data = data/10000%10;

     3'b010  : show_data = data/1000;

     3'b011  : show_data = data/100%10;

     3'b100  : show_data = data/10%10;

     3'b101  : show_data = data%10;

     default : show_data = 0;

   endcase

 end

 

 reg [7:0] seg_r;

 

 always @ (*)

 begin

   case(show_data)

     0  : seg_r = 8'b1100_0000;

     1  : seg_r = 8'b1111_1001;

     2  : seg_r = 8'b1010_0100;

     3  : seg_r = 8'b1011_0000;

     4  : seg_r = 8'b1001_1001;

     5  : seg_r = 8'b1001_0010;

     6  : seg_r = 8'b1000_0010;

     7  : seg_r = 8'b1111_1000;

     8  : seg_r = 8'b1000_0000;

     9  : seg_r = 8'b1001_0000;

     default : seg_r = 8'b1111_1111;

   endcase

 end

 

 assign seg = (sel == 3'b010) ? seg_r & 8'b0111_1111 : seg_r;

endmodule


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空