1. DAC8550数模转换器简介
通信方式:SPI,时钟速率达到30MHz
分辨率:16bit
封装:VSSOP
引脚定义如图1所示
重要的几个引脚描述:
SYNC:电平触发的控制输入(低电平有效)。 这是输入数据的帧同步信号。 当SYNC变为低电平时,它使能输入移位寄存器,并在随后的时钟的下降沿传输数据。 DAC在第24个时钟后更新(除非在该边沿之前将SYNC设为高电平,否则SYNC的上升沿将作为中断,并且DAC8550将忽略写序列)。 施密特触发器逻辑输入。
SCLK:串行时钟
Din:串行数据输入,在SCLK的下降沿输入移位寄存器。
写入数据的波形如图2所示:
注意一点,FPGA输出的数据要在SCLK的上升沿改变,以便DAC在下降沿锁存数据。
以下是我的代码:
`timescale 1ns / 1ps
//***********************************************************
//Project Name ProjectDAC
//Author chaonan Song
//Email songchaonan@gmail.com
//moduleName ProjectDAC
//Create Time 2020/2/26
//***********************************************************
module ProjectDAC(
input clk,
input rst_n,
input endac,
output reg sclk,
output reg SYNC_n,
output reg dout,
output reg[15:0] data_out,
output reg[4:0] bit_cnt
);
//-----------------------------------------------------------
//------------------鍐呴儴绔彛澹版槑-----------------------------
//-----------------------------------------------------------
//reg [23:0] shift_reg;
//reg [15:0] data_out;
reg [1:0] cnt;
wire [23:0] shift_reg;
//reg [4:0] bit_cnt;
//-----------------------------------------------------------
//------------------閫昏緫鍔熻兘瀹炵幇-----------------------------
//-----------------------------------------------------------
//------------------cnt--------------------------------------
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 2'b00;
else if(cnt == 2'b11)
cnt <= 2'b00;
else
cnt <= cnt + 1'b1;
//-----------------sclk-------------------------------------
always @(posedge clk or negedge rst_n)
if(!rst_n)
sclk <= 1'b0;
else if(cnt == 2'b01)
sclk <= !sclk;
else
sclk <= sclk;
//------------------SYNC_n----------------------------------
always @(posedge sclk or negedge rst_n)
if(!rst_n)
SYNC_n <= 1'b1;
else if(bit_cnt == 5'd23)
SYNC_n <= 1'b1;
else if(endac)
SYNC_n <= 1'b0;
else
SYNC_n <= SYNC_n;
//-------------------bit_cnt--------------------------------
always @(posedge sclk or negedge rst_n)
if(!rst_n)
bit_cnt <= 1'b0;
else if(bit_cnt == 5'd23 || SYNC_n == 1'b1)
bit_cnt <= 1'b0;
else if(SYNC_n == 1'b0)
bit_cnt <= bit_cnt + 1'b1;
else
bit_cnt <= bit_cnt;
//-----------------------data_out--------------------------
always @(posedge sclk or negedge rst_n)
if(!rst_n)
data_out <= 16'b0;
else if(data_out == 16'd100)
data_out <= 16'd0;
else if(bit_cnt == 5'd23)
data_out <= data_out + 1'b1;
else
data_out <= data_out;
//-----------------------shift_reg-------------------------
assign shift_reg = {8'b0, data_out};
//----------------------dout-------------------------------
always @(posedge sclk or negedge rst_n)
if(!rst_n)
dout <= 1'b1;
else if(SYNC_n == 1'b0 )
dout <= shift_reg[bit_cnt];
else if(bit_cnt == 5'd23)
dout <= 1'b1;
else
dout <= 1'b1;
endmodule
以下是我进行测试的代码
`timescale 1ns / 1ps
`define CLOCK 20
//***********************************************************
//Project Name ProjectDAC
//Author chaonan Song
//Email songchaonan@gmail.com
//moduleName ProjectDAC_tb
//Create Time 2020/2/26
//***********************************************************
module ProjectDAC_tb();
reg clk;
reg rst_n;
reg endac;
wire sclk;
wire SYNC_n;
wire dout;
wire [15:0] data_out;
reg [23:0] data_rec;
wire [4:0] bit_cnt;
//------------------------initial----------------------------
initial
begin
clk <= 1'b0;
rst_n <= 1'b0;
endac <= 1'b0;
data_rec <= 24'b0;
#(10 * `CLOCK)
rst_n <= 1'b1;
#(10 * `CLOCK)
endac <= 1'b1;
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
#(16 * `CLOCK)
datareceive();
end
always
#(`CLOCK/2) clk <= ~clk;
task datareceive;
integer i;
begin
for(i = 0; i <= 23; i = i+1)
begin
@(posedge sclk)
data_rec <= {dout, data_rec[23:1]};
end
end
endtask
ProjectDAC ProjectDAC_Init(
.clk (clk),
.rst_n (rst_n),
.endac (endac),
.sclk (sclk),
.SYNC_n (SYNC_n),
.dout (dout),
.data_out (data_out),
.bit_cnt (bit_cnt)
);
endmodule
今天的内容到此结束。
版权声明:本文为qq_30357727原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。