//-------------------------------------------------------------------------
/*******************************************************************************
* Function Name : SPI_FLASH_SendByte
* Description : Sends a byte through the SPI interface and return the byte * received from the SPI bus. * Input : byte : byte to send. * Output : None
* Return : The value of the received byte.
*******************************************************************************/
u8 SPIx_ReadWriteByte(u8 byte)
{
/* Loop while DR register in not emplty */
while ((SPI2->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
/* Send byte through the SPI1 peripheral */ //SPI_I2S_SendData(SPI2, byte); SPI2->DR = byte;
/* Wait to receive a byte */
while((SPI2->SR &SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
/* Return the byte read from the SPI bus */ //return SPI_I2S_ReceiveData(SPI2); return SPI2->DR; }
//u8 SPIx_ReadWriteByte(u8 byte)
//{
/* Loop while DR register in not emplty */
//while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
/* Send byte through the SPI1 peripheral */ //SPI_I2S_SendData(SPI2, byte);
/* Wait to receive a byte */
//while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
//return SPI_I2S_ReceiveData(SPI2); //}
/*******************************************************************************
* Function Name : SPI_FLASH_ReadByte
* Description : Reads a byte from the SPI Flash.
* This function must be used only if the Start_Read_Sequence * function has been previously called. * Input : None
* Output : None
* Return : Byte Read from the SPI Flash.
*******************************************************************************/
u8 SPI_ReadByte(void) {
return (SPIx_ReadWriteByte(Dummy_Byte)); }
//-----------------------------------------------------------------------------------------------------------------------------------
//等待SD卡回应
//Response:要得到的回应值 //返回值:0,成功得到了该回应值 // 其他,得到回应值失败
u8 SD_GetResponse(u8 Response) {
u16 Count=0xFFF;//等待次数
while ((SPIx_ReadWriteByte(0XFF)!=Response)&&Count) Count--;//等待得到准确的回应 if (Count==0)
{
return MSD_RESPONSE_FAILURE;//得到回应失败 } else {
return MSD_RESPONSE_NO_ERROR;//正确回应 }
}
//------------------------------------------------------------------------
//等待SD卡写入完成 //返回值:0,成功; // 其他,错误代码;
u8 SD_WaitDataReady(void) {
u8 r1=MSD_DATA_OTHER_ERROR;
u32 retry; retry=0; do {
r1=SPIx_ReadWriteByte(0xFF)&0X1F; //读到回应 if(retry==0xfffe)return 1; retry++; switch (r1) {
case MSD_DATA_OK: //数据接收正确了 r1=MSD_DATA_OK; break;
case MSD_DATA_CRC_ERROR: //CRC校验错误 return MSD_DATA_CRC_ERROR;
case MSD_DATA_WRITE_ERROR: //数据写入错误 return MSD_DATA_WRITE_ERROR; default: //未知错误 r1=MSD_DATA_OTHER_ERROR; break; }
}while(r1==MSD_DATA_OTHER_ERROR); //数据错误时一直等待 retry=0;
while(SPIx_ReadWriteByte(0XFF)==0) //读到数据为0,则数据还未写完成 {
retry++;
//delay_us(10); //SD卡写等待需要较长的时间 if(retry>=0XFFFFFFFE)return 0XFF; //等待失败了 };
return 0; //成功了 }
//----------------------------------------------------------------- //向SD卡发送一个命令 //输入: u8 cmd 命令 // u32 arg 命令参数 // u8 crc crc校验值
//返回值:SD卡返回的响应
u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc) {
u8 r1;
u8 Retry=0;
sd_cs_1;
SPIx_ReadWriteByte(0xff); //高速写命令延时 SPIx_ReadWriteByte(0xff); SPIx_ReadWriteByte(0xff);
//片选端置低,选中SD卡 sd_cs_0;
//发送
SPIx_ReadWriteByte(cmd | 0x40); //分别写入命令 SPIx_ReadWriteByte(arg >> 24); SPIx_ReadWriteByte(arg >> 16); SPIx_ReadWriteByte(arg >> 8); SPIx_ReadWriteByte(arg); SPIx_ReadWriteByte(crc);
//等待响应,或超时退出
while((r1=SPIx_ReadWriteByte(0xFF))==0xFF) {
Retry++;
if(Retry>200)break; }
//关闭片选 sd_cs_1;
//在总线上额外增加8个时钟,让SD卡完成剩下的工作 SPIx_ReadWriteByte(0xFF); //返回状态值 return r1; }
//-----------------------------------------------------------
//向SD卡发送一个命令(结束是不失能片选,还有后续数据传来) //输入:u8 cmd 命令 // u32 arg 命令参数 // u8 crc crc校验值
//返回值:SD卡返回的响应
u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc) {
u8 Retry=0;
u8 r1;
SPIx_ReadWriteByte(0xff);//高速写命令延时 SPIx_ReadWriteByte(0xff);
sd_cs_0;//片选端置低,选中SD卡
//发送
SPIx_ReadWriteByte(cmd | 0x40); //分别写入命令 SPIx_ReadWriteByte(arg >> 24); SPIx_ReadWriteByte(arg >> 16); SPIx_ReadWriteByte(arg >> 8); SPIx_ReadWriteByte(arg); SPIx_ReadWriteByte(crc);
//等待响应,或超时退出
while((r1=SPIx_ReadWriteByte(0xFF))==0xFF) {
Retry++;
if(Retry>200)break; }
//返回响应值 return r1; }
//------------------------------------------------------------ //把SD卡设置到挂起模式 //返回值:0,成功设置 // 1,设置失败 u8 SD_Idle_Sta(void) { u16 i; u8 retry;
for(i=0;i<0xf00;i++); //纯延时,等待SD卡上电完成
//先产生>74个脉冲,让SD卡自己初始化完成 for(i=0;i<10;i++)SPIx_ReadWriteByte(0xFF);
//-----------------SD卡复位到idle开始-----------------
//循环连续发送CMD0,直到SD卡返回0x01,进入IDLE状态 //超时则直接退出 retry = 0; do