SPI协议的Verilog-实现

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1SPISPISPISPI通信�原理Spi接口是一种外围串行接口,主要由四根线组成:SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。(1)SDO主机输出/从机输入。(2)SDI主机输入/从机输出。(3)SCK–时钟信号,由主设备产生。(4)CS–从设备使能信号,由主设备控制。在一个基于SPI的设备中,至少有一个主控设备。与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,工作简单高效。然而SPI接口也有缺点:没有指定的流控制,没有应答机制确认是否接收到数据。SPI通讯是通过数据交换完成的。在主机提供的时钟脉冲SCK下,SDI,SDO完成数据传输。数据输出通过SDO线,在SCK时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被从机读取,完成一位数据传输。输入情况同理。因此,在至少8次时钟信号的改变(上沿和下沿为一次),可以完成8位数据的传输。SPI总线有四种工作方式可以选择,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI主\从设备时钟相位和极性应该一致。本次实践采用第一种工作方式,具体情况将在之后的仿真波形中分析介绍。�SPI—MOSI代码(见附录)�仿真及分析2数据发送:图1、数据发送如图1所示,传输时钟SCK由busy信号控制,在busy信号有效期间产生八个周期的主从设备交换数据时钟信号,在每一个周期内完成一位数据的发送和接收。测试中,待发送数据为10101001。经过数据线SDO发送后,在SCK的第一个跳边沿进行数据采样,在每个sck下降沿完成一位数据的交换。由上图可知,在一个busy信号有效期内,sdo发送的数据为10101001,与待发送数据一致。而busy信号的产生,与片选信号cs、写信号wr和地址信号addr有关。在busy信号为低电平时,只有片选有效,且当前为写状态,才能由addr决定是否使能busy信号,开始数据发送。而在busy信号使能时,只有片选有效,才能进行数据发送,当片选无效则暂停下一位数据发送。当然,每发送完8bit数据,busy信号会自动关闭使能状态,等待命令……3数据接收:图2、数据接收数据接收与数据发送使用同一个时钟信号SCK和片选信号CS。其工作情况大致如下:在每个SCK时钟的上升沿对接收数据进行采样。由图2可知,在一个busy信号使能阶段,采到的数据为10110111,即十进制183。在busy信号关闭使能后,只有片选使能且处于允许读状态,接收到的数据才会被存储,否则丢弃。Chipscope数据抓取DataPort[5]-DataPort[0]:busy、sdo、addr、cs、wr、rdDataPort[21]-DataPort[14]:待发送8bit数据DataPort[13]-DataPort[6]:接收的8bit数据4�总结完成时间:12.4--12.12前期:该阶段主要是熟悉SPI工作原理,进一步掌握和认识SPI通信协议。Chipscore的使用之前未曾接触,在这一阶段,我先通过简单编程结合开发板抓取数据进行分析达到对其的基本掌握。中期:在熟悉SPI的工作原理之后,开始尝试编写代码。写了两三次代码,效果均不理想,很多问题在编写代码的时候没有考虑清楚,导致到了仿真阶段结果与预期有所差距,且代码冗长复杂。参考了一些资料,效果也不是很好,特别是数据传输暂停部分,很多都省略了。不过借鉴别人写的代码也让我收获了不少编写的经验,有些情况下,运用不同的逻辑思维可以让代码更简洁、更具有健壮性。当然期间也遇到了一些自己无法解决的问题,非常感谢福星学长耐心的指导,让我学到了不少知识和经验。后期:该阶段主要是对代码进行再修改、波形仿真以及抓数据调试。问题及分析:小问题遇到不少,不过大多都通过error的提示,或者上网搜索,找到了问题的原因,并予以解决。也有软件上的原因,比如:第一次装ISE的时候可能没有安装好,上板调试的时候,cable不能识别。经过测试分析发现ISE里的drive没有装上。考虑到这样一个问题的出现可能还会附带有一些软件上的漏洞,重装了一遍ISE,问题解决。使用chipscope的时候,芯片配置不对连接失败,查阅该电路板的资料,重新配置,问题解决。在chipscope里面有些触发信号找不到,经分析是被优化了,通过简单修改代码避免它被优化后,问题解决。运行chipscope后发现waveform始终没反应,经过一番分析,认为时钟线的引脚配置有问题,重换一个时钟信号线I/O引脚,问题解决。解决后发现抓取的波形没有明显的高低跳变,经分析可能是参考时钟选取不对,重选后问题解决。附录:流程图5代码://////////////////////////////////////////////////////////////////////////////////modulespi_mosi(addr,rd,wr,cs,clk,sdi,sdo,sck,spi_bps,data);inputwireaddr;inputwirerd;inputwirewr;inputwirecs;inputwireclk;output[size:1]data;inputsdi;inoutsdo;inoutsck;inoutspi_bps;reg[size:1]out_data=0;regsck_buffer=0;regsdo_buffer=0;regbusy=0;reg[size:1]in_buffer=0;reg[size:1]out_buffer=0;reg[6:0]count=0;reg[7:0]clkcount=0;regspi_bps_reg=0;reg[12:0]clk_cnt;reg[size:1]in_data=8'b10101001;6parametersize=8;parameterpara=6400;parameterpara_half=3200;assigndata=out_data;assignsck=sck_buffer;assignsdo=sdo_buffer;assignspi_bps=spi_bps_reg;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////分频模块////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////always@(posedgeclk)beginif((clk_cnt=0)&&(clk_cntpara_half))beginclk_cnt=clk_cnt+1'b1;spi_bps_reg=1'b0;endelseif((clk_cnt=para_half)&&(clk_cntpara))beginclk_cnt=clk_cnt+1'b1;spi_bps_reg=1'b1;endelseclk_cnt=13'd0;end///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////发送接收模块////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////always@(csorrdorbusy)beginif(!busy&&cs&&rd)//beginout_data=out_buffer;end//接收数据存入out_dataelsebeginout_data=8'b0;endendalways@(posedgespi_bps)beginif(!busy)//空闲状态beginif(cs&&wr)//片选使能且处于写状态7begincase(addr)1'b0:beginin_buffer=in_data;busy=1'b1;end//待发数据存入缓存区,转入工作状态1'b1:beginbusy=1'b0;endendcaseendendelsebeginif(cs)beginclkcount=clkcount+1'b1;if(clkcount=8'b10)//控制SCK周期beginclkcount=0;if((count%2)==0)//发送数据beginsdo_buffer=in_buffer[8];in_buffer=in_buffer1;endif(count0&&count17)//在未达到8个sck周期时,每次触发条件满足,信号反转一次beginsck_buffer=~sck_buffer;endcount=count+1'b1;if(count17)begincount=0;busy=1'b0;endendendendendalways@(posedgesck_buffer)beginout_buffer=out_buffer1;out_buffer[1]=sdi;//接收从机发送过来的数据endendmodule8触发信号控制部分:modulespi_mem(spi_bps,rd,wr,cs,sdi,addr);inputspi_bps;outputrd;outputwr;outputcs;outputsdi;outputaddr;regrd_reg;regwr_reg;regcs_reg;regsdi_reg;regaddr_reg;assignrd=rd_reg;assignwr=wr_reg;assigncs=cs_reg;assignsdi=sdi_reg;assignaddr=addr_reg;parametersize=8;reg[size:1]cnt_set;reg[size:1]cnt_sdi;always@(posedgespi_bps)beginif(cnt_set8'd250)begincnt_set=cnt_set+1'b1;endelsebegincnt_set=8'd0;endendalways@(posedgespi_bps)beginif(cnt_sdi8'd9)begincnt_sdi=cnt_sdi+1'b1;endelsebegincnt_sdi=8'd0;endendalways@(posedgespi_bps)beginif(cnt_sdi8'd5)beginsdi_reg=1'b1;end9elsebeginsdi_reg=1'b0;enden

1 / 10
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功