DSP

TMS320F280X SPI SPIA使用入门与总结

2019-07-13 19:30发布

 我使用过NXP ARM LPC2138SPI口,ATMEL AT91SAM7S256SPIMSP430F5438SPI口,
还有STM32 SPI模块。都是用来读 SPI FLASH 例如 AT45DB642D之类。

本以为对SPI已经入门了, 谁不知使用TMS320F280XSPI后,才知道自己其实还是一知半解。
TMS320F280X SPI 真是好好给我上了一课!

不久前有款 OLED 真彩 {MOD}液晶。使用的是SSD1351控制器SPI接口 想测试一下它的速度。就把它接到我的
TMS320F280XDSP 开发板上。之前使用DSPIO模拟,运行程序OLED的效果不错的。
本想这次使用SPI应该没事吧『虽然I/O模拟也是使用这个SPI的引进』?

新建立一个工程 MYOLED, 拷贝一些TMS320F28X相关的头文件C文件。把工程的设置好后,编译OK!
加上定时器中断用来点亮一个LED,把I/O模拟的工程相关文件的两个子函数改为SPI方式的。
在编译。文件太大非得使用FLASH下载仿真

发现程序不能运行! 没办法改回RAM仿真,把很多函数注释掉。仅仅留下测试OLED的程序。
SSD1351的测试程序,向它写某命令码,可以改变GPIO1/GPIO2引脚的电平。
其实移植就是仅仅这两个SPI底层函数:
void Write_Data(unsigned char Data)
void Write_Command(unsigned char Data)

测试好几次都没反应,  因此 就有下面的入门与详解了。

使用的是SPIA模块,如果SPIB没有什么特别(功能设置与SPIA差不多的话)也是没什么问题的。
但是我之前使用SPIB测试过,发觉SPIB还是与SPIA有区别的。这点我也很不解~。
按道理应该不会这样。但事实却是如此.


TMS320F280XSPI 支持1-16位的数据类型。
而且 只有MSB先发送,不像ARM7/STM32等可以设MSBLSB先发送。
TMS320F280XSPI有回环模式, 可以用于测试,自发自收。
TMS320F280XSPITX FIFORX FIFO. 及其中断字节设置。

看来没什么特别? 是吧~?  先别小看啊~,就是搞不定它呢!


首先是要回环模式,这样就是一个自发自收,方便测试。

其实现在看来,我曾经范了几点毛病。

1.
使用8位模式,但SPIA总线,发送接收等寄存器都是16位模式。

2.
数据的位数设置不对

3.
时钟极性与时钟相位。

4.
使用了 TX FIFORX FIFO.
其实不用使用FIFO比较好。为什么?下面会讲。

5.
没有完全理解SPIA的发送与接收是【同时】进行的概念,这点实在很惭愧!

6.
发送是MSB对齐先发送,接收是LSB对齐接收,发送与接收是【同时】进行的!


SSD1351的设置,是:
时钟 空闲保持高电平。第二个时钟边沿数据采样捕获,第一时钟边沿锁存

SCLK
的空闲无效状态是高电平 (其实也可以是低电平,但相位就要改改了,变为第二个时钟边沿锁存,,第一时钟边沿数据采样捕获)

数据的MSB 先发送。

好了,看看我是如何范这些毛病的,
void Write_Data(unsigned char Data)
void Write_Command(unsigned char Data)

看出参数都是8位的数据,比如要发送Data=0x55;那么传输到DSP SPI寄存器里这就出问题了!
是吧? 因为是MSB先发送,这样0x55到了16位的SPI寄存器例如SpiaRegs.SPITXBUF

SpiaRegs.SPIDAT
就变为0x0055了,由于SPIA 设置位8位模式,而且是MSB 先发送。

那么就是只发送 0x0055 00(8)了,低855就没有发送了。

因此 发送前要做如下变换:

Uint16 tmp;


tmp=Data;



tmp<<=8;



。。。。



SpiaRegs.SPIDAT =tmp




       而接收时无需移位,SpiaRegs.SPIDATSpiaRegs.SPIRXBUF中低8位就是发送的tmp
      

SPIA
的数据宽度设为8位。


SpiaRegs.SPICCR.bit.SPICHAR=7

       这个其实很简单,看看手册就知道了,不过我在网上看的HOTPOWER有关C54XSPI设置。
       就把SpiaRegs.SPICCR.bit.SPICHAR=8;来设8位的,这点我认为是不对了,虽然我不了解C54SPI设置。
       但估计也与C28X是一样的吧?哈哈!看来HOTPOWER也会范这样的低级毛病?不会吧?
      
时钟极性与时钟相位,其实我的OLED要求的是      
【时钟 空闲保持高电平。第二个时钟边沿数据采样捕获,第一时钟边沿锁存,SCLK的空闲无效状态是高电平】     
这个我想当然的搞错了:

SpiaRegs.SPICCR.bit.CLKPOLARITY=1; //
空闲时是高电平 这是对的



SpiaRegs.SPICTL.bit.CLK_PHASE=1;//
这个是错的!**




后来我认真看看了TI C28X SPI的数据手册,这个大家一定要好好看看啊!




   
这个图就是数据在时钟下跳沿改变、锁存,在时钟上升沿被捕获采样。

如果不明白可以看看我的《精解 SPI
CPHA
时钟相位 CPLK 时钟极性》

正确如下:

SpiaRegs.SPICCR.bit.CLKPOLARITY=1; //
空闲时是高电平 这是对的



SpiaRegs.SPICTL.bit.CLK_PHASE=0;//


SPIA的发送与接收是【同时】进行的概念
SPIA数据发送移位寄存器SpiaRegs.SPIDAT 是先发送MSB位,也就是BIT15位移位出SIMO
同时从SOMI采样一位数据到LSB 也就是BIT0。如此类推
BIT14移位到BIT15,然后发送到SIMO
BIT0移位到BIT1,然后从SOMI移入一位数据到BIT0……..

这个过程发送到SIMO和接收SOMI是同时进行的。
因此发生到底完成没有,可以查看接收到完整的8位数据没有。不过数据线怎样,只要有MSB移除SIMO就有数据从SOMI移入BIT0,哪怕全是0或全是1.

都有点不同的是,C28X SPI手册上说当数据接收完毕的SpiaRegs.SPIDAT,就好把SpiaRegs.SPIDAT的数据
输入SpiaRegs.RXBUFRX FIFO中,并置位SpiaRegs.SPISTS.bit.INT_FLAG.
这点,我认为TI的数据手册在忽悠我们。 真实情况是非的要关闭FIFO增强才会出现这个情况。
就是SpiaRegs.SPIFFTX.bit.SPIFFENA=0;
这样我们要查询到的数据发送完毕没有,只有等到SpiaRegs.SPIFFTX.bit.SPIFFENA置位就可以了。

哎,有点晚了,明天还要上班啦~,大家请原谅在下了,

其实有决心写这个全是因为当时出了问题比较着急,但在网上GOOGLE却没有什么收获!真让人气愤!
全大陆这么多大学的YY,GG ,不是很会出啥书啥书的吗?汗!
      真是希望大家从这文中有点收获~,不要再被C28XSPI折腾和TI文档的折腾了~!哈哈。
希望TI别见怪啦~!
  原文地址:http://bbs.21ic.com/icview-132026-1-1.html