STM32(HAL)——SPI通信

6. SPI

6.1 基本概念

全称Serial Peripheral Interface,是一种全双工,同步通信

6.1.1 物理层

共四条线:MOSI、MISO、SCK、NSS

信号线 作用
MOSI 主机输出,从机输入
MISO 主机输入,从机输出
SCK 时钟信号,由主机产生,用于通讯同步
NSS 从机使能信号,由主机控制(片选线)

6.1.2 协议层

通讯的起始和停止

通讯起始:NSS线信号由高变低,对应的从机被选中,开始通讯

通讯结束:NSS线信号由低变高,对应的从机取消选中状态

SPI的四种模式

四种模式的区别:总线空闲时sck的时钟状态(CPOL)及数据采样时刻(CPHA)。

CPOL:SPI通讯设备处于空闲时(NSS为高电平时)SCK的状态。CPOL=0,则SCK线在空闲时为低电平;CPOL=1,则SCK线在空闲时为高电平

CPHA:数据采样的时刻。CPHA=0,MOSI或MISO线上的信号将在SCK线的奇数个跳变沿被采样;CPHA=1,MOSI或MISO线上的信号在SCK线的偶数个个跳变沿被采样。

在这里插入图片描述

:四种模式都可以使用,但是主从设备必须采用同一种模式。

6.2 STM32的SPI

STM32中SPI个数从3到6个不等,支持Motorola和TI协议。STM32还支持I2S功能。

6.3 CubeMX配置

  1. 左侧目录>Connectivity>点SPI1/SPI2……~> 勾选模式

### 启动DMA突发读操作 对于STM32系列微控制器,在使用DMA进行突发读取时,`HAL_TIM_DMABurst_ReadStart` 函数用于初始化并启动基于定时器的DMA突发传输。此函数允许从外设到内存的数据传输,并且可以配置为在特定事件触发下自动执行数据块转移。 #### 参数说明 该函数接受多个参数来定义具体的传输行为: - `TIM_HandleTypeDef* htim`: 定时器句柄指针,包含了定时器实例以及其状态信息。 - `uint32_t BurstBaseAddress`: 突发传输的基础地址,即要访问的第一个寄存器的位置。 - `uint32_t BurstRequestSource`: 请求源的选择,决定了哪个信号会触发一次新的突发请求。 - `uint32_t DataLength`: 数据长度,表示每次突发将传输多少字节的数据。 - `uint8_t* pData`: 指向目标缓冲区的指针,用来存储接收到的数据。 - `uint16_t BurstLength`: 单次突发期间传输的最大数据项数量。 ```c HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSource, uint32_t DataLength, uint8_t *pData, uint16_t BurstLength); ``` 为了确保正确设置和调用这个API接口,下面是一个简单的例子展示如何利用它来进行ADC采样结果通过DMA传送到指定数组中[^1]。 #### 示例代码 假设有一个场景是在PWM周期结束时捕获ADC转换的结果并通过DMA将其保存至内部SRAM中的某个位置,则可按照如下方式编写程序片段: ```c // 声明全局变量用于接收ADC样本值 static uint16_t aADCxConvertedValues[BUFFER_SIZE]; /* 初始化 ADC 和 DMA */ void MX_ADC_Init(void){ /* ...省略其他必要的初始化... */ // 设置DMA通道处理来自ADC的数据流 hdma_adc.Instance = DMA1_Channel1; hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc.Init.MemInc = DMA_MINC_ENABLE; hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc.Init.Mode = DMA_CIRCULAR; if (HAL_DMA_Init(&hdma_adc) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(htim_base, hdma[TIM_DMA_ID_CC1], hdma_adc); } /* 开始DMA突发读取 */ if(HAL_TIM_DMABurst_ReadStart(&htim1,TIM_DMABASE_CR1,TIM_DMA_UPDATE,sizeof(aADCxConvertedValues), (uint8_t*)aADCxConvertedValues,BUFFER_SIZE)!= HAL_OK ) { // 错误处理逻辑... } ``` 上述代码展示了如何链接DMA与定时器资源,并发起一个DMA突发读取命令。需要注意的是实际应用环境中还需要考虑更多细节如错误检测、回调机制等以增强系统的健壮性和可靠性。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值