This commit is contained in:
2026-04-23 10:50:18 +08:00
commit a436fda935
844 changed files with 272643 additions and 0 deletions

View File

@ -0,0 +1,422 @@
/*
*********************************************************************************
ͷ<>ļ<EFBFBD>
*********************************************************************************
*/
#include "SPI_SD_driver.h"
#include "spi.h"
/*
*********************************************************************************
<20><><EFBFBD><EFBFBD>
*********************************************************************************
*/
u8 SD_Type=0;
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_SPI_ReadWriteByte()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: SD<53><44><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
* <09><> <20><> <20><>data:Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
u8 SD_SPI_ReadWriteByte(u8 data)
{
return SPI2_ReadWriteByte(data);
}
//SD<53><44><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,<2C><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
void SD_SPI_SpeedLow(void)
{
SPI2_SetSpeed(SPI_BaudRatePrescaler_256);//<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ģʽ
}
//SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,<2C><><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD><EFBFBD><EFBFBD>
void SD_SPI_SpeedHigh(void)
{
SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ģʽ
}
/**********************************************
*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void SPI_Configuration(void)
*<2A><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*<2A><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*<2A><><EFBFBD><EFBFBD>ֵ <20><><EFBFBD><EFBFBD>
*<2A><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>SPIģ<49><C4A3><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49>ڵij<DAB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
**********************************************/
void SD_SPI_Init(void)
{
SPI2_Init();
//SPI2_SetSpeed(7);
SD_SPI_SpeedHigh();
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_DisSelect()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: ȡ<><C8A1>Ƭѡ
* <09><> <20><> <20><><EFBFBD><EFBFBD>
* <20><> <20><> <20><><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
void SD_DisSelect(void)
{
SD_CS_DISABLE() ;
SD_SPI_ReadWriteByte(0xff);//<2F><EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>ʱ<EFBFBD><CAB1>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_Select()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: ѡ<><D1A1>sd<73><64>,<2C><><EFBFBD>ҵȴ<D2B5><C8B4><EFBFBD>׼<EFBFBD><D7BC>OK
* <09><> <20><> <20><><EFBFBD><EFBFBD>
* <20><> <20><> <20><>0,׼<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD><><CAA7>;
*********************************************************************************************************
*/
u8 SD_Select(void)
{
SD_CS_ENABLE();
if(SD_WaitReady()==0)return 0;//<2F>ȴ<EFBFBD><C8B4>ɹ<EFBFBD>
SD_DisSelect();
return 1;//<2F>ȴ<EFBFBD>ʧ<EFBFBD><CAA7>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_WaitReady()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20>ȴ<EFBFBD><C8B4><EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD>
* <09><> <20><> <20><>Response:Ҫ<>õ<EFBFBD><C3B5>Ļ<EFBFBD>Ӧֵ
* <20><> <20><> <20><>0,׼<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD><><CAA7>;
*********************************************************************************************************
*/
u8 SD_WaitReady(void)
{
u32 t=0;
do
{
if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK
t++;
}while(t<0XFFFFFF);//<2F>ȴ<EFBFBD>
return 1;
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_GetResponse()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20>ȴ<EFBFBD>SD<53><44><EFBFBD><EFBFBD>Ӧ
* <09><> <20><> <20><>Response:Ҫ<>õ<EFBFBD><C3B5>Ļ<EFBFBD>Ӧֵ
* <20><> <20><> <20><>0,<2C>ɹ<EFBFBD>;<3B><><EFBFBD><EFBFBD><><CAA7>;
*********************************************************************************************************
*/
u8 SD_GetResponse(u8 Response)
{
u16 Count=0xFFFF;//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//<2F>ȴ<EFBFBD><C8B4>õ<EFBFBD>׼ȷ<D7BC>Ļ<EFBFBD>Ӧ
if (Count==0)return MSD_RESPONSE_FAILURE;//<2F>õ<EFBFBD><C3B5><EFBFBD>Ӧʧ<D3A6><CAA7>
else return MSD_RESPONSE_NO_ERROR;//<2F><>ȷ<EFBFBD><C8B7>Ӧ
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_RecvData()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>sd<73><64><EFBFBD><EFBFBD>ȡһ<C8A1><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <09><> <20><> <20><>buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD> len:Ҫ<><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>.
* <20><> <20><> <20><>0,<2C>ɹ<EFBFBD>;<3B><><EFBFBD><EFBFBD><><CAA7>;
*********************************************************************************************************
*/
u8 SD_RecvData(u8*buf,u16 len)
{
if(SD_GetResponse(0xFE))return 1;//<2F>ȴ<EFBFBD>SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>0xFE
while(len--)//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
*buf=SPI2_ReadWriteByte(0xFF);
buf++;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>αCRC<52><43>dummy CRC<52><43>
SD_SPI_ReadWriteByte(0xFF);
SD_SPI_ReadWriteByte(0xFF);
return 0;//<2F><>ȡ<EFBFBD>ɹ<EFBFBD>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_SendCmd()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>sd<73><64>д<EFBFBD><D0B4>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 512<31>ֽ<EFBFBD> cmd:ָ<><D6B8>
* <09><> <20><> <20><>buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
* <20><> <20><> <20><>0,<2C>ɹ<EFBFBD>;<3B><><EFBFBD><EFBFBD><><CAA7>;
*********************************************************************************************************
*/
u8 SD_SendBlock(u8*buf,u8 cmd)
{
u16 t;
if(SD_WaitReady())return 1;//<2F>ȴ<EFBFBD>׼<EFBFBD><D7BC>ʧЧ
SD_SPI_ReadWriteByte(cmd);
if(cmd!=0XFD)//<2F><><EFBFBD>ǽ<EFBFBD><C7BD><EFBFBD>ָ<EFBFBD><D6B8>
{
for(t=0;t<512;t++)SPI2_ReadWriteByte(buf[t]);//<2F><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>,<2C><><EFBFBD>ٺ<EFBFBD><D9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
SD_SPI_ReadWriteByte(0xFF);//<2F><><EFBFBD><EFBFBD>crc
SD_SPI_ReadWriteByte(0xFF);
t=SD_SPI_ReadWriteByte(0xFF);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ
if((t&0x1F)!=0x05)return 2;//<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
}
return 0;//д<><D0B4><EFBFBD>ɹ<EFBFBD>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_SendCmd()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <09><> <20><> <20><>u8 cmd <20><><EFBFBD><EFBFBD> u32 arg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> u8 crc crcУ<63><D0A3>ֵ
* <20><> <20><> <20><>SD<53><44><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>Ӧ
*********************************************************************************************************
*/
u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
{
u8 r1;
u8 Retry=0;
SD_DisSelect();//ȡ<><C8A1><EFBFBD>ϴ<EFBFBD>Ƭѡ
if(SD_Select())return 0XFF;//ƬѡʧЧ
//<2F><><EFBFBD><EFBFBD>
SD_SPI_ReadWriteByte(cmd | 0x40);//<2F>ֱ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SD_SPI_ReadWriteByte(arg >> 24);
SD_SPI_ReadWriteByte(arg >> 16);
SD_SPI_ReadWriteByte(arg >> 8);
SD_SPI_ReadWriteByte(arg);
SD_SPI_ReadWriteByte(crc);
if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
//<2F>ȴ<EFBFBD><C8B4><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>˳<EFBFBD>
Retry=0X1F;
do
{
r1=SD_SPI_ReadWriteByte(0xFF);
}while((r1&0X80) && Retry--);
//<2F><><EFBFBD><EFBFBD>״ֵ̬
return r1;
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_GetCID()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>ȡSD<53><44><EFBFBD><EFBFBD>CID<49><44>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
* <09><> <20><> <20><>u8 *cid_data(<28><><EFBFBD><EFBFBD>CID<49><44><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD>16Byte<74><65>
* <20><> <20><> <20><>0<EFBFBD><30>NO_ERR 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
u8 SD_GetCID(u8 *cid_data)
{
u8 r1;
//<2F><>CMD10<31><30><EFBFBD><EFBFBD><EEA3AC>CID
r1=SD_SendCmd(CMD10,0,0x01);
if(r1==0x00)
{
r1=SD_RecvData(cid_data,16);//<2F><><EFBFBD><EFBFBD>16<31><36><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
}
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
if(r1)return 1;
else return 0;
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_GetCSD()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>ȡSD<53><44><EFBFBD><EFBFBD>CSD<53><44>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD>Ϣ
* <09><> <20><> <20><>u8 *cid_data(<28><><EFBFBD><EFBFBD>CID<49><44><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD>16Byte<74><65>
* <20><> <20><> <20><>0<EFBFBD><30>NO_ERR 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
u8 SD_GetCSD(u8 *csd_data)
{
u8 r1;
r1=SD_SendCmd(CMD9,0,0x01);//<2F><>CMD9<44><39><EFBFBD><EFBFBD><EEA3AC>CSD
if(r1==0)
{
r1=SD_RecvData(csd_data, 16);//<2F><><EFBFBD><EFBFBD>16<31><36><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
}
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
if(r1)return 1;
else return 0;
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_GetSectorCount()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>ȡSD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <09><> <20><> <20><><EFBFBD><EFBFBD>
* <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Capacity <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
u32 SD_GetSectorCount(void)
{
u8 csd[16];
u32 Capacity;
u8 n;
u16 csize;
//ȡCSD<53><44>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0
if(SD_GetCSD(csd)!=0) return 0;
//<2F><><EFBFBD><EFBFBD>ΪSDHC<48><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<E6B7BD><CABD><EFBFBD><EFBFBD>
if((csd[0]&0xC0)==0x40) //V2.00<EFBFBD>Ŀ<EFBFBD>
{
csize = csd[9] + ((u16)csd[8] << 8) + 1;
Capacity = (u32)csize << 10;//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}else//V1.XX<58>Ŀ<EFBFBD>
{
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
Capacity= (u32)csize << (n - 9);//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
return Capacity;
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_Initialize()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: SD<53><44><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
* <09><> <20><> <20><><EFBFBD><EFBFBD>
* <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
*********************************************************************************************************
*/
u8 SD_Initialize(void)
{
u8 r1; // <20><><EFBFBD><EFBFBD>SD<53><44><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>ֵ
u16 retry; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
u8 buf[4];
u16 i;
SD_SPI_Init(); //<2F><>ʼ<EFBFBD><CABC>IO
SD_SPI_SpeedLow(); //<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ģʽ
for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>74<37><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
retry=20;
do
{
r1=SD_SendCmd(CMD0,0,0x95);//<2F><><EFBFBD><EFBFBD>IDLE״̬
}while((r1!=0X01) && retry--);
SD_Type=0;//Ĭ<><C4AC><EFBFBD>޿<EFBFBD>
if(r1==0X01)
{
if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
{
for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF); //Get trailing return value of R7 resp
if(buf[2]==0X01&&buf[3]==0XAA)//<2F><><EFBFBD>Ƿ<EFBFBD>֧<EFBFBD><D6A7>2.7~3.6V
{
retry=0XFFFE;
do
{
SD_SendCmd(CMD55,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD55
r1=SD_SendCmd(CMD41,0x40000000,0X01);//<2F><><EFBFBD><EFBFBD>CMD41
}while(r1&&retry--);
if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//<2F><><EFBFBD><EFBFBD>SD2.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ
{
for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//<2F>õ<EFBFBD>OCRֵ
if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //<2F><><EFBFBD><EFBFBD>CCS
else SD_Type=SD_TYPE_V2;
}
}
}else//SD V1.x/ MMC V3
{
SD_SendCmd(CMD55,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD55
r1=SD_SendCmd(CMD41,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD41
if(r1<=1)
{
SD_Type=SD_TYPE_V1;
retry=0XFFFE;
do //<2F>ȴ<EFBFBD><C8B4>˳<EFBFBD>IDLEģʽ
{
SD_SendCmd(CMD55,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD55
r1=SD_SendCmd(CMD41,0,0X01);//<2F><><EFBFBD><EFBFBD>CMD41
}while(r1&&retry--);
}else
{
SD_Type=SD_TYPE_MMC;//MMC V3
retry=0XFFFE;
do //<2F>ȴ<EFBFBD><C8B4>˳<EFBFBD>IDLEģʽ
{
r1=SD_SendCmd(CMD1,0,0X01);//<2F><><EFBFBD><EFBFBD>CMD1
}while(r1&&retry--);
}
if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//<2F><><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>
}
}
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
SD_SPI_SpeedHigh();//<2F><><EFBFBD><EFBFBD>
if(SD_Type)
return 0;
else if(r1)
return r1;
return 0xaa;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_ReadDisk()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <09><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD> buf <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>sector <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cnt
* <20><> <20><> <20><>r1 0,ok;<3B><><EFBFBD><EFBFBD><><CAA7>.
*********************************************************************************************************
*/
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
{
u8 r1;
if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//ת<><D7AA>Ϊ<EFBFBD>ֽڵ<D6BD>ַ
if(cnt==1)
{
r1=SD_SendCmd(CMD17,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(r1==0)//ָ<><EFBFBD>ͳɹ<CDB3>
{
r1=SD_RecvData(buf,512);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
}
}else
{
r1=SD_SendCmd(CMD18,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
do
{
r1=SD_RecvData(buf,512);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
buf+=512;
}while(--cnt && r1==0);
SD_SendCmd(CMD12,0,0X01); //<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
}
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
return r1;//
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SD_WriteDisk()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: <20><>SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
* <09><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> buf <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>sector <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cnt
* <20><> <20><> <20><>r1 0,ok;<3B><><EFBFBD><EFBFBD><><CAA7>.
*********************************************************************************************************
*/
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
{
u8 r1;
if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//ת<><D7AA>Ϊ<EFBFBD>ֽڵ<D6BD>ַ
if(cnt==1)
{
r1=SD_SendCmd(CMD24,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(r1==0)//ָ<><EFBFBD>ͳɹ<CDB3>
{
r1=SD_SendBlock(buf,0xFE);//д512<31><32><EFBFBD>ֽ<EFBFBD>
}
}else
{
if(SD_Type!=SD_TYPE_MMC)
{
SD_SendCmd(CMD55,0,0X01);
SD_SendCmd(CMD23,cnt,0X01);//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
}
r1=SD_SendCmd(CMD25,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(r1==0)
{
do
{
r1=SD_SendBlock(buf,0xFC);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
buf+=512;
}while(--cnt && r1==0);
r1=SD_SendBlock(0,0xFD);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
}
}
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
return r1;//
}
/***************************** END OF FILE *********************************************************************/

View File

@ -0,0 +1,78 @@
#ifndef _SPI_SD_DRIVER_H_
#define _SPI_SD_DRIVER_H_
#include "stm32l1xx.h" //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ͷ<EFBFBD>ļ<EFBFBD>
#include "bsp.h"
//typedef uint32_t u32;
//typedef uint16_t u16;
//typedef uint8_t u8;
/* Private define ------------------------------------------------------------*/
/* SPI<50><49><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD><EFBFBD>*/
#define SPI_SPEED_LOW 0
#define SPI_SPEED_HIGH 1
// SD<53><44><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
#define SD_TYPE_ERR 0X00
#define SD_TYPE_MMC 0X01
#define SD_TYPE_V1 0X02
#define SD_TYPE_V2 0X04
#define SD_TYPE_V2HC 0X06
// SD<53><44>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>
#define CMD0 0 //<2F><><EFBFBD><EFBFBD>λ
#define CMD1 1
#define CMD8 8 //<2F><><EFBFBD><EFBFBD>8 <20><>SEND_IF_COND
#define CMD9 9 //<2F><><EFBFBD><EFBFBD>9 <20><><EFBFBD><EFBFBD>CSD<53><44><EFBFBD><EFBFBD>
#define CMD10 10 //<2F><><EFBFBD><EFBFBD>10<31><30><EFBFBD><EFBFBD>CID<49><44><EFBFBD><EFBFBD>
#define CMD12 12 //<2F><><EFBFBD><EFBFBD>12<31><32>ֹͣ<CDA3><D6B9><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>
#define CMD16 16 //<2F><><EFBFBD><EFBFBD>16<31><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SectorSize Ӧ<><D3A6><EFBFBD><EFBFBD>0x00
#define CMD17 17 //<2F><><EFBFBD><EFBFBD>17<31><37><EFBFBD><EFBFBD>sector
#define CMD18 18 //<2F><><EFBFBD><EFBFBD>18<31><38><EFBFBD><EFBFBD>Multi sector
#define CMD23 23 //<2F><><EFBFBD><EFBFBD>23<32><33><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>sectorд<72><D0B4>ǰԤ<C7B0>Ȳ<EFBFBD><C8B2><EFBFBD>N<EFBFBD><4E>block
#define CMD24 24 //<2F><><EFBFBD><EFBFBD>24<32><34>дsector
#define CMD25 25 //<2F><><EFBFBD><EFBFBD>25<32><35>дMulti sector
#define CMD41 41 //<2F><><EFBFBD><EFBFBD>41<34><31>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>0x00
#define CMD55 55 //<2F><><EFBFBD><EFBFBD>55<35><35>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>0x01
#define CMD58 58 //<2F><><EFBFBD><EFBFBD>58<35><38><EFBFBD><EFBFBD>OCR<43><52>Ϣ
#define CMD59 59 //<2F><><EFBFBD><EFBFBD>59<35><39>ʹ<EFBFBD><CAB9>/<2F><>ֹCRC<52><43>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>0x00
//<2F><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
//SD<53><44><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MSD_RESPONSE_NO_ERROR 0x00
#define MSD_IN_IDLE_STATE 0x01
#define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04
#define MSD_COM_CRC_ERROR 0x08
#define MSD_ERASE_SEQUENCE_ERROR 0x10
#define MSD_ADDRESS_ERROR 0x20
#define MSD_PARAMETER_ERROR 0x40
#define MSD_RESPONSE_FAILURE 0xFF
//<2F>ⲿ<EFBFBD><E2B2BF>Ӧ<EFBFBD><D3A6><EFBFBD>ݾ<EFBFBD><DDBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>!
//Mini STM32ʹ<32>õ<EFBFBD><C3B5><EFBFBD>PA3<41><33>ΪSD<53><44><EFBFBD><EFBFBD>CS<43><53>.
#define SD_CS_ENABLE() GPIO_ResetBits(GPIOC,GPIO_Pin_6) //ѡ<><D1A1>SD<53><44>
#define SD_CS_DISABLE() GPIO_SetBits(GPIOC,GPIO_Pin_6) //<2F><>ѡ<EFBFBD><D1A1>SD<53><44>
extern u8 SD_Type;//SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Private function prototypes -----------------------------------------------*/
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void SD_SPI_Init(void);
u8 SD_SPI_ReadWriteByte(u8 data);
void SD_SPI_SpeedLow(void);
void SD_SPI_SpeedHigh(void);
u8 SD_WaitReady(void); //<2F>ȴ<EFBFBD>SD<53><44>׼<EFBFBD><D7BC>
u8 SD_Select(void);
u8 SD_GetResponse(u8 Response); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ
u8 SD_Initialize(void); //<2F><>ʼ<EFBFBD><CABC>
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt); //<2F><><EFBFBD><EFBFBD>
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt); //д<><D0B4>
u32 SD_GetSectorCount(void); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
u8 SD_GetCID(u8 *cid_data); //<2F><>SD<53><44>CID
u8 SD_GetCSD(u8 *csd_data); //<2F><>SD<53><44>CSD
#endif

View File

@ -0,0 +1,101 @@
/*
*************************************************************
ͷ<>ļ<EFBFBD>
*************************************************************
*/
#include "spi.h"
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SPI2_Init()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: SPI2<49><32>ʼ<EFBFBD><CABC>
* <09><> <20><> <20><><EFBFBD><EFBFBD>
* <20><> <20><> <20><><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
// /* Enable SCK, MOSI and MISO GPIO clocks */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//<2F><><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//<2F><><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_6);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//<2F><><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
/* SPI configuration -------------------------------------------------------*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI<50><49><EFBFBD><EFBFBD>Ϊ˫<CEAA><CBAB>˫<EFBFBD><CBAB>ȫ˫<C8AB><CBAB>
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //<2F><><EFBFBD><EFBFBD>SPI<50><49><EFBFBD><EFBFBD>ģʽ:<3A><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>spi
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE); //ʹ<><CAB9>SPI<50><49><EFBFBD><EFBFBD>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SPI2_SetSpeed()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: SPI2<49>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
* <09><> <20><> <20><>SpeedSet:0~7
* <20><> <20><> <20><><EFBFBD><EFBFBD>
*********************************************************************************************************
*/
void SPI2_SetSpeed(u8 SpeedSet)
{
SpeedSet&=0X07; //<2F><><EFBFBD>Ʒ<EFBFBD>Χ
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SpeedSet<<3; //<2F><><EFBFBD><EFBFBD>SPI2<49>ٶ<EFBFBD>
SPI2->CR1|=1<<6; //SPI<50>ʹ<E8B1B8><CAB9>
}
/*
*********************************************************************************************************
* <09><> <20><> <20><>: SPI2_ReadWriteByte()
* <09><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>: SPI2<49><32>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
* <09><> <20><> <20><>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TxData
* <20><> <20><> <20><>SPI2->DR;
*********************************************************************************************************
*/
u8 SPI2_ReadWriteByte(u8 TxData)
{
u16 retry=0;
while((SPI2->SR&1<<1)==0) //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
retry++;
if(retry>=0XFFFE)return 0; //<2F><>ʱ<EFBFBD>˳<EFBFBD>
}
SPI2->DR=TxData; //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>byte
retry=0;
while((SPI2->SR&1<<0)==0) //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>byte
{
retry++;
if(retry>=0XFFFE)return 0; //<2F><>ʱ<EFBFBD>˳<EFBFBD>
}
return SPI2->DR; //<2F><><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
/***************************** END OF FILE *********************************************************************/

View File

@ -0,0 +1,58 @@
#ifndef __SPI_H
#define __SPI_H
#include "stm32l1xx.h"
#include "stm32l1xx_gpio.h"
#include "stm32l1xx_spi.h"
#include "stm32l1xx_rcc.h"
// SPI<50><49><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD><EFBFBD>
#define SPI_SPEED_2 0
#define SPI_SPEED_4 1
#define SPI_SPEED_8 2
#define SPI_SPEED_16 3
#define SPI_SPEED_32 4
#define SPI_SPEED_64 5
#define SPI_SPEED_128 6
#define SPI_SPEED_256 7
#define u8 uint8_t
#define u16 uint16_t
void SPI2_Port_Init(void);
void SPI2_Init(void); //<2F><>ʼ<EFBFBD><CABC>SPI2<49><32>
void SPI2_SetSpeed(uint8_t SpeedSet); //<2F><><EFBFBD><EFBFBD>SPI2<49>ٶ<EFBFBD>
uint8_t SPI2_ReadWriteByte(uint8_t TxData);//SPI2<49><32><EFBFBD>߶<EFBFBD>дһ<D0B4><D2BB><EFBFBD>ֽ<EFBFBD>
#endif