DAC8811驱动编写遇到的问题

7 篇文章 0 订阅
7 篇文章 1 订阅

这次错误导致我调了半天DAC也没有正常的波形,坑了做硬件的队友

* 错误1:时序图有问题

这里写图片描述

错误2:数据DIN计算有问题
这里写图片描述

这个公式给的明明白白,就是让你计算补码为偏移二进制,你的数学敏感还是要锻炼!

这里写图片描述
* 反思:写驱动一定要认真分析时序图,那些Interface Timing是你一定要认真分析好好关注的
这里写图片描述
附上我写的DAC8811驱动程序:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: Peter
// 
// Create Date: 2017/03/19 12:23:48
// Design Name: 
// Module Name: DAC8811_Drive
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//



module DAC8811_Drive
(   
    output reg CS,
    output reg DIN,
    input clk,
    output wire sclk,
    //output reg [4:0]state,

    input [15:0]DATA
);
    //All reg definition and initial
    reg[25:0]count;
    reg[9:0]wait_count;
    reg encount;
    reg [15:0]temp_buff;
    reg[4:0]state;          //use 18 states to describe the state machine

    //Verilog simulation requires initialization of reg
    initial begin 
    encount = 0; count = 1'b0; state = 5'b0;
    DIN = 0;CS = 1; 
    temp_buff=0;
    end

    //FSM
    parameter S0  = 5'd0;
    parameter S1  = 5'd1; 
    parameter S2  = 5'd2;
    parameter S3  = 5'd3;
    parameter S4  = 5'd4;
    parameter S5  = 5'd5;
    parameter S6  = 5'd6;
    parameter S7  = 5'd7;
    parameter S8  = 5'd8;
    parameter S9  = 5'd9;
    parameter S10 = 5'd10;
    parameter S11 = 5'd11;
    parameter S12 = 5'd12;
    parameter S13 = 5'd13;
    parameter S14 = 5'd14;
    parameter S15 = 5'd15;
    parameter S16 = 5'd16;
    parameter Start = 5'd17;
    parameter wait_time_0 = 10'd4;
    parameter wait_time_1 = 10'b100;

    //time div counter
    parameter clk_div_time = 26'd8;

        always@(negedge clk)begin
        if(count < 4'd1)
        //if(count < 26'd499)
            count <= count + 4'b1;
            else
            count <=0;
        end
    wire en_count = (count == 4'd1);
    //wire encount = (count == 26'd499);
    assign sclk = (count>4'b0);
        //wait time counter

    initial wait_count=0;
    always@(negedge clk)begin
        if(encount)
            wait_count = wait_count + 10'b1;
        else
            wait_count = 10'b0;
        end

    //Finite state machine. One paragraph
    always@(negedge sclk)begin
        case(state)
        S0:begin    CS=1'b1;encount=1'b1;state = S1;    end

    //CS must be brought high for a minimum of 20 ns 
    //before the next write sequence 
        S1:begin
                if(wait_count >wait_time_0)begin
                    temp_buff[15:0] = DATA[15:0];
                    CS<=1'b0;encount <= 1'b0;DIN <= DATA[15];state <= S2;D15~D0 data output from FPGA
                    end
                else begin
                    CS <= 1'b1; encount <= encount;state <= S1;
                    end
            end
    D15~D0 data output from FPGA       
        //Start:begin DIN =DATA[15];state = S2; end
        S2:begin DIN = temp_buff[14]; state = S3; end
        S3:begin DIN = temp_buff[13]; state = S4; end
        S4:begin DIN = temp_buff[12]; state = S5; end
        S5:begin DIN = temp_buff[11]; state = S6; end
        S6:begin DIN = temp_buff[10]; state = S7; end
        S7:begin DIN = temp_buff[9]  ; state = S8; end
        S8:begin DIN = temp_buff[8]  ; state = S9; end
        S9:begin DIN = temp_buff[7]; state = S10; end
        S10:begin DIN=temp_buff[6]; state = S11; end
        S11:begin DIN=temp_buff[5]; state = S12; end
        S12:begin DIN=temp_buff[4]; state = S13; end
        S13:begin DIN=temp_buff[3]; state = S14; end
        S14:begin DIN=temp_buff[2]; state = S15; end
        S15:begin DIN=temp_buff[1]; state = S16; end
        S16:begin DIN=temp_buff[0]; state = S0;   end

        default : state = S0;
        endcase

    end


endmodule

module top
(
    input clk,
    output CS,
   output  DIN,
    output  sclk,

    output Mul_CS,
    output Mul_DIN,
    output Mul_sclk,
    output [2:0]led,

    input [1:0]freq_ctr,
    input phase

);

    wire tick;
    wire signed [15:0] sin;
    wire [39:0]freqword ;
    assign freqword = (freq_ctr==2'b01)?40'd10995116:((freq_ctr==2'b10)?40'd109951163:40'd1099511628);
    assign led = (freq_ctr==2'b01)?3'b001:((freq_ctr==2'b10)?'b010:'b100);
     wire [39:0]phaseword;
    assign phaseword = (phase==1'b1)?40'd274877906900:40'd0;
    dds
    #(
        .PHASE_W(40),
        .DATA_W(16),  
        .TABLE_AW(8),
        .MEM_FILE("sin256x16.dat")
    )

    //100Hz sin signal
    the_dds
    (
        .FreqWord(freqword),
        .PhaseShift(phaseword),
        .Clock(clk),
        .ClkEn(1'b1),
        .Out(sin)
    );
        wire [15:0]data;
        wire signed [15:0]out;
         wire signed [15:0]out1;
//    assign data = sin +16'd32768;
    wire signed[32:0] sum = (33'sd1*sin)  * 33'sd12582;
    assign out=(sum >>>15)+16'd32768;

//    wire signed[34:0] sum1 = (35'sd1*sin)  * 35'sd12582* 35'sd2;

//    assign out1=(sum1 >>>15)+16'd32768;
assign out1=sin+16'd32768;

DAC8811_Drive Sin
(   
    . CS    (CS),
    . DIN   (DIN),
    . clk   (clk),
    . sclk  (sclk),
    . DATA  (out)
);

DAC8811_Drive MUL
(   
    . CS    (Mul_CS),
    . DIN   (Mul_DIN),
    . clk   (clk),
    . sclk  (Mul_sclk),
    . DATA  (out1)
);


endmodule

注意!我的正弦表是有符号16位,所以才要加上2^15

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值