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

📄 mmc_sd.c

📁 用LPC2103(ARM7)操作SD卡代码。
💻 C
字号:
/*************************************************************/
/*                   SD/MMC操作函数库                        */
/*  环境WinAVR 20060421                                      */
/*  作者:Bozai(章其波)                                    */
/*  E-mail:sudazqb@163.com                                  */
/*  2006年11月26日                                           */
/*************************************************************/





#include "lpc2103.h"
#include "MMC_SD.h"

#define MMC_SD_CS_PIN     1<<18
#define SPI_CS_Assert()   IOCLR |= SPI_CS 
#define SPI_CS_Deassert() IOSET |= SPI_CS
#define SPI_CS MMC_SD_CS_PIN
//低速模式
void SPI_Low(void)
{
	//PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500;		// 设置管脚连接SPI
	//PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x15 << 8) ;	// SSEL0当作595片选
    S0SPCCR = 0xD2;		            	// 设置SPI时钟分频
    S0SPCR  = (0 << 3) |				// CPHA = 0, 数据在SCK 的第一个时钟沿采样
              (1 << 4) |				// CPOL = 1, SCK 为低有效
              (1 << 5) |				// MSTR = 1, SPI 处于主模式
              (0 << 6) |				// LSBF = 0, SPI 数据传输MSB (位7)在先
              (0 << 7);					// SPIE = 0, SPI 中断被禁止
}

//高速模式
void SPI_High(void)
{
	//PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500;		// 设置管脚连接SPI
	//PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x15 << 8) ;	// SSEL0当作595片选
    S0SPCCR = 0x52;		            	// 设置SPI时钟分频
 	S0SPCR  = (0 << 3) |				// CPHA = 0, 数据在SCK 的第一个时钟沿采样
 			  (1 << 4) |				// CPOL = 1, SCK 为低有效
 			  (1 << 5) |				// MSTR = 1, SPI 处于主模式
 			  (0 << 6) |				// LSBF = 0, SPI 数据传输MSB (位7)在先
 			  (0 << 7);					// SPIE = 0, SPI 中断被禁止
}
//端口初始化,模式初始化
void SPI_Init(void)
{
	PINSEL0 |= 0x00001500;								// 设置SPI管脚连接-SSEL0当作595片选,故不作SPI管脚
	PINSEL1 |= 0x00000000;
	IODIR   |= SPI_CS;
   	IOSET	|= SPI_CS;
}

//写读一个字节
U8 SPI_WriteByte(U8 val)
{
        //IOCLR |= SPI_CS;			    		// 片选
   
	S0SPDR = val;
	while(0 == (S0SPSR & 0x80));		// 等待SPIF置位,即等待数据发送完毕
   
	//IOSET = SPI_CS;
	return(S0SPDR);
}

/*U8 SPI_ReadByte(void)
{
	SPDR = 0xff;
	while(!(SPSR & _BV(SPIF)));
	return SPDR;
}*/
//sd卡初始化
void MMC_SD_Init(void)
{
	SPI_Init();
        
	SPI_CS_Deassert();
}

//sd卡写命令
U8 MMC_SD_SendCommand(U8 cmd, U32 arg)
{
	U8 r1;
	U8 retry=0;
	
	SPI_WriteByte(0xff);
	SPI_CS_Assert();
	
	SPI_WriteByte(cmd | 0x40);//分别写入命令
	SPI_WriteByte(arg>>24);
	SPI_WriteByte(arg>>16);
	SPI_WriteByte(arg>>8);
	SPI_WriteByte(arg);
	SPI_WriteByte(0x95);
	
	while((r1 = SPI_WriteByte(0xff)) == 0xff)//等待响应,
		if(retry++ > 8) break;//超时退出

	SPI_CS_Deassert();

	return r1;//返回状态值
}

//sd卡复位
U8 MMC_SD_Reset(void)
{
	U8 i;
	U8 retry;
	U8 r1=0;
	retry = 0;
	SPI_Low();
	do
	{
		for(i=0;i<10;i++) SPI_WriteByte(0xff);
		r1 = MMC_SD_SendCommand(0, 0);//发idle命令
		retry++;
		if(retry>10) return 1;//超时退出
	} while(r1 != 0x01);


	retry = 0;
	do
	{
		r1 = MMC_SD_SendCommand(1, 0);//发active命令
		retry++;
		if(retry>100) return 1;//超时退出
	} while(r1);
	SPI_High();
	r1 = MMC_SD_SendCommand(59, 0);//关crc

	r1 = MMC_SD_SendCommand(16, 512);//设扇区大小512

	return 0;//正常返回
}

//读一个扇区
U8 MMC_SD_ReadSingleBlock(U32 sector, U8* buffer)
{
	U8 r1;
	U16 i;
	//U8 retry=0;

	r1 = MMC_SD_SendCommand(17, sector<<9);//读命令
	
	if(r1 != 0x00)
		return r1;

	SPI_CS_Assert();
	//等数据的开始
	while(SPI_WriteByte(0xff) != 0xfe);//if(retry++ > 50){SPI_CS_Deassert();return 1;}

	for(i=0; i<512; i++)//读512个数据
	{
		*buffer++ = SPI_WriteByte(0xff);
	}

	SPI_WriteByte(0xff);//伪crc
	SPI_WriteByte(0xff);
	
	SPI_CS_Deassert();

	return 0;
}


//写一个扇区
U8 MMC_SD_WriteSingleBlock(U32 sector, U8* buffer)
{
	U8 r1;
	U16 i;
	//U8 retry=0;

	r1 = MMC_SD_SendCommand(24, sector<<9);//写命令
	if(r1 != 0x00)
		return r1;

	SPI_CS_Assert();
	
	SPI_WriteByte(0xff);
	SPI_WriteByte(0xff);
	SPI_WriteByte(0xff);

	SPI_WriteByte(0xfe);//发开始符
	
	for(i=0; i<512; i++)//送512字节数据
	{
		SPI_WriteByte(*buffer++);
	}
	
	SPI_WriteByte(0xff);
	SPI_WriteByte(0xff);
	
	r1 = SPI_WriteByte(0xff);
	
	if( (r1&0x1f) != 0x05)//等待是否成功
	{
		SPI_CS_Deassert();
		return r1;
	}
	//等待操作完
	while(!SPI_WriteByte(0xff));//if(retry++ > 50){SPI_CS_Deassert();return 1;}

	SPI_CS_Deassert();

	return 0;
}

⌨️ 快捷键说明

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