发新帖我要提问
123
返回列表
打印
[牛人杂谈]

NUC970 SD卡驱动(SDIO)

[复制链接]
楼主: nawu
手机看帖
扫描二维码
随时随地手机跟帖
41
nawu|  楼主 | 2021-6-7 19:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_SetBlockSize(SDIO_SD_HANDLE *pHandle, u16 BlockSize)
* 功能                        :        设置SD卡块大小
* 参数                        :        pHandle:句柄;BlockSize:设置SD卡块大小
* 返回                        :        SDIO_Error
* 依赖                        :        底层寄存器操作函数
* 作者                        :        cp1300@139.com
* 时间                        :        20120516
* 最后修改时间         :         2018-03-28
* 说明                        :         通常取512B
                                        2020-02-21:尝试设置不同大小的块,以提高速度,但是SDHC卡是不支持设置块大小的
*************************************************************************************************************************/
SDIO_Error SD_SetBlockSize(SDIO_SD_HANDLE *pHandle, u16 BlockSize)
{
        SDIO_Error errorstatus = SDIO_OK;
        u32 temp;
       
        //如果卡锁定了则返回
        pHandle->pInterface->SDIO_GetResponse(SDIO_RESP_Short, &temp);        //获取响应
        if (temp & SD_CARD_LOCKED) //锁了
        {
                errorstatus = SDIO_LOCK_UNLOCK_FAILED;
                return(errorstatus);
        }

        //CMD16 Set Block Size for Card
        pHandle->pInterface->SDIO_SendCommand(CMD16, BlockSize, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();
        if (errorstatus != SDIO_OK)
        {
                DEBUG("CMD16 ERROR %d\r\n",errorstatus);
                //如果失败了,尝试切换到512字节
                //CMD16 Set Block Size for Card
                pHandle->pInterface->SDIO_SendCommand(CMD16, 512, SDIO_Response_Short);
                errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();
                if (errorstatus != SDIO_OK)
                {
                        DEBUG("恢复默认配置失败 ,CMD16 ERROR %d\r\n",errorstatus);
                }
                else
                {
                        pHandle->SDIO_BlockSize = GetSDIO_BlockSizeForSDBlock(512);                                //SDIO传输块大小
                        DEBUG("使用默认512B块大小,设置成功\r\n");
                }
        }
        else //设置成功了
        {
                pHandle->SDIO_BlockSize = GetSDIO_BlockSizeForSDBlock(BlockSize);                        //SDIO传输块大小
        }
       
        return(errorstatus);
}



使用特权

评论回复
42
nawu|  楼主 | 2021-6-7 19:59 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_ReadBlock(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, u8 *pBlockBuff)
* 功能                        :        读SD卡一个块
* 参数                        :        pHandle:句柄;BlockAddr:块地址;BlockBuff:块缓冲区地址
* 返回                        :        SDIO_Error
* 依赖                        :        底层寄存器操作函数
* 作者                        :        cp1300@139.com
* 时间                        :        20120516
* 最后修改时间         :        2018-03-28
* 说明                        :         读SD卡一个块
*************************************************************************************************************************/
SDIO_Error SD_ReadBlock(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, u8 *pBlockBuff)
{
        SDIO_Error errorstatus = SDIO_OK;
        u32 ReadLen;                                        //读取的数据长度

        if (pBlockBuff == NULL)                        //没有分配接收缓冲区,返回
        {
                errorstatus = SDIO_INVALID_PARAMETER;
                return(errorstatus);
        }

        if(pHandle->CardType != SD_HIGH_CAPACITY_SD_CARD)
        {
                BlockAddr <<= 9;                        //小容量卡,转换为字节单位
        }

        pHandle->pInterface->SDIO_ClearDataTrans();                                                                                //清除数据传输
        //发送CMD17 READ_SINGLE_BLOCK,块读取指令,参数:块地址,短回复,R1
        pHandle->pInterface->SDIO_SendCommand(CMD17, BlockAddr, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                DEBUG("CMD17 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
        pHandle->pInterface->SDIO_SetAndStartDataTrans(pBlockBuff, TRUE, pHandle->SDIO_BlockSize, pHandle->SDCardInfo.CardBlockSize);        //初始化DMA,并准备读取数据
        errorstatus = pHandle->pInterface->SDIO_WaitTransComplete(TRUE, &ReadLen, 150);        //SDIO等待传输完成(等待读取或写入数据完成)(超时:150ms)
        if(errorstatus == SDIO_OK && ReadLen != pHandle->SDCardInfo.CardBlockSize)
        {
                DEBUG("读取数据错误,需要读取:%dB,实际返回:%dB\r\n", pHandle->SDCardInfo.CardBlockSize, ReadLen);
        }

        return(errorstatus);
}



使用特权

评论回复
43
nawu|  楼主 | 2021-6-7 20:00 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_ReadMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, u8 *pBlockBuff, u16 NumberOfBlocks)
* 功能                        :        读SD卡多个块
* 参数                        :        pHandle:句柄;BlockAddr:块地址;pBlockBuff:块缓冲区地址;NumberOfBlocks:块数量
* 返回                        :        SDIO_Error
* 依赖                        :        底层寄存器操作函数
* 作者                        :        cp1300@139.com
* 时间                        :        20120516
* 最后修改时间         :         2018-03-28
* 说明                        :         读SD卡多个(大于1个)块
*************************************************************************************************************************/
SDIO_Error SD_ReadMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, u8 *pBlockBuff, u16 NumberOfBlocks)
{
        SDIO_Error errorstatus = SDIO_OK;
        SDIO_Error error1;
        u32 ReadLen;                                        //读取的数据长度

        if (pBlockBuff == NULL)                        //没有分配接收缓冲区,返回
        {
                errorstatus = SDIO_INVALID_PARAMETER;
                return(errorstatus);
        }
       
        //限制读取的块数量
        if(NumberOfBlocks > pHandle->MaxTransBlockCount)
        {
                DEBUG("限制一次读取%d块,当前一次读取%d\r\n", pHandle->MaxTransBlockCount, NumberOfBlocks);
                NumberOfBlocks = pHandle->MaxTransBlockCount;
        }

        if(pHandle->CardType != SD_HIGH_CAPACITY_SD_CARD)
        {
                BlockAddr <<= 9;                        //小容量卡,转换为字节单位
        }
        pHandle->pInterface->SDIO_ClearDataTrans();                                                                                //清除数据传输
        //发送CMD18 SDIO_READ_MULT_BLOCK;多区段读命令,参数:开始地址,短返回,R1(发送后会不停的发送数据出来,需要CMD12命令取消发送)
        pHandle->pInterface->SDIO_SendCommand(CMD18, BlockAddr, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD18 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
        pHandle->pInterface->SDIO_SetAndStartDataTrans(pBlockBuff, TRUE, pHandle->SDIO_BlockSize, pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks);        //初始化DMA开始读取数据
        errorstatus = pHandle->pInterface->SDIO_WaitTransComplete(TRUE, &ReadLen, 100*NumberOfBlocks);                                                                                                        //SDIO等待传输完成(等待读取或写入数据完成)(超时:100ms*NumberOfBlocks)
       
        if(errorstatus == SDIO_OK && ReadLen != (pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks))
        {
                DEBUG("读取数据错误,需要读取:%dB,实际返回:%dB\r\n", pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks, ReadLen);
        }
       
        //发送CMD12 SDIO_STOP_TRANSMISSION命令,终止读取;参数:0,短响应,R1
        pHandle->pInterface->SDIO_SendCommand(CMD12, 0, SDIO_Response_Short);
        error1 = pHandle->pInterface->SDIO_CmdResp1Error();
        if(error1 != SDIO_OK)        //获取回复
        {
                DEBUG("CMD12 error (%d)!\r\n",error1);
        }
       
        return(errorstatus);
}



使用特权

评论回复
44
nawu|  楼主 | 2021-6-7 20:01 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_WriteBlock(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, const u8 *pBlockBuff)
* 功能                        :        写SD卡一个块
* 参数                        :        BlockAddr:块地址;
                                        writebuff:写缓冲区地址
* 返回                        :        SDIO_Error
* 依赖                        :        底层寄存器操作函数
* 作者                        :        cp1300@139.com
* 时间                        :        2018-03-29
* 最后修改时间         :         2018-03-29
* 说明                        :         写SD卡一个块
**************************************************************************************************************************/
SDIO_Error SD_WriteBlock(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, const u8 *pBlockBuff)
{
        SDIO_Error errorstatus = SDIO_OK;
        u32 cardstatus = 0;
        u32 ReadLen = 0;
        u32 timeout;

        if (pBlockBuff == NULL)
        {
                errorstatus = SDIO_INVALID_PARAMETER;
                return(errorstatus);
        }

        if(pHandle->CardType != SD_HIGH_CAPACITY_SD_CARD)
        {
                BlockAddr <<= 9;                        //小容量卡,转换为字节单位
        }

        //检查
        timeout = 100;        //超时100ms`
        do
        {
                //发送CMD13,SDIO_SEND_STATUS,读 Card_Status 寄存器,参数,RCA地址,短返回,R1;
                pHandle->pInterface->SDIO_SendCommand(CMD13, (u32) pHandle->RCA << 16, SDIO_Response_Short);
                errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
                if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
                {
                        pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                        DEBUG("CMD13 error (%d)!\r\n",errorstatus);
                        return(errorstatus);
                }
                pHandle->pInterface->SDIO_GetResponse(SDIO_RESP_Short, &cardstatus);                        //获取响应的状态
                if((cardstatus & 0x00000100) == 0) //没有准备好
                {
                        SYS_DelayMS(1);        //延时
                }
                else //READY_FOR_DATA位有效,卡已经准备好写入了
                {
                        break;
                }
                timeout --;
        }
        while (timeout);
       
        if (timeout == 0)
        {
                DEBUG("等待卡写入超时,错误:%d\r\n",errorstatus);
                return(SDIO_ERROR);
        }
       
        pHandle->pInterface->SDIO_ClearDataTrans();                                                                                //清除数据传输
        //发送CMD24,SDIO_WRITE_SINGLE_BLOCK,写命令,参数:地址(大容量卡为块地址),短响应,R1
        pHandle->pInterface->SDIO_SendCommand(CMD24, BlockAddr, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD24 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
               
        //开始传输-写入数据
        pHandle->pInterface->SDIO_SetAndStartDataTrans((u8 *)pBlockBuff, FALSE, pHandle->SDIO_BlockSize, pHandle->SDCardInfo.CardBlockSize);
        //等待传输完成
        errorstatus = pHandle->pInterface->SDIO_WaitTransComplete(FALSE, &ReadLen, 150);//SDIO等待传输完成(等待读取或写入数据完成)(超时:150ms)
        if(errorstatus == SDIO_OK && ReadLen != pHandle->SDCardInfo.CardBlockSize)
        {
                DEBUG("写入数据错误,需要写入:%dB,实际写入:%dB\r\n", pHandle->SDCardInfo.CardBlockSize, ReadLen);
        }
       
    //读取卡编程状态,等待写入完成
        errorstatus = SD_WaitProgrammingFinish(pHandle, 100);                                                        //等待编程完成
       
        return(errorstatus);
}



使用特权

评论回复
45
nawu|  楼主 | 2021-6-7 20:02 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_WriteMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, const u8 *pBlockBuff, u16 NumberOfBlocks)
* 功能                        :        写SD卡多个块
* 参数                        :        pHandle:句柄;BlockAddr:块地址;BlockBuff:块缓冲区地址NumberOfBlocks:块数量
* 返回                        :        SD_OK:成功,其它见SD Card Error code.
* 依赖                        :        底层寄存器操作函数
* 作者                        :        cp1300@139.com
* 时间                        :        2018-03-30
* 最后修改时间         :         2018-03-30
* 说明                        :         写SD卡多个(大于1个)块
**************************************************************************************************************************/
SDIO_Error SD_WriteMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, const u8 *pBlockBuff, u16 NumberOfBlocks)
{
        SDIO_Error errorstatus = SDIO_OK;
        u32 cardstatus = 0;
        u32 ReadLen = 0;
        u32 timeout;

        if (pBlockBuff == NULL)
        {
                errorstatus = SDIO_INVALID_PARAMETER;
                return(errorstatus);
        }

        //限制读取的块数量
        if(NumberOfBlocks > pHandle->MaxTransBlockCount)
        {
                DEBUG("限制一次读取%d块,当前一次读取%d\r\n", pHandle->MaxTransBlockCount, NumberOfBlocks);
                NumberOfBlocks = pHandle->MaxTransBlockCount;
        }
       
        //地址检查
        if(pHandle->CardType != SD_HIGH_CAPACITY_SD_CARD)
        {
                BlockAddr <<= 9;                        //小容量卡,转换为字节单位
        }

        //检查
        timeout = 100;        //超时100ms`
        do
        {
                //发送CMD13,SDIO_SEND_STATUS,读 Card_Status 寄存器,参数,RCA地址,短返回,R1;
                pHandle->pInterface->SDIO_SendCommand(CMD13, (u32) pHandle->RCA << 16, SDIO_Response_Short);
                errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
                if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
                {
                        pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                        DEBUG("CMD13 error (%d)!\r\n",errorstatus);
                        return(errorstatus);
                }
                pHandle->pInterface->SDIO_GetResponse(SDIO_RESP_Short, &cardstatus);                        //获取响应的状态
                if((cardstatus & 0x00000100) == 0) //没有准备好
                {
                        SYS_DelayMS(1);        //延时
                }
                else //READY_FOR_DATA位有效,卡已经准备好写入了
                {
                        break;
                }
                timeout --;
        }
        while (timeout);
       
        if (timeout == 0)
        {
                DEBUG("等待卡写入超时,错误:%d(状态0x%X)\r\n",errorstatus,cardstatus);
                return(SDIO_ERROR);
        }
       
        pHandle->pInterface->SDIO_ClearDataTrans();                                                                                //清除数据传输
        //发送CMD25,SDIO_WRITE_MULT_BLOCK,参数:字节地址(大容量卡为块地址),短返回,R1
        pHandle->pInterface->SDIO_SendCommand(CMD25, BlockAddr, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD25 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
               
        //开始传输-写入数据
        pHandle->pInterface->SDIO_SetAndStartDataTrans((u8 *)pBlockBuff, FALSE, pHandle->SDIO_BlockSize, pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks);
        //等待传输完成
        errorstatus = pHandle->pInterface->SDIO_WaitTransComplete(FALSE, &ReadLen, 100*NumberOfBlocks);//SDIO等待传输完成(等待读取或写入数据完成)(超时:100ms*NumberOfBlocks)
        if(errorstatus == SDIO_OK && ReadLen != (pHandle->SDCardInfo.CardBlockSize*NumberOfBlocks))
        {
                DEBUG("写入数据错误,需要写入:%dB,实际写入:%dB\r\n", pHandle->SDCardInfo.CardBlockSize, ReadLen);
        }
       
        //发送CMD12 SDIO_STOP_TRANSMISSION命令,终止读取;参数:0,短响应,R1
        pHandle->pInterface->SDIO_SendCommand(CMD12, 0, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD12 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
       
       
    //读取卡编程状态,等待写入完成
        errorstatus = SD_WaitProgrammingFinish(pHandle, 100);                                                        //等待编程完成
       
        return(errorstatus);
}


使用特权

评论回复
46
nawu|  楼主 | 2021-6-7 20:03 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_EraseBlock(SDIO_SD_HANDLE *pHandle,u32 BlockAddr, u32 NumberOfBlocks)
* 功能                        :        擦除指定的块
* 参数                        :        pHandle:句柄;BlockAddr:擦除的块地址;NumberOfBlocks:擦除的块数量
* 返回                        :        SDIO_Error
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2018-03-30
* 最后修改时间         :         2018-03-30
* 说明                        :         地址必须是块地址-擦除特别慢
*************************************************************************************************************************/
SDIO_Error SD_EraseBlock(SDIO_SD_HANDLE *pHandle,u32 BlockAddr, u32 NumberOfBlocks)
{
        SDIO_Error errorstatus = SDIO_OK;
       
        /*!< Check if the card coomnd class supports erase command */
        if (((pHandle->CSD_Tab[1] >> 20) & SD_CCCC_ERASE) == 0)         //卡不支持擦除命令
        {
                errorstatus = SDIO_REQUEST_NOT_APPLICABLE;
                return (errorstatus);
        }
       
        //发送CMD32 ERASE_GROUP_START命令,写入擦除开始地址;参数:擦除开始地址,短响应,R1
        pHandle->pInterface->SDIO_SendCommand(CMD32, BlockAddr, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD32 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
       
        //发送CMD33 SD_ERASE_GRP_END命令,写入擦除结束地址;参数:擦除结束地址,短响应,R1
        pHandle->pInterface->SDIO_SendCommand(CMD33, BlockAddr+NumberOfBlocks, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD33 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }
       
        //发送CMD38 ERASE命令,参数0,开始擦除,响应R1b
        pHandle->pInterface->SDIO_SendCommand(CMD38, 0, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();                                                //获取回复
        if (errorstatus != SDIO_OK)                                                                                                                //命令发送错误,返回
        {
                pHandle->pInterface->SDIO_ClearDataTrans();                                                                        //清除数据传输
                DEBUG("CMD38 error (%d)!\r\n",errorstatus);
                return(errorstatus);
        }       
         //读取卡编程状态,等待擦除完成
        errorstatus = SD_WaitProgrammingFinish(pHandle, NumberOfBlocks*500);                        //等待编程完成
       
        return(errorstatus);
}


使用特权

评论回复
47
nawu|  楼主 | 2021-6-7 20:04 | 只看该作者
/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_WaitProgrammingFinish(SDIO_SD_HANDLE *pHandle, u32 TimeOutMs)
* 功能                        :        等待编程完成
* 参数                        :        pHandle:句柄;TimeOutMs:通信超时时间
* 返回                        :        SDIO_Error
* 依赖                        :        底层宏定义
* 作者                        :        cp1300@139.com
* 时间                        :        2018-03-30
* 最后修改时间         :         2018-03-30
* 说明                        :         用于写入完成后等待编程完成
*************************************************************************************************************************/
SDIO_Error SD_WaitProgrammingFinish(SDIO_SD_HANDLE *pHandle, u32 TimeOutMs)
{
        SDIO_Error Status = SDIO_OK;
        u32 respR1 = 0;
        u8 cardstate;
       
        while(TimeOutMs)
        {
                //发送CMD13,SDIO_SEND_STATUS,读 Card_Status 寄存器,参数,RCA地址,短返回,R1;
                pHandle->pInterface->SDIO_SendCommand(CMD13, (u32) pHandle->RCA << 16, SDIO_Response_Short);
                Status = pHandle->pInterface->SDIO_CmdResp1Error();                                                                //获取回复
                if (Status != SDIO_OK)                                                                                                                        //命令发送错误,返回
                {
                        DEBUG("CMD13 error (%d)!\r\n",Status);
                        return(Status);
                }
               
                 pHandle->pInterface->SDIO_GetResponse(SDIO_RESP_Short, &respR1);                                //获取响应的状态
                //返回状态错误查询-加入以下状态可以在编程错误时方便找出问题
                if (respR1 & SDIO_OCR_ADDR_OUT_OF_RANGE)
                {
                        Status = (SDIO_ADDR_OUT_OF_RANGE);
                }
                else if (respR1 & SDIO_OCR_ADDR_MISALIGNED)
                {
                        Status = (SDIO_ADDR_MISALIGNED);
                }
                else if (respR1 & SDIO_OCR_BLOCK_LEN_ERR)
                {
                        Status =(SDIO_BLOCK_LEN_ERR);
                }
                else if (respR1 & SDIO_OCR_ERASE_SEQ_ERR)
                {
                        Status = (SDIO_ERASE_SEQ_ERR);
                }
                else if (respR1 & SDIO_OCR_BAD_ERASE_PARAM)
                {
                        Status = (SDIO_BAD_ERASE_PARAM);
                }
                else if (respR1 & SDIO_OCR_WRITE_PROT_VIOLATION)
                {
                        Status = (SDIO_WRITE_PROT_VIOLATION);
                }
                else if (respR1 & SDIO_OCR_LOCK_UNLOCK_FAILED)
                {
                        Status = (SDIO_LOCK_UNLOCK_FAILED);
                }
                else if (respR1 & SDIO_OCR_COM_CRC_FAILED)
                {
                        Status = (SDIO_COM_CRC_FAILED);
                }
                else if (respR1 & SDIO_OCR_ILLEGAL_CMD)
                {
                        Status = (SDIO_ILLEGAL_CMD);
                }
                else if (respR1 & SDIO_OCR_CARD_ECC_FAILED)
                {
                        Status = (SDIO_CARD_ECC_FAILED);
                }
                else if (respR1 & SDIO_OCR_CC_ERROR)
                {
                        Status = (SDIO_CC_ERROR);
                }
                else if (respR1 & SDIO_OCR_GENERAL_UNKNOWN_ERROR)
                {
                        Status =(SDIO_GENERAL_UNKNOWN_ERROR);
                }
                else if (respR1 & SDIO_OCR_STREAM_READ_UNDERRUN)
                {
                        Status = (SDIO_STREAM_READ_UNDERRUN);
                }
                else if (respR1 & SDIO_OCR_STREAM_WRITE_OVERRUN)
                {
                        Status = (SDIO_STREAM_WRITE_OVERRUN);
                }
                else if (respR1 & SDIO_OCR_CID_CSD_OVERWRIETE)
                {
                        Status = (SDIO_CID_CSD_OVERWRITE);
                }
                else if (respR1 & SDIO_OCR_WP_ERASE_SKIP)
                {
                        Status = (SDIO_WP_ERASE_SKIP);
                }
                else if (respR1 & SDIO_OCR_CARD_ECC_DISABLED)
                {
                        Status = (SDIO_CARD_ECC_DISABLED);
                }
                else if (respR1 & SDIO_OCR_ERASE_RESET)
                {
                        Status = (SDIO_ERASE_RESET);
                }
                else if (respR1 & SDIO_OCR_AKE_SEQ_ERROR)
                {
                        Status = (SDIO_AKE_SEQ_ERROR);
                }
       
                if (Status != SDIO_OK)                                                                                                                        //命令发送错误,返回
                {
                        DEBUG("CMD13 resp error (%d)!\r\n",Status);
                        return(Status);
                }
               
                /* Find out card status */
                cardstate = (u8) ((respR1 >> 9) & 0x0000000F);
                if((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))                //卡在编程中,等待
                {
                        Status = SDIO_ERASE_RESET;        //等待编程完成超时
                        SYS_DelayMS(1);
                }
                else
                {
                        return SDIO_OK;                //操作成功了
                }
               
                TimeOutMs--;
        }
       
        return Status;
}



使用特权

评论回复
48
nawu|  楼主 | 2021-6-7 20:04 | 只看该作者

/*************************************************************************************************************************
* 函数                        :        SDIO_Error SD_GetSDSCR(SDIO_SD_HANDLE *pHandle, u32 pSCR[2])
* 功能                        :        获取SCR信息
* 参数                        :        pHandle:句柄;prca:RCA缓冲区指针
* 返回                        :        SDIO_Error
* 依赖                        :        底层寄存器操作函数
* 作者                        :        cp1300@139.com
* 时间                        :        2020-09-13
* 最后修改时间         :         2020-09-13
* 说明                        :        
*************************************************************************************************************************/
SDIO_Error SD_GetSDSCR(SDIO_SD_HANDLE *pHandle, u32 pSCR[2])
{
        SDIO_Error errorstatus = SDIO_OK;
        u32 cnt = 0;
        u8 Buff[8];

        //设置块大小为8字节
        //发送SDIO_SET_BLOCKLEN,参数8,短响应
        pHandle->pInterface->SDIO_SendCommand(CMD16, 8, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();

        if (errorstatus != SDIO_OK)
        {
                DEBUG("SDIO_SET_BLOCKLEN error(%d)!\n",errorstatus);        //调试,打印错误信息
                goto _error;
        }
       
        //发送CMD55 SDIO_APP_CMD;命令参数:RCA;返回响应R1,设置RCA为0,短响应
          pHandle->pInterface->SDIO_SendCommand(SDIO_CMD_APP_CMD, (u32)pHandle->RCA << 16, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();
        if (errorstatus != SDIO_OK)
        {
                goto _error;
        }
       
        pHandle->pInterface->SDIO_ClearDataTrans();                                                                                //清除数据传输
        //发送ACMD51 SD_APP_SEND_SCR,参数0,短响应,R1
        pHandle->pInterface->SDIO_SendCommand(SDIO_CMD_SDIO_APP_SEND_SCR, 0, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();
        if (errorstatus != SDIO_OK)
        {
                goto _error;
        }
       
        pHandle->pInterface->SDIO_SetAndStartDataTrans(Buff, TRUE, SDIO_DataBlockSize_8B, 8);//设置SDIO并开始准备数据传输
        errorstatus = pHandle->pInterface->SDIO_WaitTransComplete(TRUE, &cnt, 500);
        if(errorstatus == SDIO_OK)
        {
                pSCR[0] = Buff[0];
                pSCR[0] <<= 8;
                pSCR[0] |= Buff[1];
                pSCR[0] <<= 8;
                pSCR[0] |= Buff[2];
                pSCR[0] <<= 8;
                pSCR[0] |= Buff[3];
               
                pSCR[1] = Buff[4];
                pSCR[1] <<= 8;
                pSCR[1] |= Buff[5];
                pSCR[1] <<= 8;
                pSCR[1] |= Buff[6];
                pSCR[1] <<= 8;
                pSCR[1] |= Buff[7];
        }

_error:
        //恢复块大小为 SD_BLOCK_SIZE
        pHandle->pInterface->SDIO_SendCommand(CMD16, SD_BLOCK_SIZE, SDIO_Response_Short);
        errorstatus = pHandle->pInterface->SDIO_CmdResp1Error();

        if (errorstatus != SDIO_OK)
        {
                DEBUG("SDIO_SET_BLOCKLEN error(%d)!\n",errorstatus);        //调试,打印错误信息
        }

        return (errorstatus);
}


使用特权

评论回复
49
nawu|  楼主 | 2021-6-7 20:05 | 只看该作者
//sdio_sdcard.h

/*************************************************************************************************************
* 文件名                        :        sdio_sdcard.c
* 功能                                :        SDIO接口SD卡驱动
* 作者                                :        cp1300@139.com
* 创建时间                        :        2018-03-27
* 最后修改时间                :        2018-03-27
* 详细                                :        源程序借鉴了意法STM32F103X库函数
                                                分离了底层SDIO接口,但是依赖一些数据定义,在sdio_const中
*************************************************************************************************************/
#ifndef _SDIO_SDCARD_H_
#define _SDIO_SDCARD_H_
#include "sdio_const.h"
#include "system.h"



//SD卡 CSD
typedef struct       /* Card Specific Data */
{
        u8  CSDStruct;            /* CSD structure */
        u8  SysSpecVersion;       /* System specification version */
        u8  Reserved1;            /* Reserved */
        u8  TAAC;                 /* Data read access-time 1 */
        u8  NSAC;                 /* Data read access-time 2 in CLK cycles */
        u8  MaxBusClkFrec;        /* Max. bus clock frequency */
        u16 CardComdClasses;      /* Card command classes */
        u8  RdBlockLen;           /* Max. read data block length */
        u8  PartBlockRead;        /* Partial blocks for read allowed */
        u8  WrBlockMisalign;      /* Write block misalignment */
        u8  RdBlockMisalign;      /* Read block misalignment */
        u8  DSRImpl;              /* DSR implemented */
        u8  Reserved2;            /* Reserved */
        u16 DeviceSize;           /* Device Size */
        u8  MaxRdCurrentVDDMin;   /* Max. read current @ VDD min */
        u8  MaxRdCurrentVDDMax;   /* Max. read current @ VDD max */
        u8  MaxWrCurrentVDDMin;   /* Max. write current @ VDD min */
        u8  MaxWrCurrentVDDMax;   /* Max. write current @ VDD max */
        u8  DeviceSizeMul;        /* Device size multiplier */
        u8  EraseGrSize;          /* Erase group size */
        u8  EraseGrMul;           /* Erase group size multiplier */
        u8  WrProtectGrSize;      /* Write protect group size */
        u8  WrProtectGrEnable;    /* Write protect group enable */
        u8  ManDeflECC;           /* Manufacturer default ECC */
        u8  WrSpeedFact;          /* Write speed factor */
        u8  MaxWrBlockLen;        /* Max. write data block length */
        u8  WriteBlockPaPartial;  /* Partial blocks for write allowed */
        u8  Reserved3;            /* Reserded */
        u8  ContentProtectAppli;  /* Content protection application */
        u8  FileFormatGrouop;     /* File format group */
        u8  CopyFlag;             /* Copy flag (OTP) */
        u8  PermWrProtect;        /* Permanent write protection */
        u8  TempWrProtect;        /* Temporary write protection */
        u8  FileFormat;           /* File Format */
        u8  ECC;                  /* ECC code */
        u8  CSD_CRC;              /* CSD CRC */
        u8  Reserved4;            /* always 1*/
} SD_CSD;


//SD卡CID
typedef struct      /*Card Identification Data*/
{
        u8  ManufacturerID;       /* ManufacturerID */
        u16 OEM_AppliID;          /* OEM/Application ID */
        u32 ProdName1;            /* Product Name part1 */
        u8  ProdName2;            /* Product Name part2*/
        u8  ProdRev;              /* Product Revision */
        u32 ProdSN;               /* Product Serial Number */
        u8  Reserved1;            /* Reserved1 */
        u16 ManufactDate;         /* Manufacturing Date */
        u8  CID_CRC;              /* CID CRC */
        u8  Reserved2;            /* always 1 */
} SD_CID;



//SD卡信息
typedef struct
{
        SD_CSD SD_csd;
        SD_CID SD_cid;
        u64 CardCapacity;          //SD卡容量,单位:字节,最大支持2^64字节大小的卡
        u32 CardBlockSize;         //SD卡块大小       
        u16 RCA;                        //卡相对地址
        u8 CardType;                //卡类型
} SD_CardInfo;



/* Supported Memory Cards */
typedef enum
{
        SD_STD_CAPACITY_SD_CARD_V1_1            =        0x0,        //SD V1.1版
        SD_STD_CAPACITY_SD_CARD_V2_0            =        0x1,        //SD V2.0版
        SD_HIGH_CAPACITY_SD_CARD                =        0x2,        //大容量SD卡-必须以块为单位读取
        SD_MULTIMEDIA_CARD                       =        0x3,        //MMC卡
        SD_SECURE_DIGITAL_IO_CARD                =        0x4,        //普通SD卡
        SD_HIGH_SPEED_MULTIMEDIA_CARD            =        0x5,        //高速SD卡
        SD_SECURE_DIGITAL_IO_COMBO_CARD         =        0x6,
        SD_HIGH_CAPACITY_MMC_CARD                =        0x7,        //大容量MMC卡
}SD_CARD_TYPE;


//SD卡扇区大小定义-注意大容量卡不支持此设置,只能使用512字节
#define SD_BLOCK_SIZE                512                                                //SD卡块大小
#if(SD_BLOCK_SIZE != 512 && SD_BLOCK_SIZE != 1024 && SD_BLOCK_SIZE != 2048 && SD_BLOCK_SIZE != 4096)
#error("无效的SD卡块大小");
#endif //SD_BLOCK_SIZE

//获取与SD卡块大小对应的SDIO传输块大小
__inline SDIO_DataBlockSize GetSDIO_BlockSizeForSDBlock(u32 SD_BlockSize)
{
        switch(SD_BlockSize)
        {
                case 512: return SDIO_DataBlockSize_512B;
                case 1024: return SDIO_DataBlockSize_1024B;
                case 2048: return SDIO_DataBlockSize_2048B;
                default:return SDIO_DataBlockSize_512B;
        }
}

//SD接口
typedef struct
{
        void (*SDIO_Init)(void);                                                                                                        //SDIO初始化
       
        void (*SDIO_SetLowSpeedClock)(void);                                                                                //SDIO设置低速时钟
        void (*SDIO_SetHighpeedClock)(void);                                                                                //SDIO设置高速时钟
        void (*SDIO_Set1BitBusWide)(void);                                                                                        //SDIO设置单线模式
        void (*SDIO_Set4BitBusWide)(void);                                                                                        //SDIO设置4线模式
        void (*SDIO_SendCommand)(u8 CmdIndex,u32 CmdArg,SDIO_WAIT_RESP WaitResp);        //SDIO发送一个命令
        void (*SDIO_SetAndStartDataTrans)(u8 *pDataBuff, bool isEnableReadData, SDIO_DataBlockSize SDIOBlockSize, u32 TransDataLen);//设置SDIO并开始准备数据传输
        void (*SDIO_ClearDataTrans)(void);                                                                                        //SDIO清除数据传输
        SDIO_Error (*SDIO_WaitTransComplete)(bool isEnableReadData, u32 *pDataLen, u32 TimeOutMs);//SDIO等待传输完成(等待读取或写入数据完成)
       
        void (*SDIO_GetResponse)(SDIO_RESP_TYPE RespIndex, u32 *pRespData);                        //获取返回响应状态 2020-09-12 更换接口形态,更通用一些
        SDIO_Error (*SDIO_CmdError)(void);                                                                                        //获取指令执行状态(无响应)
        SDIO_Error (*SDIO_CmdResp1Error)(void);                                                                                //指令执行状态(R1)
        SDIO_Error (*SDIO_CmdResp2Error)(void);                                                                                //指令执行状态(R2,CID or CSD)
        SDIO_Error (*SDIO_CmdResp3Error)(void);                                                                                //指令执行状态(R3,OCR)
        SDIO_Error (*SDIO_CmdResp6Error)(u16*prca);                                                                        //指令执行状态(R6,RCA)
        SDIO_Error (*SDIO_CmdResp7Error)(void);                                                                                //获取指令执行状态(R7)
        u32 (*SDIO_GetMaxTransBlockCount)(void);                                                                        //获取最大传输块数量,2020-09-13新增接口
}SDIO_SD_INTERFACE;



//SDIO句柄
typedef struct
{
        const SDIO_SD_INTERFACE *pInterface;                                                                                //所需的SDIO接口

        SD_CARD_TYPE        CardType;                                                                                                        //卡类型
        u32 CSD_Tab[4];
        u32 CID_Tab[4];
        u32 SCR_Tab[2];
        u32 RCA;
        u32 MaxTransBlockCount;                                                                                                                //SD卡控制器一次能传输的块最大数量
        SD_CardInfo SDCardInfo;                                                                                                                //SD卡信息
        SDIO_DataBlockSize SDIO_BlockSize;                                                                                        //SD卡block大小
}SDIO_SD_HANDLE;


//相关接口
void SD_InterfaceInit(SDIO_SD_HANDLE *pHandle, const SDIO_SD_INTERFACE *pInterface);                                                //SD卡底层接口初始化
SDIO_Error SD_Init(SDIO_SD_HANDLE *pHandle);                                                                                                                                //SD卡初始化
SDIO_Error SD_ReadStatus(SDIO_SD_HANDLE *pHandle, u32 *pSCR);                                                                                                //读取SD卡状态寄存器
SDIO_Error SD_ReadBlock(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, u8 *pBlockBuff);                                                        //读SD卡一个块
SDIO_Error SD_ReadMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr, u8 *pBlockBuff, u16 NumberOfBlocks);        //读取SD卡多个块
SDIO_Error SD_WriteBlock(SDIO_SD_HANDLE *pHandle, u32 BlockAddr,const  u8 *pBlockBuff);                                                                //写SD卡一个块
SDIO_Error SD_WriteMultiBlocks(SDIO_SD_HANDLE *pHandle, u32 BlockAddr,const  u8 *pBlockBuff, u16 NumberOfBlocks);        //写SD卡多个块
SDIO_Error SD_EraseBlock(SDIO_SD_HANDLE *pHandle,u32 BlockAddr, u32 NumberOfBlocks);                                                //擦除指定的块

#endif //_SDIO_SDCARD_H_


使用特权

评论回复
50
nawu|  楼主 | 2021-6-7 20:06 | 只看该作者
//中间层接口

/*************************************************************************************************************
* 文件名                        :        SDIO_SD_Interface.c
* 功能                                :        SD卡所需的SDIO接口
* 作者                                :        cp1300@139.com
* 创建时间                        :        2018-03-27
* 最后修改时间                :        2018-03-27
* 详细                                :        定义了SDIO SD卡所需的底层SDIO接口       
*************************************************************************************************************/
#include "system.h"
#include "SDIO_SD_Interface.h"
#include "sdio.h"
#include "sdio_const.h"
#include "board.h"

void BI_SDIO_Init(void);                                        //SDIO SD卡初始化
void BI_SDIO_SetLowSpeedClock(void);                //SDIO设置低速时钟
void BI_SDIO_SetHighpeedClock(void);                //SDIO设置高速时钟
void BI_SDIO_Set1BitBusWide(void);                        //SDIO设置单线模式
void BI_SDIO_Set4BitBusWide(void);                        //SDIO设置4线模式

//默认的SD卡接口
const SDIO_SD_INTERFACE g_DefaultSD_Interface =                                
{
        BI_SDIO_Init,                                        //SDIO初始化
       
        BI_SDIO_SetLowSpeedClock,                //SDIO设置低速时钟
        BI_SDIO_SetHighpeedClock,                //SDIO设置高速时钟
        BI_SDIO_Set1BitBusWide,                        //SDIO设置单线模式
        BI_SDIO_Set4BitBusWide,                        //SDIO设置4线模式
        SDIO_SendCommand,                                //SDIO发送一个命令
        SDIO_SetAndStartDataTrans,                //SDIO设置并开始数据传输
        SDIO_ClearDataTrans,                        //SDIO清除数据传输
        SDIO_WaitTransComplete,                        //SDIO等待传输完成(等待读取或写入数据完成)
       
        SDIO_GetResponse,                                //获取返回响应状态
        SDIO_CmdError,                                        //获取指令执行状态(无响应)
        SDIO_CmdResp1Error,                                //指令执行状态(R1)
        SDIO_CmdResp2Error,                                //指令执行状态(R2,CID or CSD)
        SDIO_CmdResp3Error,                                //指令执行状态(R3,OCR)
        SDIO_CmdResp6Error,                                //指令执行状态(R6,RCA)
        SDIO_CmdResp7Error,                                //获取指令执行状态(R7)
        SDIO_GetMaxTransBlockCount,                //获取最大传输块数量,2020-09-13新增接口
};

//SDIO SD卡初始化
void BI_SDIO_Init(void)
{
        //SDIO 相关IO初始化
        SYS_GPIOx_SetAF(GPIO_PD6_SD0_nCD);
        SYS_GPIOx_SetAF(GPIO_PD5_SD0_DATA3);
        SYS_GPIOx_SetAF(GPIO_PD4_SD0_DATA2);
        SYS_GPIOx_SetAF(GPIO_PD3_SD0_DATA1);
        SYS_GPIOx_SetAF(GPIO_PD2_SD0_DATA0);
        SYS_GPIOx_SetAF(GPIO_PD1_SD0_SCK);
        SYS_GPIOx_SetAF(GPIO_PD0_SD0_CMD);

        SDIO_Init();                                        //SDIO接口初始化
        SDIO_SetPortSelect(0);                        //设置SDIO当前port(0-1)
        SDIO_SetOut74Clock();                        //SDIO输出74个时钟
}


//SDIO设置低速时钟
void BI_SDIO_SetLowSpeedClock(void)                                                                               
{
        SDIO_SetClockSpeed(SDIO_CLK_400K);                                //SDIO设置时钟速度
}


//SDIO设置高速时钟
void BI_SDIO_SetHighpeedClock(void)                                                                               
{
        SDIO_SetClockSpeed(SDIO_CLK_25M);                                //SDIO设置时钟速度
}

//SDIO设置单线模式
void BI_SDIO_Set1BitBusWide(void)                                                                                       
{
        SDIO_SetBusWide(SDIO_BusWide_1b);        //SDIO设置总线宽度
}

//SDIO设置4线模式
void BI_SDIO_Set4BitBusWide(void)
{
        SDIO_SetBusWide(SDIO_BusWide_4b);        //SDIO设置总线宽度
}       


使用特权

评论回复
51
nawu|  楼主 | 2021-6-7 20:07 | 只看该作者
//测试

#include "typedef.h"
#include "nuc970_system.h"
#include "uart.h"
#include "stdlib.h"
#include "timer.h"
#include "main.h"
#include "test.h"
#include "sdio_sdcard.h"
#include "sdio_sd_interface.h"
#include "stdio.h"

//sd卡测试
void sdcard_test(void)
{
        u8 *pDataBuff = (u8 *)malloc(4096);
        u32 len;
        SDIO_Error Status;
        u32 i;
        STOP_WATCH_HANDLE mStopWatchHandle;
       
        SD_InterfaceInit(&g_SysGlobal.mSD0_Handle, &g_DefaultSD_Interface);                //SD卡底层接口初始化
       
        while(SD_Init(&g_SysGlobal.mSD0_Handle) != SDIO_OK)
        {
                SYS_DelayMS(1000);
        }
        //扇区读取
        g_mStopWatchClass.Restart(&mStopWatchHandle);
        g_mStopWatchClass.Start(&mStopWatchHandle);
        Status = SD_ReadBlock(&g_SysGlobal.mSD0_Handle, 0, pDataBuff);                        //读SD卡一个块
        g_mStopWatchClass.Stop(&mStopWatchHandle);
        uart_printf("\r\n读取一个扇区耗时:%lluus\r\n", g_mStopWatchClass.GetElapsedUs(&mStopWatchHandle));
        if(SDIO_OK == Status)
        {
                uart_printf("读取一个扇区成功:\r\n");
                //SD卡扇区读取成功
                for(i = 0;i < 512;i ++)
                {
                        uart_printf("%02X ", pDataBuff);
                }
                uart_printf("\r\n");
        }
        else
        {
                uart_printf("读取一个扇区错误:%d\r\n", Status);
        }
       
        //写单个扇区
        pDataBuff[10] = 0x35;
        pDataBuff[20] = 0x68;
        g_mStopWatchClass.Restart(&mStopWatchHandle);
        g_mStopWatchClass.Start(&mStopWatchHandle);
        Status = SD_WriteBlock(&g_SysGlobal.mSD0_Handle, 0, pDataBuff);                        //写SD卡一个块
        g_mStopWatchClass.Stop(&mStopWatchHandle);
        uart_printf("\r\n写一个扇区耗时:%lluus\r\n", g_mStopWatchClass.GetElapsedUs(&mStopWatchHandle));
        if(SDIO_OK == Status)
        {
                uart_printf("写一个扇区成功:\r\n");
        }
        else
        {
                uart_printf("写一个扇区错误:%d\r\n", Status);
        }
       
       
        //多扇区读取
        g_mStopWatchClass.Restart(&mStopWatchHandle);
        g_mStopWatchClass.Start(&mStopWatchHandle);
        Status = SD_ReadMultiBlocks(&g_SysGlobal.mSD0_Handle, 0, pDataBuff, 2);                        //读SD卡2个块
        g_mStopWatchClass.Stop(&mStopWatchHandle);
        uart_printf("\r\n读取多个扇区耗时:%lluus\r\n", g_mStopWatchClass.GetElapsedUs(&mStopWatchHandle));
        if(SDIO_OK == Status)
        {
                uart_printf("读取多个扇区成功:\r\n");
                //SD卡扇区读取成功
                for(i = 0;i < 1024;i ++)
                {
                        uart_printf("%02X ", pDataBuff);
                }
                uart_printf("\r\n");
        }
        else
        {
                uart_printf("读取多个扇区错误:%d\r\n", Status);
        }
       
        //多扇区写入
        pDataBuff[10] ++;
        pDataBuff[20] ++;
        pDataBuff[512+10] ++;
        pDataBuff[512+20] ++;
        g_mStopWatchClass.Restart(&mStopWatchHandle);
        g_mStopWatchClass.Start(&mStopWatchHandle);
        Status = SD_WriteMultiBlocks(&g_SysGlobal.mSD0_Handle, 0, pDataBuff, 2);                        //写SD卡2个块
        g_mStopWatchClass.Stop(&mStopWatchHandle);
        uart_printf("\r\n写多个扇区耗时:%lluus\r\n", g_mStopWatchClass.GetElapsedUs(&mStopWatchHandle));
        if(SDIO_OK == Status)
        {
                uart_printf("写多个扇区成功:\r\n");
               
        }
        else
        {
                uart_printf("写多个扇区错误:%d\r\n", Status);
        }
       
       
        //释放内存
        free(pDataBuff);
        while(1)
        {
                SYS_DelayMS(500);
        }
}


测试结果




使用特权

评论回复
52
guijial511| | 2021-6-7 21:21 | 只看该作者
这是看程序来了

使用特权

评论回复
53
huquanz711| | 2021-6-8 07:54 | 只看该作者
新唐的Linux驱动配套做的咋样?

使用特权

评论回复
54
单片小菜| | 2021-6-8 16:08 | 只看该作者
总是感觉你的速度设置的不是很快,读写的时候是不是有等待?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则