STM32
直播中

李萍

7年用户 1418经验值
私信 关注
[问答]

STM32f405 SPI DMA接收异常的原因?

芯片:STM32f405,  做的功能是SPI的dma传输,
      
      st正常接收是这样的,0xAB 0xBA 0xA0 ~~~~~~
       假如出现异常   0x0 0xAB 0xBA 0xA0~~~~~
       出现这种情况,我如何让系统SPI恢复,能正常接收。

void DMA2_Stream0_IRQHandler(void)
{
  GPIOB->BSRRH = GPIO_Pin_5;
  /* Test on DMA Stream Transfer Complete interrupt */
  //if (DMA_GetFlagStatus(SPIx_RX_DMA_STREAM,SPIx_RX_DMA_FLAG_TCIF))
  if(DMA_GetiTStatus(SPIx_RX_DMA_STREAM, DMA_IT_TCIF0))
  {
     DMA_ClearITPendingBit(SPIx_RX_DMA_STREAM, DMA_IT_TCIF0);  
     DMA_ClearFlag(SPIx_RX_DMA_STREAM,SPIx_RX_DMA_FLAG_TCIF);  



            ab =spi_aRxBuffer[0];
             ba =spi_aRxBuffer[1];            
            spi_head_cmd =spi_aRxBuffer[2];
       if((ab ==0xAB)     (ba ==0xBA ))
               {
                  spi_deal_handle(package_status);
                    ab =0;
                    ba =0;
           }
           else  //这是异常处理,但是我发现没有恢复正常
                   {
                        dma_reinit();

           }

函数如下:
void dma_reinit(void)
{
     DMA_Cmd(SPIx_RX_DMA_STREAM,DISABLE);  
     DMA_ClearFlag(SPIx_RX_DMA_STREAM,DMA_FLAG_TEIF0 | DMA_FLAG_DMEIF0 | DMA_FLAG_FEIF0);
     
}


void spi_receive_data_enable(void)
{  
  DMA_ClearFlag(SPIx_RX_DMA_STREAM,SPIx_RX_DMA_FLAG_TCIF);  
  //DMA_DeInit(SPIx_TX_DMA_STREAM);
  DMA_DeInit(SPIx_RX_DMA_STREAM);
  
  /* Configure DMA Initialization Structure */
  DMA_InitStructure.DMA_BufferSize = SPI_BUFFERSIZE ;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;//DMA_MemoryBurst_Single ;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) ( (SPIx_WIFI->DR)) ;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  /* Configure TX DMA */
//  DMA_InitStructure.DMA_Channel = SPIx_TX_DMA_CHANNEL ;
//  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ;
//  DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)spi_aTxBuffer ;
//  DMA_Init(SPIx_TX_DMA_STREAM,  DMA_InitStructure);
  /* Configure RX DMA */
  DMA_InitStructure.DMA_Channel = SPIx_RX_DMA_CHANNEL ;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;
  DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)spi_aRxBuffer ;
  DMA_Init(SPIx_RX_DMA_STREAM,  DMA_InitStructure);
  
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
   SPI_Init(SPIx_WIFI,  SPI_InitStructure);
            //DMA_ClearFlag(SPIx_RX_DMA_STREAM,SPIx_RX_DMA_FLAG_TCIF);
        DMA_ITConfig(SPIx_RX_DMA_STREAM, DMA_IT_TC, ENABLE); //wyz add
        DMA_Cmd(SPIx_RX_DMA_STREAM,ENABLE);  
         SPI_I2S_DMACmd(SPIx_WIFI, SPI_I2S_DMAReq_Rx, ENABLE);      
        SPI_Cmd(SPIx_WIFI, ENABLE);
}
  spi_receive_data_enable();

  
  }
}

回帖(1)

张鹏

2024-5-13 18:10:30
STM32F405 SPI DMA接收异常的原因可能有以下几点:

1. 配置错误:确保SPI和DMA的配置正确,包括时钟、端口、数据宽度等。

2. 硬件连接问题:检查SPI和DMA的硬件连接是否正确,包括数据线、时钟线、片选线等。

3. 软件问题:检查SPI和DMA的初始化代码是否正确,以及中断处理函数是否正确处理了异常情况。

4. 外部干扰:可能存在外部电磁干扰,导致SPI通信不稳定。尝试增加屏蔽线或使用差分信号。

5. 电源问题:不稳定的电源可能导致SPI通信异常。确保电源稳定,可以考虑使用稳压器。

为了解决这个问题,你可以尝试以下步骤:

1. 仔细检查SPI和DMA的配置,确保它们正确设置。

2. 检查硬件连接,确保所有连接都正确无误。

3. 检查SPI和DMA的初始化代码,确保它们正确初始化。

4. 在中断处理函数中添加错误处理逻辑,例如:

```c
void DMA2_Stream0_IRQHandler(void)
{
    GPIOB->BSRRH = GPIO_Pin_5; // 指示中断发生

    // 检查DMA中断标志
    if (DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TEIF) != RESET)
    {
        // 传输错误中断,重置DMA
        DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TEIF);
        DMA_Cmd(DMA2_Stream0, DISABLE); // 禁用DMA
        DMA_Init(DMA2_Stream0, ...); // 重新初始化DMA
        DMA_Cmd(DMA2_Stream0, ENABLE); // 启用DMA
    }

    // 检查SPI中断标志
    if (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_RXNE) != RESET)
    {
        // 接收到数据,处理数据
        while (SPI_I2S_GetITStatus(SPIx, SPI_I2S_IT_RXNE) != RESET)
        {
            uint8_t data = SPI_I2S_ReceiveData(SPIx);
            // 处理接收到的数据
        }
    }
}
```

5. 如果问题仍然存在,尝试使用示波器检查SPI通信信号,以确定是否存在外部干扰或硬件问题。

6. 确保电源稳定,可以考虑使用稳压器。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分