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

SPI接收中断溢出后该如何处理?

[复制链接]
any012 提问时间:2017-5-13 10:26 /
悬赏20ST金币已解决
本帖最后由 any012 于 2017-5-13 11:04 编辑

用STM32F103的SPI2作为SPI从设备接收主设备发送过来的固定长度的数据。
主设备每秒发送一次。切有个类似片选信号给了从设备的PC6引脚。
那么我在PC6上升沿中断里,开启SPI中断接收函数。

现在主设备先启动后,从设备再启动,接收没问题。
如果主从设备同时启动,则从设备只接收了一次数据就不再接收了,且接收的数据是错误的。(也许主设备启动时发送的数据就是错的)
现在发现出错时是SPI接收溢出了。

我在溢出判断部分那里,加了个printf语句,如果printf语句里有\r\n,则接收错误出现两次后就变正常了。而是其他的字符的话,则一直是溢出错误。
请教,为什么会一直是溢出错误呢?这里明明是判断溢出错误后就把溢出标志清楚了,然后调用了错误处理回调函数(没有处理,也就是空的吧)。那么为什么下次接收数据时还是溢出错误呢?

SPI中断处理函数为:

  1. void SPI2_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN SPI2_IRQn 0 */

  4.   /* USER CODE END SPI2_IRQn 0 */
  5.   HAL_SPI_IRQHandler(&hspi2);
  6.   /* USER CODE BEGIN SPI2_IRQn 1 */

  7.   /* USER CODE END SPI2_IRQn 1 */
  8. }
复制代码

然后HAL_SPI_IRQHandler()函数里有:
  1. <div>        /* SPI Overrun error interrupt occurred -----------------------------------*/
  2.         if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) != RESET)
  3.         {
  4.             printf("hahahaha!");       //这里改为printf("\r\n");则接收错误两次后就正确了。
  5.            if (hspi->State != HAL_SPI_STATE_BUSY_TX)
  6.             {
  7.                 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
  8.                 __HAL_SPI_CLEAR_OVRFLAG(hspi);
  9.                 printf("spi ovr err.");
  10.             }
  11. </div><div>        }</div>
复制代码
下图为溢出错误判断部分,加入了printf("\r\n")语句后的接收数据。是利用串口发送上来的。
QQ图片20170513110003.png

下图为将printf语句中的\r\n去掉后的情况。
QQ图片20170513110138.png


最佳答案

查看完整内容

在中断服务函数里调用printf可真糟糕,中断执行时间太长,来不及处理。
收藏 1 评论9 发布时间:2017-5-13 10:26

举报

9个回答
zoomdy 回答时间:2017-5-13 10:26:04
在中断服务函数里调用printf可真糟糕,中断执行时间太长,来不及处理。
any012 回答时间:2017-5-16 11:19:48
一般出现溢出错误,按说应该会立刻关闭中断,直到下次PC6上升沿来时再开启中断。
可现在的结果是,开机时,第1秒内,有多次溢出错误处理。以后就是每秒一次。难道开机时PC6引脚有多次脉冲?
  1. if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
  2.         {
  3. //            HAL_GPIO_WritePin(ERR_GPIO_Port, ERR_Pin, GPIO_PIN_SET);
  4.             __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
  5.             hspi->State = HAL_SPI_STATE_READY;
  6.             HAL_SPI_ErrorCallback(hspi);
  7.         }
复制代码

any012 回答时间:2017-5-18 09:40:27
本帖最后由 any012 于 2017-5-18 09:47 编辑

找到问题了。
接收的时候,出现异常时,接收数据溢出,中断处理函数里,判断溢出错误后,就清掉溢出错误标志,然后转到错误处理部分。
错误处理部分里关闭了接收中断,但是在关闭接收中断之前,又有新的数据到来,结果又溢出错误了。
最后的结果就是下次开启接收中断时,直接就溢出错误了。以上,周而复始。

在错误处理部分,关闭接收中断后,再清一次溢出错误标志即可。
或者,开启SPI接收的时候,是否应该先把各标志位清一遍?

  1. /* SPI Overrun error interrupt occurred -----------------------------------*/
  2.         if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) != RESET)
  3.         {
  4.             if (hspi->State != HAL_SPI_STATE_BUSY_TX)
  5.             {
  6.                 SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
  7.                 __HAL_SPI_CLEAR_OVRFLAG(hspi);
  8.                 printf("spi ovr err.");
  9.             }
  10.         }

  11.         /* Call the Error call Back in case of Errors */
  12.         if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
  13.         {
  14.             __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
  15.             __HAL_SPI_CLEAR_OVRFLAG(hspi);                                                         //关闭中断后,再清一次溢出错误标志。
  16.             hspi->State = HAL_SPI_STATE_READY;
  17.             HAL_SPI_ErrorCallback(hspi);
  18.         }
复制代码



any012 回答时间:2017-5-18 11:06:23
虽然SPI中断接收遇到的这个问题解决了,但是用DMA方式接收还是没解决...
any012 回答时间:2017-5-18 14:30:08
额,用万用表表笔反复碰触,结果接收数据仍发生位移,且位移会一直保持。和DMA方式接收的现象基本一致。
xingfudaxia 回答时间:2020-2-25 12:35:31
DMA的模式解决了么?现在我也遇到这样的问题了,但是一直溢出错误。
非我非非我 回答时间:2020-3-12 14:35:26
xingfudaxia 发表于 2020-2-25 12:35
DMA的模式解决了么?现在我也遇到这样的问题了,但是一直溢出错误。

同溢出错误,请问有解决吗?
xingfudaxia 回答时间:2020-6-23 13:49:22
非我非非我 发表于 2020-3-12 14:35
同溢出错误,请问有解决吗?

可以查看溢出错误标志位,根据清除标志位就可。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版