`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/08/29 11:35:42
// Design Name:
// Module Name: AD5545_DAC
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// AD5545_DAC IOUTA IOUTB 输出2路电流
//////////////////////////////////////////////////////////////////////////////////
代码借鉴以下这位大佬
//https://blog.youkuaiyun.com/xiakunpei123/article/details/143864515
数模转换AD5545芯片驱动程序设计Verilog代码VIVADO仿真
module AD5545_DAC(
input wire clk_200m,
input wire rst_n,
input wire data_en,
input wire [15:0] data_A,
input wire [15:0] data_B,
output reg DA_SDI,
output reg DA_CLK,
output reg DA_CS_n,
output reg DA_LDAC_n,
output reg DA_RS_n,
output reg send_done
);
reg flag_AB = 0;
reg [1:0] A1A0 = 2'd0;//01--A;10--B
reg [15:0] data_DA = 16'd0;//DA数据
reg [7:0] count;
reg [17:0] data_all;
reg data_en_r0;
reg data_en_r1;
wire data_en_pos;
reg clear_flag;
assign data_en_pos = data_en_r0 & (~data_en_r1);
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)begin
data_en_r0 <= 1'd0;
data_en_r1 <= 1'd0;
end
else begin
data_en_r0 <= data_en;
data_en_r1 <= data_en_r0;
end
end
//作用是:防止data_en 信号来的时候,
//还没开始发data_A,data_B,
//就开始send_done == 1'b1 了
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)begin
clear_flag <= 1'd0;
end
else if(count == 8'd199)begin
clear_flag <= 1'd0;
end
else if(data_en_pos == 1'b1)begin
clear_flag <= 1'd1;
end
end
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)begin
DA_RS_n <= 1'd0;
end
else begin
DA_RS_n <= 1'd1;
end
end
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)
count <= 8'd0;
else if(count == 8'd199)
count <= 8'd0;
else if(count < 8'd199) //flag_AB==0时输出A数据,=1时输出B数据
count <= count + 1'b1;
end
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)
send_done <= 1'd0;
else if(clear_flag == 1'b1)
send_done <= 1'd0;
else if(count >= 8'd189 && count <= 8'd195)//Synchronized to a 40M, 25ns/5ns = 5,10 >(195 -189) >5
send_done <= 1'd1;
else
send_done <= 1'd0;
end
//count= 0~5 --- cs=1 ldac=1;
//count= 6~150 --- cs=0 ldac=1;
//count= 160~200 --- cs=1 ldac=0;
//控制DA_CS_n
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)
DA_CS_n <= 1;
else if(count < 8'd6)
DA_CS_n <= 1;
else if(count >= 8'd6 && count < 8'd160)
DA_CS_n <= 0;
else
DA_CS_n <= 1;
end
//控制DA_LDAC_n
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)
DA_LDAC_n <= 1;
else if(count < 8'd160)
DA_LDAC_n <= 1;
else
DA_LDAC_n <= 0;
end
//可以按照频率来改,不一定要按照count == 8'd199
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)begin
flag_AB <= 1'd0;
end
else if(count == 8'd199)begin
flag_AB <= ~flag_AB; //flag_AB==0时输出A数据,=1时输出B数据
end
end
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)begin
A1A0 <= 2'b10; //01--DACA;10--DACB
data_DA <= data_A;
end
else if(flag_AB == 0)begin //flag_AB==0时输出A数据,=1时输出B数据
A1A0 <= 2'b10; //01--DACA;10--DACB
data_DA <= data_A;
end
else begin
A1A0 <= 2'b01; //01--DACA;10--DACB;
data_DA <= data_B;
end
end
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)
data_all <= 18'd0;
else
data_all <= {A1A0,data_DA};
end
//控制DA_CLK 50mhz
//数据速率为1M,AB分别0.5M,500khz,电子负载最多50khz ,要记得转换
always@(posedge clk_200m or negedge rst_n)begin
if(~rst_n)begin
DA_SDI <= data_all[17];
DA_CLK <= 0;
end
else begin
case(count)
8'd0: begin DA_CLK <= 0; end
8'd10: begin DA_CLK <= 0; DA_SDI <= data_all[17]; end//第1个时钟
8'd14: begin DA_CLK <= 1; end
8'd18: begin DA_CLK <= 0; DA_SDI <= data_all[16]; end//第2个时钟
8'd22: begin DA_CLK <= 1; end
8'd26: begin DA_CLK <= 0; DA_SDI <= data_all[15]; end//第3个时钟
8'd30: begin DA_CLK <= 1; end
8'd34: begin DA_CLK <= 0; DA_SDI <= data_all[14]; end//第4个时钟
8'd38: begin DA_CLK <= 1; end
8'd42: begin DA_CLK <= 0; DA_SDI <= data_all[13]; end//第5个时钟
8'd46: begin DA_CLK <= 1; end
8'd50: begin DA_CLK <= 0; DA_SDI <= data_all[12]; end//第6个时钟
8'd54: begin DA_CLK <= 1; end
8'd58: begin DA_CLK <= 0; DA_SDI <= data_all[11]; end//第7个时钟
8'd62: begin DA_CLK <= 1; end
8'd66: begin DA_CLK <= 0; DA_SDI <= data_all[10]; end//第8个时钟
8'd70: begin DA_CLK <= 1; end
8'd74: begin DA_CLK <= 0; DA_SDI <= data_all[9]; end//第9个时钟
8'd78: begin DA_CLK <= 1; end
8'd82: begin DA_CLK <= 0; DA_SDI <= data_all[8]; end//第10个时钟
8'd86: begin DA_CLK <= 1; end
8'd90: begin DA_CLK <= 0; DA_SDI <= data_all[7]; end//第11个时钟
8'd94: begin DA_CLK <= 1; end
8'd98: begin DA_CLK <= 0; DA_SDI <= data_all[6]; end//第12个时钟
8'd102:begin DA_CLK <= 1; end
8'd106:begin DA_CLK <= 0; DA_SDI <= data_all[5]; end//第13个时钟
8'd110:begin DA_CLK <= 1; end
8'd114:begin DA_CLK <= 0; DA_SDI <= data_all[4]; end//第14个时钟
8'd118:begin DA_CLK <= 1; end
8'd122:begin DA_CLK <= 0; DA_SDI <= data_all[3]; end//第15个时钟
8'd126:begin DA_CLK <= 1; end
8'd130:begin DA_CLK <= 0; DA_SDI <= data_all[2]; end//第16个时钟
8'd134:begin DA_CLK <= 1; end
8'd138:begin DA_CLK <= 0; DA_SDI <= data_all[1]; end//第17个时钟
8'd142:begin DA_CLK <= 1; end
8'd146:begin DA_CLK <= 0; DA_SDI <= data_all[0]; end//第18个时钟
8'd150:begin DA_CLK <= 1; end
8'd154:begin DA_CLK <= 0; end
default:;
endcase
end
end
endmodule
上板测试过,结果很满意。
1339

被折叠的 条评论
为什么被折叠?



