SDIO操作遇到问题了...请教

2019-07-20 10:54发布

初始化部分:
[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库试过多个版本,均是如此,不知道我是哪里弄错了
还请大侠指教.

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。