📄 51
字号:
/********************************************************************************************************************
** 函数名称: uchar SD_SendCmd()
** 功能描述: 向卡发送命令,并取得响应
** 输 入: uchar cmd : 命令字0-63
ulong arg : 命令参数,长度为4字节
** 输 出: 0: 正确 >0: 错误码
********************************************************************************************************************/
uchar SD_SendCmd(uchar cmd, ulong arg)
{
uchar i;
uchar tmp;
CS_SD_DIS;
for(i=0;i<8;i++)
{
SPI_WriteByte(0xff);
}
CS_SD_EN;
write_byte_spi((cmd & 0x3F) | 0x40); /* 发送命令头和命令字 */
SPI_WriteByte(arg>>24);
SPI_WriteByte(arg>>16);
SPI_WriteByte(arg>>8);
SPI_WriteByte(arg);
SPI_WriteByte(0x95);
//用SD模式需要用CRC校验,SPI不用
/*#if SD_CRC_EN
tmp = SD_GetCmdByte6((cmd & 0x3F) | 0x40, param);
SPI_SendByte(tmp);
#else
SPI_SendByte(0x95); /* CRC校验码,只用于第1个命令 CRC,only used for the first command
#endif*/
i = 0;
do /* 等待响应,响应的开始位为0 */
{ /* Wait for a response,a response is a start bit(zero) */
tmp = read_byte_spi();
i++;
}while (((tmp & 0x80) != 0) && (i < 100));
if (i >= 100)
{
CS_SD_DIS();
return 0; /* 返回命令超时 return response timeout of command */
}
/* for (i = rlen - 1; i >= 0; i--)
{
resp[i] = tmp;
tmp = read_byte_spi(); /* 循环的最后发送8clock
}*/
CS_SD_DIS;
return temp; /* 返回执行成功 return perform sucessfully */
}
/* SD卡初始化(SPI-MODE) */
/*--------------------------------------------------------------------*/
uchar sd_init(void)
{
uchar retry,temp,i,cmd[6];
//检测卡是否完全插入
if(SD_ChkCard==1) return 0;
/* send 74 clock at least! 不一定为25,具体多少需要调*/
CS_SD_DIS; //不选SD卡
for(i=0;i<25;i++)
{
write_byte_spi(0xff);
}
CS_SD_EN;
/* send command CMD0 to SD Card (reset SD Card) */
retry=0;
//cmd[0]=0,cmd[1]=0,cmd[2]=0,cmd[3]=0,cmd[4]=0,cmd[5]=0x95;
do
{
temp=SD_SendCmd(0,0);
retry++;
if(retry>200)
{ /* CMD0 error */
return 0;
}
}while(temp != 1);
/* send command CMD1 to SD Card (set SD Card Model:SPI) */
retry=0;
//cmd[0]=1,cmd[1]=0,cmd[2]=0,cmd[3]=0,cmd[4]=0,cmd[5]=0xff;
do
{
temp=SD_SendCmd(1,0);
retry++;
if(retry>100)
{ /* CMD1 error */
return 0;
}
}while(temp != 0);
//cmd10,查询卡的制造商和序列号
retry=0;
do
{
temp=SD_SendCmd(10,0);
retry++;
if(retry>100)
{ /* CMD1 error */
return 0;
}
}while(temp != 0);
//赋值给public数组
for(i=0;i<30;i++)public[i]=read_byte_spi();
return 1;
}
/*--------------------------------------------------------------------*/
/* 从SD卡读一个扇区 Return 0 if no Error */
/*--------------------------------------------------------------------*/
uchar sd_read_block(ulong address,uchar *data)
{
uchar temp;
uint i;
uchar cmd[6]={0x51,0,0,0,0,0xff}; //CMD17 read block
address=address<<9; /* address = address * 512 */
cmd[1]=((address & 0xff000000) >>24 );
cmd[2]=((address & 0x00ff0000) >>16 );
cmd[3]=((address & 0x0000ff00) >>8 );
temp=sd_write_command(cmd);
if(temp!=0)
{ /* 读数据出错 */
return(temp);
}
while(read_byte_spi()!=0xfe); /* 等待数据开始位0xfe */
for(i=0;i<512;i++)
{
*data++=read_byte_spi();
}
read_byte_spi(); /* CRC - Byte */
read_byte_spi(); /* CRC - Byte */
PORTB |= ~BIT(ss); /* 关闭SD卡使能 */
return(temp);
}
/********************************************************************************************************************
** 函数名称: void SD_PackParam() Name: void SD_PackParam()
** 功能描述: 将32位的参数转为字节形式 Function: change 32bit parameter to bytes form
** 输 入: INT8U *parameter: 字节参数缓冲区 Input: INT8U *parameter: the buffer of bytes parameter
INT32U value : 32位参数 INT32U value : 32bit parameter
** 输 出: 无 Output: NULL
*********************************************************************************************************************/
void SD_PackParam(INT8U *parameter, INT32U value)
{
parameter[3] = (INT8U)(value >> 24);
parameter[2] = (INT8U)(value >> 16);
parameter[1] = (INT8U)(value >> 8);
parameter[0] = (INT8U)(value);
}
/********************************************************************************************************************
** 函数名称: 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
*********************************************************************************************************************/
INT8U SD_BlockCommand(INT8U cmd, INT8U resptype, INT32U parameter)
{
INT8U 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 */
/* 结束数据传输失败 stop transmission operation fail */
if (resp != 0)
return SD_ERR_CMD_RESP; /* 响应错误 response is error */
return SD_NO_ERR;
}
/*
************************************************
下面为SD卡SPI命令
************************************************
*/
/********************************************************************************************************************
** 函数名称: INT8U SD_ResetSD() Name: INT8U SD_ResetSD()
** 功能描述: 复位SD卡 Function: reset sd card
** 输 入: 无 Input: NULL
** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code
*********************************************************************************************************************/
INT8U SD_ResetSD(void)
{
INT8U param[4] = {0,0,0,0},resp;
return (SD_SendCmd(CMD0, param, CMD0_R, &resp)); /* 复位命令 command that reset sd card */
}
/********************************************************************************************************************
** 函数名称: INT8U SD_ReadCSD() Name: INT8U SD_ReadCSD()
** 功能描述: 读SD卡的CSD寄存器 Function: read CSD register of sd card
** 输 入: INT8U csdlen : 寄存器长度(固定为16) INT8U csdlen : len of register (fixed,is 16)
INT8U *recbuf : 接收缓冲区 INT8U *recbuf : recbuffer
** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code
*********************************************************************************************************************/
INT8U SD_ReadCSD(INT8U csdlen, INT8U *recbuf)
{
INT8U param[4] = {0,0,0,0},resp,ret;
if (resp != 0)
return SD_ERR_CMD_RESP; /* 响应错误 response is error */
return (SD_ReadRegister(csdlen, recbuf));
}
/*******************************************************************************************************************
** 函数名称: INT8U SD_ReadCID() Name: INT8U SD_ReadCID()
** 功能描述: 读SD卡的CID寄存器 Function: read CID register of sd card
** 输 入: INT8U cidlen : 寄存器长度(固定为16) INT8U cidlen : len of register (fixed,is 16)
INT8U *recbuf : 接收缓冲区 INT8U *recbuf : recbuffer
** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code
********************************************************************************************************************/
#if SD_ReadCID_EN
INT8U SD_ReadCID(INT8U cidlen, INT8U *recbuf)
{
INT8U param[4] = {0,0,0,0},resp,ret;
ret = SD_SendCmd(CMD10, param, CMD10_R, &resp); /* 读CID寄存器命令 command that read CID register */
if ( ret != SD_NO_ERR)
return ret;
if (resp != 0)
return SD_ERR_CMD_RESP; /* 响应错误 response is error */
return (SD_ReadRegister(cidlen, recbuf));
}
#endif
/********************************************************************************************************************
** 函数名称: INT8U SD_StopTransmission() Name: INT8U SD_StopTransmission()
** 功能描述: 停止数据传输 Function: stop data transmission
** 输 入: 无 Input: NULL
** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code
*********************************************************************************************************************/
INT8U SD_StopTransmission(void)
{
INT8U param[4] = {0,0,0,0},resp;
return (SD_SendCmd(CMD12, param, CMD12_R, &resp)); /* 结束数据传输命令失败 stop transmission command fail */
}
/*********************************************************************************************************************
** 函数名称: 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
**********************************************************************************************************************/
INT8U SD_ReadCard_Status(INT8U len, INT8U *buffer)
{
INT8U param[4] = {0,0,0,0};
return (SD_SendCmd(CMD13, param, CMD13_R, buffer)); /* 读 Card Status 寄存器 */
/* read register of Card Status */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -