【代码更新】SPI时序——AD数模数转换

【代码更新】SPI时序------AD数模数转换

AD芯片手册:https://www.ti.com.cn/cn/lit/ds/symlink/ads8558.pdf?ts=1709473143911\&ref_url=https%253A%252F%252Fwww.ti.com.cn%252Fproduct%252Fcn%252FADS8558

下图是芯片需要配置信号的时序图

寄存器配置时序:

项目硬件连接图:

整体代码如下:

复制代码
  1 //SCK  MAX  --->  36MHz
  2 //
  3 //PAR/SER = BVDD1 板子已经处于串行接口模式
  4 //
  5 //
  6 //U57-M8  -->SDOC-->M8
  7 //U57-M7  -->SDOB-->M7
  8 //U57-N5   -->SDOA-->N5
  9 //
 10 //不控制:
 11 //SEL_A 
 12 //SEL_B
 13 //SEL_C 都接高电平,选择SDOA/SDOB/SDOC
 14 //
 15 //BUSY/INT ---->DO
 16 //
 17 //RANGE/XCLK---->U42-RANGE--->P8--->max 20MHz  tpye 18MHz
 18 //CLKSEL --->high ---> C11=1
 19 //
 20 //
 21 `timescale 1ns / 1ps
 22 module ad_collect(
 23 //
 24 input wire  clk  ,//50MHz
 25 //
 26 output wire  xclk,//---->max 20MHz--->p8---->tpye 18MHz
 27 output reg  reset, //RESET---->PIN28 --->高复位中止转换----->大于50ns-->内部控制寄存器复位至0x000003FF    
 28 output wire hw_sw, //HW/SW = REFEN/WR --->T4-->'b1--->software mode(HW/SW =1)     
 29 output reg  cs_fs, //--->帧同步/FS 的下降沿控制帧传输    
 30 //
 31 input  wire busy_int,  
 32 //
 33 output reg  convst_a,//IO_L05P_2----->CONVST_A--->T4
 34 output wire convst_b,//IO_L06P_2----->CONVST_B--->T5
 35 output wire convst_c,//IO_L06N_2----->CONVST_C--->T6 -->最好三个脚连在一起,不连在一起两两之间间隔不超过4ns
 36 //
 37 output reg      sclk, 
 38 output reg       sdi, 
 39 //
 40 input wire      sdo_a, 
 41 input wire      sdo_b, 
 42 input wire      sdo_c,
 43 //
 44 output reg [15:0] data_a0,//A通道数据高位
 45 output reg [15:0] data_a1,//A通道数据低位
 46 output reg [15:0] data_b0,
 47 output reg [15:0] data_b1,
 48 output reg [15:0] data_c0,
 49 output reg [15:0] data_c1,
 50 //
 51 output wire         ad_a0,//3-8译码器配置带你看 
 52 output wire         ad_a1, 
 53 output wire         ad_a2, 
 54 //
 55 output reg  data_abc_vaild
 56 );
 57 //
 58 reg [15:0] cnt_rst_n ='d0;
 59 always@(posedge clk)
 60 begin
 61     if(cnt_rst_n > 'd5000)
 62         cnt_rst_n <='d5001;
 63     else
 64         cnt_rst_n<=cnt_rst_n+1'b1;
 65 end
 66 //
 67 reg  rst_n;
 68 always@(posedge clk)
 69 begin
 70     if(cnt_rst_n == 'd5001)
 71         rst_n<='b1;
 72     else
 73         rst_n<='b0;
 74 end
 75 //
 76 //------------------------clock-分频-----------------------------------------
 77 reg [1:0] div_cnt1;
 78 always@(posedge clk)
 79 begin
 80     if(!rst_n)
 81         div_cnt1<=2'b00;
 82     else
 83         div_cnt1<=div_cnt1+1'b1;
 84 end
 85 
 86 reg div4_o_r;         //----->12.5MHz ---80ns
 87 always@(posedge clk)  //四分频 
 88 begin                 //计数器放在外面 来实现计数   div_cnt1
 89     if(!rst_n)         //00 01 10 11 捕捉00和10 实现四分频
 90         div4_o_r<=1'b0;
 91     else if(div_cnt1==2'b00 || div_cnt1==2'b10)
 92         div4_o_r<=~div4_o_r;
 93     else
 94         div4_o_r<=div4_o_r;
 95 end
 96 
 97 assign xclk = div4_o_r;//----->12.5MHz//--->CR C11(CLKSE) set high
 98 
 99 //FPGA 配置引脚
100 //HW/SW = REFEN/WR ------->T4-->'b1  ---->software mode(HW/SW =1) 
101 assign hw_sw = 1'b1;
102 assign convst_b = convst_a;
103 assign convst_c = convst_a;
104 assign ad_a0=1'b0;
105 assign ad_a1=1'b0; 
106 assign ad_a2=1'b1; 
107 //
108 reg [5:0] cnt0;
109 wire      add_cnt0;
110 wire      end_cnt0;
111 always@(posedge clk or negedge rst_n)begin
112     if(rst_n==1'b0)begin
113         cnt0<=0;
114     end
115     else if(add_cnt0)begin
116         if(end_cnt0)
117             cnt0<=0;
118         else
119             cnt0<=cnt0+1;
120     end 
121 end
122  
123 reg cs_fs_temp;
124 assign add_cnt0 = cs_fs_temp == 1'b0;
125 // assign end_cnt0 = add_cnt0 && cnt0 == 10-1;//5MHz       
126 assign end_cnt0 = add_cnt0 && cnt0 == 4-1;//50/4 = 12.5MHz   //四分频计数器实现
127 
128 reg [5:0] cnt1;
129 wire      add_cnt1;
130 wire      end_cnt1;
131 always@(posedge clk or negedge rst_n)begin
132     if(rst_n==1'b0)begin
133         cnt1<=0;
134     end
135     else if(add_cnt1)begin
136         if(end_cnt1)
137             cnt1<=0;
138         else
139             cnt1<=cnt1+1;
140     end 
141 end 
142 assign add_cnt1 = end_cnt0;
143 assign end_cnt1 = add_cnt1 && cnt1 == 34-1;//配置32bit计数器实现 32bit配置 冗余1bit
144 //
145 wire idle2s1_start;
146 wire   s12s2_start;
147 wire   s22s3_start;
148 wire   s32s4_start;
149 wire   s42s5_start;
150 wire   s52s3_start;
151 //
152 reg [2:0] state_c;
153 reg [2:0] state_n;
154 parameter  IDLE = 3'h0;
155 parameter  S1  =  3'h1;
156 parameter  S2   = 3'h2;
157 parameter  S3   = 3'h3;
158 parameter  S4   = 3'h4;
159 parameter  S5   = 3'h5;
160 //
161 always@(posedge clk or negedge rst_n)begin
162     if(rst_n==1'b0)begin
163         state_c <=IDLE;
164     end
165     else begin    
166         state_c <=state_n;    
167     end     
168 end
169 //
170 always@(*)begin
171 case(state_c)
172 IDLE:begin
173     if(idle2s1_start)begin
174         state_n = S1;
175     end
176     else begin
177         state_n = state_c;
178     end
179 end 
180 S1:begin
181     if(s12s2_start)begin
182         state_n = S2;
183     end
184     else begin
185         state_n = state_c;
186     end
187 end
188 S2:begin
189     if(s22s3_start)begin
190         state_n = S3;
191     end
192     else begin
193         state_n = state_c;
194     end
195 end
196 S3:begin
197     if (s32s4_start)begin 
198         state_n = S4;
199     end
200     else begin
201         state_n = state_c;
202     end
203 end
204 S4:begin
205     if(s42s5_start)begin
206         state_n = S5;
207     end
208     else begin
209         state_n = state_c;
210     end
211 end
212 S5:begin
213     if (s52s3_start)begin 
214         state_n = S3;
215     end
216     else begin
217         state_n = state_c;
218     end
219 end
220 default:begin 
221     state_n = IDLE;
222 end
223 endcase
224 end
225 //
226 reg [1:0] cnt_reset;
227 //
228 assign idle2s1_start = state_c == IDLE&& cnt_reset == 'd3;//&& busy_int == 1; 复位后进入下一个状态
229 assign s12s2_start   = state_c == S1  && reset== 'b0;//&& busy_int == 0;
230 assign s22s3_start   = state_c == S2  && end_cnt1;   //配置完32bit
231 assign s32s4_start   = state_c == S3  && busy_int == 1;//BUSY/INT ---->DO   忙的时候busy_int拉高
232 assign s42s5_start   = state_c == S4  && busy_int == 0;//BUSY/INT ---->DO   不忙的时候busy_int拉低,进入下一个状态
233 assign s52s3_start   = state_c == S5  && end_cnt1;  //配置完32bit
234 //
235 always @(posedge clk or negedge rst_n)begin
236     if(!rst_n)begin
237         convst_a<=0;
238     end 
239     else if(state_c == S5 && add_cnt1 && cnt1 == 33-1)begin
240         convst_a<=0;
241     end
242     else if((state_c == S2 || state_c == S5) && add_cnt1 && cnt1 == 34-1)begin
243         convst_a<=1;
244     end    
245 end
246 //IO_L05P_2----->CONVST_A--->T4
247 //IO_L06P_2----->CONVST_B--->T5
248 //IO_L06N_2----->CONVST_C-->T6 -->最好三个脚连在一起,不连在一起两两之间间隔不超过4ns
249 //For simultaneous sampling, connecting all associated CONVST_x pins together is recommended.
250 //
251 always @(posedge clk or negedge rst_n)begin
252     if(!rst_n)begin
253         cs_fs_temp<=1;
254     end 
255     else if((state_c == S2  || state_c == S5) )begin
256         cs_fs_temp<=0;
257     end
258     else  begin
259         cs_fs_temp<=1;//中间信号
260     end
261 end
262 
263 always @(posedge clk or negedge rst_n)begin
264     if(!rst_n)begin
265         cs_fs<=1;
266     end 
267     else if( (~cs_fs_temp) && add_cnt1 && cnt1 == 1-1 )begin
268         cs_fs<=0;
269     end
270     else if( (~cs_fs_temp) && add_cnt1 && cnt1 == 33-1) begin
271         cs_fs<=1;//CS#/FS# --->帧同步/FS 的下降沿控制帧传输
272     end
273 end
274 
275 always@(posedge clk or negedge rst_n)begin
276     if(rst_n==1'b0)begin
277         sclk<=1;
278     end
279     // else if(add_cnt0 && cnt0 == 5-1 && cnt1 >= 1 && cnt1 < 33)begin
280     else if(add_cnt0 && cnt0 == 2-1 && cnt1 >= 1 && cnt1 < 33)begin    
281         sclk<=0;    
282     end 
283     else if(end_cnt0)begin
284         sclk<=1;    //IO_L05P_2--->SCLK--->T4--->Serial interface clock input (36 MHz, max)
285     end     
286 end
287 
288 // parameter data1=32'b111_000_100_000_0_000_000_0_10_1111_1111_11;
289 // parameter data1=32'b111_000_000_000_0_000_000_0_10_1111_1111_11;
290 parameter data1=32'hE2000BFF;//首次配,参考CR 寄存器配置
291 // parameter data2=8'hE0;
292 parameter data2=8'hE2;//二次配   参考CR 寄存器配置
293 //---------------------CR------------------------------------------
294 //
295 //C26         C27         C28
296 //RANGE_A     RANGE_B     RANGE_C
297 //0-->4 VREF  1-->2 VREF 
298 //
299 //C16
300 //C23:0_EN // 1 = Entire control register update enabled (serial mode only) 
301 //
302 //C23
303 //SEQ  1 1 = Sequential convert start mode enabled (bit 11 must be '1' in this case)
304 //
305 //C11
306 //CLKSEL  1 = External conversion clock (applied through pin 27) used 
307 //
308 //
309 //C20   BUSY L/H
310 //0 = BUSY active high when INT is active low (default) 
311 // C21  BUSY/INT 
312 //0 = BUSY/INT pin in normal mode (BUSY) (default)
313 //
314 //C18 
315 //VREF 0 = Internal reference voltage: 2.5 V (default) //1 = 3V
316 
317 always@(posedge clk or negedge rst_n)begin
318     if(rst_n==1'b0)begin
319         sdi <=1;
320     end
321     else if(state_c == S2 && end_cnt0 && cnt1 < 32)begin    
322         sdi <=data1[31-cnt1];    
323     end 
324     else if(state_c == S5 && end_cnt0 && cnt1 < 8)begin    
325         sdi <=data2[7-cnt1];    
326     end    
327 end
328 //SPI接口
329 //IO_L08P_2 --->SDI---->P7
330 //
331 reg [31:0] data_a;
332 always@(posedge clk or negedge rst_n)begin
333     if(rst_n==1'b0)begin
334         data_a<=0;
335     end
336     // else if(state_c == S5 && add_cnt0 && cnt0 == 5-1 && cnt1 >= 1 && cnt1 <= 32)begin    
337     else if(state_c == S5 && add_cnt0 && cnt0 == 2-1 && cnt1 >= 1 && cnt1 <= 32)begin        
338         data_a['d32- cnt1]<=sdo_a;    //A通道数据过来采集
339     end                
340 end
341 
342 reg [31:0] data_b;
343 always@(posedge clk or negedge rst_n)begin
344     if(rst_n==1'b0)begin
345         data_b<=0;
346     end
347     // else if(state_c == S5 && add_cnt0 && cnt0 == 5-1 && cnt1 >= 1 && cnt1 <= 32)begin    
348     else if(state_c == S5 && add_cnt0 && cnt0 == 2-1 && cnt1 >= 1 && cnt1 <= 32)begin        
349         data_b['d32- cnt1]<=sdo_b;    //B通道数据过来采集
350     end                
351 end 
352 
353 reg [31:0] data_c;
354 always@(posedge clk or negedge rst_n)begin
355     if(rst_n==1'b0)begin
356         data_c<=0;//C通道数据过来采集
357     end
358     // else if(state_c == S5 && add_cnt0 && cnt0 == 5-1 && cnt1 >= 1 && cnt1 <= 32)begin    
359     else if(state_c == S5 && add_cnt0 && cnt0 == 2-1 && cnt1 >= 1 && cnt1 <= 32)begin        
360         data_c['d32- cnt1]<=sdo_c;    
361     end                
362 end  
363 
364 always@(posedge clk or negedge rst_n)begin
365     if(rst_n==1'b0)begin
366         data_abc_vaild<=0;
367     end
368     else if(state_c == S5 &&  add_cnt1 && cnt1 == 33-1)begin    
369         data_abc_vaild<=1;    //通道数据采集完毕
370     end
371     else begin    
372         data_abc_vaild<=0;    
373     end        
374 end 
375 
376 always@(posedge clk or negedge rst_n)begin
377     if(rst_n==1'b0)begin
378         data_a0<='d0;            
379         data_a1<='d0;            
380         data_b0<='d0;            
381         data_b1<='d0;            
382         data_c0<='d0;            
383         data_c1<='d0;            
384     end
385     else if(data_abc_vaild)begin//    通道数据采集完毕,给出去                        
386             data_a0<=data_a[31:16];            
387             data_a1<=data_a[15:0 ];            
388             data_b0<=data_b[31:16];            
389             data_b1<=data_b[15:0 ];            
390             data_c0<=data_c[31:16];            
391             data_c1<=data_c[15:0 ];        
392     end                
393 end
394 //
395 always@(posedge clk)
396 begin
397     if(!rst_n)
398         cnt_reset<='d0;
399     else
400         begin
401             if(cnt_reset == 'd3)
402                 cnt_reset<= 'd3;
403             else
404                 cnt_reset<=cnt_reset+1'b1;
405         end 
406 end
407 //
408 always@(posedge clk)
409 begin
410     if(!rst_n)
411         reset<='b0;
412     else
413         begin
414             if(cnt_reset == 'd3) 
415                 reset<= 'b0;
416             else
417                 reset<= 'b1;  //4 x 20 = 80ns  ---复位大于50ns
418         end 
419 end
420 //
421 endmodule 

ad_collect