你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F4作为SPI从机,主机发送完数据后,从机没有正确进入中断

[复制链接]
GlossTsai 提问时间:2024-4-16 14:28 / 已解决

NXP的1176作为主机,STM32F405作为从机,通信波特率为8.3MHz左右。cubeMX配置如下,开启了SPI中断。

image.png

每次进入HAL_SPI_TxRxCpltCallback(),都通过IO输出一个脉冲信号,如下图第二行所示。第一行为定时器6溢出回调函数的脉冲,第四行是SPI时钟信号。可以从图中看出,第四个时钟信号结束后,没有触发HAL_SPI_TxRxCpltCallback。且定时器中断在188.54ms处停止触发,一直到189.7ms处,HAL_SPI_TxRxCpltCallback出发后才恢复。又因为所配置的SPI中断优先级高于定时器中断优先级,我推测,由于某些原因导致通信结束后,SPI中断阻塞了。image.png

但是我没有任何解决思路,请各位帮忙,不胜感激!如果提问有任何不完善,请提示我补充信息。

image.png
image.png
收藏 评论7 发布时间:2024-4-16 14:28

举报

7个回答
GlossTsai 最优答案 回答时间:2024-4-22 11:07:38

butterflyspring 发表于 2024-4-17 10:23
因为看到你描述的波特率8.3Mhz。</p>
<p>那如果怀疑阻塞了,那就先屏蔽可能阻塞的代码(比如某些中断),反向验证 ...

是的,我将SPI_EndRxTxTransaction函数中的等待BSY位的阻塞部分注释掉,就不再发生这个情况了。

/* Wait BSY flag during 1 Byte time transfer in case of Full-Duplex and Tx transfer
    * If Timeout is reached, the transfer is considered as finish.
    * User have to calculate the timeout value to fit with the time of 1 byte transfer.
    * This time is directly link with the SPI clock from Master device.
    */

看注释,需要修改宏SPI_BSY_FLAG_WORKAROUND_TIMEOUT的值,用来匹配1字节的通信时间。我们的波特率为8MHz左右,那么通信1字节需要1us左右。而HAL库默认是1000us,因此经常在此阻塞,直到超时,或者到下一帧的第一个字节被HAL库接收。

line217 #define SPI_DEFAULT_TIMEOUT 100U

line218 #define SPI_BSY_FLAG_WORKAROUND_TIMEOUT 3U /*!< Timeout 1000 µs */

butterflyspring 回答时间:2024-4-16 14:44:48
可以大致估算一下时间,中断频率不到一个微秒,应该是响应不过来。
GlossTsai 回答时间:2024-4-16 14:47:58

butterflyspring 发表于 2024-4-16 14:44
可以大致估算一下时间,中断频率不到一个微秒,应该是响应不过来。

定时器中断频率是100us,SPI通信频率是1kHz。

butterflyspring 回答时间:2024-4-17 10:23:38
因为看到你描述的波特率8.3Mhz。

那如果怀疑阻塞了,那就先屏蔽可能阻塞的代码(比如某些中断),反向验证一下。
xmshao 回答时间:2024-4-17 10:55:16
从你给出的信息来看,感觉一度SPI中断跟TIM中断同时阻塞,会不会是代码里有其它更高优先级中断?还是说有其它临时关闭中断响应的操作?
你可以检查下代码里到底开启哪些中断,各种中断优先级是怎样安排的?
GlossTsai 回答时间:2024-4-22 11:08:58

xmshao 发表于 2024-4-17 10:55
从你给出的信息来看,感觉一度SPI中断跟TIM中断同时阻塞,会不会是代码里有其它更高优先级中断?还是说有其 ...

SPI中断为优先级组4的优先级0,应该不会有其他应用能够抢占它。

GlossTsai 回答时间:2024-4-22 14:15:23

butterflyspring 发表于 2024-4-17 10:23
因为看到你描述的波特率8.3Mhz。</p>
<p>那如果怀疑阻塞了,那就先屏蔽可能阻塞的代码(比如某些中断),反向验证 ...

仔细阅读了源码,并经过验证,阻塞来自于文件stm32f4xx_hal_spi.c中的函数SPI_EndRxTxTransaction()。它在判断BSY位时阻塞,函数中的注释如下。

#define SPI_DEFAULT_TIMEOUT 100U
#define SPI_BSY_FLAG_WORKAROUND_TIMEOUT 1000U /*!< Timeout 1000 µs             */
...
static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
{
  /* Timeout in µs */
  __IO uint32_t count = SPI_BSY_FLAG_WORKAROUND_TIMEOUT * (SystemCoreClock / 24U / 1000000U);
  ...
  /* Wait BSY flag during 1 Byte time transfer in case of Full-Duplex and Tx transfer
    * If Timeout is reached, the transfer is considered as finish.
    * User have to calculate the timeout value to fit with the time of 1 byte transfer.
    * This time is directly link with the SPI clock from Master device.
    */
    do
    {
        if (count == 0U)
        {
            break;
        }
        count--;
    } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_BSY) != RESET);
}

意思是需要将宏SPI_BSY_FLAG_WORKAROUND_TIMEOUT的值修改为SPI通信一个字节的时间长度。本工程的SPI波特率为8MHz左右,也即一个字节通信周期为1us左右。而该宏的默认值为1000us,因此偶尔出现一下两种情况。一是阻塞时间较长(850us+),二是中断阻塞,直到第二帧第一字节被HAL库接收。修改该宏的值为3us后,解决该问题。

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版