在ARM Cortex M3上实现非标准SPI变体

在ARM Cortex M3上实现非标准SPI变体,c,embedded,arm,cortex-m3,C,Embedded,Arm,Cortex M3,我需要为连接到STM32 Cortex M3 MCU的闪存芯片创建一个驱动程序。芯片通过SPI总线控制。我打算使用MCU的集成SPI外围设备,但不幸的是,它只支持8位或16位数据包,而闪存芯片命令的长度为14位。因此,我必须使用GPIOs从头开始实现协议。我的问题是:什么是确保信号正确计时的正确方法?我目前考虑在中断被禁用的情况下在断言和解除断言GPIO行之间插入,但对我来说这似乎相当不可靠。有更好的方法吗?如果可能,我建议使用内置SPI和DMA 您可以将数据重新映射到大小为14位倍数的字节数组

我需要为连接到STM32 Cortex M3 MCU的闪存芯片创建一个驱动程序。芯片通过SPI总线控制。我打算使用MCU的集成SPI外围设备,但不幸的是,它只支持8位或16位数据包,而闪存芯片命令的长度为14位。因此,我必须使用GPIOs从头开始实现协议。我的问题是:什么是确保信号正确计时的正确方法?我目前考虑在中断被禁用的情况下在断言和解除断言GPIO行之间插入,但对我来说这似乎相当不可靠。有更好的方法吗?

如果可能,我建议使用内置SPI和DMA

您可以将数据重新映射到大小为14位倍数的字节数组中。 因此,每次必须发送7*4位=28字节的倍数。
然后可以使用8位大小的标准SPI


但是使用SPI/DMA应该比使用GPIO快得多。

Jeb的答案是首选方法,如果可能的话,您应该使用硬件SPI,如果DMA是一个不错的选择,那么也应该使用硬件SPI

如果出于某种原因发现无法使用硬件SPI,但必须通过GPIO上的“位碰撞”来实现,则应检查MCU上的定时器/PWM硬件中有哪些可用选项。你不能也不应该使用直截了当的“爱好者烧掉延迟”,因为在你发布的链接中,实时性能将是垃圾,你将100%占用CPU

大多数MCU定时器都带有引脚输出功能,允许引脚在定时器失效时改变状态。然后,伪代码将是:

  • 确定下一个要发送的位是1还是0
  • 相应地设置MCU极性寄存器,以便将引脚切换到高电平或低电平
  • 当计时器过期时,您需要再次设置极性,可能是通过中断。如何做到这一点非常依赖于硬件
  • 在对数据进行位处理(MOSI)的同时,还需要生成时钟和芯片选择。时钟可以与数据相同的方式生成,如果该选项可用,也可以通过PWM信号生成。芯片选择是最简单的部分,因为在数据传输过程中,您只需将引脚拉低

最后,关于如何为特定MCU编写软件SPI,很可能有一些应用说明或官方示例。

一些使用模糊数据长度的设备设计为在事务开始时忽略第一个“1”之前的所有“0”位,或忽略所有“1”位在第一个“0”之前计时的位。如果您的设备恰好是以这种方式设计的,那么您可以使用8位或16位SPI模式,方法是将两个“垃圾”位与感兴趣的位一起计时。

我会抵制具有如此模糊接口的内存。有很多使用“标准SPI”的内存,因为有一个SPI标准。@Lundin,不幸的是,硬件部分不是我设计的,显然我们现在不能扔掉它。我同意一个接口更方便的芯片会是一个更好的选择。也许其他制造商也有引脚兼容的替代品?即使重新设计硬件不是一个选项,你至少应该问一个为什么使用这个特定部件的理由。我想这只是没有考虑好。我们正在寻找兼容的芯片:)你能告诉我们什么是闪存设备吗?