新闻  |   论坛  |   博客  |   在线研讨会
TMS320F280X SPI SPIA使用入门与总结
mayer | 2009-09-06 13:25:05    阅读:2637   发布文章

TMS320F280X SPI SPIA使用入门与总结

 

TMS320F280X SPI SPIA使用入门与总结
Netjob @ 2009 831日晚

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

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

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

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

发现程序不能运行! 没办法改回RAM仿真,把很多函数注释掉。仅仅留下测试OLED的程序。
SSD1351的测试功能,向它写命令码,可以改变 GPIO1/GPIO2引脚的电平。这样测试SSD1351引脚的电平就知道SPI 驱动函数是否成功了。
其实移植就是仅仅这两个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.SPITXBUFSpiaRegs.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.SPISTS.bit.INT_FLAG置位就可以了。

之前在网上有个 《TMS320F2812 SPI 总结》,
http://blog.chinaunix.net/u/31491/showart_654915.html
文中说"spi速率不能超过15M,超过后会出现严重误码"
这个应该不对的,  我的这个OLED与C28X SPIA的通信速度就到了20M.(其实还可以到30MHZ, 恐怕OLED受不了)
SpiaRegs.SPIBRR =0x0002;        // 60MHZ/(2+1)=20MHZ SPI SPEED
而且是烧写到FLASH里运行,一直没问题。


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

其实有决心写这个全是因为当时出了问题比较着急,但在网上GOOGLE却没有什么收获!真让人气愤!
全大陆这么多大学的YY,GG ,不是很会出啥书啥书的吗?汗!
    希望各位能从这文中有点收获~,不要再被C28XSPI折腾和TI文档的折腾了~!哈哈。
希望TI别见怪啦~!

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客