标题:
单片机读写sd卡例程与电路原理图
[打印本页]
作者:
lean96
时间:
2018-4-16 19:47
标题:
单片机读写sd卡例程与电路原理图
51单片机读写sd卡例程分享给大家
电路原理图如下:
0.jpg
(32.3 KB, 下载次数: 56)
下载附件
2018-4-17 03:03 上传
单片机源程序如下:
/**************************************************************************************
//------------------ MMC/SD-Card Reading and Writing implementation -------------------
****************************************************************************************/
sbit SPI_DI =P2^1;
sbit SPI_DO =P2^5;
sbit SPI_SCL=P2^2;
sbit SPI_CS =P2^0;
//------------------------------------------------------------
// Error define
//-------------------------------------------------------------
#define INIT_CMD0_ERROR 0x01
#define INIT_CMD1_ERROR 0x02
#define WRITE_BLOCK_ERROR 0x03
#define READ_BLOCK_ERROR 0x04
//-------------------------------------------------------------
// data type
//-------------------------------------------------------------
// this structure holds info on the MMC card currently inserted
typedef struct MMC_VOLUME_INFO
{ //MMC/SD Card info
unsigned int size_MB;
unsigned char sector_multiply;
unsigned int sector_count;
unsigned char name[6];
} VOLUME_INFO_TYPE;
typedef struct STORE
{
unsigned char dat[100];
} BUFFER_TYPE; //256 bytes, 128 words
BUFFER_TYPE sectorBuffer; //512 bytes for sector buffer
//--------------------------------------------------------------
unsigned int readPos=0;
unsigned char sectorPos=0;
unsigned char LBA_Opened=0; //Set to 1 when a sector is opened.
unsigned char Init_Flag; //Set it to 1 when Init is processing.
//---------------------------------------------------------------
void delay(unsigned int time)
{
while(time--);
}
//****************************************************************************
// Port Init
void MMC_Port_Init()
//****************************************************************************
{
SPI_SCL=1;
SPI_DO =1;
SPI_CS=1;
send_s("Port Init!");
/*
//Config ports
SPI_DI=1; //Set Pin MMC_DI as Input
SPI_SCL=1; //Set Pin MMC_Clock as Output
SPI_DO=1; //Set Pin MMC_DO as Output
SPI_CS=1; //Set MMC_Chip_Select to High,MMC/SD Invalid.
//busy led port init
//SPI_BY=1; //Set spi busy led port output
//MMC_BUSY_LED=1; //busy led off
*/
}
//****************************************************************************
//Routine for sending a byte to MMC/SD-Card
void Write_Byte_MMC(unsigned char value)
//****************************************************************************
{
unsigned char i;
//Software SPI
for (i=0;i<8;i++)
{ //write a byte
if (((value>>(7-i))&0x01)==0x01)
SPI_DI=1; //Send bit by bit(MSB First)
else SPI_DI=0;
SPI_SCL=0; //set Clock Impuls low
if(Init_Flag)
delay(9);
SPI_SCL=1; //set Clock Impuls High
if(Init_Flag)
delay(9);
}//write a byte
//MMC_BUSY_LED=1;
}
//****************************************************************************
//Routine for reading a byte from MMC/SD-Card
unsigned char Read_Byte_MMC()
//****************************************************************************
{
unsigned char temp=0;
unsigned char i;
//Software SPI
for (i=0;i<8;i++) //MSB First
{
SPI_DO=1;
SPI_SCL=0; //Clock Impuls (Low)
if(Init_Flag)
delay(9);
temp=(temp<<1)+(unsigned char)SPI_DO; //read mmc data out pin
SPI_SCL=1; //set Clock Impuls High
if(Init_Flag)
delay(9);
}
return (temp);
}
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
unsigned char Write_Command_MMC(unsigned char *CMD)
//****************************************************************************
{
unsigned char tmp;
unsigned char retry=0;
unsigned char i;
//set MMC_Chip_Select to high (MMC/SD-Card disable)
SPI_CS=1;
//send 8 Clock Impulse
Write_Byte_MMC(0xFF);
//set MMC_Chip_Select to low (MMC/SD-Card active)
SPI_CS=0;
//send 6 Byte Command to MMC/SD-Card
for (i=0;i<0x06;i++)
{
Write_Byte_MMC(*CMD++);
}
//get 16 bit response
Read_Byte_MMC(); //read the first byte,ignore it.
do
{ //Only last 8 bit is used here.Read it out.
tmp = Read_Byte_MMC();
retry++;
}
while((tmp==0xff)&&(retry<100));
return(tmp);
}
//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
unsigned char MMC_Init()
//****************************************************************************
{
unsigned char retry,temp;
unsigned char i;
unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
send_s("SD CARD Init!");
MMC_Port_Init(); //Init SPI port
delay(200);
Init_Flag=1; //Set the init flag
for (i=0;i<0x0f;i++)
{
Write_Byte_MMC(0xff); //send 74 clock at least!!!
}
//Send Command CMD0 to MMC/SD Card
send_s("Send Command CMD0 to MMC/SD Card");
retry=0;
do
{ //retry 200 times to send CMD0 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==200)
{ //time out
return(INIT_CMD0_ERROR);//CMD0 Error!
}
}
while(temp!=1);
//Send Command CMD1 to MMC/SD-Card
send_s("Send Command CMD1 to MMC/SD-Card");
CMD[0] = 0x41; //Command 1
CMD[5] = 0xFF;
retry=0;
do
{ //retry 100 times to send CMD1 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{ //time out
return(INIT_CMD1_ERROR);//CMD1 Error!
}
}
while(temp!=0);
Init_Flag=0; //Init is completed,clear the flag
SPI_CS=1; //set MMC_Chip_Select to high
send_s("SD CARD Init Suc!!");
return(0x55); //All commands have been taken.
}
//****************************************************************************
//Routine for reading data Registers of MMC/SD-Card
//Return 0 if no Error.
unsigned char MMC_Read_Block(unsigned char *CMD,unsigned char *Buffer,unsigned int Bytes)
//****************************************************************************
{
unsigned int i;
unsigned retry,temp;
//Send Command CMD to MMC/SD-Card
retry=0;
do
{ //Retry 100 times to send command.
temp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{
return(READ_BLOCK_ERROR); //block write Error!
}
}
while(temp!=0);
//Read Start Byte form MMC/SD-Card (FEh/Start Byte)
while (Read_Byte_MMC()!=0xfe);
//Write blocks(normal 512Bytes) to MMC/SD-Card
for (i=0;i<Bytes;i++)
{
*Buffer++ = Read_Byte_MMC();
}
//CRC-Byte
Read_Byte_MMC();//CRC - Byte
Read_Byte_MMC();//CRC - Byte
//set MMC_Chip_Select to high (MMC/SD-Card invalid)
SPI_CS=1;
return(0);
}
//***************************************************************************
//Routine for reading CSD Registers from MMC/SD-Card (16Bytes)
//Return 0 if no Error.
unsigned char Read_CSD_MMC(unsigned char *Buffer)
//***************************************************************************
{
//Command for reading CSD Registers
unsigned char CMD[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
unsigned char temp;
temp=MMC_Read_Block(CMD,Buffer,16); //read 16 bytes
return(temp);
}
//***************************************************************************
//Routine for reading CID Registers from MMC/SD-Card (16Bytes)
//Return 0 if no Error.
unsigned char Read_CID_MMC(unsigned char *Buffer)
//***************************************************************************
{
//Command for reading CID Registers
unsigned char CMD[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
unsigned char temp;
temp=MMC_Read_Block(CMD,Buffer,16); //read 16 bytes
return(temp);
}
//****************************************************************************
//returns the :
// size of the card in MB ( ret * 1024^2) == bytes
// sector count and multiplier MB are in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
// name of the media
void MMC_get_volume_info(void)
//****************************************************************************
{ unsigned char i;
unsigned char c_temp[5];
VOLUME_INFO_TYPE MMC_volume_Info,*vinf;
send_s("SD CARD Information Read!!");
vinf=&MMC_volume_Info; //Init the pointoer;
// read the CSD register
Read_CSD_MMC(sectorBuffer.dat);
// get the C_SIZE value. bits [73:62] of data
// [73:72] == sectorBuffer.data[6] && 0x03
// [71:64] == sectorBuffer.data[7]
// [63:62] == sectorBuffer.data[8] && 0xc0
vinf->sector_count = sectorBuffer.dat[6] & 0x03;
vinf->sector_count <<= 8;
vinf->sector_count += sectorBuffer.dat[7];
vinf->sector_count <<= 2;
vinf->sector_count += (sectorBuffer.dat[8] & 0xc0) >> 6;
// get the val for C_SIZE_MULT. bits [49:47] of sectorBuffer.data
// [49:48] == sectorBuffer.data[5] && 0x03
// [47] == sectorBuffer.data[4] && 0x80
vinf->sector_multiply = sectorBuffer.dat[9] & 0x03;
vinf->sector_multiply <<= 1;
vinf->sector_multiply += (sectorBuffer.dat[10] & 0x80) >> 7;
// work out the MBs
// mega bytes in u08 == C_SIZE / (2^(9-C_SIZE_MULT))
vinf->size_MB = vinf->sector_count >> (9-vinf->sector_multiply);
// get the name of the card
Read_CID_MMC(sectorBuffer.dat);
vinf->name[0] = sectorBuffer.dat[3];
vinf->name[1] = sectorBuffer.dat[4];
vinf->name[2] = sectorBuffer.dat[5];
vinf->name[3] = sectorBuffer.dat[6];
vinf->name[4] = sectorBuffer.dat[7];
vinf->name[5] = 0x00; //end flag
//----------------------------------------------------------
/*
while(1)
{
P1=~(unsigned char)((vinf->size_MB)>>8);
delay(50000);
delay(50000);
delay(50000);
delay(50000);
delay(50000);
P1=~(unsigned char)((vinf->size_MB));
delay(50000);
delay(50000);
delay(50000);
delay(50000);
delay(50000);
}*/
//LCDclrscr();
//Print Product name on lcd
i=0;
send_s("Product Name:");
//while((vinf->name[i]!=0x00)&&(i<16)) send(vinf->name[i++]);
send_s(vinf->name);
//Print Card Size(eg:128MB)
//gotoxy(1,0);
send_s("Tot:");
send_s(ftoa(vinf->size_MB,c_temp,0));
send_s("MB ");
//gotoxy(2,0);
//writestring("sector_mult:"); writeNumber(vinf->sector_multiply);
//gotoxy(3,0);
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
SD卡模块.rar
(277.79 KB, 下载次数: 52)
2018-4-16 19:47 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
a461624201
时间:
2018-7-30 11:36
不知道为什么,到了Send Command CMD0 to MMC/SD Card 后,就没见发送CMD1命令?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1