zoukankan      html  css  js  c++  java
  • [原创].串行ADC TLC549读取实验,Verilog版本

    原理图

    image

    时序图

    image

    image

    笔记

    image

    源代码

    顶层文件

    module tlc_549_test(
      input  CLOCK_50, // 板载50MHz时钟 
      input  RST_N,
      //
      output ADC549_CLK,
      output ADC549_CS_N,
      input ADC549_DATA,
      //
      output [7:0] SEG7_SEG, // 七段数码管 段脚              
      output [7:0] SEG7_DIG  // 七段数码管 位脚 
    );
    
    wire [7:0] ad_data;
    tlc549_driver tlc549_driver_inst(
        .CLOCK_50(CLOCK_50),
        .RST_N(RST_N),
        //
        .ad_enable(1'b1),
        .ad_data(ad_data),
        // 
        .nCS(ADC549_CS_N),
        .SCK(ADC549_CLK),
        .SDO(ADC549_DATA)
    );
    
    seg7x8_drive u0(
      .i_clk            (CLOCK_50),
      .i_rst_n          (RST_N),
      
      .i_turn_off       (8'b1111_1100), // 熄灭位[2进制]
      .i_dp             (8'b0000_0000), // 小数点位[2进制]
      .i_data           (ad_data), // 欲显数据[16进制]
      
      .o_seg            (SEG7_SEG),
      .o_dig            (SEG7_DIG)
    );
    
    endmodule
    

    数码管驱动http://www.cnblogs.com/yuphone/archive/2011/04/24/2026318.html

    TLC549驱动

    module tlc549_driver
    (
        input CLOCK_50,
        input RST_N,
        //
        input ad_enable,
        output reg [7:0] ad_data,
        // 
        output reg nCS,
        output reg SCK,
        input SDO
    );
    
    function integer log2(input integer n);
        integer i;
        for(i=0; 2**i <=n; i=i+1) log2=i+1;
    endfunction
    
    /**************************************
    * 生成40ns的tick时钟
    **************************************/
    reg cnt_40ns;
    always@(posedge CLOCK_50) cnt_40ns <= cnt_40ns + 1'b1;
    wire tick_40ns = (cnt_40ns == 1'b1) ? 1 : 0;
    
    /**************************************
    * 根据tick时钟生成ad基准计数器
    **************************************/
    reg [log2(700):1] ad_ref_cnt; // [0,700]
    always@(posedge CLOCK_50, negedge RST_N)
        if(!RST_N) ad_ref_cnt <= 0;
        else begin
            if(!ad_enable) ad_ref_cnt <= 0;
            else begin
                if(tick_40ns) begin
                    if(ad_ref_cnt < 700) 
                        ad_ref_cnt <= ad_ref_cnt + 1'b1;
                    else ad_ref_cnt <= 0;
                end
            end
        end
        
    /**************************************
    * 根据基准计数器生成串行信号
    **************************************/
    reg samping_flag; // 采样标志
    always@(posedge CLOCK_50, negedge RST_N)
        if(!RST_N) begin
            nCS <= 1;
            SCK <= 0;
            samping_flag <= 0;
        end
        else begin
            if(tick_40ns) begin
                case(ad_ref_cnt)
                    // 采样期
                    36,58,80,102,124,146,168,190 : SCK <= 1;
                    48,70,92,114,136,158,180,202 : SCK <= 0;          
                    default : ; // 缺省不操作
                endcase
                case(ad_ref_cnt)
                    0 : nCS <= 1;
                    1 : nCS <= 0;
                    // 转换期
                    202: nCS <= 1;            
                    default : ; // 缺省不操作
                endcase
                case(ad_ref_cnt)
                    0 : samping_flag <= 0;
                    // 采样期
                    36 : samping_flag <= 1;
                    // 转换期
                    202: samping_flag <= 0;
                    default : ; // 缺省不操作
                endcase
            end
        end
    wire samping_end = (ad_ref_cnt == 202) ? 1 : 0; // 采样结束标志
    
    /**************************************
    * 根据串行信号读取串行样本数据
    **************************************/
    reg [7:0] sample_data;
    always@(posedge SCK, negedge RST_N)
        if(!RST_N) sample_data <= {8{1'b0}};
        else begin
            if(SCK) begin
                if (samping_flag != 0) begin
                    sample_data[7:1] <= sample_data[6:0];
                    sample_data[0] <= SDO;
                end
            end
        end
    
    always@(posedge CLOCK_50, negedge RST_N)
        if(!RST_N) ad_data <= {8{1'b0}};
        else begin
            if (samping_end)
                ad_data <= sample_data;
            else ad_data <= ad_data;
        end
    
    endmodule
    

    Signaltap硬件仿真

    image

    image

    参考资料

    http://focus.ti.com.cn/cn/lit/ds/symlink/tlc549.pdf

  • 相关阅读:
    8086 CPU 寄存器
    python中 * 的用法
    字典的相应操作
    tesseract学习记录
    C学习之路2012.8.28
    函数库管理
    2013.3.19C++浏览记录。。。
    自动生成makefile文件学习
    整理做过的东西(电子警察)
    基于zed的tesseract移植过程记录
  • 原文地址:https://www.cnblogs.com/yuphone/p/2026377.html
Copyright © 2011-2022 走看看