📄 sd.c
字号:
/****************************************Copyright (c)**************************************************
** 上海新时达电气有限公司
** 研 发 中 心
** 研发一部
**
** http://www.stepelevatar.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: sd.c
**创 建 人: 吕海安
**最后修改日期: 2007年05月31日
**描 述: SD 卡读写程序
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 吕海安
** 版 本: v1.0
** 日 期: 2007.07.03
** 描 述: 原始版本
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"
#include "vs1003.h"
#include "delay.h"
#include "sd.h"
INT8U BUFFER[512]; // 缓冲区
INT8U FlagReading = 0;
#define MMC_CS_PIN (1 << 22)
#define MMC_PORT_SET IO0SET
#define MMC_PORT_CLR IO0CLR
/*****************************************************************************************
* 名称:MMCCS
* 功能:SD卡芯片选择
* 输入:INT8U State:1,不选中
* 0,选中
* 返回:无
*****************************************************************************************/
void MMCCS(INT8U State)
{
if(State)
{
MMC_PORT_SET = MMC_CS_PIN;
}
else
{
MMC_PORT_CLR = MMC_CS_PIN;
}
}
/*****************************************************************************************
* 名称:MMCCS
* 功能:SD卡芯片选择
* 输入:INT8U State:1,不选中
* 0,选中
* 返回:无
*****************************************************************************************/
void sd_port_init()
{
MMCCS(1);
}
/*****************************************************************************************
* 名称:SD_Write_Command
* 功能:Send a Command to MMC/SD-Card
* 输入:INT8U cmd,
* INT32U arg
* 返回:temp : the second byte of response register of MMC/SD-Card
*****************************************************************************************/
INT8U SD_Write_Command(INT8U cmd,INT32U arg)
{
INT8U tmp = 0;
INT8U retry = 0;
MMCCS(1); // SD卡关闭
//send 8 Clock Impulse
Write_Byte_SPI(0xFF);
//set MMC_Chip_Select to low (MMC/SD-Card active)
MMCCS(0); // SD卡使能
Write_Byte_SPI(cmd | 0x40); // 送头命令
Write_Byte_SPI(arg>>24);
Write_Byte_SPI(arg>>16); // send 6 Byte Command to MMC/SD-Card
Write_Byte_SPI(arg>>8);
Write_Byte_SPI(arg&0xff);
Write_Byte_SPI(0x95); // 仅仅对RESET有效的CRC效验码
// get 8 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_SPI();
retry++;
}
while(((tmp & 0x80) != 0 ));//&& (retry < 100)); //当没有收到有效的命令的时候
if(FlagReading == 0)
{
MMCCS(1); // MMC_CS_PIN = 1;
}
else
{
MMCCS(0); // MMC_CS_PIN = 0;
}
return(tmp);
}
/*****************************************************************************************
* 名称:SD_Init
* 功能:SD卡初始化(SPI-MODE)
* 输入:无
* 返回:0:All commands have been taken
*****************************************************************************************/
INT8U SD_Init(void)
{
INT8U retry,temp;
INT8U i;
MMCCS(0); // SD卡使能
delay_nus(250); // Wait MMC/SD ready...
for (i=0; i<0x20; i++)
{
Write_Byte_SPI(0xff); // send 74 clock at least!!!
}
MMCCS(1);
for (i=0; i<0x2; i++)
{
Write_Byte_SPI(0xff); // send 8 clock at least!!!
}
// Send Command CMD0 to MMC/SD Card
retry = 0;
// retry 200 times to send CMD0 command
do
{
temp = SD_Write_Command(0,0);
retry++;
if(retry == 100)
{
retry = retry;// CMD0 Error!
}
}
while(temp != 1) ;
// Send Command CMD1 to MMC/SD-Card
retry = 0;
// retry 100 times to send CMD1 command
do
{
temp = SD_Write_Command(1,0);
retry++;
if(retry == 100)
{
retry = retry;
}
}
while(temp != 0);
retry = 0;
SD_Write_Command(16,512); // 设置一次读写BLOCK的长度为512个字节
MMCCS(1); // MMC_CS_PIN = 1;
// set MMC_Chip_Select to high
return(0); // All commands have been taken.
}
/*****************************************************************************************
* 名称:SD_Read_Block
* 功能:从SD卡读一个扇区
* 输入:INT32U address
* 返回:0:if no Error.
*****************************************************************************************/
INT8U SD_Read_Block(INT32U address)
{
INT8U temp = 0;
INT16U i = 0;
FlagReading = 1;
temp = SD_Write_Command(17,address); // 读出RESPONSE
while (Read_Byte_SPI()!= 0xfe)
{;} // 直到读取到了数据的开始头0XFE,才继续
for(i=0; i<512; i++)
{
BUFFER[i] = Read_Byte_SPI();
}
Read_Byte_SPI(); // CRC - Byte
Read_Byte_SPI(); // CRC - Byte
FlagReading = 0;
MMCCS(1); // 关闭SD卡
return(temp);
}
/*****************************************************************************************
* 名称:SD_Read_Block2
* 功能:从SD卡读一个扇区
* 输入:INT32U address,
* INT8U *buf
* 返回:0:if no Error.
*****************************************************************************************/
INT8U SD_Read_Block2(INT32U address,INT8U *buf)
{
INT8U temp = 0;
INT16U i = 0;
FlagReading = 1;
temp = SD_Write_Command(17,address); // 读出RESPONSE
while (Read_Byte_SPI()!= 0xfe)
{;} // 直到读取到了数据的开始头0XFE,才继续
for(i=0; i<512; i++)
{
buf[i] = Read_Byte_SPI();
}
Read_Byte_SPI(); // CRC - Byte
Read_Byte_SPI(); // CRC - Byte
FlagReading = 0;
MMCCS(1); // 关闭SD卡
return(temp);
}
/*****************************************************************************************
* 名称:SD_Read_Word
* 功能:从SD卡读一个扇区的偏移个字节
* 输入:INT32U address,
* INT16U offset
* 返回:读出的数据
*****************************************************************************************/
INT16U SD_Read_Word(INT32U address,INT16U offset)
{
INT8U temp = 0;
INT16U i = 0;
INT8U k = 0;
INT8U buf[2];
FlagReading = 1;
temp = SD_Write_Command(17,address<<9); // 读出RESPONSE
while (Read_Byte_SPI()!= 0xfe); // 直到读取到了数据的开始头0XFE,才继续
for(i=0; i<offset; i++) Read_Byte_SPI();
for(; i<offset+2; i++) buf[k++] = Read_Byte_SPI();
for(; i<512; i++) Read_Byte_SPI();
Read_Byte_SPI(); // CRC - Byte
Read_Byte_SPI(); // CRC - Byte
FlagReading = 0;
MMCCS(1); // 关闭SD卡
// SD_Write_Command(12,0);
return (*((INT16U*) &((INT8S*)buf)[0])) ;
}
/*****************************************************************************************
* 名称:SD_Read_Word
* 功能:连续读取指定扇区offset偏移位置,bytes个数据
* 输入:INT32U address,
* INT8U *buf,
* INT16U offset,
* INT16U bytes
* 返回:无
*****************************************************************************************/
void SD_Read_Bytes(INT32U address,INT8U *buf,INT16U offset,INT16U bytes)
{
INT8U temp = 0;
INT16U i = 0;
FlagReading = 1;
temp = SD_Write_Command(17,address<<9); // 读出RESPONSE
while (Read_Byte_SPI()!= 0xfe)
{;} // 直到读取到了数据的开始头0XFE,才继续
for(i=0; i<offset; i++) Read_Byte_SPI();
for(; i<offset+bytes; i++) *buf++ = Read_Byte_SPI();
for(; i<512; i++) Read_Byte_SPI();
Read_Byte_SPI();
Read_Byte_SPI();
FlagReading = 0;
MMCCS(1); // 关闭SD卡
}
/*****************************************************************************************
* 名称:SD_Read_Dword
* 功能:连续读取指定扇区offset偏移位置
* 输入:INT32U address,
* INT16U offset
* 返回:读出的数据
*****************************************************************************************/
INT32U SD_Read_Dword(INT32U address,INT16U offset)
{
INT8U temp = 0;
INT16U i = 0;
INT8U k = 0;
INT8U buf[4];
FlagReading = 1;
temp = SD_Write_Command(17,address<<9); // 读出RESPONSE
while (Read_Byte_SPI()!= 0xfe)
{;} // 直到读取到了数据的开始头0XFE,才继续
for(i=0; i<offset; i++) Read_Byte_SPI();
for(; i<offset+4; i++) buf[k++] = Read_Byte_SPI();
for(; i<512; i++) Read_Byte_SPI();
Read_Byte_SPI();
Read_Byte_SPI();
FlagReading = 0;
MMCCS(1); // 关闭SD卡
// SD_Write_Command(12,0);
return (*((INT32U*) &((INT8S*)buf)[0])) ;
}
/*****************************************************************************************
* END OF FILE
*****************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -