本帖最后由 lai832 于 2016-12-14 10:00 编辑
因为需要 (一外部芯片的时序有些奇怪,NSS先于MISO一个时钟周期,利用这超前周期唤醒这个芯片)
时序如下图
说明:
1.上面是主机芯片的接收时序(只有SCO的相性可以改:选择上升沿或下降沿触发)
2.SCO是长期存在的(10MHz). 通过外接门开关,当FSI低时选通送到SPI_SCK (没办法因为SCO是长期存在,只能选用FSI的虚线波形,要不是可以考虑TI模式---但也是有问题的)
3.请注意FSI比SDI超前一个时钟周期
4.FSI是主机的输入---------------------这个很重要,即MCU的SPI从机是用I/O模拟NSS输出的,不是输入
5.因为SCO是长期连续的,两个16BIT间只能连续, STM32F4只支持最大一次发16BIT
情况:
1.MCU的SPI作为从机
2.因为STM32F的SPI_NSS问题, 只能选用I/O连接到FSI ------模拟NSS
------这就造成了只有在发后16BIT时,等待N个系统周期拉高FSI, 试过等待BUSY标志,不可行.程序:whit(busy); FSI = 1; //F4跑168M, SPI会多收到1个/2个SCO,导致多压入一个16BIT到移位寄存器.
3.发送方式:
3.1直接将32BIT分两次压入SPI->DR,这样没有超前一个时钟周期(发送流程与3.2差不多,只发32BIT)
3.2
a.发送BUFF[3]; 将实际的32BIT移位为1BIT(0) + 32BIT +15BIT(0),(前高位,后低位)
b.关总中断,
c.清标志
d.SPI->DR = BUFF[2] ----------发送1BIT(0) + 高15BIT,1BIT(0)作为超前FSI用
e.拉低FSI ----------打开门选通开关,SCO送到SPI_SCK脚,开始传输
f.等TXE标志
g.SPI->DR = BUFF[1] ----------发送BIT[16:1]
h.等TXE标志
i. SPI->DR = BUFF[0] -----------发送BIT[0]; 这里会将15BIT(0)也压入移位寄存器
j.while(N--); -----------计N个系统周期,使FSI对齐BIT[0],即SPI_SCK刚好收到33个时钟,
k.拉高FSI -----------发送完成,
以上发送完成.
问题:
1. 3.1方式缺少超前的FSI; 如果是拉低FSI,再更新SPI-DR,会出现超前16BIT的情况
2. 3.2方式; 到3.2.K处,因为最后16BIT只发送了最高的1BIT,还有15BIT(0),存在发送移位寄存器中,
下次收到SPI_SCK时,将发发送这15BIT(0),但这是无用的数据
这就有了一个问题,如何清除这残留的移位寄存器数据,
没找到方法,
失能SPI,再使能, 不行
只能复位SPI,再初始化
下面是别的论坛之前有人也在找清移位寄存器数据的方法
http://www.openedv.com/thread-22859-1-1.html
|
|