【代码更新】SPI时序------AD数模数转换
下图是芯片需要配置信号的时序图
寄存器配置时序:
项目硬件连接图:
整体代码如下:
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