集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
楼主: lcytms

FPGA初级课程第二十二讲 AD

[复制链接]
 楼主| lcytms 发表于 2017-2-8 20:29:05 | 显示全部楼层
进行分析综合检查。
进行仿真设置。
查看仿真结果。
片选信号cs_n被拉低后,adc_clk依次输出8个脉冲。
adc_clk时钟上升沿采样,下降沿时数据更新。
随后片选信号cs_n置高。
时间间隔与设计要求一致。
仿真功能正确。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 20:32:31 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-8 20:35 编辑

向工程文件夹添加第四讲的数码管模块seg7.v。
module seg7 (clk, rst_n, data, sel, seg);

        input clk, rst_n;
        input [23:0] data;
       
        output reg [2:0] sel;
        output reg [7:0] seg;
       
        reg clk_1k;
       
        parameter T1ms = 25_000;                //half_width
        reg [19:0] count;
       
        always @ (posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        count <= 0;
                                        clk_1k <= 1;
                                end
                        else
                                begin
                                        if (count < T1ms - 1)
                                                begin
                                                        count <= count + 20'b1;
                                                end
                                        else
                                                begin
                                                        count <= 0;
                                                        clk_1k <= ~clk_1k;
                                                end
                                end
                end
       
        reg [2:0] state;
        reg [3:0] data_temp;
       
        always @ (posedge clk_1k or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        sel <= 3'b000;
                                        state <= 0;
                                end
                        else
                                begin
                                        case (state)
                                        0        :        begin
                                                                sel <= 3'b000;
                                                                data_temp <= data[23:20];
                                                                state <= 1;
                                                        end
                                                       
                                        1        :        begin
                                                                sel <= 3'b001;
                                                                data_temp <= data[19:16];
                                                                state <= 2;
                                                        end
                                                       
                                        2        :        begin
                                                                sel <= 3'b010;
                                                                data_temp <= data[15:12];
                                                                state <= 3;
                                                        end
                                                       
                                        3        :        begin
                                                                sel <= 3'b011;
                                                                data_temp <= data[11:8];
                                                                state <= 4;
                                                        end
                                                       
                                        4        :        begin
                                                                sel <= 3'b100;
                                                                data_temp <= data[7:4];
                                                                state <= 5;
                                                        end
                                                       
                                        5        :        begin
                                                                sel <= 3'b101;
                                                                data_temp <= data[3:0];
                                                                state <= 0;
                                                        end
                                                       
                                        default        :        state <= 0;
                                       
                                        endcase
                                end
                end

        always @ (*)
                begin
                        if (!rst_n)
                                begin
                                        seg = 8'b1111_1111;                //null
                                end
                        else
                                begin
                                        case (data_temp)
                                        0        :        seg = 8'b1100_0000;                //d0
                                        1        :        seg = 8'b1111_1001;                //d1
                                        2        :        seg = 8'b1010_0100;                //d2
                                        3        :        seg = 8'b1011_0000;                //d3
                                        4        :        seg = 8'b1001_1001;                //d4
                                        5        :        seg = 8'b1001_0010;                //d5
                                        6        :        seg = 8'b1000_0010;                //d6
                                        7        :        seg = 8'b1111_1000;                //d7
                                        8        :        seg = 8'b1000_0000;                //d8
                                        9        :        seg = 8'b1001_0000;                //d9
                                        10        :        seg = 8'b1000_1000;                //dA
                                        11        :        seg = 8'b1000_0011;                //db
                                        12        :        seg = 8'b1100_0110;                //dC
                                        13        :        seg = 8'b1010_0001;                //dd
                                        14        :        seg = 8'b1000_0110;                //dE
                                        15        :        seg = 8'b1000_1110;                //dF
                                        default        :        seg = 8'b1111_1111;                //null
                                        endcase
                                end
                end

endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 20:37:23 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-8 20:45 编辑

新建数码管数据预处理模块pre_seg7.v。
module pre_seg7(clk, rst_n, data_in, BCD4);
       
        input        clk, rst_n;
        input [7:0] data_in;
       
        output [15:0] BCD4;                                   //数码管显示数据

        reg [11:0] data;                                          //转换后的数据

        parameter T100ms = 5_000_000;                // time to update data for display
       
        reg [25:0] cnt100ms;
       
        always @(posedge clk or negedge rst_n)
                begin
                        if (!rst_n)
                                begin
                                        cnt100ms <= 0;
                                        data <= 0;
                                end
                        else
                                begin
                                        if (cnt100ms < T100ms - 1)
                                                cnt100ms <= cnt100ms + 26'd1;
                                        else
                                                begin
                                                        cnt100ms <= 0;
                                                        data <= (data_in * 2500) / 256;
                                                end
                                end
                end
       
        assign BCD4[ 3: 0] =  data % 10;
        assign BCD4[ 7: 4] =  data / 10 % 10;
        assign BCD4[11: 8] =  data / 100 % 10;
        assign BCD4[15:12] =  data / 1000 % 10;
       
endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 20:47:43 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-8 20:50 编辑

新建数码管显示后处理模块post_seg7.v。
module post_seg7 (sel, seg_o, seg);

        input [2:0] sel;
        input [7:0] seg_o;
       
        output reg [7:0] seg;
       
        always @ (*)
                begin
                        case (sel)
                        0        :        seg = 8'b1111_1111;                // null
                        1        :        seg = 8'b1111_1111;                // null
                        2        :        seg = {1'b0, seg_o[6:0]};                // add decimal point
                        default        :        seg = seg_o;
                        endcase
                end

endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 20:53:42 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-8 20:55 编辑

新建top.v顶层模块,将以上四个模块都加入到top.v顶层模块中进行例化。
将top.v模块设置为顶层模块。
编写top.v模块如下。
module top(clk, rst_n, adc_in, cs_n, adc_clk, sel, seg);

        input clk, rst_n;
        input adc_in;                  //输入串行数据

        output adc_clk;                 //输出 I/O CLOCK
        output cs_n;                    //片选信号 低有效
        output [2:0] sel;        
        output [7:0] seg;

        wire [7:0] data8;
        wire [15:0] BCD4;
        wire [7:0] seg_o;
       
        adc adc(.clk(clk), .rst_n(rst_n), .sid(adc_in), .adc_clk(adc_clk), .cs_n(cs_n), .data(data8));
               
        pre_seg7 pre_seg7(.clk(clk), .rst_n(rst_n), .data_in(data8), .BCD4(BCD4));       

        seg7 seg7 (.clk(clk), .rst_n(rst_n), .data({8'b0, BCD4}), .sel(sel), .seg(seg_o));
       
        post_seg7 post_seg7 (.sel(sel), .seg_o(seg_o), .seg(seg));

endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 20:58:06 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-8 20:59 编辑

运行.tcl文件设置好FPGA管脚

将ad.tcl文件拷贝到工程文件夹的根目录下面。
在主界面Tools菜单下选择Tcl scripts,运行ad.tcl文件,对FPGA芯片管脚进行设置。

ad.tcl文件相关内容如下所示。

        #set_global_assignment -name FAMILY "Cyclone IV"
        #set_global_assignment -name DEVICE ep4ce6e22c8n

set_location_assignment PIN_23 -to    clk        

# KEY 轻触按键
set_location_assignment PIN_69 -to   rst_n         

# AD
set_location_assignment PIN_99 -to  adc_clk
set_location_assignment PIN_87 -to  adc_in
set_location_assignment PIN_98 -to  cs_n                  
                        
         
# SEG7 x 8 七段数码管
set_location_assignment PIN_119 -to   sel[2]
set_location_assignment PIN_115 -to   sel[1]
set_location_assignment PIN_114 -to   sel[0]
set_location_assignment PIN_127 -to   seg[0]     
set_location_assignment PIN_128 -to   seg[1]   
set_location_assignment PIN_124 -to   seg[2]     
set_location_assignment PIN_121 -to   seg[3]     
set_location_assignment PIN_120 -to   seg[4]     
set_location_assignment PIN_126 -to   seg[5]     
set_location_assignment PIN_129 -to   seg[6]     
set_location_assignment PIN_125 -to   seg[7]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 21:01:10 | 显示全部楼层
FPGA芯片配置结果如图所示。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 21:03:34 | 显示全部楼层
.sof文件下载到FPGA
全编译FPGA工程,生成.sof文件,连接至芯ZX-2开发板并上电。
打开Programmer通过Jtag口,将.sof文件下载到FPGA进行在线仿真。
.sof文件下载界面如下图所示。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 21:06:08 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-8 21:08 编辑

开发板运行效果
开发板运行效果如下图所示。
经检查,开发板运行效果与设计相符。

程序下载后,使用一字改锥调整蓝色可变电阻器的阻值。
观察数码管显示电压值,并使用数字万用表测量开发板上的AD芯片模拟电压输入脚(2脚ANIN)的实际电压,比较二者是否一致。
比如,数码管显示1.250,同时数字万用表测得模拟电压值为1.24V。
功能验证正确。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| lcytms 发表于 2017-2-8 21:09:03 | 显示全部楼层
本帖最后由 lcytms 于 2017-2-9 11:29 编辑

好了,今天的课程就讲到这里。
通过今天的课程,我们学习了AD转换芯片工作的基本原理,并对AD驱动逻辑电路进行了建模、仿真,结合第四讲的数码管一起编写一个完整的演示逻辑,进行了下板检查。
希望大家掌握AD转换芯片工作的基本原理,并熟练运用Verilog语言编写相关驱动逻辑。
另外,我们在第二十一讲 SPI中讲到了SPI串行外设接口的基本原理,大家可以结合本次课程学习的基于SPI协议进行通信控制的AD转换芯片TLC549驱动应用案例,加深对SPI驱动逻辑的理解。
更复杂的知识和技巧我们将逐步通过后面的课程展现给大家。

课程到此结束,谢谢大家的关注!
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-5-19 11:58 , Processed in 0.090294 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表