1 module DAC7512( 2 input clk_25m,//25MHz左右的时钟信号 3 input nrst,//低电平复位 4 input syc_sig,//外部产生的同步输出信号,当其出现上升沿时刷新输出电压 5 output cs_da, 6 output mosi_da, 7 output sck_da, 8 input [11:0] data_in//待转换的数据,在每次开始转换之前被锁存到模块中,只有低12位有效 9 ); 10 reg[7:0] cnt_cs; 11 reg cs_da_reg; 12 reg sck_da_reg; 13 reg[2:0] sck_timer;//用于测量单个DAC通信时钟长度的计数器 14 /////////以下用25MHz时钟,产生片选信号//////// 15 assign cs_da = cs_da_reg; 16 always @ (posedge clk_25m or negedge nrst) 17 begin 18 if(!nrst) 19 begin 20 cnt_cs[7:0] <= 8'd0; 21 cs_da_reg <= 1'b1; 22 end 23 else begin 24 if(syc_sig == 1'b1)//同步信号高电平时,回复到计数初始状态 25 begin 26 cnt_cs[7:0] <= 8'd0; 27 cs_da_reg <= 1'b1; 28 end 29 else 30 begin 31 if(cnt_cs[7:0] < 8'd98) //98个脉冲,少一个防止竞争现象 32 begin 33 cnt_cs[7:0] <= cnt_cs[7:0] + 8'd1; 34 cs_da_reg <= 1'b0; 35 end 36 else begin 37 cnt_cs[7:0] <= cnt_cs[7:0]; 38 cs_da_reg <= 1'b1; 39 end 40 end 41 end 42 end 43 ////////以下产生串行同步输出时钟//////////// 44 assign sck_da = sck_da_reg; 45 always @(posedge clk_25m or posedge cs_da) 46 begin 47 if(cs_da) 48 begin 49 sck_timer[2:0] <= 3'd0; 50 sck_da_reg <= 1'b0; 51 end 52 else begin 53 if(sck_timer[2:0] < 3'd2) 54 begin 55 sck_timer[2:0] <= sck_timer[2:0] + 3'd1; 56 sck_da_reg <= sck_da_reg; 57 end 58 else begin 59 sck_timer[2:0] <= 3'd0; 60 sck_da_reg <= !sck_da_reg; 61 end 62 end 63 end 64 ///////////产生串行输出信号,需要串行输出的数据在CS下降沿在并行输入口被锁存///////// 65 reg[16:0] shift_reg; 66 //注意这里多一个位,是因为DAC7512在下降沿读取数据,而我们的数据在第一个SCK脉冲上升沿就开始移出,因此会多移出一个位(第一位) 67 assign mosi_da = shift_reg[16]; 68 always @ (posedge sck_da or posedge cs_da) 69 begin 70 if(cs_da) 71 shift_reg[16:0] <= {5'b00000,data_in[11:0]};//对于dac7512而言,最高四位为0000,表示输出使能,且连接1KΩ负载 72 else 73 shift_reg[16:0] <= shift_reg[16:0]<<1; 74 end 75 endmodule DAC7512驱动电路