DAC8811驱动编写遇到的问题

来源:互联网 发布:用友软件介绍 编辑:程序博客网 时间:2024/04/28 08:11

这次错误导致我调了半天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    endendmodule
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