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

📄 sd.c

📁 avr+TFT+SD卡实现数码相框功能
💻 C
字号:
//*****************************************************************************
//
// File Name	: 'sd.c'
// Title		: SD Flash Card Interface
// Author		: Andy Zhu - Copyright (C) 2008.7
// Created		: 2008.07.20
// Revised		: 2008.07.20
// Version		: 0.1
// Target MCU	: Atmel AVR mega128
//
//*****************************************************************************
#include <avr/io.h>
#include <stdint.h>
#include "sd.h"
#include "spi.h"


//CID_Reg *pCID;
//pCID = &SD_CID_infor;
//-----------------------------------
void SD_Init(void)
{
	
	SPI_init();
	SD_CS_PORT |= (1<<SD_CS_PIN);	//cs=1
	SD_CS_DDR |= (1<<SD_CS_PIN);	//cs pin output	
}
//------------------------------------
uint8_t SD_Reset(void)
{
	uint8_t retry = 0;
	uint8_t temp ,i;

	for (i=0; i<12; i++)
	{
		spiTransferByte(0xFF);
	}
	do
	{
		temp = SD_SendCommand(SD_GO_IDLE_STATE, 0);
		retry++;
		if(retry>200)
		{
			return ERROR;
		}
	}while(temp != SD_R1_IDLE_STATE);

	retry = 0;
	do
	{
		// initializing card for operation
		temp = SD_SendCommand(SD_SEND_OP_COND, 0);
		
		retry++;	// do retry counter
		if(retry>100) return ERROR;		
	}while(temp);
	return 0;	//初始化成功,返回0
}
//------------------------------------
uint8_t SD_SendCommand(uint8_t cmd, uint32_t arg)
{
	uint8_t temp;

	spiTransferByte(0xff);

	// assert chip select
	SD_CS_SELECT();

	// issue the command
	temp = SD_Command(cmd, arg);

	// release chip select
	SD_CS_RELEASE();

	spiTransferByte(0xff);	// extra 8 CLK
	return temp;
}

//--------------------------------------------
uint8_t SD_Command(uint8_t cmd, uint32_t arg)
{
	uint8_t temp;
	uint8_t retry=0;

	// send command,every command is 6 bytes long
	//|<---BYTE1---->|<------BYTE2~5------>|<----BYTE6------>|
	//|7 6|5        0|31                  0|7             1|0|
	//|0 1|-COMMAND--|---Command Argument--|----- CRC------|1|

	spiTransferByte(cmd | 0x40);	//send command
	spiTransferByte(arg>>24);
	spiTransferByte(arg>>16);
	spiTransferByte(arg>>8);
	spiTransferByte(arg);
	spiTransferByte(0x95);			//crc valid only for SD_GO_IDLE_STATE

	// end command
	// wait for response
	// if more than 8 retries, card has timed-out
	// return the received 0xFF
	while((temp = spiTransferByte(0xff)) == 0xff)
		if(retry++ > 8) break;

	// return response
	return temp;
}
//-------------------------------------------

uint8_t Read_SD_Reg(uint8_t *buffer,uint8_t CMD,uint8_t length)
{
	uint8_t temp,i;
	uint8_t retry;

	retry = 0;
	spiTransferByte(0xff);

	// assert chip select
	SD_CS_SELECT();
	do
	{
		temp = SD_Command(CMD, 0);	//read CID Register
		//temp = SD_Command(SD_SEND_CSD, 0);
		retry++;
		if (retry >200)
		{
		 	SD_CS_RELEASE();
			return ERROR;
		}
	}while(temp != 0x00);
	//--------------------------------
	if (CMD == SD_APP_CMD)
	{
		return 0;
	}
	//-------------------------------
	if (CMD != SD_READ_OCR)
		while((temp = spiTransferByte(0xff)) != 0xfe);	//wait for start byte

	for (i=0; i<length ;i++)
   	{
      	*buffer++ = spiTransferByte(0xff);
   	}
   	temp = spiTransferByte(0xff);	//crc1
   	temp = spiTransferByte(0xff);	//crc0

	// release chip select
	SD_CS_RELEASE();

	spiTransferByte(0xff);	// extra 8 CLK
	return 0;
}

uint8_t SD_ReadSingleBlock(uint32_t sector, uint8_t *buffer)
{
	uint16_t retry,i;
	uint8_t temp;
	retry = 0;
	spiTransferByte(0xff);

	// assert chip select
	SD_CS_SELECT();
	do
	{
		temp = SD_Command(SD_READ_SINGLE_BLOCK, (sector << 9));	//read singblock
		retry++;
		if (retry >200)
		{
		 	SD_CS_RELEASE();
			return ERROR;
		}
	}while(temp != 0x00);	//读到正确的回应

	retry = 0;
	while((temp = spiTransferByte(0xff)) != 0xfe)	//wait for start byte
	{
		if (retry++ >= 200)
		{
			SD_CS_RELEASE();
			return ERROR;
		}
	}

	for (i=0; i<512 ;i++)
   	{
      	*buffer++ = spiTransferByte(0xff);
	}
   	temp = spiTransferByte(0xff);	//crc1
   	temp = spiTransferByte(0xff);	//crc0

	// release chip select
	SD_CS_RELEASE();

	spiTransferByte(0xff);	// extra 8 CLK
	return 0;
}

//-----------------------------------------

void Get_SD_card_CID_Infor(unsigned char *tag_buf)
{
	SD_CID_infor.MID = tag_buf[0];
	SD_CID_infor.OID |= tag_buf[1];
	SD_CID_infor.OID <<= 8;
	SD_CID_infor.OID |= tag_buf[2];
	SD_CID_infor.PNM[0] = tag_buf[3];
	SD_CID_infor.PNM[1] = tag_buf[4];
	SD_CID_infor.PNM[2] = tag_buf[5];
	SD_CID_infor.PNM[3] = tag_buf[6];
	SD_CID_infor.PNM[4] = tag_buf[7];
	SD_CID_infor.PRV = tag_buf[8];
	SD_CID_infor.PSN[0] = tag_buf[9];
	SD_CID_infor.PSN[1] = tag_buf[10];
	SD_CID_infor.PSN[2] = tag_buf[11];
	SD_CID_infor.PSN[3] = tag_buf[12];
	SD_CID_infor.MDT |= tag_buf[13];
	SD_CID_infor.MDT <<= 8;
	SD_CID_infor.MDT |= tag_buf[14];
	SD_CID_infor.CID_CRC7 = tag_buf[15] & 0XFE;
}
//------------------------------------------
void Get_SD_card_CSD_Infor(unsigned char *tag_buf)
{
	SD_CSD_infor.CSD_STRUCTURE = tag_buf[0] >> 6;
	SD_CSD_infor.TAAC = tag_buf[1];
	SD_CSD_infor.NSAC = tag_buf[2];
	SD_CSD_infor.TRAN_SPEED = tag_buf[3];
	SD_CSD_infor.CCC |= tag_buf[4];
	SD_CSD_infor.CCC <<= 4;
	SD_CSD_infor.CCC |= (tag_buf[5] & 0XF0) >> 4;
	SD_CSD_infor.READ_BL_LEN = tag_buf[5] & 0X0F;
	SD_CSD_infor.READ_BL_PARTIAL = (tag_buf[6] & 0X80) >> 7;
	SD_CSD_infor.WRITE_BLK_MISALIGN = (tag_buf[6] & 0X40) >> 6;
	SD_CSD_infor.READ_BLK_MISALIGN = (tag_buf[6] & 0X20) >> 5;
	SD_CSD_infor.DSR_IMP = (tag_buf[6] & 0X10) >> 4;
	SD_CSD_infor.C_SIZE |= tag_buf[6];
	SD_CSD_infor.C_SIZE <<= 8;
	SD_CSD_infor.C_SIZE |= tag_buf[7];
	SD_CSD_infor.C_SIZE <<= 2;
	SD_CSD_infor.C_SIZE |= (tag_buf[8] >> 6) & 0x03;
	SD_CSD_infor.C_SIZE &= 0x0fff;
	SD_CSD_infor.VDD_R_CURR_MIN = (tag_buf[8] & 0x3f) >> 3;
	SD_CSD_infor.VDD_R_CURR_MAX = tag_buf[8] & 0x07;
	SD_CSD_infor.VDD_W_CURR_MIN = (tag_buf[9] & 0xe0) >> 5;
	SD_CSD_infor.VDD_W_CURR_MAX = (tag_buf[9] & 0x1f) >> 2;
	SD_CSD_infor.C_SIZE_MULT = (tag_buf[9] & 0x03) << 1;
	SD_CSD_infor.C_SIZE_MULT |= (tag_buf[10] & 0x80) >> 7;
	SD_CSD_infor.ERASE_BLK_EN = (tag_buf[10] & 0x40) >> 6;
	SD_CSD_infor.SECTOR_SIZE = (tag_buf[10] & 0x3f) << 1;
	SD_CSD_infor.SECTOR_SIZE |= (tag_buf[11] & 0x80) >> 7;
	SD_CSD_infor.WP_GRP_SIZE = tag_buf[11] & 0x7f;
	SD_CSD_infor.WP_GRP_ENABLE = (tag_buf[12] & 0x80) >> 7;
	SD_CSD_infor.R2W_FACTOR = (tag_buf[12] & 0x1f) >> 2;
	SD_CSD_infor.WRITE_BL_LEN = (tag_buf[12] & 0x03) << 2;
	SD_CSD_infor.WRITE_BL_LEN |= (tag_buf[13] & 0xc0) >> 6;
	SD_CSD_infor.WRITE_BL_PARTIAL = (tag_buf[13] & 0x20) >> 5;
	SD_CSD_infor.FILE_FORMAT_GRP = (tag_buf[14] & 0x80) >> 7;
	SD_CSD_infor.COPY = (tag_buf[14] & 0x40) >> 6;
	SD_CSD_infor.PERM_WRITE_PROTECT = (tag_buf[14] & 0x20) >> 5;
	SD_CSD_infor.TMP_WRITE_PROTECT = (tag_buf[14] & 0x10) >> 4;
	SD_CSD_infor.FILE_FORMAT = (tag_buf[14] & 0x0c) >> 2;
	SD_CSD_infor.CSD_CRC7 = tag_buf[15] & 0XFE;
}
//------------------------------------------
void Get_SD_card_OCR_Infor(unsigned char *tag_buf)
{
	SD_OCR_infor.OCR_3 = tag_buf[0];
	SD_OCR_infor.OCR_2 = tag_buf[1];
	SD_OCR_infor.OCR_1 = tag_buf[2];
	SD_OCR_infor.OCR_0 = tag_buf[3];
}
//-------------------------------------------
void Get_SD_card_SCR_Infor(unsigned char *tag_buf)
{
	SD_SCR_infor.SCR_STRUCTURE = (tag_buf[0] & 0Xf0) >> 4;
	SD_SCR_infor.SD_SPEC = tag_buf[0] & 0x0f;
	SD_SCR_infor.DATA_STAT_AFTER_ERASE = (tag_buf[1] & 0X80) >> 7;
	SD_SCR_infor.SD_SECURITY = (tag_buf[1] & 0X70) >> 4;
	SD_SCR_infor.SD_BUS_WIDTHS = tag_buf[1] & 0X0f;
}
//-------------------------------------------
void Get_SD_card_Volume_Infor(void)
{
	SD_CAPACITY_infor.Capacity = (((unsigned long int)SD_CSD_infor.C_SIZE+1) \
	<< (SD_CSD_infor.READ_BL_LEN + 2)) << SD_CSD_infor.C_SIZE_MULT;
	SD_CAPACITY_infor.size_MB = (unsigned int)(SD_CAPACITY_infor.Capacity >> 20);
}
//---------------------------------------------





⌨️ 快捷键说明

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