|
使用stm32f7+w5500实现网络通信,想使用spi+dma的模式来进行数据发送
以下是关于dma的部分代码
/*##-3- Configure the DMA streams ##########################################*/
/* Configure the DMA handler for Transmission process */
SPI1_HDMA_TX.Instance = DMA2_Stream5; //SPI1_TX采用DMA2数据流5 通道3
SPI1_HDMA_TX.Init.Channel = DMA_CHANNEL_3;
SPI1_HDMA_TX.Init.Direction = DMA_MEMORY_TO_PERIPH;
SPI1_HDMA_TX.Init.PeriphInc = DMA_PINC_DISABLE;
SPI1_HDMA_TX.Init.MemInc = DMA_MINC_ENABLE;
SPI1_HDMA_TX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
SPI1_HDMA_TX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
SPI1_HDMA_TX.Init.Mode = DMA_NORMAL;
SPI1_HDMA_TX.Init.Priority = DMA_PRIORITY_HIGH;
SPI1_HDMA_TX.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
SPI1_HDMA_TX.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
SPI1_HDMA_TX.Init.MemBurst = DMA_MBURST_SINGLE;
SPI1_HDMA_TX.Init.PeriphBurst = DMA_MBURST_SINGLE;
// SPI1_HDMA_TX.XferCpltCallback = W5500_TxCpltCallback_dma;
HAL_DMA_Init(&SPI1_HDMA_TX);
/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmatx, SPI1_HDMA_TX);
/* Configure the DMA handler for Transmission process */
SPI1_HDMA_RX.Instance = DMA2_Stream0; //SPI1_RX采用DMA2数据流0 通道3
SPI1_HDMA_RX.Init.Channel = DMA_CHANNEL_3;
SPI1_HDMA_RX.Init.Direction = DMA_PERIPH_TO_MEMORY;
SPI1_HDMA_RX.Init.PeriphInc = DMA_PINC_DISABLE;
SPI1_HDMA_RX.Init.MemInc = DMA_MINC_ENABLE;
SPI1_HDMA_RX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
SPI1_HDMA_RX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
SPI1_HDMA_RX.Init.Mode = DMA_NORMAL;
SPI1_HDMA_RX.Init.Priority = DMA_PRIORITY_HIGH;
SPI1_HDMA_RX.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
SPI1_HDMA_RX.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
SPI1_HDMA_RX.Init.MemBurst = DMA_MBURST_SINGLE;
SPI1_HDMA_RX.Init.PeriphBurst = DMA_MBURST_SINGLE;
HAL_DMA_Init(&SPI1_HDMA_RX);
/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmarx, SPI1_HDMA_RX);
/*##-4- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt (SPI3_TX) */
HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
/* NVIC configuration for DMA transfer complete interrupt (SPI3_RX) */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
...........
//SPI发送回调函数
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI1)
{
W5500_TxCpltCallback();
}
}
//SPI接收回调函数
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI1)
{
W5500_RxCpltCallback();
}
}
.........
void W5500_TxCpltCallback_dma(DMA_HandleTypeDef *hdma)
{
osThreadFlagsSet(tid_app_osInterface, 0x04);
}
void W5500_RxCpltCallback_dma(DMA_HandleTypeDef *hdma)
{
;
}
...........
void SPIx_DMA_TX_IRQHandler(void)
{
HAL_DMA_IRQHandler(&SPI1_HDMA_TX);
}
void SPIx_DMA_RX_IRQHandler(void)
{
HAL_DMA_IRQHandler(&SPI1_HDMA_RX);
}
//w5500利用spi_dma发送
void W5500_DMA_Configuration(uint8_t* MemBaseAddr, uint32_t len)
{
uint8_t p_rxbuf = 0;
if (HAL_SPI_TransmitReceive_DMA(&SPI1_Handle, MemBaseAddr,&p_rxbuf, len) != HAL_OK)
{
bsp_os_printf("error: bsp_W5500_os: DMA HAL error \r\n");
// Error_Handler();
}
if ((osThreadFlagsWait(0x04,osFlagsWaitAny,1000)&0x04 )==0)
{
bsp_os_printf("error: bsp_W5500_os: DMA error \r\n");
}
}
现在的现象是 进入调试模式 程序运行到 if ((osThreadFlagsWait(0x04,osFlagsWaitAny,1000)&0x04 )==0)卡死, 点击stop查看程序卡死在哪个地方
发现程序不断进出
void SPIx_DMA_TX_IRQHandler(void)
{
HAL_DMA_IRQHandler(&SPI1_HDMA_TX);
}
void SPIx_DMA_RX_IRQHandler(void)
{
HAL_DMA_IRQHandler(&SPI1_HDMA_RX);
}
这两个函数
进入HAL_DMA_IRQHandler 中断处理函数
发现会进入
/* FIFO Error Interrupt management ******************************************/
if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
{
/* Clear the FIFO error flag */
regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_FE;
}
}
研究很久也没发现问题所在。请问下是什么原因导致的呀
|
评分
-
查看全部评分
|