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

📄 sd.c

📁 ARM7 lpc2132+vs1003+sdcard 制作的 MP3 此程序在ADS1.2环境下编译
💻 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 + -