【代码更新】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
【代码更新】SPI时序——AD数模数转换的更多相关文章
- FPGA构造spi时序——AD7176为例(转)
reference:https://blog.csdn.net/fzhykx/article/details/79490330 项目中用到了一种常见的低速接口(spi),于是整理了一下关于spi相关的 ...
- SPI接口扫盲 SPI定义/SPI时序(CPHA CPOL)
SPI接口扫盲 douqingl@gmail.com 为何要写这篇文档?百度上找出来的SPI接口中文描述都说的太过简略,没有一篇文档能够详尽的将SPI介绍清楚的.wikipedia英文版[注释 ...
- Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测
Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测 2017年12月13日 17:39:11 机器之心V 阅读数:5931 近日,Artur Suilin 等人发布了 Kaggl ...
- SPI总线协议及SPI时序图详解
SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚 ...
- Unity手游之路<十三>手游代码更新策略探讨
http://blog.csdn.net/janeky/article/details/25923151 这几个月公司项目非常忙,加上家里事情也多,所以blog更新一直搁置了.最近在项目开发上线过程中 ...
- python学习之——计算给出代码中注释、代码、空行的行数
题目:计算给出代码中注释.代码.空行的行数 来源:网络 思路:注释行以 ‘#’开头,空行以 ‘\n’ 开头,以此作为判断 def count_linenum(fname): fobj = open(f ...
- WebGIS中以version方式实现代码更新后前端自动读取更新代码的方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 前言 GIS代码进行更新后,由于用户前端已有缓存,导致更新的功能不 ...
- SPI总线协议及SPI时序图详解【转】
转自:https://www.cnblogs.com/adylee/p/5399742.html SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接 ...
- Unity手游之路手游代码更新策略探讨
版权声明: https://blog.csdn.net/janeky/article/details/25923151 这几个月公司项目非常忙.加上家里事情也多,所以blog更新一直搁置了. 近期在项 ...
- git如何merge github forked repository里的代码更新?(转)
参考内容:git如何merge github forked repository里的代码更新? [refer to ]http://www.haojii.com/2011/08/how-to-git- ...
随机推荐
- WPF内嵌Http协议的Server端
需求:有时后比如WPF,WinForm,Windows服务这些程序可能需要对外提供接口用于第三方服务主动通信,调用推送一些服务或者数据. 想到的部分实现方式: 一.使用Socket/WebSocket ...
- C/C++ 操作数组与指针笔记
指针数组: #include <stdio.h> #include <stdlib.h> #include <string.h> void PrintInt() { ...
- 6.用户输入和 while 循环--《Python编程:从入门到实践》
6.1 input 函数 函数input()接受一个参数:即要向用户显示的提示或说明.input 将用户输入解释为字符串. name = input("Please enter your n ...
- 使用HttpServletResponse实现curl接口时控制台输出(续)
上一篇文章的问题 在上一篇文章 Spring Boot RestController接口如何输出到终端 中讨论了如何使用 HttpSerlvetResponse 写入输出流,使应急接口通过 curl ...
- pandas 用户数据分析
import pandas as pd import numpy as np from matplotlib import pyplot as plt """ 第一部分: ...
- Executors.newFixedThreadPool(int nThreads)存在的缺陷
一般来讲是不推荐直接使用JAVA提供的Executors类来初始化线程池,如果有需要可以自行通过ThreadPoolExecutor来封装进行初始化. 可以用newFixedThreadPool(in ...
- 【LGR-156-Div.3】洛谷网校 8 月普及组月赛 I & MXOI Round 1 & 飞熊杯 #2(同步赛)
[LGR-156-Div.3]洛谷网校 8 月普及组月赛 I & MXOI Round 1 & 飞熊杯 #2(同步赛) \(T1\) luogu P9581 宝箱 \(100pts\) ...
- Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
正月初九,开工大吉! 2024年,更上一层楼! 写在开头 其实在List的继承关系中,除了ArrayList和LinkedList之外,还有另外一个集合类stack(栈),它继承自vector,线程安 ...
- JavaScript 的灵异事件之一
场景 在做项目的时候需要用到Ajax 做多次的异步处理数据, 三次Ajax:A --ok--> B --ok--> C 在入参数据相同的情况下,做了两论这个操作,但发现没有发送 A 的 A ...
- 【分布式】load balance 01-负载均衡基础知识
负载均衡系列专题 01-负载均衡基础知识 02-一致性 hash 原理 03-一致性哈希算法 java 实现 04-负载均衡算法 java 实现 负载均衡 负载均衡是高可用网络基础架构的关键组件,通常 ...
