在stm32上使用HAL_SPI_TransmitReceive_DMA做数据传输时,在回调函数中使用HAL_Delay会让程序卡死

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

#一个有趣情况的记录
提示:这里可以添加本文要记录的大概内容:

今天在stm32U5A5上使用DMA做SPI数据传输时发现了一个神奇的现象。
过程:使用了HAL的HAL_SPI_TransmitReceive_DMA函数,该函数负责实现SPI通讯,并在实现后会调用一个叫做HAL_SPI_TxRxCpltCallback的回调函数。如果在HAL_SPI_TxRxCpltCallback使用HAL_Delay函数,程序便会一直卡死。
如下图:理论上在完成通讯后,会点亮一个LED灯0.5S,接着熄灭。但是程序却卡在了这里,灯并没有熄灭。程序也没有进行下一步。
的


在这里插入图片描述
如上图灯一直在亮,程序也没有离开回调函数而是卡死在Hal_delay。很有趣的现象,但是本人知识水平匮乏,不知道原因是什么。如果有大佬解惑就好了。

`

### 使用HALSTM32上通过SPI进行通信 #### 初始化SPI外设 为了使能并配置SPI接口,需调用`HAL_SPI_Init`函数。此函数接受一个指向`SPI_HandleTypeDef`结构体的指针作为参数,该结构体包含了所有必要的初始化参数[^1]。 ```c // 定义SPI句柄 SPI_HandleTypeDef hspi1; void MX_SPI1_Init(void) { hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; // 设置为主模式 hspi1.Init.Direction = SPI_DIRECTION_2LINES;// 双向全双工模式 hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 数据大小为8位 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // 钟极性低电平有效 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // 钟相位第一个边沿采样 hspi1.Init.NSS = SPI_NSS_SOFT; // 软件管理NSS信号 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB先行 hspi1.Init.TIMode = SPI_TIMODE_DISABLE; // 禁用TI模式 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; if (HAL_SPI_Init(&hspi1) != HAL_OK){ Error_Handler(); } } ``` #### 发送和接收数据 对于简单的发送或接收操作可以分别使用`HAL_SPI_Transmit`和`HAL_SPI_Receive`;而当需要同步执行发送与接收,则应采用`HAL_SPI_TransmitReceive`来处理。 ```c uint8_t txData[] = {0xAA, 0xBB}; uint8_t rxData[2]; if(HAL_SPI_TransmitReceive(&hspi1, txData, rxData, sizeof(txData), HAL_MAX_DELAY)!= HAL_OK){ /* 错误处理 */ } ``` #### DMA支持下的异步传输 利用DMA可实现更高效的非阻塞式的数据交换过程。此推荐运用`HAL_SPI_TransmitReceive_DMA`来进行数据传送,并确保不在其对应的完成回调函数内加入任何可能导致延迟的操作,比如不应在此处调用`HAL_Delay()`,因为这可能会造成程序挂起[^2]。 ```c extern uint8_t g_aTxBuffer[]; extern uint8_t g_aRxBuffer[]; /* 启动带DMA的收发 */ HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(&hspi1, g_aTxBuffer, g_aRxBuffer, COUNT); /* 在回调函数中避免长间运行的任务 */ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi){ // 不要在这里放置延或其他耗指令 // 更新状态标志或者其他轻量级任务 } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值