初始化部分:
[mw_shl_code=cpp,true]uint8_t BSP_SD_Init()
{
uSdHandle.Instance = SDIO;
uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B;
uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV+3;
if (HAL_SD_Init(&uSdHandle) != HAL_OK)
return MSD_ERR;
if (HAL_SD_ConfigWideBusOperation(&uSdHandle, SDIO_BUS_WIDE_4B) != HAL_OK)
return MSD_ERR;
else
return MSD_OK;
}[/mw_shl_code]MspInit部分:[mw_shl_code=cpp,true]void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (hsd->Instance == SDIO)
{
LED_Init();
__HAL_RCC_SDIO_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitStruct.Pin = (GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11
| GPIO_PIN_12);
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
#if (SDIO_DMA_ENABLED==1)
verbo("SDIO DMA ENABLED");
__HAL_RCC_DMA2_CLK_ENABLE();
hdma_sdio_tx.Instance = DMA2_Stream6;
hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_DeInit(&hdma_sdio_tx);
HAL_DMA_Init(&hdma_sdio_tx);
__HAL_LINKDMA(hsd, hdmatx, hdma_sdio_tx);
hdma_sdio_rx.Instance = DMA2_Stream3;
hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_DeInit(&hdma_sdio_rx);
HAL_DMA_Init(&hdma_sdio_rx);
__HAL_LINKDMA(hsd, hdmarx, hdma_sdio_rx);
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 2, 0);
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
#endif
}
}[/mw_shl_code]看了很多例子,这部分代码貌似没有什么问题,但是我在测试过程中,发现[mw_shl_code=cpp,true]MSD_Status status = MSD_ERR;
if (HAL_SD_ReadBlocks_DMA(&uSdHandle, (uint8_t *)buff, readAddr, NumbOfBlocks) == HAL_OK)
{
while ((timeout--) != 0)
{
HAL_SD_StateTypeDef sdio_state = HAL_SD_GetState(&uSdHandle);
HAL_SD_CardStateTypeDef sd_state = HAL_SD_GetCardState(&uSdHandle);
debug("[RD] SDIO: %d CARD: %d (time left:%u)", sdio_state, sd_state, timeout);
if ((sdio_state == HAL_SD_STATE_READY)&&(sd_state == HAL_SD_CARD_TRANSFER))
{
status = MSD_OK;
break;
}
}
HAL_SD_StateTypeDef sdio_state = HAL_SD_GetState(&uSdHandle);
HAL_SD_CardStateTypeDef sd_state = HAL_SD_GetCardState(&uSdHandle);
debug("[RD] RESULT SDIO: %d CARD: %d", sdio_state, sd_state);
}[/mw_shl_code]当我用DMA模式读取的时候,貌似是正常的,完成操作以后,返回的是
HAL_SD_STATE_READY 和 HAL_SD_CARD_TRANSFER
[mw_shl_code=cpp,true]if (HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t *)buff, writeAddr, NumbOfBlocks) == HAL_OK)
{
while (timeout-- != 0)
{
sdio_state = HAL_SD_GetState(&uSdHandle);
sd_state = HAL_SD_GetCardState(&uSdHandle);
debug("[WR] SDIO: %d CARD: %d ERROR: %d(time left:%u)", sdio_state, sd_state, BSP_SD_GetError(), timeout);
if (sdio_state == HAL_SD_STATE_READY &&sd_state == HAL_SD_CARD_TRANSFER)
{
status = MSD_OK;
break;
}
}
sdio_state = HAL_SD_GetState(&uSdHandle);
sd_state = HAL_SD_GetCardState(&uSdHandle);
debug("[WR] RESULT SDIO: %d CARD: %d", sdio_state, sd_state);
}[/mw_shl_code]
但是当写入的时候,SD卡状态为HAL_SD_CARD_TRANSFER时.SDIO控制器依然返回HAL_SD_STATE_BUSY.这样就导致了超时写入失败,没有触发DMA2_Stream6_IRQHandler
HAL库试过多个版本,均是如此,不知道我是哪里弄错了
还请大侠指教.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>