两块STM32之间的SPI主从通信实例(附代码工程)

最近因为工作需要,要实现控制板之间的 SPI 通讯。两块 STM32 之间的 SPI 通讯平时用的比较少,之前我也没有用过,网上也查了很多资料,没有找到现成的、直接能用的例子。做软件的不就是ctrl+c、ctrl+v吗?

所以只能自己来实现了,本以为与在同一片 STM32 上做 SPI 主、从机通信一样,以为挺简单的,但是实际做起来还是遇到了不少问题,比如出现数据移位、多出了一些数据等问题。下面简单分享一下实现过程:

一、整体框图及说明

这里使用 STM32F429IGT6 作为主机,STM32F103ZET6 作为从机,都配置为全双工。本例要实现的功能就是主、从机之间的数据互传。

主机往从机发送的数据为:

从机往主机发送的数据为:

二、关键代码

主机关键代码:

从机关键代码:

可见,主机与从机的代码大多都一样。只是从机多了一步启动传输的操作,这一步很关键,少了这一步传输就不正常。这是为了制造主机发送的同时也要接收到数据的条件。这一点参考手册里也有相关说明:

此处,要营造这样的条件,必须先启动从机,然后再启动主机。只有保证主机发送的同时有接收到数据,才能保证其时序的正常,否则可能会产生数据错位,或者会产生多余数据等情况。

三、调试

我们平时在做实际的开发时,一般很难做到把所有代码写完,跑一遍就能成功,都是需要进行各个子模块的调试,一步一步来,确保各个子模块都没有问题之后,整体跑起来自然就比较稳定。

一些经验丰富的软件工程师常会教导一些年轻的软件工程师:在接到一个开发任务之前,先不要急着码代码,首先需要明确你这项任务的需求是什么,把任务分解成各个模块,然后在电脑上或纸上画出整体框图,确保框图的正确性之后,再根据框图来编写代码、调试。

同样的,我的主管也是这么教导我们的。此处,我们要调试 SPI 主从通信,自然也是这样分模块进行调试的:

  • 确认主机是否能正确发送数据

  • 确认从机是否能正确发送数据(返回数据给从机)

  • 确认从机是否接收到主机发过来的数据

  • 确认主机是否接收到从机发过来的数据

若这几个点明确了,都没问题之后。就可以明确我们的 SPI 主、从机的基本通讯没有问题了,之后就可以进行我们的协议方面处理了(本例中没有这一部分)。下面分别看一些这几个点:

1、确认主机是否能正确发送数据

方法:使用逻辑分析仪捕捉主机的 MOSI、SCK 这两条信号线,查看其波形。实际测得地结果如下:

其中,白色为 SCK 信号线波形,橙色为 MOSI 信号线波形。显然,从 MOSI 波形可以看出其与我们主机发送的数据一致,自然就可以确认主机发送数据没问题了。

此处,细心的朋友可能会发现时钟线波形的两个数据交互处的高电平总是宽一些,这里我们的 SPI 传输数据的位数设置为 8bit,则每一个数据对应的第 8 位对应的时钟信号的高电平总会长一些;若我们的 SPI 传输数据的位数配置为 16 位,则第 16 位对应的时钟信号的高电平总会长一些。

出现这个现象其实与我们的代码是有一定关系的。实际测试中发现是因为我们用 while 循环来做逻辑处理的问题,想办法把 while 等待替换为 if 判断,就可以改善这个问题。但是考虑到这并不会影响我们的数据,并且另一方面还有助于我们分析波形,所以使用 while。

2、确认从机是否能正确发送数据(返回数据给从机)

使用逻辑分析仪来捕捉 MISO 的波形,其波形如下(此处只捕捉了数据波形):

显然,我们的从机发送数据也是没问题的。

3、确认从机是否接收到主机发过来的数据

这里使用在线调试的方法检测从机的接收 buf,结果如下:

显然,从机收到的数据与主机发送的数据一致,说明从机接收也是没有问题的。由于手头里只有一个仿真器,所以也就没有同时监测主机的接收 buf,监视主机的接收 buf 与监视从机的方法是一样的。

四、需要注意的问题

1、两块板子一定要共地。

2、两块板子的 MOSI 与 MISO 无需交叉连接。

五、代码获取

(0)

相关推荐