zynq外设SPI使用经验

  • Post author:
  • Post category:其他


1、综述

SPI的具体使用可以去查看ug585的文档,并配合附录里的寄存器。

我这里记录调试SPI的过程和经验。

2、需求

由于工程中,需要使用SPI来进行大数据块的传输,其数据块是900个字节,已经远远超出了SPI的FIFO深度。由于SPI的寄存器并没有指示数据已经发送完毕的标志(SPI的发送寄存器中的数据发送完毕),因此采用收取到的字节数=发送的字节数来判别是否已经发送完毕(类似于系统启动前BIT)。

3、方法

配置:

主模式,手动设置CS,空闲时时钟为高电平,下降沿发送数据,上升沿接收数据

整个工程思路:先发送第一包128字节的数据,并设置FIFO中还剩余4个字节未发送时,触发发送中断,在该中断中把需要发送的数据送入发送FIFO中,并接收SPI的数据,当接收到的字节数与发送的字节数相等时,拉低CS,关闭中断,关闭SPI使能。

核心伪代码如下:

中断处理:

while(SpiPs_GetSR & SpiIxR_RXNEMPTY)

{


SpiPs_Rx;

RCnt++;

}

if(RCnt==TheSpi.ByteCnt) {


//已完成传输

if(TheSpi.BufRef) (*(TheSpi.BufRef))–;

if(TheSpi.SpiCallBack) (TheSpi.SpiCallBack)();

//取消片选

SpiPs_SetCR(SpiCrDefalut|SpiCR_CsMask);

//关闭中断

SpiPs_DisableInt(SpiIxR_TXUF|SpiIxR_RXFULL|SpiIxR_RXNEMPTY|SpiIxR_TXFULL|

SpiIxR_TXOW|SpiIxR_MODF|SpiIxR_RXOVR);

//标记传输完成

TheSpi.ByteCnt=0;

return;

}

4、问题

由于每次中断,都会一直读取数据,一直到接收FIFO中不再有数据,而读取一个字节的数据,需要完成2次读AXI总线,实际最终使用的是APB总线,总线时钟远远小于CPU的666.66MHz的工作时钟,这里16MHz的SPI传输速度,完成128字节数据的读取,测试总共花掉了33us的时间,该时间是在中断中发生的,这种方式是相当不值得采取的。

但是鉴于目前SPI外设并没有更好的寄存器来标识SPI的工作状态,只能这样。

虽然

FIFO有发送空的标志位,但是FIFO空并不能代表MOSI上没有数据发送,因为发送寄存器中可能还在发送最后一个字节

。可以向xilinx公司提出意见,增加SPI的状态寄存器,表明当前SPI是空闲还是忙状态,空闲则代表当前MOSI线上没有数据传输,忙代表当前有数据传输。



版权声明:本文为weixin_43221453原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。