在线时间26 小时
UID3318563
ST金币135
蝴蝶豆4
注册时间2016-10-11
该用户从未签到
中级会员
- 最后登录
- 2020-6-2
|
系统介绍:
1.MCU :STM32L151RDT6
2.时钟配置: 外部晶振12M ,PLL分频得到48M给SDIO适配器使用,PLL分频得到系统主时钟32M SDIO外设 PCLK2时钟32M
3.SD_CK上电初始化时400KHz,初始化完成后分频改成24MHz。
SD原理图:
问题:
SD卡上电初始化没有问题,能够读取卡的CID,块的大小等信息。在测试块写入数据时提示SD_TX_UNDERRUN 错误,也就是FIFO下溢错误。
我尝试减小时钟频率的话出现SD_DATA_CRC_FAIL错误,也就是数据块CRC错误。不知什么原因造成的。我是按照原子STM32F407SD卡的例子改的。
- SD_Error SD_WriteBlock(u8 *buf,long long addr, u16 blksize)
- {
- SD_Error errorstatus = SD_OK;
-
- u8 power=0,cardstate=0;
-
- u32 timeout=0,bytestransferred=0;
-
- u32 cardstatus=0,count=0,restwords=0;
-
- u32 tlen=blksize; //总长度
-
- u32*tempbuff=(u32*)buf;
-
- if(buf==NULL)return SD_INVALID_PARAMETER;//参数错误
-
- SDIO->DCTRL=0x0; //数据寄存器清零关DMA
-
- SDIO_DataInitStructure.SDIO_DataBlockSize= 0;//清除DPSM状态机配置
- SDIO_DataInitStructure.SDIO_DataLength= 0 ;
- SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
- SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
- SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
- SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
- SDIO_DataConfig(&SDIO_DataInitStructure);
-
-
- if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
- if(CardType==SDIO_HIGH_CAPACITY_SD_CARD) //大容量卡
- {
- blksize=512;
- addr/=512;
- }
- if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
- {
- power=convert_from_bytes_to_power_of_two(blksize);
-
- SDIO_CmdInitStructure.SDIO_Argument = blksize;//发送CMD16+设置数据长度 blksize,短响应
- SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
- SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
- SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
- SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
- SDIO_SendCommand(&SDIO_CmdInitStructure);
-
- errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应
-
- if(errorstatus!=SD_OK)return errorstatus; //这里返回SD_OK
-
- }else return SD_INVALID_PARAMETER;
-
- SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应
- SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
- SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
- SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
- SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
- SDIO_SendCommand(&SDIO_CmdInitStructure);
- errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //等待R1响应
-
- if(errorstatus!=SD_OK)return errorstatus; //这里返回SD_OK
- cardstatus=SDIO->RESP1;
- timeout=SD_DATATIMEOUT;
- while(((cardstatus&0x00000100)==0)&&(timeout>0)) //¼ì²éREADY_FOR_DATAλÊÇ·ñÖÃλ
- {
- timeout--;
-
- SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应
- SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
- SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
- SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
- SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
- SDIO_SendCommand(&SDIO_CmdInitStructure);
-
- errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //等待R1响应
-
- if(errorstatus!=SD_OK)return errorstatus;
-
- cardstatus=SDIO->RESP1;
- }
- if(timeout==0)return SD_ERROR;
- SDIO_CmdInitStructure.SDIO_Argument = addr;//发送CMD24,写单块指令,短响应
- SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
- SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
- SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
- SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
- SDIO_SendCommand(&SDIO_CmdInitStructure);
-
- errorstatus=CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);//等待R1响应
-
- if(errorstatus!=SD_OK)return errorstatus;//这里反会SD_OK
-
- StopCondition=0; //单块写不需要发送停止传输指令
- SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ; //blksize, 控制器到卡
- SDIO_DataInitStructure.SDIO_DataLength= blksize ;
- SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
- SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
- SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
- SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
- SDIO_DataConfig(&SDIO_DataInitStructure);
- timeout=SDIO_DATATIMEOUT;
-
- if(errorstatus!=SD_OK)return errorstatus; //这里返回OK
复制代码
|
|