⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdcmd.c

📁 合众达的DM642示例工程
💻 C
📖 第 1 页 / 共 2 页
字号:
** 功能描述: 写单块命令								Function: write single block command
** 输   入: INT32U blockaddr: block address		Input:	  INT32U blockaddr: block address
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
*********************************************************************************************************************/
Uint8 SD_WriteSingleBlock(Uint32 blockaddr)
{
	return (SD_BlockCommand(CMD24, CMD24_R, blockaddr)); /* 写单块命令 command that write single block */
}
/*******************************************************************************************************************
** 函数名称: INT8U SD_ReadBlockData()			Name:	  INT8U SD_ReadBlockData()
** 功能描述: 从SD卡中读取数据块					Function: read block data from sd card
** 输   入: INT32U len    : 长度				Input:	  INT32U len    : length
			 INT8U *recbuf : 接收缓冲区					  INT8U *recbuf : the buffer of receive
** 输   出: 0:   正确    >0:   错误码		  	Output:	  0:  right		>0:  error code
*******************************************************************************************************************/
Uint8 SD_ReadBlockData(Uint32 len, Uint8 *recbuf)
{
    Uint8 tmp;
    Uint32 i = 0;
    
    GPIO_pinWrite(hGpio,GPIO_PIN3,0x0);   
    do
    { 											    /* 等待接收数据开始令牌0xFE  wait for receiving data start token 0xFE */
        tmp = SPI_RecByte();
        i++;
     }while((tmp != 0xFE) && (i < sds.timeout_read));//原语句是while((tmp == 0xFF) && (i < sds.timeout_read));
	
	if (i >= sds.timeout_read)
	{
		GPIO_pinWrite(hGpio,GPIO_PIN3,0x1);
       	return SD_ERR_TIMEOUT_READ;					/* 返回读超时错误码  return error timeout error code of reading */
	}
		
	/*if (tmp != SD_TOK_READ_STARTBLOCK)				/* 块读开始令牌错误 read start block token is error */
	/*{
		SPI_SendByte(0xFF);
		GPIO_pinWrite(hGpio,GPIO_PIN3,0x1);
		return SD_ERR_DATA_START_TOK;
	}*/
	
	for (i = 0; i < len; i++)
   		recbuf[i] = SPI_RecByte();					/* 接收数据 receive data */
   		
    i = SPI_RecByte();								
    i = (i << 8) + SPI_RecByte();    				/* 读取16位CRC get 16-bit CRC */	

#if SD_CRC_EN 
   	if (i != SD_GetCRC16(recbuf, len))
   	{												/* CRC校验错误 CRC check is error */
   		SPI_SendByte(0xFF); 
   		GPIO_pinWrite(hGpio,GPIO_PIN3,0x1);						
  		return SD_ERR_DATA_CRC16;					/* 返回CRC16错误  return error of CRC16 */				
  	}    
#endif   

	SPI_SendByte(0xFF); 
	GPIO_pinWrite(hGpio,GPIO_PIN3,0x1);

  	return SD_NO_ERR;								/* 返回函数执行成功 return function perform sucessfully */
}


/********************************************************************************************************************
** 函数名称: INT8U SD_WriteMultipleBlock()			Name:	  INT8U SD_WriteMultipleBlock()
** 功能描述: 写多块命令								Function: write multiple block command
** 输   入: INT32U blockaddr: 块地址				Input:	  INT32U blockaddr: block address
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right	>0:  error code
*********************************************************************************************************************/
Uint8 SD_WriteMultipleBlock(Uint32 blockaddr)
{
	return (SD_BlockCommand(CMD25, CMD25_R, blockaddr)); /* 写多块命令 command that write multiple block */
}
/*******************************************************************************************************************
** 函数名称: INT8U SD_WriteBlockData()				Name:	  INT8U SD_WriteBlockData()
** 功能描述: 向sd卡写数据块							Function: write block data to sd card
** 输   入: INT8U bmulti  : 是否为多块操作1:是0:否 Input:	  INT8U bmulti   : multi blocks operate 1:Y 0:N 
			 INT32U len    : 长度						  	  INT32U len     : length
			 INT8U *sendbuf: 发送缓冲区					 	  INT8U *sendbuf : the buffer of send
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
********************************************************************************************************************/
Uint8 SD_WriteBlockData(Uint8 bmulti, Uint32 len, Uint8 *sendbuf)
{
	Uint16 i;
	Uint8 tmp;

	GPIO_pinWrite(hGpio,GPIO_PIN3,0x0);
	//EVMDM642_waitusec(100);
		
    SPI_SendByte(0xFF);								/* 开始发送数据之前发送8个clock clock out 8 clk before start */
    SPI_SendByte(0xFF);								/* 开始发送数据之前发送8个clock clock out 8 clk before start */
    SPI_SendByte(0xFF);								/* 开始发送数据之前发送8个clock clock out 8 clk before start */
    
    if (bmulti == 1)
        SPI_SendByte(SD_TOK_WRITE_STARTBLOCK_M);	/* 写多块开始令牌 start token of write multi blocks */
	else
		SPI_SendByte(SD_TOK_WRITE_STARTBLOCK);		/* 写单块开始令牌 start token of write single block */

	for (i = 0; i < len; i++)
        SPI_SendByte(sendbuf[i]);					/* 发送数据 send data */

#if SD_CRC_EN	
	i = SD_GetCRC16(sendbuf,len);					/* 计算CRC16 calculate CRC16 */
#endif

	SPI_SendByte((i >> 8) & 0xFF);
	SPI_SendByte(i & 0xFF); 						/* 发送CRC16校验码 send CRC16 check code */
    //SD_WaitBusy	(SD_WAIT_WRITE);
    do
    {	    
	tmp = SPI_RecByte();
  	}while((tmp & SD_RESP_DATA_MSK) != 0x05);//SD_RESP_DATA_ACCETPTED);
  //	if ((tmp & SD_RESP_DATA_MSK) != SD_RESP_DATA_ACCETPTED)	
  	//{		
   	//	SPI_SendByte(0xFF);							/* 返回之前发送8个clock  clock out 8 clk before return */
   	///	GPIO_pinWrite(hGpio,GPIO_PIN3,0x1);
   	//	return SD_ERR_DATA_RESP;					/* 数据响应错误 data response error */
    //}
        
    GPIO_pinWrite(hGpio,GPIO_PIN3,0x01);
     		
    if (SD_WaitBusy(SD_WAIT_WRITE) != SD_NO_ERR)			
    	return SD_ERR_TIMEOUT_WRITE;				/* 写入超时 write time out */
    else
    	return SD_NO_ERR; 							/* 写入正确 write right */
 }
 /********************************************************************************************************************
** 函数名称: INT8U SD_StopTransmission()			Name:	  INT8U SD_StopTransmission()
** 功能描述: 停止数据传输							Function: stop data transmission 
** 输   入: 无								 		Input:    NULL
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
*********************************************************************************************************************/
Uint8 SD_StopTransmission(void)
{
	Uint8 param[4] = {0,0,0,0},resp;
	
 	return (SD_SendCmd(CMD12, param, CMD12_R, &resp));	/* 结束数据传输命令失败 stop transmission command fail */
}
/*******************************************************************************************************************
** 函数名称: void SD_StopMultiToken()				Name:	  void SD_StopMultiToken(void)
** 功能描述: 发送多块写停止令牌						Function: send the token that stop multiple block write
** 输   入: 无									    Input:	  NULL
** 输   出: 无										Output:	  NULL
********************************************************************************************************************/
void SD_StopMultiToken(void)
{
	GPIO_pinWrite(hGpio,GPIO_PIN3,0x0);
	
	SPI_SendByte(0xFF);								/* 先发送8个clock send 8 clock first */
	SPI_SendByte(SD_TOK_STOP_MULTI);				/* 发送停止数据传输令牌 send stop transmission token */
	SPI_RecByte();
	
    GPIO_pinWrite(hGpio,GPIO_PIN3,0x01);
}
/********************************************************************************************************************
** 函数名称: INT8U SD_GetNumWRBlcoks()				Name:	  INT8U SD_GetNumWRBlcoks()
** 功能描述: 得到正确写入的块数						Function: get the block numbers that written correctly
** 输   入: INT32U *blocknum: 返回的块数			Input:	  INT32U blocknum	: the block numbers returned
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
*********************************************************************************************************************/
#if SD_WriteMultiBlock_EN
Uint8 SD_GetNumWRBlcoks(Uint32 *blocknum)
{
    Uint8 tmp[4] = {0,0,0,0},resp,ret;
  
    ret = SD_SendCmd(CMD55, tmp, CMD55_R, &resp);	  			/* 后续命令为一个应用命令 */
    if (ret != SD_NO_ERR) 										/* command that the followed commnad is a specific application */
    	return ret;
    	 
    if (resp != 0)
    	return SD_ERR_CMD_RESP;    	
 											
   	ret = SD_SendCmd(ACMD22, tmp, ACMD22_R, &resp);  			/* 读取正确写入的块数命令 */
   	if (ret != SD_NO_ERR)										/* command that read the numbers of block written correctly */
   		return ret;											    
   		 														
	if (resp != 0)
    	return SD_ERR_CMD_RESP;									/* 响应错误 response is error */
    		
    ret = SD_ReadBlockData(4, tmp);								/* 读块数 read the numbvers of block */
    if (ret != SD_NO_ERR)
    	return ret;
    	
    *blocknum = (tmp[0] << 24) + (tmp[1] << 16) + (tmp[2] << 8) + tmp[3];	
    															/* 转换为32位 change to 32 bits */

	return SD_NO_ERR;    										/* 返回执行成功 return perform sucessfully */		
}
#endif

/********************************************************************************************************************
** 函数名称: INT8U SD_BlockCommand()				Name:	  INT8U SD_BlockCommand()
** 功能描述: 块命令									Function: command about block operation
** 输   入: INT8U cmd	     : 命令字				Input:	  INT8U cmd	      : command byte 
			 INT8U resptype  : 响应类型						  INT8U resptype  : response type
			 INT32U parameter: 块操作参数			 		  INT32U parameter: parameter of block operation
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
*********************************************************************************************************************/
Uint8 SD_BlockCommand(Uint8 cmd, Uint8 resptype, Uint32 parameter)
{
	Uint8 param[4],resp,ret;
	
	parameter <<= SD_BLOCKSIZE_NBITS;					 /* 调整地址:左移9位 adjust address: move 9 bits left */

	SD_PackParam(param, parameter);						 /* 将参数转化为字节形式 change the parameter to bytes form */	

	ret = SD_SendCmd(cmd, param, resptype, &resp);
	if (ret != SD_NO_ERR)
	   	 return ret;							 		 /* 结束数据传输失败 stop transmission operation fail */
	
	if (resp != 0)
		 return SD_ERR_CMD_RESP;		 				 /* 响应错误 response is error */
		 
	return SD_NO_ERR;
}
#if SD_EraseBlock_EN

/********************************************************************************************************************
** 函数名称: INT8U SD_EraseEndBlock()				Name:	  INT8U SD_EraseEndBlock()
** 功能描述: 设置块擦除终止地址						Function: select the end block address of erasing operation  
** 输   入: INT32U endblock: 块地址				Input:	  INT32U Length	: block address
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right	   >0:  error code
*********************************************************************************************************************/
Uint8 SD_EraseEndBlock(Uint32 endblock)
{
	return (SD_BlockCommand(CMD33, CMD33_R, endblock));     /* 发送擦除终止块地址 send the end block address of erasing operation */
}
/********************************************************************************************************************
** 函数名称: INT8U SD_EraseStartBlock()				Name:	  INT8U SD_EraseStartBlock()
** 功能描述: 设置块擦除起始地址						Function: select the start block address of erasing operation 
** 输   入: INT32U startblock: 块地址				Input: 	  INT32U startblock	: block address
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right	   >0:  error code
*********************************************************************************************************************/
Uint8 SD_EraseStartBlock(Uint32 startblock)
{
	return (SD_BlockCommand(CMD32, CMD32_R, startblock));	/* 发送擦除起始块地址 send the start block address of erasing operation */
}
/********************************************************************************************************************
** 函数名称: INT8U SD_EraseSelectedBlock()			Name:	  INT8U SD_EraseSelectedBlock()
** 功能描述: 擦除已选中的块							Function: erase block selected
** 输   入: 无										Input:	  NULL
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
*********************************************************************************************************************/
Uint8 SD_EraseSelectedBlock(void)
{
	Uint8 param[4],resp,tmp;
	
	SD_PackParam(param, 0);
	
	tmp = SD_SendCmd(CMD38, param, CMD38_R, &resp);	 	    /* 擦除所选择的块  erase blocks selected */
	if (tmp != SD_NO_ERR)
		return tmp;							 	
	
	if (SD_WaitBusy(SD_WAIT_ERASE) != SD_NO_ERR)			/* 等待擦除完成 wait for finishing erasing */
		return SD_ERR_TIMEOUT_ERASE;
	else
		return SD_NO_ERR;									
}	
#endif
/********************************************************************************************************************
** 函数名称: void SD_WaitBusy()						Name:	  void SD_WaitBusy()
** 功能描述: 查询SD卡是否处于忙状态					Function: poll SD Card wheather it is busy
** 输   入: INT32U waittype: 超时类型				Input:	  INT32U timeout: time out type
** 输   出: 0: 未超时  >0: 错误码					Output:	  0: not time out   > 0: error code
*********************************************************************************************************************/
Uint8 SD_WaitBusy(Uint8 waittype)
{
    Uint32 timeout, i = 0;
    Uint8 tmp;
    
    if (waittype == SD_WAIT_WRITE)
    	timeout = sds.timeout_write;
    else
    	timeout = sds.timeout_erase;

	//GPIO_pinWrite(hGpio,GPIO_PIN3,0x0);	
   	do
   	{ 												/* 等待忙结束 wait for being busy end */
        tmp = SPI_RecByte();
        i++;
    }while ((tmp == !0xff) && (i < timeout));		/* 忙时收到的值为0xFF always receive 0xFF when card is busy */    
	//GPIO_pinWrite(hGpio,GPIO_PIN3,0x1);								/* 有错 */
	
	if(i < timeout) 
		return SD_NO_ERR;							/* 返回0,表示没超时 return 0 indicate that operation is not time out */
	else 
		return SD_ERR_TIMEOUT_WAIT;					/* 返回错误码,表示超时 return error code indicate that operation is time out */
}
/*********************************************************************************************************************
** 函数名称: INT8U SD_ReadCard_Status()				Name:	  INT8U SD_ReadCard_Status()
** 功能描述: 读SD卡的 Card Status 寄存器			Function: read Card Status register of sd card 
** 输   入: INT8U len: 	 寄存器长度(固定为2)			  INT8U len:      len of register (fixed,is 2)
			 INT8U *recbuf : 接收缓冲区					      INT8U *recbuf : recbuffer
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
**********************************************************************************************************************/
Uint8 SD_ReadCard_Status(Uint8 len, Uint8 *buffer)
{
    Uint8 param[4] = {0,0,0,0};

    return (SD_SendCmd(CMD13, param, CMD13_R, buffer)); /* 读 Card Status 寄存器 */
}    									 	 			/* read register of Card Sta*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -