AD7356_SPI驱动程序设计_5MSPS_Verilog

news2024/11/18 2:52:31

好久没动手了,使用Verilog编写一个AD7356的SPI驱动程序。
AD7356是一个双通道、12位、低功耗的ADC。最高采样速率可达5MSPS,全功率输入带宽为110MHz。AD7356的引脚图如下。
在这里插入图片描述
SPI的时序图如下,为了使单通道的采样速率达到最高的5MSPS,只能选择第一种时序。第二种时序,可以实现只使用一根数据线读取两个通道的数据的功能,但理论最高采样速率就减半了。
在这里插入图片描述
下表是手册中SPI时序的约束。
在这里插入图片描述
为了使采样速率达到5MSPS,必须在200ns内完成数据转换与数据读取。经分析,可以使用 f = 160  MHz f=160\text{ MHz} f=160 MHz的时钟,周期为 t = 6.25  ns t=6.25\text{ ns} t=6.25 ns,再使用该时钟分频出 80  MHz 80\text{ MHz} 80 MHz的SPI时钟,SPI时钟周期为 t s c l k = 12.5  ns t_{sclk}=12.5\text{ ns} tsclk=12.5 ns。则
t CONVERT = t 2 + 13 × t sclk t_{\text{CONVERT}}=t_2 + 13 \times t_{\text {sclk}} tCONVERT=t2+13×tsclk
t 2 = t t_2 = t t2=t,则 t CONVERT = 168.75  ns t_{\text{CONVERT}}=168.75 \text { ns} tCONVERT=168.75 ns,再加上半个SPI时钟周期 t s c l k / 2 = 6.25  ns t_{sclk}/2=6.25 \text { ns} tsclk/2=6.25 ns和最小 t QUIT = t = 6.25  ns t_{\text{QUIT}}=t =6.25\text{ ns} tQUIT=t=6.25 ns。则总时间为 181.25  ns 181.25 \text{ ns} 181.25 ns,可见在160MHz的时钟下实现该模块是可以满足需求的。
同时,为了实现连续触发和单次触发的功能,加入采样触发信号,以触发信号的上升沿为一次数据读取的标志。程序如下:

module spi_80M_5M(
    input clk,   //160M
    input rst_n,
    input clk_5M,//5M  
    input sdata_A,
    input sdata_B,
    
    output cs,
    output sclk, //80M
    output [11:0] out_A,
    output [11:0] out_B, 
    output out_A_valid, 
    output out_B_valid
);

//上升沿检测
wire start_flag;
reg [1:0] start_flag_dly;
assign start_flag = ~start_flag_dly[1] & start_flag_dly[0];
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        start_flag_dly <= 2'd0;
    end
    else begin
        start_flag_dly <= {start_flag_dly[0], clk_5M};
    end
end

reg trans_valid;
reg [4:0] clk_cnt;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        trans_valid <= 1'b0;
    end
    else if(start_flag == 1'b1) begin
        trans_valid <= 1'b1;
    end
    else if(clk_cnt == 5'd31) begin
        trans_valid <= 1'b0;
    end
    else begin
        trans_valid <= trans_valid;
    end
end
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        clk_cnt <= 5'd0;
    end
    else if(trans_valid == 1'b1) begin
        clk_cnt <= clk_cnt + 5'd1;
    end
    else begin
        clk_cnt <= clk_cnt;
    end
end

//sclk计数 0-31
reg [4:0] sclk_reg_cnt;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        sclk_reg_cnt <= 5'd0;
    end
    else if(trans_valid == 1'b1) begin
        sclk_reg_cnt <= sclk_reg_cnt + 5'd1;
    end
    else begin
        sclk_reg_cnt <= sclk_reg_cnt;
    end
end

//CS控制
reg cs_reg;
assign cs = cs_reg;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cs_reg <= 1'b1;
    end
    else if(sclk_reg_cnt == 5'd0 && trans_valid == 1'b1) begin
        cs_reg <= 1'b0;
    end
    else if(sclk_reg_cnt == 5'd28 && trans_valid == 1'b1) begin
        cs_reg <= 1'b1;
    end
    else begin
        cs_reg <= cs_reg;
    end
end

//产生SPI串行时钟
reg sclk_reg;
assign sclk = (cs_reg == 1'b0) ? sclk_reg : 1'b1;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        sclk_reg <= 1'b1;
    end 
    else if(sclk_reg_cnt[0] == 1'b1) begin
        sclk_reg <= 1'b0;
    end
    else if(sclk_reg_cnt[0] == 1'b0) begin
        sclk_reg <= 1'b1;
    end
    else begin
        sclk_reg <= 1'b1;
    end
end

//sclk上升沿更新数据
reg [13:0] data_A_reg;
reg [13:0] data_B_reg;
always @(negedge sclk or negedge rst_n) begin
    if(!rst_n) begin
        data_A_reg <= 'd0;
        data_B_reg <= 'd0;
    end 
    else begin
        data_A_reg <= {data_A_reg, sdata_A};
        data_B_reg <= {data_B_reg, sdata_B};
    end
end

//输出12位有效数据
assign out_A = ( (cs_reg == 1'b1) && (sclk_reg_cnt > 5'd29) ) ? data_A_reg[11:0] : 12'd0;
assign out_B = ( (cs_reg == 1'b1) && (sclk_reg_cnt > 5'd29) ) ? data_B_reg[11:0] : 12'd0;
assign out_A_valid = ( (cs_reg == 1'b1) && (sclk_reg_cnt > 5'd29) )? 1'b1 : 1'b0;
assign out_B_valid = ( (cs_reg == 1'b1) && (sclk_reg_cnt > 5'd29) )? 1'b1 : 1'b0;

endmodule

为了验证SPI时序的正确性,简单起见,芯片的连接方式如下。
在这里插入图片描述
设置sclk、cs、sdataA、sdataB的引脚。vinA=2.5V,vinB = 0V。使用ila抓取数据如下。
在这里插入图片描述
ila的时钟为160MHz,上图可以看出单次采样的整个时序的长度为32个时钟周期,即200ns。
cs的下降沿到sclk的第一个下降沿的时间为6.25ns,大于时序约束中的 t 2 t_2 t2最小值5ns。
sclk时钟为80MHz,小于sclk时钟的最大值100MHz。
t CONVERT t_{\text{CONVERT}} tCONVERT为27个ila时钟周期,即168.75 ns。 t QUIT t_{\text{QUIT}} tQUIT 为4个ila时钟周期,即25 ns,大于时序约束最小值5 ns。
最后在sclk的下降沿取1比特数据,构成12位采样数据输出。此时,out_A[11:0] = 4095,out_B[11:0] = 2047。AD7356的模拟输入与数字输出对应关系如下图。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mac m1的docker nacos2.0.3访问宿主机器的mysql

一、环境介绍&#xff1a; 我的mac系统&#xff1a;m1芯片 macOs Ventura 13.1 我的docker版本&#xff1a;v20.10.8 本机msyql&#xff1a;8.0.25 端口&#xff1a;3306。 mysql版本查询脚本&#xff1a;select version() from dual; 二、准备安装nacos2.0.3 m1版本的镜像 …

Vue+Echarts 项目演练(中)后台数据接口的创建

全局引用Echarts与axios 后台接口创建express路由 api接口数据创建 全局引用Echarts与axios vue3.0的挂载方式&#xff1a;使用Provide/Inject依赖注入&#xff0c;将替代vue2中在原型链上挂载一些属性在app.vue中使用provider来给后代们提供数据 <script> import { p…

组态王与FX3U之间无线通讯(485BD口)

设备与设备之间互相通信&#xff0c;需要一座桥梁把二者连接起来&#xff0c;那就是传输通路与通信协议。 传输通路由传输介质与传输接口组成&#xff0c;传输介质可分为有线和无线传输介质两大类。传输接口即通信模块。传输接口常见的有三种RS-232、RS-485和RS-422通信模块。…

干货|英国专利申请

英国是世界上公认的一个实施现代专利制度的国家。英国1624年颁布的《垄断法案》被认为是世界上一部具有现代意义的专利法&#xff0c;并成为现代专利保护制度系的起点。英国现行的专利法于1977年颁布&#xff0c;并于1978年生效。英国的专利制度在保护发明创造&#xff0c;促进…

21.Java网络通信

目录 1. Java基本介绍 2. JDK下载安装及其环境配置 3. 一个简单的java程序 4. Eclipse基本使用、数据类型、运算符 5. 控制语句&#xff08;if、switch、for、while、foreach&#xff09; 6. Java数组 7. Java字符串对象(String|StringBuffer|StringBuilder|StringJoiner…

Asp.NET CORE实验室信息管理系统源码,支持LIS独立部署,Docker部署

技术架构&#xff1a;Asp.NET CORE 3.1 MVC SQLserver Redis等 基于B/S架构的实验室管理系统源码&#xff0c;整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。全套系统采用云部署模式&#xff0c;部署一套可支持多家医院检验科…

Java ---Object根类

(一&#xff09;定义 官方说法&#xff1a; 在Java中&#xff0c; Object 类是所有类的父类&#xff0c;即Java 的所有类都继承了 Object&#xff0c;子类可以使用 Object 的所有方法。 注意&#xff1a; Object类型的变量与除Object以外的任意引用数据类型的对象都多态引用 所…

youdiancms 9.5.0 版本 SQL注入(vulfocus复现)

启动服务 从上述信息&#xff0c;可以看到&#xff0c;web服务的80端口被映射到62461端口&#xff0c;并且该服务对外开启了3306端口并映射到20130 端口。并且给了数据库的相关信息。 配置web数据库 登陆后台&#xff0c;后台如下&#xff1a; 探测注入点 上述提到注入点是M…

OpenGL教程之 纹理练习

网址 LearnOpenGL 练习一 修改片段着色器&#xff0c;仅让笑脸图案朝另一个方向看。  解析&#xff1a;朝向另一个方向很简单&#xff0c;即让上文中的图片进行左右对称变换即可&#xff0c;即将片段着色器中笑脸的纹理坐标从textCord转换为vec2( 1 - textCord.x, text.y …

【淘宝】商品列表页数据采集+商品销量数据采集代码

采集场景 在淘宝首页&#xff08;https://s.taobao.com/&#xff09;输入关键词搜索&#xff0c;采集搜索后得到的商品列表页数据。示例中关键词为【耐克】&#xff0c;可根据需求进行更换&#xff0c;同时支持自动批量输入多个关键词。 采集字段 采集字段包括关键字文本值…

Nginx和tomcat反向代理(动静分离)

正向代理&#xff1a; 当用户想访问某一网址时&#xff0c;用户先访问代理服务器&#xff0c;然后由代理服务器向目标网址发送请求最终将数据返回代理服务器&#xff0c;最后代理服务器将数据返回给用户这一过程我们称之为正向代理。 反向代理&#xff1a;基本流程是与正向代理…

【react全家桶学习】如何创建一个react组件(超详)

前提是你安装了react脚手架&#xff0c;不会的看这里&#xff0c;然后再进行创建哦~ 【react全家桶学习】初始化react脚手架及项目结构讲解_suohs Blog的博客-CSDN博客 目录 问题1&#xff1a;如何创建一个简单的hello组件&#xff1f; 问题2&#xff0c;如果组件特别多怎么…

庚顿数据正式发布军工版实时数据库庚金3.0,鼎力支撑中国国防数字化

庚金实时数据库管理系统是北京庚顿数据科技有限公司旗下自主知识产权的军工级产品&#xff0c;可有效满足特种行业自主产权、高性能、高安全、高稳定等高端需求&#xff0c;轻松实现海量实时数据高频采集、海量存储等应用场景&#xff0c;切实保障了客户生产活动的稳定运行。庚…

c/c++:数组做函数参数,传入函数的首地址,相当于传址,指针做函数返回值,数组止做c语言中函数的返回值

c/c:数组做函数参数&#xff0c;传入函数的首地址&#xff0c;相当于传址&#xff0c;指针做函数返回值&#xff0c;数组禁止做c语言中函数的返回值 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;此时学会c的话&#xff0…

Python小姿势 - Python基础知识

Python基础知识 Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。 Python的创始人为吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;&#xff0c;于1989年底发布第一个公开发行版本——0.9.0。 自2004年以来&#xff0c;Python已经成为顶级开源项目&…

从浏览器地址栏输入 url 到显示主页的过程?

当在浏览器地址栏输入一个URL并按下回车键后&#xff0c;发生了一系列复杂的过程&#xff1a; DNS解析&#xff1a;浏览器会对输入的URL进行DNS解析&#xff0c;将域名转换为服务器的IP地址。这一过程包括浏览器缓存、操作系统缓存、本地HOST文件配置、本地DNS服务器以及远程DN…

多通道振弦传感器无线采集仪 数据发送详解

多通道振弦传感器无线采集仪 数据发送过程 每次采集仪启动后会将采集到的传感器数据进行内部存储&#xff0c;并在设置好的时间间隔将数据发送出去&#xff0c;通过修改“数据发送方式”参数&#xff0c;监测数据可由数据接口输出也可经由无线网络发送。 在发送监测数据时&…

SpringCloud --- Nacos注册中心、配置管理

一、Nacos注册中心 1.1、认识和安装Nacos Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在国内受欢迎程度较高。 1.2、服务注册到nacos Nacos是SpringCloudAlibaba的组件&#xff0c;而SpringCloudAlibaba也遵循Spr…

3dtiles之点云pnts文件详解

3DTiles是一种用于在WebGL环境中渲染大规模三维地理数据的规范&#xff0c;它允许开发者将复杂的三维数据以高效的方式传输、存储和呈现。而PNTS格式则是3DTiles规范中用于存储点云数据的格式之一。在本文中&#xff0c;我们将探讨3DTiles和PNTS的基本原理以及它们如何用于处理…

集成学习(Ensembles)

Ensembles 前言EnsemblesAveraging,StackingWhy does averaging work?如何理解&#xff1a;In practice errors won’t be completely independent due to noise in the labels Random ForestsDoes averaging work if you use trees with the same parameters?Bootstrap Samp…