打印
[应用相关]

两片STM32使用HAL完成SPI全双工主从通信

[复制链接]
8352|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

SPI是一种非常简单易用的全双工主从式通信协议。

本文使用两片STM32F429,一个作为主机,一个作为从机完成SPI的全双工通信测试。


使用特权

评论回复
沙发
xiyaoko2365|  楼主 | 2021-6-23 23:19 | 只看该作者
在STM32的HAL库中简化了SPI主机端的发送接收,但是HAL库没有提供一个简单的SPI从机代码接口,这样就需要自己拼接接口来完成全双工的通信。以下都以实现全双工通信为目的进行配置和编写:

使用特权

评论回复
板凳
xiyaoko2365|  楼主 | 2021-6-23 23:20 | 只看该作者
一 主机端:

使用特权

评论回复
地板
xiyaoko2365|  楼主 | 2021-6-25 23:50 | 只看该作者
禁止使用SPI的硬件片选信号,因为这个信号是SPI使能了之后就一直为低,直到禁止了SPI之后才为高。可以使用某一个普通IO来充当片选信号。

使用特权

评论回复
5
xiyaoko2365|  楼主 | 2021-6-25 23:51 | 只看该作者

使用特权

评论回复
6
xiyaoko2365|  楼主 | 2021-6-25 23:52 | 只看该作者
这里选用一个较低的速率来通信,在HAL库的spi头文件中有说明各个模式下SPI的最大速度。

使用特权

评论回复
7
xiyaoko2365|  楼主 | 2021-6-25 23:52 | 只看该作者
二 从机端:

使用特权

评论回复
8
xiyaoko2365|  楼主 | 2021-6-25 23:53 | 只看该作者

使用特权

评论回复
9
xiyaoko2365|  楼主 | 2021-6-25 23:54 | 只看该作者

使用特权

评论回复
10
xiyaoko2365|  楼主 | 2021-6-25 23:54 | 只看该作者
主从的速率要一样,从机打开SPI中断



三 硬件连接:

主机                        从机



CS                          CS



CLK                        CLK



MISO                      MISO



MOSI                      MOSI



接收和发送都是直连不需要交叉。

使用特权

评论回复
11
xiyaoko2365|  楼主 | 2021-6-25 23:55 | 只看该作者
四 主机代码:
 /* USER CODE BEGIN 3 */

HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_RESET);



HAL_SPI_TransmitReceive(&hspi1, txbuf, rxbuf, 1, 0xFF);

HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);

HAL_Delay(500);

  }

  /* USER CODE END 3 */

使用特权

评论回复
12
xiyaoko2365|  楼主 | 2021-6-25 23:56 | 只看该作者
五 从机代码:
现在while之前打开spi接收中断:



  /* USER CODE BEGIN 2 */

HAL_SPI_Receive_IT(&hspi1, rxbuf, 1);

  /* USER CODE END 2 */

在中断中使用阻塞函数把数据发送出去:



/* USER CODE BEGIN 4 */

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

{

if (hspi == &hspi1)

{

HAL_SPI_Transmit(&hspi1, txbuf, 1, 0xFFFF);

HAL_SPI_Receive_IT(&hspi1, rxbuf, 1);

}

}

/* USER CODE END 4 */

使用特权

评论回复
13
xiyaoko2365|  楼主 | 2021-6-25 23:57 | 只看该作者
使用逻辑分析仪可以看到主机在发送的同时也收到了从机返回的数据。



可能在中断里调用阻塞发送不是很好,如果有更好的方法欢迎指正。

使用特权

评论回复
14
xiyaoko2365|  楼主 | 2021-6-25 23:57 | 只看该作者
另外在一片stm32上使用两个SPI接口模拟主从机通信好像不能正常工作。





最后需要注意的是如果你使用了以上方法,能测试spi通信成功,但是当主程序有其他任务的时候就会非常卡顿,因为在中断中调用了阻塞发送的函数。为了让程序更加流畅一种方法是减小HAL_SPI_Transmit的等待时间,另外一种方法就是使用DMA.



因为这里我只需要用DMA回复SPI master数据,所以我只开启了从机的SPI发送DMA,而且没有使能DMA中断。

使用特权

评论回复
15
xiyaoko2365|  楼主 | 2021-6-25 23:58 | 只看该作者
将spi.c中的代码更改如下:
/* USER CODE BEGIN 1 */

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

{

if (hspi == &hspi1)

{

HAL_SPI_Transmit_DMA(&hspi1, p_phase_buf, 1);

//HAL_SPI_Transmit(&hspi1, p_phase_buf, 1, 0xFFF);

HAL_SPI_Receive_IT(&hspi1, p_pwm_freq, 1);

}

}

/* USER CODE END 1 */

使用特权

评论回复
16
xiyaoko2365|  楼主 | 2021-6-25 23:59 | 只看该作者
添加DMA就是这么简单,由此就看到HAL库高效的地方了,使用起来确实能大幅提高工作效率

使用特权

评论回复
17
菜鸟的第一步| | 2021-6-30 16:48 | 只看该作者
使用cube是真的简单,这个工具大大简化了原始工程构建,就是代码太冗杂,执行效率太低。

使用特权

评论回复
18
skyred| | 2021-7-1 15:21 | 只看该作者
这是cube的应用啊~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

418

帖子

0

粉丝