基于FPGA的SPI控制器Word文件下载.docx

上传人:b****5 文档编号:16961520 上传时间:2022-11-27 格式:DOCX 页数:10 大小:188.11KB
下载 相关 举报
基于FPGA的SPI控制器Word文件下载.docx_第1页
第1页 / 共10页
基于FPGA的SPI控制器Word文件下载.docx_第2页
第2页 / 共10页
基于FPGA的SPI控制器Word文件下载.docx_第3页
第3页 / 共10页
基于FPGA的SPI控制器Word文件下载.docx_第4页
第4页 / 共10页
基于FPGA的SPI控制器Word文件下载.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

基于FPGA的SPI控制器Word文件下载.docx

《基于FPGA的SPI控制器Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于FPGA的SPI控制器Word文件下载.docx(10页珍藏版)》请在冰豆网上搜索。

基于FPGA的SPI控制器Word文件下载.docx

数据输出通过 

SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。

完成一位数据传输,输入也使用同样原理。

这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。

要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。

同样,在一个基于SPI的设备中,至少有一个主控设备。

这样传输的特点:

这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。

也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。

SPI还是一个数据交换协议:

因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。

不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。

在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。

在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

最后,SPI接口的一个缺点:

没有指定的流控制,没有应答机制确认是否接收到数据。

AT91RM9200的SPI接口主要由4个引脚构成:

SPICLK、MOSI、MISO及 

/SS,其中SPICLK是整个SPI总线的公用时钟,MOSI、MISO作为主机,从机的输入输出的标志,MOSI是主机的输出,从机的输入,MISO 

是主机的输入,从机的输出。

/SS是从机的标志管脚,在互相通信的两个SPI总线的器件,/SS管脚的电平低的是从机,相反/SS管脚的电平高的是主机。

在一个SPI通信系统中,必须有主机。

SPI总线可以配置成单主单从,单主多从,互为主从。

SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS0~3接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS0~3,输出用于16个外设的选择。

二 

SPI协议举例

SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。

假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。

那么第一个上升沿来的时候 

数据将会是sdo=1;

寄存器=0101010x。

下降沿到来的时候,sdi上的电平将所存到寄存器中去,那么这时寄存器=0101010sdi,这样在 

8个时钟脉冲以后,两个寄存器的内容互相交换一次。

这样就完成里一个spi时序。

举例:

假设主机和从机初始化就绪:

并且主机的sbuff=0xaa,从机的sbuff=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:

假设上升沿发送数据 

这样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。

其中ss引脚作为主机的时候,从机可以把它拉底被动选为从机,作为从机的是时候,可以作为片选脚用。

根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。

SPI 

总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:

一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;

用于CPU与各种外围器件进行全双工、同步串行通讯。

SPI主要特点有:

可以同时发出和接收串行数据;

可以当作主机或从机工作;

提供频率可编程时钟;

发送结束 

中断标志;

写冲突保护;

总线竞争保护等。

下图示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式 

(实线表示):

SPI总线四种工作方式 

模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。

如果 

CPOL=0,串行同步时钟的空闲状态为低电平;

如果CPOL=1,串行同步时钟的空闲状态为高电平。

时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。

如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;

如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。

SPI主模块和与之通信的外设备时钟相位和极性应该一致。

SPI总线包括1根串行同步时钟信号线以及2根数据线。

SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。

如果CPOL=0,串行同步时钟的空闲状态为低电平;

SPI主模块和与之通信的外设音时钟相位和极性应该一致。

SPI接口时序如图3、图4所示。

补充:

上文中最后一句话:

个人理解这句话有2层意思:

其一,主设备SPI时钟和极性的配置应该由外设来决定;

其二,二者的配置应该保持一致,即主设备的SDO同从设备的SDO配置一致,主设备的SDI同从设备的SDI配置一致。

因为主从设备是在SCLK的控制下,同时发送和接收数据,并通过2个双向移位寄存器来交换数据。

工作原理演示如下图:

上升沿主机SDO发送数据1,同时从设备SDO发送数据0;

紧接着在SCLK的下降沿的时候从设备的SDI接收到了主机发送过来的数据1,同时主机也接收到了从设备发送过来的数据0.

三 

FPGA实现源码

LIBRARYieee;

USEieee.std_logic_1164.ALL;

USEieee.std_logic_arith.ALL;

USEieee.std_logic_unsigned.ALL;

ENTITYspiIS

PORT

--全局信号

NReset 

:

IN 

STD_LOGIC;

--全局复位信号

Clk 

--全局时钟

-- 

ResetWdi 

BUFFER 

--看门狗的喂狗信号

--SPI通讯端口

SPINcs 

INOUT 

--SPI片选(低有效)

SPIClk 

--SPI时钟

SPIMOSI 

--SPI的主出从入

SPIMISO 

--SPI的主入从出

--SPI数据寄存器

SPITxdata 

STD_LOGIC_VECTOR(15DOWNTO0);

--待发送数据

SPIRxdata 

--接收数据

--SPI状态寄存器

SPIStatus 

STD_LOGIC_VECTOR(7DOWNTO0);

--第5位为trdy(发送器准备好),第6位rrdy(接收器准备好)

--SPI控制寄存器

SPIControl 

--第0位为mode(模式设置,0为主模式,1为从模式),

--第1位为clkpolarity(时钟极性,0时为空闲是低,1为空闲是高),

--第2位为clkphasic(时钟相位,0时为前沿检测,1为后沿检测),

--第3位为datapriority(数据先后,0时为MSB在前,1为LSB在前),

--第4位为start(上升沿开始发送数据),

--第7位sso(1时始终置cs为1(无效))

SPILength 

--数据位数寄存器

--SPI频率设置寄存器

SPISetClk 

STD_LOGIC_VECTOR(31DOWNTO0) 

--SPIClk为Clk的SPISetClk分频

);

ENDspi;

ARCHITECTURErtlOFspiIS

TYPEStateTypeIS(S0_Wait,S1_Data,S2_Stop);

--状态机定义

SIGNAL 

StateIndex 

StateType;

--状态机

CntCycle 

integerRANGE0TO16383;

--位周期计数器

CntBit 

integerRANGE0TO15;

--位数计数器

SPITxdataTmp 

--数据锁存

CycleBit 

--位周期

SPIClkCut 

STD_LOGIC_VECTOR(31DOWNTO0);

--生成SPIClk计数器

SPIBitCut 

--SPI的数据位数计数

--看门狗计数

CntWdi 

STD_LOGIC_VECTOR(9DOWNTO0);

BEGIN

--看门狗的喂狗信号的产生

--CntWdi<

=CntWdi+1WHEN(Clk'

EVENTANDClk='

1'

--ResetWdi<

=CntWdi(9);

--设置SPI的主从模式,若为主模式则设置SPINcs和SPIClk

PROCESS(NReset,Clk)

IF(NReset='

0'

)THEN 

--复位状态

SPINcs<

='

Z'

;

SPIClk<

SPIMOSI<

SPIMISO<

SPIStatus<

="

01100000"

SPIRxdata<

=X"

0000"

StateIndex<

=S0_Wait;

SPIClkCut<

00000000"

SPIBitCut<

=0;

ELSIF(Clk'

)THEN

IF(SPIControl(0)='

--主模式状态

CASEStateIndexIS

WHENS0_Wait=>

=SPIControl

(1);

IF(SPIControl(4)='

) 

THEN 

--判断起始标志

=SPIControl(7);

IF(SPIControl(3)='

--判断数据MSB还是LSB在前

=SPITxdata(CONV_INTEGER(SPILength)-1);

ELSE

=SPITxdata(0);

ENDIF;

=S1_Data;

=StateIndex;

WHENS1_Data=>

IF(SPIClkCut 

=('

&

SPISetClk(31DOWNTO1)-'

))THEN 

--SPIClk前沿

=NOTSPIClk;

=SPIClkCut+1;

IF(SPIControl

(2)='

--前沿检测

=SPIMOSI;

=SPIRxdata;

SPIRxdata(CONV_INTEGER(SPILength)-SPIBitCut-1)<

=SPIMISO;

SPIRxdata(SPIBitCut)<

ELSE 

--后沿检测

=SPITxdata(CONV_INTEGER(SPILength)-SPIBitCut-1);

=SPITxdata(SPIBitCut);

=SPIBitCut;

ELSIF(SPIClkCut>

=(SPISetClk(31DOWNTO0)-'

--SPIClk后沿

=SPITxdata(CONV_INTEGER(SPILength)-SPIBitCut-2);

IF(SPIBitCut>

=CONV_INTEGER(SPILength)-1)THEN

=S2_Stop;

=SPIBitCut+1;

=SPIClk;

WHENS2_Stop=>

))THEN

=SPINcs;

=SPIStatus;

WHENOTHERS=>

ENDCASE;

--从模式状态

ENDPROCESS;

ENDrtl;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 解决方案

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1