目录
- 基于stm32的spi从机实验HAL库编程
- 前言
- 业务场景
- 硬件设计接线
- 配置swd接口
- 配置spi
- 配置DMA
- 配置中断
- 配置系统时钟
- 配置工程
- 生成代码
- 写点从机代码
- 上机现象
- 后记
- 本文使用的测试工程
基于stm32的spi从机实验HAL库编程
前言
在微控制器的世界中,串行外设接口(SPI)是一种广泛使用的接口,它允许设备之间进行快速通信。在这篇文章中,我将介绍如何使用STM32的硬件抽象层(HAL)库来编程一个SPI从机。我们将通过一个实验来理解SPI在实际应用中的运作方式,并且深入了解STM32的编程方法。
业务场景
假设有一个板子A作为主机端,通过一个接口的方式向外通讯交互,我们有一个板子B作为从机,用作接收端,现在按照主机端的协议来跟主机进行交互。
硬件设计接线
在我的这个硬件中,手头有一个stm32g0f6p6的板子,所以我以这个板子用作从机端进行设计。
打开STM32CubeMX进行操作
配置swd接口
配置spi
圈起来的参数要迎合主机端,不然通讯交互会出错,不知道主机端是什么配置时,则需要根据主机端底层通讯展示出来的波形来配置,用一个逻辑分析仪抓取分析一下,以我的这个场景为例,我的底层通讯呈现如下的波形:
按照我这里的展示,数据线1是对应MOSI,数据线2对应MISO,可以看到主机端时钟空闲电平是高电平,所以参数CPOL选择High参数,可以观察到数据1在交互时在第二边沿时电平很稳定,所以我这里CPHA的参数选择第一个边沿。至于是LSB先发,还是MSB先发,这个得双方进行约定,我这里以MSB先发为例。
配置DMA
配置中断
配置系统时钟
配置工程
生成代码
写点从机代码
在我的这个场景中,主机端每隔4ms发来一次数据,主机的数据格式如下:
从机端的代码如下:
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_SPI1_Init();/* USER CODE BEGIN 2 */HAL_SPI_TransmitReceive_DMA(&hspi1,g_tx_buff,g_rx_buff,4);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
从机使用DMA的方式进行接收,接收完成之后会进入一个回调函数,在回调函数里面我重新开启DMA接收,这是因为不是使用DMA的循环模式,循环模式自己用得不是很熟,这里是收完一次在重新打开。
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{if(hspi->Instance == SPI1){HAL_SPI_TransmitReceive_DMA(&hspi1,g_tx_buff,g_rx_buff,4);}
}
至于这个回调函数在哪里,可以在对应的.h中看到相关的声明,我们把对应的函数拿出来用就行了。
上机现象
可以看到,从机端在正常接收数据,在回调函数里面把数据摘取出来,就可以进行下一步的数据控制了。
后记
这里我只是进行简单的交互实验,实际工程中,数据交互会按照协议来进行设计,哪些字节表示命令,哪些字节表示校验,哪些字节表示长度,哪些字节表示参数,这些字节是什么含义,只有熟悉整个系统的设计者知道。
本文记录到此,算是自己工程的一次实践,希望这篇文章能帮助到你,本文完!!感谢阅读,感谢关注。
本文使用的测试工程
https://download.csdn.net/download/weixin_44317448/89286989