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

📄 sd.c

📁 一个基于ATmega64、VS1003、SD卡的mp3播放程序
💻 C
字号:
//***************************************************
#include "includes.h"
#include "SD.h"

#define SD_WRITE PORTB
#define SD_READ PINB
#define SD_CLOCK 1
#define SD_DO 2


//***************************************************
//函数名称:SD_SPI_Low()
//函数功能:设置SPI为低速模式
//输入:无
//输出:无
//说明:以Fosc/128 SCK频率运行
//***************************************************

void SD_SPI_Low(void)
{
	SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);
	SPSR&=~(1<<SPI2X);
}

//***************************************************
//函数名称:SD_SPI_High()
//函数功能:设置SPI为高速模式
//输入:无
//输出:无
//说明:以Fosc/2 SCK频率运行
//***************************************************

void SD_SPI_High(void)
{
	SPCR=(1<<SPE)|(1<<MSTR);
	SPSR|=(1<<SPI2X);
}

//***************************************************
//函数名称:SD_SPI_Init()
//函数功能:SPI端口初始化并置为低速模式
//输入:无
//输出:无
//***************************************************

void SD_SPI_Init(void)
{
	SPI_PORT_INIT();
	SD_SPI_Low();
}

//***************************************************
//函数名称:SD_Init()
//函数功能:SD端口初始化
//输入:无
//输出:无
//***************************************************

void SD_Init(void)
{
	SD_SPI_Init();
	SD_Disable();
}

//***************************************************
//函数名称:SD_SPI_WriteByte(unsigned char val)
//函数功能:SPI发送或读取一个字节
//输入:val:将发送的字节
//输出:读取到的一字节
//***************************************************

unsigned char SD_SPI_WriteByte(unsigned char val)
{
	SPDR=val;
	while(!(SPSR&(1<<SPIF)));
	return SPDR;
}

//***************************************************
//函数名称:SD_SendCommand(unsigned char cmd,unsigned long arg)
//函数功能:向SD写入命令
//输入:cmd:命令代码  arg:命令参数
//输出:1字节的响应
//***************************************************
unsigned char SD_SendCommand(unsigned char cmd,unsigned long arg)
{
	unsigned char r1;
	unsigned char retry=0;
	PORTG=0XFF;
	SD_SPI_WriteByte(0xff);
	SD_Enable();
	SD_SPI_WriteByte(cmd|0x40);//分别写入命令
	SD_SPI_WriteByte(arg>>24);
	SD_SPI_WriteByte(arg>>16);
	SD_SPI_WriteByte(arg>>8);
	SD_SPI_WriteByte(arg);
	SD_SPI_WriteByte(0x95);
	while((r1=SD_SPI_WriteByte(0xff))==0xff)//等待响应
		if(retry++>0xfe)break;//超时退出
	SD_Disable();
	SD_SPI_WriteByte(0xff);	
	PORTG=0X00;
	return r1;//返回状态值
}
//***************************************************
//函数名称:SD_Reset()
//函数功能:SD卡的软件复位
//输入:无
//输出:复位结果:0正常复位,1超时退出
//***************************************************
unsigned char SD_Reset(void)
{
	unsigned char i;
	unsigned char retry;
	unsigned char r1=0;
	retry=0;
	SD_SPI_Low();
	do
	{
		for(i=0;i<10;i++)SD_SPI_WriteByte(0xff);
		r1=SD_SendCommand(0,0);//发idle命令
		retry++;
		if(retry>0xfe)return 1;//超时退出
	}while(r1!=0x01);
	retry=0;
	do
	{
		r1=SD_SendCommand(1,0);//发active命令
		retry++;
		if(retry>0xfe)return 1;//超时退出
	}while(r1);
	SD_SPI_High();
	r1=SD_SendCommand(59,0);//关闭CRC功能
	r1=SD_SendCommand(16,512);//设扇区大小512	
	return 0;//正常返回
}
//***************************************************
//函数名称:SD_Read_One_Sector(unsigned long sector)
//函数功能:SD卡单块读操作
//输入:sector:4字节块起始地址 buffer:512字节数据缓冲区首址
//输出:操作结果:0:正常读取 1:超时或1字节的响应
//***************************************************
unsigned char SD_Read_One_Sector(unsigned long sector)
{
	unsigned char r1;
	unsigned int i;
	unsigned int retry=0;
	PORTG=0XFF;
	r1=SD_SendCommand(17,sector<<9);//读命令	
	if(r1!=0x00)return r1;
	SD_Enable();
	while(SD_SPI_WriteByte(0xff)!=0xfe)//等数据的开始
	if(retry++>0xfffe){SD_Disable();return 1;}
	for(i=0;i<512;i++)//读512个数据	
	{
		Sector_Buffer[i]=SD_SPI_WriteByte(0xff);
	}
	SD_SPI_WriteByte(0xff);//伪CRC
	SD_SPI_WriteByte(0xff);
	SD_Disable();
	SD_SPI_WriteByte(0xff);//额外8个时钟
	PORTG=0X00;
	return 0;
}
//***************************************************
//函数名称:SD_Write_One_Sector(unsigned long sector)
//函数功能:SD卡写一扇区数据
//输入:sector:4字节块起始地址
//输出:操作结果:0:正常写入 1:超时或1字节的响应
//说明:写入数据为长度为512字节的Sector_Buffer缓冲区
//***************************************************

unsigned char SD_Write_One_Sector(unsigned long sector)
{
	unsigned char r1;
	unsigned int i;
	unsigned int retry=0;
	r1=SD_SendCommand(24,sector<<9);//写命令
	if(r1!=0x00)return r1;
	SD_Enable();
	SD_SPI_WriteByte(0xff);
	SD_SPI_WriteByte(0xff);
	SD_SPI_WriteByte(0xff);
	SD_SPI_WriteByte(0xfe);//发送开始符
	for(i=0;i<512;i++)//送512字节数据
	{
		SD_SPI_WriteByte(Sector_Buffer[i]);
	}
	SD_SPI_WriteByte(0xff);			//虚拟CRC
	SD_SPI_WriteByte(0xff);
	r1=SD_SPI_WriteByte(0xff);
	if((r1&0x1f)!=0x05)//等待是否成功
	{
		SD_Disable();
		return r1;
	}
	while(!SD_SPI_WriteByte(0xff))//等待操作完成
	    if(retry++>0xfffe){SD_Disable();return 1;}
	SD_Disable();
	SD_SPI_WriteByte(0xff);//额外8个时钟
	return 0;
}

//***************************************************
//函数名称:SD_Read_Capacity(void)
//函数功能:获取SD的总容量
//输入:无
//输出:4字节容量
//说明://memorycapacity=BLOCKNR*BLOCK_LEN
//	BLOCKNR=(C_SIZE+1)*MULT
//  MULT = 2^(C_SIZE_MULT+2)
//	BLOCK_LEN = 2^READ_BL_LEN
//***************************************************

unsigned long SD_Read_Capacity(void)
{
	unsigned char r1;
	unsigned int i;
	unsigned int temp;
	unsigned char buffer[16];
	unsigned long Capacity;
	unsigned int retry=0;
	r1=SD_SendCommand(9,0);//写命令
	if(r1!=0x00)return r1;
	SD_Enable();
	while(SD_SPI_WriteByte(0xff)!=0xfe)
	    if(retry++>0xfffe){SD_Disable();return 1;}
    for(i=0;i<16;i++)
	{
		buffer[i]=SD_SPI_WriteByte(0xff);
	}
	SD_SPI_WriteByte(0xff);
	SD_SPI_WriteByte(0xff);
	SD_SPI_WriteByte(0xff);
	SD_Disable();
	SD_SPI_WriteByte(0xff);//额外8个时钟
//*********************************
//获取C_SIZE
	i=buffer[6]&0x03;
	i<<=8;
	i+=buffer[7];
	i<<=2;
	i+=((buffer[8]&0xc0)>>6);
//**********************************
//获取C_SIZE_MULT
	r1=buffer[9]&0x03;
	r1<<=1;
	r1+=((buffer[10]&0x80)>>7);
//**********************************
//获取BLOCKNR
	r1+=2;
	temp=1;
	while(r1)
	{
		temp*=2;
		r1--;
	}
	Capacity=((unsigned long)(i+1))*((unsigned long)temp);
//**********************************
//获取READ_BL_LEN
	i=buffer[5]&0x0f;
//*************************
//获取BLOCK_LEN
	temp=1;
	while(i)
	{
		temp*=2;
		i--;
	}
//************************
//最终结果
	Capacity*=(unsigned long)temp;	 
	return Capacity;		
}

⌨️ 快捷键说明

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