FPGA构造spi时序——AD7176为例(转)
reference:https://blog.csdn.net/fzhykx/article/details/79490330
项目中用到了一种常见的低速接口(spi),于是整理了一下关于spi相关的知识,与AD采样的芯片7176通信的协议为spi
一.对spi协议的理解
spi扫盲
除了供电、接地两个模拟连接以外,SPI总线定义四组数字信号:
- 接口时钟SCLK(Serial Clock,也叫SCK、CLK),master输出至slave的通讯时钟。
- MOSI( Master Output Slave Input,也叫SIMO、MTSR、DI、DIN、SI)自master输出至slave的数据线。
- MISO (Master Input Slave Output,也叫SOMI、MRST、DO、DOUT、SO)自slave输出至master的数据线。
- SS(Slave select,也叫nSS、CS、CSB、CSN、EN、nSS、STE、SYNC)master对slave的片选信号,自master输出至slave,低有效。
SPI接口是一种典型的全双工接口,通过同步时钟SCLK的脉冲将数据一位位地传送。所以在开始通讯前,master首先要配置接口时钟(确定其通讯频率是SLAVE可以支持的,通常为数兆赫兹)。
当MASTER片选一个SLAVE时,每向SLAVE发送一个周期的SCLK信号,都会有1bit的数据从MOSI发送至slave,与此同时,slave每收到一个周期的SCLK信号,都会从MISO向master发送1bit的数据。这种全双工通讯,是由硬件保证的(MASTER与HOST中各有一个移位寄存器作为收发数据的缓存)。
二.AD7176使用简单说明
1>写入与读入方法
对于FPGA为master而言,要注意SCLK下降沿发数给AD7176,上升沿读AD7176的数。在写入的时候,先用SPI时序,写入一个8bits的CMD,CMD就是通信寄存器,负责控制写入还是读出和要通信的寄存器名称,随后写写入8bit/16bit/24bit的数据。
在读数据的时候也需要通过通信寄存器也就是CMD读取,要规定好读数据和读哪个寄存器的值。
2>AD7176配置流程
具体寄存器还需要查看手册具体配置。
三.程序源代码讲解
1>程序源码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2017/03/10 11:08:45
// Design Name:
// Module Name: spi_core
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////// module spi_core(
input clk,//50M
input rst, input [:] din, //要输出
input s_valid, //要输出
input[:] readnum,//指示指令读取数据的长度 2’b00:0,2'b01:8,2'b10:256,2'b11:1664480(320*257*2)
output spi_ready, output [:] dout,
output m_valid, input cfg_finsih, input spi_miso,
output spi_mosi,
output spi_cs,
output spi_clk,
output empty );
/*
本模块只完成SPI协议所规定的时序,不涉及FLASH指令的编写
*/
parameter IDLE = 'd0;
parameter S1 = 'd1;
parameter S2 = 'd2;
parameter S3 = 'd3;
parameter S4 = 'd4;
parameter S5 = 'd5;
parameter S6 = 'd6;
parameter Smid ='d7;
reg [:] sta_spi;
reg spi_ready_r;
reg spi_clk_r;
reg spi_cs_r;
reg spi_mosi_r; wire wr_en;
reg rd_en;
wire dout_fifo;
//wire empty;
wire full;
wire[:] rd_count; assign spi_clk = spi_clk_r;
assign spi_cs = spi_cs_r;
assign spi_mosi = dout_fifo;//spi_mosi_r;
assign spi_ready = spi_ready_r;
assign wr_en = s_valid;
//fifo_generator_0 fifo_generator_0 (
//.rst(~rst), // input wire rst
//.wr_clk(clk), // input wire wr_clk
//.rd_clk(clk), // input wire rd_clk
//.din(din), // input wire [7 : 0] din
//.wr_en(wr_en), // input wire wr_en
//.rd_en(rd_en), // input wire rd_en
//.dout(dout_fifo), // output wire [0 : 0] dout
//.full(full), // output wire full
//.empty(empty), // output wire empty
//.rd_data_count(rd_count)
//);
fifo_generator_0 fifo_generator_0 (
.clk(clk), // input wire clk
.srst(~rst), // input wire srst
.din(din), // input wire [7 : 0] din
.wr_en(wr_en), // input wire wr_en
.rd_en(rd_en), // input wire rd_en
.dout(dout_fifo), // output wire [0 : 0] dout
.full(full), // output wire full
.empty(empty) // output wire empty
// .rd_data_count(rd_count) // output wire [15 : 0] rd_data_count
);
reg recv_reg;
reg recv_ok;
reg [:] recv_num;
reg [:] NUM;
always @(posedge clk)
begin
if(~rst)begin
sta_spi <= IDLE;
spi_clk_r <= 'b1;
spi_cs_r <= 'b1;
spi_mosi_r <='b0;
rd_en <= 'b0;
recv_reg <= 'b0;
recv_ok <= 'b0;
spi_ready_r <= 'b0;
recv_num <= 'd0;
end
else begin
case(sta_spi)
IDLE:begin
recv_ok <= 'b0;
recv_num <= 'd0;
spi_clk_r <= 'b1;
if(~empty)begin
rd_en <= 'b1;
sta_spi <= S1;
spi_ready_r <= 'b0;
end
else
spi_ready_r <= 'b1;
end
S1:begin
rd_en <= 'b0;
spi_clk_r <= 'b0;
spi_cs_r <= 'b0;
spi_mosi_r <= dout_fifo;
sta_spi <= S2;
end
S2:begin
spi_clk_r <= 'b1;
// sta_spi <= S3;
if(~empty)begin
rd_en <= 'b1;
sta_spi <= S1;
end
// else if(empty)
// spi_cs_r<=1'b1;
else if(readnum!='b00) //就是要读数的意思
sta_spi <= S4;
else
sta_spi <= S3;
end
S3:begin
sta_spi <= IDLE;
spi_clk_r <= 'b0;
spi_cs_r <= 'b1;
end
S4:begin
spi_clk_r <= 'b0;
recv_ok <= 'b0;
sta_spi <= S5;
end
S5:begin
spi_clk_r <= 'b1;
recv_num <= recv_num +'b1;
recv_reg <= spi_miso;
recv_ok <= 'b1;
if(recv_num!=NUM)
sta_spi <= S4;
else begin
sta_spi <= IDLE;
spi_cs_r <= 'b1;
end
end
endcase
end
end always @(posedge clk)
begin
if(~rst)
NUM <= 'd0;
else begin
case(readnum)
'b00:NUM <= 21'd0;
'b01:NUM <= 21'd7;
'b11:NUM <= 21'd23;
endcase
end
end
reg [:] dout_r;
reg m_valid_r;
reg [:] cnt_bit;
always @(posedge clk)
begin
if(~rst)begin
dout_r <= 'd0;
m_valid_r <= 'b0;
cnt_bit <= 'd0;
end
else if(recv_ok)begin
//m_valid_r <= 1'b0;
dout_r <= {dout_r[:],recv_reg};
cnt_bit <= cnt_bit + 'b1;
if(cnt_bit=='d15)
m_valid_r <= 'b1;
else
m_valid_r <= 'b0;
end
else
m_valid_r <= 'b0;
end
assign dout = dout_r;
assign m_valid = m_valid_r; /*********************************/
endmodule
2>软件仿真时序
配置过程也就是FPGA用SPI输出过程,每次片选信号CS拉低,下降沿发数
3>读数阶段软件仿真
波形也和手册的时序相对应
FPGA构造spi时序——AD7176为例(转)的更多相关文章
- ARM与FPGA通过spi通信设计2.spi master的实现
这里主要放两个代码第一个是正常的不使用状态机的SPI主机代码:第二个是状态机SPI代码 1.不使用状态机:特权同学<深入浅出玩转FPGA>中DIY数码相框部分代码: /////////// ...
- 基于FPGA的SPI FLASH控制器设计
1.SPI FLASH的基本特征 本文实现用FPGA来设计SPI FLASH,FLASH型号为W25Q128BV.支持3种通信方式,SPI.Dual SPI和Quad SPI.FLASH的存储单元无法 ...
- SPI总线协议及SPI时序图详解
SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚 ...
- FPGA的SPI从机模块实现
一. SPI总线协议 SPI(Serial Peripheral Interface)接口,中文为串行外设接口.它只需要3根线或4根线即可完成通信工作(这里讨论4根线的情况). ...
- FPGA中改善时序性能的方法_advanced FPGA design
本文内容摘自<advanced FPGA design>对应中文版是 <高级FPGA设计,结构,实现,和优化>第一章中的内容 FPGA中改善时序,我相信也是大家最关心的话题之一 ...
- ARM与FPGA通过spi通信设计1.spi基础知识
SPI(Serial Peripheral Interface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息.SPI总线可直接与各个厂家生产 ...
- SPI总线协议及SPI时序图详解【转】
转自:https://www.cnblogs.com/adylee/p/5399742.html SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接 ...
- SPI接口扫盲 SPI定义/SPI时序(CPHA CPOL)
SPI接口扫盲 douqingl@gmail.com 为何要写这篇文档?百度上找出来的SPI接口中文描述都说的太过简略,没有一篇文档能够详尽的将SPI介绍清楚的.wikipedia英文版[注释 ...
- 使用软件模拟spi 时序时注意点
软件模拟 spi 时序有以下几个点需要注意: cs 使能后到第一个 sck 边沿需要延时. 最后一个sck 边沿到下一个 cs 需要延时. sck 的高电平和低电平本身需要维持时间. mosi 需要先 ...
随机推荐
- <山月记>:中岛敦 -选段
因为害怕自己并非明珠而不敢刻苦琢磨,又因为有几分相信自己是明珠,而不能与瓦砾碌碌为伍,遂逐渐远离世间,疏避人群,结果在内心不断地用愤懑和羞怒饲育着自己懦弱的自尊心.世上每个人都是驯兽师,而那匹猛兽,就 ...
- 怎么检测自己fastq的Phred类型 | phred33 phred64
http://wiki.bits.vib.be/index.php/Identify_the_Phred_scale_of_quality_scores_used_in_fastQ # S - San ...
- English trip V1 - B 2. May I Help You? 它是多少钱? Teacher:Lamb Key:
In this lesson you will learn to ask for things in shops 这节课您将学习如何在商店中寻找东西 课上内容(Lesson) 你通常去哪里购物? W ...
- gitignore有时候为啥过滤不了文件或目录
一.问题介绍 使用Git过程中,有时候我们想过滤项目中的部分文件,在.gitignore中加入该文件名称或该文件所在目录的名称,比如我们的项目日志文件(.log文件) 但是有时候发现不管用.不好使. ...
- DAG最长路问题 hdu-1224
用DFS+记忆化写了一下,拓扑排序+DP的我还没弄明白.据说Codeforces 721C就是这类题目,因为有费用限制,DFS不太好写,有时间把DP法想明白来. #include <iostre ...
- 树上第k大联通块
题意:求树上第k大联通块 n,k<=1e5 考虑转化为k短路的形式. 也就是要建出一张图是的这条图上每一条S到T的路径都能代表一个联通块. 点分治建图 递归下去,假定每个子树的所有联通块中都可以 ...
- SQLServer2012数据库降级至SQLServer2008R2的方法
一. 背景 因为对方的客户的服务器安装的数据版本2012,公司开发同事需要客户数据库的备份数据,但是公司数据版本是2008R2的,无法还原. 由于2012备份无法直接还原至2008R2(MSSQ ...
- 6月3 Smarty基础读取配置
Smarty百科 Smarty是一个php模板引擎.更准确的说,它分开了逻辑程序和外在的内容,提供了一种易于管理的方法.可以描述为应用程序员和美工扮演了不同的角色,因为在大多数情况下 ,他们不可能是同 ...
- 在c++运行后出现PDB或者什么巴拉巴拉已经加载符号了的话
“stl常用排序算法.exe”(Win32): 已加载“E:\vs2015\project\stl常用排序算法\Debug\stl常用排序算法.exe”.已加载符号. “stl常用排序算法.exe”( ...
- 创建springboot的聚合工程(一)
比起传统复杂的单体工程,使用Maven的多模块配置,可以帮助项目划分模块,鼓励重用,防止POM变得过于庞大,方便某个模块的构建,而不用每次都构建整个项目,并且使得针对某个模块的特殊控制更为方便.接下来 ...