|
发表于 2009-9-26 12:19:26
|
显示全部楼层
以下是zlg的程序,主要是CMD0以后执行的初始化部分,
根据我个人的理解,该程序首先发送CMD1,然后进行判断,while (((resp[0] & MSK_IDLE) == MSK_IDLE) && (i <=SD_IDLE_WAIT_MAX));
想在指定时间内等到SD卡进入IDLE模式,感觉这么做有很大问题,如果是“薄的”SD卡,不可能识别CMD1命令,所以肯定进入不了IDLE模
式,(IDLE bit 不可能清零)则该程序就直接返回错误代码了,不能完成初始化。(其实就是因为使用了一个“薄的”SD卡)
函数的最后适用ACMD41来判断是否是SD还是MMC
ret = SD_SendCmd(ACMD41, param, ACMD41_R, resp);
/* 激活内部初始化命令 active card to initialize process internal */
if (ret != SD_NO_ERR)
return SD_ERR_UNKNOWN_CARD;
if ((resp[0] & 0xFE) == 0)
sds.card_type = CARDTYPE_SD; /* 是SD卡 the card is SD card */
else
sds.card_type = CARDTYPE_MMC; /* 是MMC卡 the card is MMC card */
应该可以这么理解:
发送ACMD41,等到response R1 进行分析,只要除了bit0 也就是idle bit 位以外都是0,就说明可以识别ACMD41,也就说明这是一个SD卡,否则就是MMC,我觉得这么做没什么问题。
但是我觉得应该把它放在前面,先判断SD还是MMC,如果是MMC在用CMD1来进行初始化,如果直接把CMD1放在前面,可能会导致一定种类的SD卡不能用就是所谓的“薄的”SD。
下面是程序源码
INT8U SD_ActiveInit(void)
{
INT8U param[4] = {0,0,0,0},resp[5],ret;
INT32U i = 0;
do
{
/* 发出CMD1, 查询卡的状态, send CMD1 to poll card status */
ret = SD_SendCmd(CMD1, param, CMD1_R, resp);
if (ret != SD_NO_ERR)
return ret;
i ++;
}while (((resp[0] & MSK_IDLE) == MSK_IDLE) && (i <= SD_IDLE_WAIT_MAX));
/* 如果响应R1的最低位Idle位为1,则继续循环 */
/* if response R1 Idle bit is 1,continue recycle */
if (i >= SD_IDLE_WAIT_MAX)
return SD_ERR_TIMEOUT_WAITIDLE;
/* 超时,返回错误 time out,return error */
ret = SD_SendCmd(CMD55, param, CMD55_R, resp);
if (ret != SD_NO_ERR)
return ret;
ret = SD_SendCmd(ACMD41, param, ACMD41_R, resp);
/* 激活内部初始化命令 active card to initialize process internal */
if (ret != SD_NO_ERR)
return SD_ERR_UNKNOWN_CARD;
if ((resp[0] & 0xFE) == 0)
sds.card_type = CARDTYPE_SD; /* 是SD卡 the card is SD card */
else
sds.card_type = CARDTYPE_MMC; /* 是MMC卡 the card is MMC card */
return SD_NO_ERR;
} |
|