OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2531|回复: 4

技术求助:STM32F429 SPI SLAVE中断方式接收数据时,SPI_SR_BSY状态位被置1,导致SPI slave接收异常

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2019-3-4
在线时间
3 小时
发表于 2019-3-4 11:52:27 | 显示全部楼层 |阅读模式
1金钱

用的是STM32F429IGT6,用 SPI2外设作为slave和其他设备通讯,通过中断方式接收外来的SPI数据,SPI通讯功能正常。
但是经常会发生在接收数据中途SPI_SR_BSY状态位一直被置1不变,导致SPI slave无法接收数据,并且重启SPI外设也没用,必须MCU复位才可以。看了手册PI_SR_BSY状态位是系统自动置1的,是硬件自动置位的,正常在数据完成接收之后就会置0。

这个问题一直找不到原因,是不是硬件哪里的配置问题。现在把SPI slave通讯相关的的代码贴上,还请大家帮忙找找可能是哪里的原因 谢谢了!
由于注释拷贝出来是乱码,就把注释删掉了。

以下是 SPI SLAVE配置代码
void SPI_COM_Init(void)
{
          uint8_t temp;
    SPI_COM_Handler.Instance=SPI_COM;                         //SPI2
    SPI_COM_Handler.Init.Mode=SPI_MODE_SLAVE;            
    SPI_COM_Handler.Init.Direction=SPI_DIRECTION_2LINES;  
    SPI_COM_Handler.Init.DataSize=SPI_DATASIZE_8BIT;      
    SPI_COM_Handler.Init.CLKPolarity=SPI_POLARITY_LOW;   
    SPI_COM_Handler.Init.CLKPhase=SPI_PHASE_1EDGE;         
    SPI_COM_Handler.Init.NSS=SPI_NSS_HARD_INPUT;               
    SPI_COM_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2;
    SPI_COM_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;      
    SPI_COM_Handler.Init.TIMode=SPI_TIMODE_DISABLE;        
    SPI_COM_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;
    SPI_COM_Handler.Init.CRCPolynomial=7;               
    HAL_SPI_Init(&SPI_COM_Handler);

        __HAL_SPI_ENABLE_IT(&SPI_COM_Handler, SPI_IT_RXNE | SPI_IT_ERR );
        HAL_NVIC_SetPriority(SPI_COM_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(SPI_COM_IRQn);
       
         __HAL_SPI_ENABLE(&SPI_COM_Handler);         
         
}


SPI 硬件管脚配置
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
    GPIO_InitTypeDef GPIO_Initure;

    SPI_COM_GPIO_CLK_ENABLE();      
    SPI_COM_CLK_ENABLE();      

    GPIO_Initure.Pin=SPI_COM_MISO_PIN | SPI_COM_NSS_PIN | SPI_COM_SCK_PIN | SPI_COM_MOSI_PIN;
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;                          
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;              
    GPIO_Initure.Alternate=SPI_COM_AF;         
    HAL_GPIO_Init(SPI_COM_GPIO_PORT,&GPIO_Initure);
}


SPI中断处理程序
void SPI_COM_IRQHandler(void)
{
        //HAL_SPI_IRQHandler(&SPI_COM_Handler);
          uint32_t tmp1 = 0,tmp2 = 0;
          uint8_t TMP_RxData;

        tmp1 = SPI_COM_Handler.Instance->SR;
         tmp2 = SPI_COM_Handler.Instance->CR2;
       
  if(tmp1 & SPI_SR_RXNE)
  {
                TMP_RxData = SPI_COM_Handler.Instance->DR;
                SPI_COM_RxBuff[SPI_COM_Cmd.RxCounter] = TMP_RxData;
                SPI_COM_Cmd.RxCounter++;               
        }
       

       
        if(tmp1& SPI_SR_OVR )
        {
                TMP_RxData = SPI_COM_Handler.Instance->DR;
                tmp1 = SPI_COM_Handler.Instance->SR;
                SPI_COM_Handler.Instance->SR = tmp1 |(~SPI_SR_OVR);
        }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2019-3-4 12:40:10 | 显示全部楼层
回复

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2019-2-26
在线时间
8 小时
发表于 2019-4-16 16:42:14 | 显示全部楼层
不知解决了没有,能否共享。
回复

使用道具 举报

7

主题

237

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1101
金钱
1101
注册时间
2019-5-6
在线时间
127 小时
发表于 2019-10-22 10:40:12 | 显示全部楼层
感谢楼主分享不知楼主解决了么?
一步一个脚印
回复

使用道具 举报

5

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2019-12-2
在线时间
27 小时
发表于 2024-9-2 17:34:05 | 显示全部楼层
遇到过相同问题,应该是上一次没传输完成(发送缓冲区非空),你再次触发传输就可能出现busy位异常。
恢复不了可以force reset spi,代码参考如下:
void spi_status_resume(SPI_HandleTypeDef *hspi)
{
    if((hspi->Instance->SR & SPI_FLAG_TXE) == RESET)
    {
                //force reset
                SPI_ERR("[SPI]force reset start SR: %08x\r\n", hspi->Instance->SR);
                HAL_SPI_DeInit(&spihdl);
                __HAL_RCC_SPI3_FORCE_RESET();
                __HAL_RCC_SPI3_RELEASE_RESET();
                HAL_SPI_Init(&spihdl);
                SPI_ERR("[SPI]force reset finish SR: %08x\r\n", hspi->Instance->SR);
    }

    if((hspi->Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY)
    {
        /* Wait until TXE flag is set */
        __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
        do
        {
            if (count == 0U)
            {
                //force reset
                SPI_ERR("[SPI]wait clear busy timeout, force reset SR: %08x\r\n", hspi->Instance->SR);
                HAL_SPI_DeInit(&spihdl);
                __HAL_RCC_SPI3_FORCE_RESET();
                __HAL_RCC_SPI3_RELEASE_RESET();
                HAL_SPI_Init(&spihdl);
                SPI_ERR("[SPI]force reset finish SR: %08x\r\n", hspi->Instance->SR);

                break;
            }
            count--;
        } while ((hspi->Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY);
    }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 10:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表