我是使用的
STM32F103VDT6
芯片,TF卡使用的是sandisk class4 4G的。使用的是SDIO+DMA官方例程,单独测试没有发现问题,但是当我开启其他中断时(不管什么中断),比如我开启
tiM3定时中断,中断频率为200Hz,中断中执行一个for循环来模拟中断处理,只要for循环的执行时间较长,就会出现TF卡的操作卡死问题,就是TF卡操作一直在等待DMA标志,并且for循环越长出现这种卡死的概率越大,当达到一定程度后TF卡完全不能操作。我大概估算了一下,差不多在中断执行时间达到总时间的20%左右就会明显有卡死现象,达到50%左右就基本上不能正常操作TF卡了。
由于我需要降低功耗,所以将主频降的比较低,4MHz,所以中断处理相对来说就显得执行时间较长,这样我才意识到这个问题,后来直接用官方例程实测,开通一个TIM3中断,执行for循环延时,当达到一定程度后,可以重现这个问题,所以我觉得应该是固件库或者是硬件的原因,不知道你们有没有发现这个问题,可以的话你们也可以这样测试一下,看能否重现这个问题,要是能解决的话,希望帮忙解决一下,要是这个问题得不到解决的话,我们只能放弃使用这个芯片了。
---------------------------------------------------
/*******************************************************************************
* Function Name : SD_ProcessIRQSrc
* Description : Allows to process all the interrupts that are high.
* Input : None
* Output : None
* Return : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_ProcessIRQSrc(void)
{
uint32_t count = 0, restwords = 0;
if (DeviceMode == SD_INTERRUPT_MODE)
{
#ifdef DISPSDINFO
printf(" SD_INTERRUPT_MODE ");
#endif
if (SDIO_GetITStatus(SDIO_IT_RXFIFOHF) != RESET)
{
for (count = 0; count < SD_HALFFIFO; count++)
{
*(DestBuffer + count) = SDIO_ReadData();
}
DestBuffer += SD_HALFFIFO;
NumberOfBytes += SD_HALFFIFOBYTES;
}
else if (SDIO_GetITStatus(SDIO_IT_TXFIFOHE) != RESET)
{
if ((TotalNumberOfBytes - NumberOfBytes) < SD_HALFFIFOBYTES)
{
restwords = ((TotalNumberOfBytes - NumberOfBytes) % 4 == 0) ?
((TotalNumberOfBytes - NumberOfBytes) / 4) :
((TotalNumberOfBytes - NumberOfBytes) / 4 + 1);
for (count = 0; count < restwords; count++, SrcBuffer++, NumberOfBytes += 4)
{
SDIO_WriteData(*SrcBuffer);
}
}
else
{
for (count = 0; count < SD_HALFFIFO; count++)
{
SDIO_WriteData(*(SrcBuffer + count));
}
SrcBuffer += SD_HALFFIFO;
NumberOfBytes += SD_HALFFIFOBYTES;
}
}
}
if (SDIO_GetITStatus(SDIO_IT_DATAEND) != RESET)
{
#ifdef DISPSDINFO
printf(" SDIO_IT_DATAEND ");
#endif
if (DeviceMode != SD_DMA_MODE)
{
while ((SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) && (NumberOfBytes < TotalNumberOfBytes))
{
*DestBuffer = SDIO_ReadData();
DestBuffer++;
NumberOfBytes += 4;
}
}
if (StopCondition == 1)
{
TransferError = SD_StopTransfer();
}
else
{
TransferError = SD_OK;
}
SDIO_ClearITPendingBit(SDIO_IT_DATAEND);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
TransferEnd = 1;
NumberOfBytes = 0;
return(TransferError);
}
if (SDIO_GetITStatus(SDIO_IT_DCRCFAIL) != RESET)
{
#ifdef DISPSDINFO
printf(" SDIO_IT_DCRCFAIL ");
#endif
SDIO_ClearITPendingBit(SDIO_IT_DCRCFAIL);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
NumberOfBytes = 0;
TransferError = SD_DATA_CRC_FAIL;
return(SD_DATA_CRC_FAIL);
}
if (SDIO_GetITStatus(SDIO_IT_DTIMEOUT) != RESET)
{
#ifdef DISPSDINFO
printf(" SDIO_IT_DTIMEOUT ");
#endif
SDIO_ClearITPendingBit(SDIO_IT_DTIMEOUT);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
NumberOfBytes = 0;
TransferError = SD_DATA_TIMEOUT;
return(SD_DATA_TIMEOUT);
}
if (SDIO_GetITStatus(SDIO_IT_RXOVERR) != RESET)
{
#ifdef DISPSDINFO
printf(" SDIO_IT_RXOVERR ");
#endif
SDIO_ClearITPendingBit(SDIO_IT_RXOVERR);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
NumberOfBytes = 0;
TransferError = SD_RX_OVERRUN;
return(SD_RX_OVERRUN);
}
if (SDIO_GetITStatus(SDIO_IT_TXUNDERR) != RESET)
{
#ifdef DISPSDINFO
printf(" SDIO_IT_TXUNDERR ");
#endif
SDIO_ClearITPendingBit(SDIO_IT_TXUNDERR);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
NumberOfBytes = 0;
TransferError = SD_TX_UNDERRUN;
return(SD_TX_UNDERRUN);
}
if (SDIO_GetITStatus(SDIO_IT_STBITERR) != RESET)
{
#ifdef DISPSDINFO
printf(" SDIO_IT_STBITERR ");
#endif
SDIO_ClearITPendingBit(SDIO_IT_STBITERR);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
NumberOfBytes = 0;
TransferError = SD_START_BIT_ERR;
return(SD_START_BIT_ERR);
}
return(SD_OK);
}
---------------------------------------------------
去掉流控,今天测试又没有出现SDIO_IT_RXOVERR错误了,程序就一直在while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)卡起,期间没有进过SDIO中断,DMA2->ISR寄存器一直是0,也就是说SDIO没有出现传输错误,也没有传输完成,甚至都没有超时,DMA的寄存器也没有反应,就是DMA也没有操作完成,好像所有一套硬件机制都冻结了一样。
一周热门 更多>