STM32-十二行代码,实现DMA+SPI从机+不定长,接收数据

(2025-4-10,zzl:本文基于STM32H7,其他型号,可能略有不同,但是核心原理应该是都成立的)

 

一、核心原理

1.不使用SPI的NSS,将NSS设置为EXTI输入

这一步是为了获得SPI完成信号。

STM32只有DMA收发全部完成后(达到收发设置的字节数),才会触发SPI完成中断,不定长数据没法使用这样的设置。

2.获得DMA收发数量

STM32的HAL库,是没有这个接口的,需要操作寄存器,从寄存器获取DMA已经传输的数据量。

 

二、代码实现

1.Cubemx设置

只需要启用DMA+EXIT即可,其他随便

 

2.EXIT中断(SPI完成数据处理,和开启新接收)


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
	if(GPIO_Pin == ZZL_SPI_NSS_Pin)
	{
		
		if(HAL_GPIO_ReadPin(ZZL_SPI2_NSS_GPIO_Port, ZZL_SPI2_NSS_Pin) == GPIO_PIN_SET)
		{
            /* 先停止SPI-DMA */
			HAL_SPI_DMAStop(&hspi2);

            /* 计算接收到的长度 */
			BDMA_Channel_TypeDef *bdma_rx = hspi2.hdmarx->Instance;
			BDMA_Channel_TypeDef *bdma_tx = hspi2.hdmatx->Instance;
			
			uint32_t len = BUFF_MAX- bdma_rx->CNDTR;

            /* 处理数据和准备下一次发送的数据 */
			// ... = buffer_rx,len 
			// buffer_tx = ... 
            
            /* 重新设置DMA */
			bdma_rx->CM0AR = (uint32_t)buffer_rx;
			bdma_rx->CNDTR = BUFF_MAX;
			bdma_tx->CM0AR = (uint32_t)buffer_tx;
			bdma_tx->CNDTR = BUFF_MAX;
			
            /* 启动DMA */
			HAL_SPI_TransmitReceive_DMA(&hspi2, buffer_tx, buffer_rx, BUFF_MAX);
		}
		
	}//if(GPIO_Pin == ZZL_SPI_NSS_Pin)
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值